1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 22:33:35 +00:00

[PM-17747] - remove emergency access attachments dialog. fix 404 (#13854)

* remove emergency access attachments dialog. fix 404

* fix types

* fix type issue
This commit is contained in:
Jordan Aasen
2025-04-01 16:48:41 -07:00
committed by GitHub
parent 84b179f53a
commit afcb656d12
12 changed files with 37 additions and 133 deletions

View File

@@ -1,66 +0,0 @@
import { Component } from "@angular/core";
import { AttachmentsComponent as BaseAttachmentsComponent } from "@bitwarden/angular/vault/components/attachments.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view";
import { DialogService, ToastService } from "@bitwarden/components";
import { KeyService } from "@bitwarden/key-management";
@Component({
selector: "emergency-access-attachments",
templateUrl: "../../../../vault/individual-vault/attachments.component.html",
})
export class EmergencyAccessAttachmentsComponent extends BaseAttachmentsComponent {
viewOnly = true;
canAccessAttachments = true;
constructor(
cipherService: CipherService,
i18nService: I18nService,
keyService: KeyService,
encryptService: EncryptService,
stateService: StateService,
platformUtilsService: PlatformUtilsService,
apiService: ApiService,
logService: LogService,
fileDownloadService: FileDownloadService,
dialogService: DialogService,
billingAccountProfileStateService: BillingAccountProfileStateService,
accountService: AccountService,
toastService: ToastService,
) {
super(
cipherService,
i18nService,
keyService,
encryptService,
platformUtilsService,
apiService,
window,
logService,
stateService,
fileDownloadService,
dialogService,
billingAccountProfileStateService,
accountService,
toastService,
);
}
protected async init() {
// Do nothing since cipher is already decoded
}
protected showFixOldAttachments(attachment: AttachmentView) {
return false;
}
}

View File

@@ -38,28 +38,6 @@
<br /> <br />
<small class="tw-text-xs">{{ currentCipher.subTitle }}</small> <small class="tw-text-xs">{{ currentCipher.subTitle }}</small>
</td> </td>
<td bitCell>
<div *ngIf="currentCipher.hasAttachments">
<button
[bitMenuTriggerFor]="optionsMenu"
type="button"
buttonType="main"
bitIconButton="bwi-ellipsis-v"
appA11yTitle="{{ 'options' | i18n }}"
></button>
<bit-menu #optionsMenu>
<button
type="button"
bitMenuItem
appStopClick
(click)="viewAttachments(currentCipher)"
>
<i class="bwi bwi-fw bwi-paperclip" aria-hidden="true"></i>
{{ "attachments" | i18n }}
</button>
</bit-menu>
</div>
</td>
</tr> </tr>
</ng-template> </ng-template>
</bit-table> </bit-table>

View File

@@ -1,15 +1,13 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
import { ModalService } from "@bitwarden/angular/services/modal.service"; import { EmergencyAccessId } from "@bitwarden/common/types/guid";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { DialogService } from "@bitwarden/components"; import { DialogService } from "@bitwarden/components";
import { CipherFormConfigService, DefaultCipherFormConfigService } from "@bitwarden/vault"; import { CipherFormConfigService, DefaultCipherFormConfigService } from "@bitwarden/vault";
import { EmergencyAccessService } from "../../../emergency-access"; import { EmergencyAccessService } from "../../../emergency-access";
import { EmergencyAccessAttachmentsComponent } from "../attachments/emergency-access-attachments.component";
import { EmergencyViewDialogComponent } from "./emergency-view-dialog.component"; import { EmergencyViewDialogComponent } from "./emergency-view-dialog.component";
@@ -20,56 +18,34 @@ import { EmergencyViewDialogComponent } from "./emergency-view-dialog.component"
}) })
export class EmergencyAccessViewComponent implements OnInit { export class EmergencyAccessViewComponent implements OnInit {
@ViewChild("attachments", { read: ViewContainerRef, static: true }) @ViewChild("attachments", { read: ViewContainerRef, static: true })
attachmentsModalRef: ViewContainerRef; id: EmergencyAccessId | null = null;
id: string;
ciphers: CipherView[] = []; ciphers: CipherView[] = [];
loaded = false; loaded = false;
constructor( constructor(
private modalService: ModalService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute,
private emergencyAccessService: EmergencyAccessService, private emergencyAccessService: EmergencyAccessService,
private dialogService: DialogService, private dialogService: DialogService,
) {} ) {}
ngOnInit() { async ngOnInit() {
// eslint-disable-next-line rxjs-angular/prefer-takeuntil const qParams = await firstValueFrom(this.route.params);
this.route.params.subscribe((qParams) => {
if (qParams.id == null) { if (qParams.id == null) {
return this.router.navigate(["settings/emergency-access"]); await this.router.navigate(["settings/emergency-access"]);
return;
} }
this.id = qParams.id; this.id = qParams.id;
this.ciphers = await this.emergencyAccessService.getViewOnlyCiphers(qParams.id);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. this.loaded = true;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.load();
});
} }
async selectCipher(cipher: CipherView) { async selectCipher(cipher: CipherView) {
EmergencyViewDialogComponent.open(this.dialogService, { EmergencyViewDialogComponent.open(this.dialogService, {
cipher, cipher,
emergencyAccessId: this.id!,
}); });
return; return;
} }
async load() {
this.ciphers = await this.emergencyAccessService.getViewOnlyCiphers(this.id);
this.loaded = true;
}
// FIXME PM-17747: This will also need to be replaced with the new AttachmentViewDialog
async viewAttachments(cipher: CipherView) {
await this.modalService.openViewRef(
EmergencyAccessAttachmentsComponent,
this.attachmentsModalRef,
(comp) => {
comp.cipher = cipher;
comp.emergencyAccessId = this.id;
},
);
}
} }

