mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 16:53:34 +00:00
[PM-18520] - Update desktop cipher forms to use the same UI as web app and extension - (#13992)
* WIP - cipher form refactor * cipher clone * cipher clone * finalize item view and form changes * fix tests * hide changes behind feature flag * set flag to false * create vault items v2. add button selector * revert change to flag and vault items * add attachments * revert change to tsconfig * move module * fix modules * cleanup * fix import * fix import * fix import * remove showForm * update feature flag * wip - cleanup * fix up services * cleanup * fix type errors * fix lint errors * add dialog component * revert changes to menu * revert changes to menu * fix vault-items-v2 * set feature flag to FALSE * add missing i18n keys. fix collection state * remove generator. update modules. bug fix * fix restricted imports * mark method as deprecated. add uri arg back * fix shared.module * fix shared.module * fix shared.module * add uri * check and prompt for premium when opening attachments dialog * move VaultItemDialogResult back * fix import in spec file * update copy functions * fix MP reprompt issue
This commit is contained in:
@@ -69,6 +69,8 @@ import {
|
||||
ToastService,
|
||||
} from "@bitwarden/components";
|
||||
import {
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
CipherFormConfig,
|
||||
CipherFormConfigService,
|
||||
CollectionAssignmentResult,
|
||||
@@ -92,10 +94,6 @@ import {
|
||||
} from "../../../vault/components/vault-item-dialog/vault-item-dialog.component";
|
||||
import { VaultItemEvent } from "../../../vault/components/vault-items/vault-item-event";
|
||||
import { VaultItemsModule } from "../../../vault/components/vault-items/vault-items.module";
|
||||
import {
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
} from "../../../vault/individual-vault/attachments-v2.component";
|
||||
import {
|
||||
BulkDeleteDialogResult,
|
||||
openBulkDeleteDialog,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { VaultViewPasswordHistoryService } from "@bitwarden/angular/services/view-password-history.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";
|
||||
@@ -21,8 +22,6 @@ import {
|
||||
DefaultChangeLoginPasswordService,
|
||||
} from "@bitwarden/vault";
|
||||
|
||||
import { WebViewPasswordHistoryService } from "../../../../vault/services/web-view-password-history.service";
|
||||
|
||||
export interface EmergencyViewDialogParams {
|
||||
/** The cipher being viewed. */
|
||||
cipher: CipherView;
|
||||
@@ -42,7 +41,7 @@ class PremiumUpgradePromptNoop implements PremiumUpgradePromptService {
|
||||
standalone: true,
|
||||
imports: [ButtonModule, CipherViewComponent, DialogModule, CommonModule, JslibModule],
|
||||
providers: [
|
||||
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
||||
{ provide: ViewPasswordHistoryService, useClass: VaultViewPasswordHistoryService },
|
||||
{ provide: PremiumUpgradePromptService, useClass: PremiumUpgradePromptNoop },
|
||||
{ provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService },
|
||||
],
|
||||
|
||||
@@ -7,6 +7,7 @@ import { firstValueFrom, Subject, switchMap } from "rxjs";
|
||||
import { map } from "rxjs/operators";
|
||||
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { VaultViewPasswordHistoryService } from "@bitwarden/angular/services/view-password-history.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
@@ -39,6 +40,9 @@ import {
|
||||
ToastService,
|
||||
} from "@bitwarden/components";
|
||||
import {
|
||||
AttachmentDialogCloseResult,
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
ChangeLoginPasswordService,
|
||||
CipherFormComponent,
|
||||
CipherFormConfig,
|
||||
@@ -50,16 +54,10 @@ import {
|
||||
} from "@bitwarden/vault";
|
||||
|
||||
import { SharedModule } from "../../../shared/shared.module";
|
||||
import {
|
||||
AttachmentDialogCloseResult,
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
} from "../../individual-vault/attachments-v2.component";
|
||||
import { WebVaultPremiumUpgradePromptService } from "../../../vault/services/web-premium-upgrade-prompt.service";
|
||||
import { RoutedVaultFilterService } from "../../individual-vault/vault-filter/services/routed-vault-filter.service";
|
||||
import { RoutedVaultFilterModel } from "../../individual-vault/vault-filter/shared/models/routed-vault-filter.model";
|
||||
import { WebCipherFormGenerationService } from "../../services/web-cipher-form-generation.service";
|
||||
import { WebVaultPremiumUpgradePromptService } from "../../services/web-premium-upgrade-prompt.service";
|
||||
import { WebViewPasswordHistoryService } from "../../services/web-view-password-history.service";
|
||||
|
||||
export type VaultItemDialogMode = "view" | "form";
|
||||
|
||||
@@ -135,7 +133,7 @@ export enum VaultItemDialogResult {
|
||||
],
|
||||
providers: [
|
||||
{ provide: PremiumUpgradePromptService, useClass: WebVaultPremiumUpgradePromptService },
|
||||
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
||||
{ provide: ViewPasswordHistoryService, useClass: VaultViewPasswordHistoryService },
|
||||
{ provide: CipherFormGenerationService, useClass: WebCipherFormGenerationService },
|
||||
RoutedVaultFilterService,
|
||||
{ provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService },
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
ItemModule,
|
||||
} from "@bitwarden/components";
|
||||
import {
|
||||
AttachmentsV2Component,
|
||||
CipherAttachmentsComponent,
|
||||
CipherFormConfig,
|
||||
CipherFormGenerationService,
|
||||
@@ -31,8 +32,6 @@ import {
|
||||
import { SharedModule } from "../../shared/shared.module";
|
||||
import { WebCipherFormGenerationService } from "../services/web-cipher-form-generation.service";
|
||||
|
||||
import { AttachmentsV2Component } from "./attachments-v2.component";
|
||||
|
||||
/**
|
||||
* The result of the AddEditCipherDialogV2 component.
|
||||
*/
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<bit-dialog dialogSize="default" background="alt">
|
||||
<span bitDialogTitle>
|
||||
{{ "attachments" | i18n }}
|
||||
</span>
|
||||
<ng-container bitDialogContent>
|
||||
<app-cipher-attachments
|
||||
*ngIf="cipherId"
|
||||
[cipherId]="cipherId"
|
||||
[submitBtn]="submitBtn"
|
||||
(onUploadSuccess)="uploadSuccessful()"
|
||||
(onRemoveSuccess)="removalSuccessful()"
|
||||
></app-cipher-attachments>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton type="submit" buttonType="primary" [attr.form]="attachmentFormId" #submitBtn>
|
||||
{{ "upload" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
@@ -1,65 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { CipherId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { DIALOG_DATA, DialogRef } from "@bitwarden/components";
|
||||
|
||||
import {
|
||||
AttachmentsV2Component,
|
||||
AttachmentDialogResult,
|
||||
AttachmentsDialogParams,
|
||||
} from "./attachments-v2.component";
|
||||
|
||||
describe("AttachmentsV2Component", () => {
|
||||
let component: AttachmentsV2Component;
|
||||
let fixture: ComponentFixture<AttachmentsV2Component>;
|
||||
|
||||
const mockCipherId: CipherId = "cipher-id" as CipherId;
|
||||
const mockParams: AttachmentsDialogParams = {
|
||||
cipherId: mockCipherId,
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AttachmentsV2Component, NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DIALOG_DATA, useValue: mockParams },
|
||||
{ provide: DialogRef, useValue: mock<DialogRef>() },
|
||||
{ provide: I18nService, useValue: mock<I18nService>() },
|
||||
{ provide: CipherService, useValue: mock<CipherService>() },
|
||||
{ provide: LogService, useValue: mock<LogService>() },
|
||||
{ provide: AccountService, useValue: mock<AccountService>() },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(AttachmentsV2Component);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it("initializes without errors and with the correct cipherId", () => {
|
||||
expect(component).toBeTruthy();
|
||||
expect(component.cipherId).toBe(mockParams.cipherId);
|
||||
});
|
||||
|
||||
it("closes the dialog with 'uploaded' result on uploadSuccessful", () => {
|
||||
const dialogRefCloseSpy = jest.spyOn(component["dialogRef"], "close");
|
||||
|
||||
component.uploadSuccessful();
|
||||
|
||||
expect(dialogRefCloseSpy).toHaveBeenCalledWith({ action: AttachmentDialogResult.Uploaded });
|
||||
});
|
||||
|
||||
it("closes the dialog with 'removed' result on removalSuccessful", () => {
|
||||
const dialogRefCloseSpy = jest.spyOn(component["dialogRef"], "close");
|
||||
|
||||
component.removalSuccessful();
|
||||
|
||||
expect(dialogRefCloseSpy).toHaveBeenCalledWith({ action: AttachmentDialogResult.Removed });
|
||||
});
|
||||
});
|
||||
@@ -1,88 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
|
||||
import { CipherId } from "@bitwarden/common/types/guid";
|
||||
import { DialogRef, DIALOG_DATA, DialogService } from "@bitwarden/components";
|
||||
import { CipherAttachmentsComponent } from "@bitwarden/vault";
|
||||
|
||||
import { SharedModule } from "../../shared/shared.module";
|
||||
|
||||
export interface AttachmentsDialogParams {
|
||||
cipherId: CipherId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the possible results of the attachment dialog.
|
||||
*/
|
||||
export enum AttachmentDialogResult {
|
||||
Uploaded = "uploaded",
|
||||
Removed = "removed",
|
||||
Closed = "closed",
|
||||
}
|
||||
|
||||
export interface AttachmentDialogCloseResult {
|
||||
action: AttachmentDialogResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component for the attachments dialog.
|
||||
*/
|
||||
@Component({
|
||||
selector: "app-vault-attachments-v2",
|
||||
templateUrl: "attachments-v2.component.html",
|
||||
standalone: true,
|
||||
imports: [CommonModule, SharedModule, CipherAttachmentsComponent],
|
||||
})
|
||||
export class AttachmentsV2Component {
|
||||
cipherId: CipherId;
|
||||
attachmentFormId = CipherAttachmentsComponent.attachmentFormID;
|
||||
|
||||
/**
|
||||
* Constructor for AttachmentsV2Component.
|
||||
* @param dialogRef - Reference to the dialog.
|
||||
* @param params - Parameters passed to the dialog.
|
||||
*/
|
||||
constructor(
|
||||
private dialogRef: DialogRef<AttachmentDialogCloseResult>,
|
||||
@Inject(DIALOG_DATA) public params: AttachmentsDialogParams,
|
||||
) {
|
||||
this.cipherId = params.cipherId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the attachments dialog.
|
||||
* @param dialogService - The dialog service.
|
||||
* @param params - The parameters for the dialog.
|
||||
* @returns The dialog reference.
|
||||
*/
|
||||
static open(
|
||||
dialogService: DialogService,
|
||||
params: AttachmentsDialogParams,
|
||||
): DialogRef<AttachmentDialogCloseResult> {
|
||||
return dialogService.open(AttachmentsV2Component, {
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an attachment is successfully uploaded.
|
||||
* Closes the dialog with an 'uploaded' result.
|
||||
*/
|
||||
uploadSuccessful() {
|
||||
this.dialogRef.close({
|
||||
action: AttachmentDialogResult.Uploaded,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an attachment is successfully removed.
|
||||
* Closes the dialog with a 'removed' result.
|
||||
*/
|
||||
removalSuccessful() {
|
||||
this.dialogRef.close({
|
||||
action: AttachmentDialogResult.Removed,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<bit-dialog background="alt">
|
||||
<span bitDialogTitle>
|
||||
{{ "passwordHistory" | i18n }}
|
||||
</span>
|
||||
<ng-container bitDialogContent>
|
||||
<vault-password-history-view [cipher]="cipher" />
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton (click)="close()" buttonType="primary" type="button">
|
||||
{{ "close" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
@@ -1,78 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Inject, Component } from "@angular/core";
|
||||
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import {
|
||||
DIALOG_DATA,
|
||||
DialogConfig,
|
||||
DialogRef,
|
||||
AsyncActionsModule,
|
||||
DialogModule,
|
||||
DialogService,
|
||||
} from "@bitwarden/components";
|
||||
import { PasswordHistoryViewComponent } from "@bitwarden/vault";
|
||||
|
||||
import { SharedModule } from "../../shared/shared.module";
|
||||
|
||||
/**
|
||||
* The parameters for the password history dialog.
|
||||
*/
|
||||
export interface ViewPasswordHistoryDialogParams {
|
||||
cipher: CipherView;
|
||||
}
|
||||
|
||||
/**
|
||||
* A dialog component that displays the password history for a cipher.
|
||||
*/
|
||||
@Component({
|
||||
selector: "app-vault-password-history",
|
||||
templateUrl: "password-history.component.html",
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
AsyncActionsModule,
|
||||
DialogModule,
|
||||
SharedModule,
|
||||
PasswordHistoryViewComponent,
|
||||
],
|
||||
})
|
||||
export class PasswordHistoryComponent {
|
||||
/**
|
||||
* The cipher to display the password history for.
|
||||
*/
|
||||
cipher: CipherView;
|
||||
|
||||
/**
|
||||
* The constructor for the password history dialog component.
|
||||
* @param params The parameters passed to the password history dialog.
|
||||
* @param dialogRef The dialog reference - used to close the dialog.
|
||||
**/
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) public params: ViewPasswordHistoryDialogParams,
|
||||
private dialogRef: DialogRef<PasswordHistoryComponent>,
|
||||
) {
|
||||
/**
|
||||
* Set the cipher from the parameters.
|
||||
*/
|
||||
this.cipher = params.cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the password history dialog.
|
||||
*/
|
||||
close() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strongly typed wrapper around the dialog service to open the password history dialog.
|
||||
*/
|
||||
export function openPasswordHistoryDialog(
|
||||
dialogService: DialogService,
|
||||
config: DialogConfig<ViewPasswordHistoryDialogParams>,
|
||||
) {
|
||||
return dialogService.open(PasswordHistoryComponent, config);
|
||||
}
|
||||
@@ -69,6 +69,9 @@ import { DialogRef, DialogService, Icons, ToastService } from "@bitwarden/compon
|
||||
import {
|
||||
AddEditFolderDialogComponent,
|
||||
AddEditFolderDialogResult,
|
||||
AttachmentDialogCloseResult,
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
CipherFormConfig,
|
||||
CollectionAssignmentResult,
|
||||
DecryptionFailureDialogComponent,
|
||||
@@ -96,11 +99,6 @@ import { VaultItem } from "../components/vault-items/vault-item";
|
||||
import { VaultItemEvent } from "../components/vault-items/vault-item-event";
|
||||
import { VaultItemsModule } from "../components/vault-items/vault-items.module";
|
||||
|
||||
import {
|
||||
AttachmentDialogCloseResult,
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
} from "./attachments-v2.component";
|
||||
import {
|
||||
BulkDeleteDialogResult,
|
||||
openBulkDeleteDialog,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Component, EventEmitter, Inject, OnInit } from "@angular/core";
|
||||
import { firstValueFrom, map, Observable } from "rxjs";
|
||||
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { VaultViewPasswordHistoryService } from "@bitwarden/angular/services/view-password-history.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
@@ -21,8 +22,8 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
|
||||
import {
|
||||
DIALOG_DATA,
|
||||
DialogConfig,
|
||||
DialogRef,
|
||||
DialogConfig,
|
||||
AsyncActionsModule,
|
||||
DialogModule,
|
||||
DialogService,
|
||||
@@ -31,8 +32,7 @@ import {
|
||||
import { CipherViewComponent } from "@bitwarden/vault";
|
||||
|
||||
import { SharedModule } from "../../shared/shared.module";
|
||||
import { WebVaultPremiumUpgradePromptService } from "../services/web-premium-upgrade-prompt.service";
|
||||
import { WebViewPasswordHistoryService } from "../services/web-view-password-history.service";
|
||||
import { WebVaultPremiumUpgradePromptService } from "../../vault/services/web-premium-upgrade-prompt.service";
|
||||
|
||||
export interface ViewCipherDialogParams {
|
||||
cipher: CipherView;
|
||||
@@ -74,7 +74,7 @@ export interface ViewCipherDialogCloseResult {
|
||||
standalone: true,
|
||||
imports: [CipherViewComponent, CommonModule, AsyncActionsModule, DialogModule, SharedModule],
|
||||
providers: [
|
||||
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
||||
{ provide: ViewPasswordHistoryService, useClass: VaultViewPasswordHistoryService },
|
||||
{ provide: PremiumUpgradePromptService, useClass: WebVaultPremiumUpgradePromptService },
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Overlay } from "@angular/cdk/overlay";
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { openPasswordHistoryDialog } from "../individual-vault/password-history.component";
|
||||
|
||||
import { WebViewPasswordHistoryService } from "./web-view-password-history.service";
|
||||
|
||||
jest.mock("../individual-vault/password-history.component", () => ({
|
||||
openPasswordHistoryDialog: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("WebViewPasswordHistoryService", () => {
|
||||
let service: WebViewPasswordHistoryService;
|
||||
let dialogService: DialogService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const mockDialogService = {
|
||||
open: jest.fn(),
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
providers: [
|
||||
WebViewPasswordHistoryService,
|
||||
{ provide: DialogService, useValue: mockDialogService },
|
||||
Overlay,
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
service = TestBed.inject(WebViewPasswordHistoryService);
|
||||
dialogService = TestBed.inject(DialogService);
|
||||
});
|
||||
|
||||
describe("viewPasswordHistory", () => {
|
||||
it("calls openPasswordHistoryDialog with the correct parameters", async () => {
|
||||
const mockCipher = { id: "cipher-id" } as CipherView;
|
||||
await service.viewPasswordHistory(mockCipher);
|
||||
expect(openPasswordHistoryDialog).toHaveBeenCalledWith(dialogService, {
|
||||
data: { cipher: mockCipher },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { openPasswordHistoryDialog } from "../individual-vault/password-history.component";
|
||||
|
||||
/**
|
||||
* This service is used to display the password history dialog in the web vault.
|
||||
*/
|
||||
@Injectable()
|
||||
export class WebViewPasswordHistoryService implements ViewPasswordHistoryService {
|
||||
constructor(private dialogService: DialogService) {}
|
||||
|
||||
/**
|
||||
* Opens the password history dialog for the given cipher ID.
|
||||
* @param cipherId The ID of the cipher to view the password history for.
|
||||
*/
|
||||
async viewPasswordHistory(cipher: CipherView) {
|
||||
openPasswordHistoryDialog(this.dialogService, { data: { cipher } });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user