View File

@@ -3,7 +3,7 @@
{{ title }} {{ title }}
</span> </span>
<div bitDialogContent #dialogContent> <div bitDialogContent #dialogContent>
<app-cipher-view [cipher]="cipher"></app-cipher-view> <app-cipher-view [emergencyAccessId]="emergencyAccessId" [cipher]="cipher"></app-cipher-view>
</div> </div>
<ng-container bitDialogFooter> <ng-container bitDialogFooter>
<button bitButton type="button" buttonType="secondary" (click)="cancel()"> <button bitButton type="button" buttonType="secondary" (click)="cancel()">

View File

@@ -4,6 +4,7 @@ import { Component, Inject } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module"; import { JslibModule } from "@bitwarden/angular/jslib.module";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { EmergencyAccessId } from "@bitwarden/common/types/guid";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service"; import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service";
import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherType } from "@bitwarden/common/vault/enums";
@@ -20,6 +21,7 @@ import { WebViewPasswordHistoryService } from "../../../../vault/services/web-vi
export interface EmergencyViewDialogParams { export interface EmergencyViewDialogParams {
/** The cipher being viewed. */ /** The cipher being viewed. */
cipher: CipherView; cipher: CipherView;
emergencyAccessId: EmergencyAccessId;
} }
/** Stubbed class, premium upgrade is not applicable for emergency viewing */ /** Stubbed class, premium upgrade is not applicable for emergency viewing */
@@ -59,6 +61,10 @@ export class EmergencyViewDialogComponent {
return this.params.cipher; return this.params.cipher;
} }
get emergencyAccessId(): EmergencyAccessId {
return this.params.emergencyAccessId;
}
cancel = () => { cancel = () => {
this.dialogRef.close(); this.dialogRef.close();
}; };

View File

@@ -23,7 +23,6 @@ import { DangerZoneComponent } from "../auth/settings/account/danger-zone.compon
import { DeauthorizeSessionsComponent } from "../auth/settings/account/deauthorize-sessions.component"; import { DeauthorizeSessionsComponent } from "../auth/settings/account/deauthorize-sessions.component";
import { DeleteAccountDialogComponent } from "../auth/settings/account/delete-account-dialog.component"; import { DeleteAccountDialogComponent } from "../auth/settings/account/delete-account-dialog.component";
import { ProfileComponent } from "../auth/settings/account/profile.component"; import { ProfileComponent } from "../auth/settings/account/profile.component";
import { EmergencyAccessAttachmentsComponent } from "../auth/settings/emergency-access/attachments/emergency-access-attachments.component";
import { EmergencyAccessConfirmComponent } from "../auth/settings/emergency-access/confirm/emergency-access-confirm.component"; import { EmergencyAccessConfirmComponent } from "../auth/settings/emergency-access/confirm/emergency-access-confirm.component";
import { EmergencyAccessAddEditComponent } from "../auth/settings/emergency-access/emergency-access-add-edit.component"; import { EmergencyAccessAddEditComponent } from "../auth/settings/emergency-access/emergency-access-add-edit.component";
import { EmergencyAccessComponent } from "../auth/settings/emergency-access/emergency-access.component"; import { EmergencyAccessComponent } from "../auth/settings/emergency-access/emergency-access.component";
@@ -115,7 +114,6 @@ import { SharedModule } from "./shared.module";
DeleteAccountDialogComponent, DeleteAccountDialogComponent,
DomainRulesComponent, DomainRulesComponent,
EmergencyAccessAddEditComponent, EmergencyAccessAddEditComponent,
EmergencyAccessAttachmentsComponent,
EmergencyAccessComponent, EmergencyAccessComponent,
EmergencyAccessConfirmComponent, EmergencyAccessConfirmComponent,
EmergencyAccessTakeoverComponent, EmergencyAccessTakeoverComponent,
@@ -173,7 +171,6 @@ import { SharedModule } from "./shared.module";
DomainRulesComponent, DomainRulesComponent,
DynamicAvatarComponent, DynamicAvatarComponent,
EmergencyAccessAddEditComponent, EmergencyAccessAddEditComponent,
EmergencyAccessAttachmentsComponent,
EmergencyAccessComponent, EmergencyAccessComponent,
EmergencyAccessConfirmComponent, EmergencyAccessConfirmComponent,
EmergencyAccessTakeoverComponent, EmergencyAccessTakeoverComponent,

View File

@@ -12,3 +12,4 @@ export type SendId = Opaque<string, "SendId">;
export type IndexedEntityId = Opaque<string, "IndexedEntityId">; export type IndexedEntityId = Opaque<string, "IndexedEntityId">;
export type SecurityTaskId = Opaque<string, "SecurityTaskId">; export type SecurityTaskId = Opaque<string, "SecurityTaskId">;
export type NotificationId = Opaque<string, "NotificationId">; export type NotificationId = Opaque<string, "NotificationId">;
export type EmergencyAccessId = Opaque<string, "EmergencyAccessId">;

View File

@@ -14,6 +14,7 @@
[cipher]="cipher" [cipher]="cipher"
[attachment]="attachment" [attachment]="attachment"
[checkPwReprompt]="true" [checkPwReprompt]="true"
[emergencyAccessId]="emergencyAccessId"
></app-download-attachment> ></app-download-attachment>
</bit-item-action> </bit-item-action>
</ng-container> </ng-container>

View File

@@ -9,7 +9,7 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { StateProvider } from "@bitwarden/common/platform/state"; import { StateProvider } from "@bitwarden/common/platform/state";
import { OrganizationId } from "@bitwarden/common/types/guid"; import { EmergencyAccessId, OrganizationId } from "@bitwarden/common/types/guid";
import { OrgKey } from "@bitwarden/common/types/key"; import { OrgKey } from "@bitwarden/common/types/key";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { import {
@@ -41,6 +41,9 @@ import { DownloadAttachmentComponent } from "../../components/download-attachmen
export class AttachmentsV2ViewComponent { export class AttachmentsV2ViewComponent {
@Input() cipher: CipherView; @Input() cipher: CipherView;
// Required for fetching attachment data when viewed from cipher via emergency access
@Input() emergencyAccessId?: EmergencyAccessId;
canAccessPremium: boolean; canAccessPremium: boolean;
orgKey: OrgKey; orgKey: OrgKey;

View File

@@ -76,7 +76,8 @@
<!-- ATTACHMENTS SECTION --> <!-- ATTACHMENTS SECTION -->
<ng-container *ngIf="cipher.attachments"> <ng-container *ngIf="cipher.attachments">
<app-attachments-v2-view [cipher]="cipher"> </app-attachments-v2-view> <app-attachments-v2-view [emergencyAccessId]="emergencyAccessId" [cipher]="cipher">
</app-attachments-v2-view>
</ng-container> </ng-container>
<!-- ITEM HISTORY SECTION --> <!-- ITEM HISTORY SECTION -->

View File

@@ -15,7 +15,7 @@ import { isCardExpired } from "@bitwarden/common/autofill/utils";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { CipherId, CollectionId, UserId } from "@bitwarden/common/types/guid"; import { CipherId, CollectionId, EmergencyAccessId, UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@@ -61,6 +61,9 @@ import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-ide
export class CipherViewComponent implements OnChanges, OnDestroy { export class CipherViewComponent implements OnChanges, OnDestroy {
@Input({ required: true }) cipher: CipherView | null = null; @Input({ required: true }) cipher: CipherView | null = null;
// Required for fetching attachment data when viewed from cipher via emergency access
@Input() emergencyAccessId?: EmergencyAccessId;
activeUserId$ = getUserId(this.accountService.activeAccount$); activeUserId$ = getUserId(this.accountService.activeAccount$);
/** /**

View File

@@ -13,7 +13,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
import { StateProvider } from "@bitwarden/common/platform/state"; import { StateProvider } from "@bitwarden/common/platform/state";
import { OrganizationId } from "@bitwarden/common/types/guid"; import { EmergencyAccessId, OrganizationId } from "@bitwarden/common/types/guid";
import { OrgKey } from "@bitwarden/common/types/key"; import { OrgKey } from "@bitwarden/common/types/key";
import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view"; import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.view";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@@ -36,6 +36,9 @@ export class DownloadAttachmentComponent {
// When in view mode, we will want to check for the master password reprompt // When in view mode, we will want to check for the master password reprompt
@Input() checkPwReprompt?: boolean = false; @Input() checkPwReprompt?: boolean = false;
// Required for fetching attachment data when viewed from cipher via emergency access
@Input() emergencyAccessId?: EmergencyAccessId;
/** The organization key if the cipher is associated with one */ /** The organization key if the cipher is associated with one */
private orgKey: OrgKey | null = null; private orgKey: OrgKey | null = null;
@@ -68,6 +71,7 @@ export class DownloadAttachmentComponent {
const attachmentDownloadResponse = await this.apiService.getAttachmentData( const attachmentDownloadResponse = await this.apiService.getAttachmentData(
this.cipher.id, this.cipher.id,
this.attachment.id, this.attachment.id,
this.emergencyAccessId,
); );
url = attachmentDownloadResponse.url; url = attachmentDownloadResponse.url;
} catch (e) { } catch (e) {