1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-21 02:33:46 +00:00

Merge branch 'autofill/pm-6921-optimize-inline-menu-background-collect-page-details-for-tab-process' into autofill/pm-5189-fix-issues-present-with-inline-menu-rendering-in-iframes

This commit is contained in:
Cesar Gonzalez
2024-03-19 15:23:42 -05:00
6 changed files with 64 additions and 51 deletions

View File

@@ -1,6 +1,9 @@
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { DefaultPassphraseGenerationOptions } from "@bitwarden/common/tools/generator/passphrase"; import { DefaultPassphraseGenerationOptions } from "@bitwarden/common/tools/generator/passphrase";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import {
DefaultPasswordGenerationOptions,
PasswordGenerationServiceAbstraction,
} from "@bitwarden/common/tools/generator/password";
import { PasswordGeneratorOptions } from "@bitwarden/common/tools/generator/password/password-generator-options"; import { PasswordGeneratorOptions } from "@bitwarden/common/tools/generator/password/password-generator-options";
import { Response } from "../models/response"; import { Response } from "../models/response";
@@ -64,7 +67,10 @@ class Options {
this.capitalize = CliUtils.convertBooleanOption(passedOptions?.capitalize); this.capitalize = CliUtils.convertBooleanOption(passedOptions?.capitalize);
this.includeNumber = CliUtils.convertBooleanOption(passedOptions?.includeNumber); this.includeNumber = CliUtils.convertBooleanOption(passedOptions?.includeNumber);
this.ambiguous = CliUtils.convertBooleanOption(passedOptions?.ambiguous); this.ambiguous = CliUtils.convertBooleanOption(passedOptions?.ambiguous);
this.length = CliUtils.convertNumberOption(passedOptions?.length, 14); this.length = CliUtils.convertNumberOption(
passedOptions?.length,
DefaultPasswordGenerationOptions.length,
);
this.type = passedOptions?.passphrase ? "passphrase" : "password"; this.type = passedOptions?.passphrase ? "passphrase" : "password";
this.separator = CliUtils.convertStringOption( this.separator = CliUtils.convertStringOption(
passedOptions?.separator, passedOptions?.separator,
@@ -74,8 +80,14 @@ class Options {
passedOptions?.words, passedOptions?.words,
DefaultPassphraseGenerationOptions.numWords, DefaultPassphraseGenerationOptions.numWords,
); );
this.minNumber = CliUtils.convertNumberOption(passedOptions?.minNumber, 1); this.minNumber = CliUtils.convertNumberOption(
this.minSpecial = CliUtils.convertNumberOption(passedOptions?.minSpecial, 1); passedOptions?.minNumber,
DefaultPasswordGenerationOptions.minNumber,
);
this.minSpecial = CliUtils.convertNumberOption(
passedOptions?.minSpecial,
DefaultPasswordGenerationOptions.minSpecial,
);
if (!this.uppercase && !this.lowercase && !this.special && !this.number) { if (!this.uppercase && !this.lowercase && !this.special && !this.number) {
this.lowercase = true; this.lowercase = true;

View File

@@ -1,13 +1,7 @@
<app-header></app-header> <app-header></app-header>
<bit-container> <bit-container>
<form <form [formGroup]="exportForm" [bitSubmit]="submit">
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
[formGroup]="exportForm"
*ngIf="exportForm"
>
<bit-callout type="danger" title="{{ 'vaultExportDisabled' | i18n }}" *ngIf="disabledByPolicy"> <bit-callout type="danger" title="{{ 'vaultExportDisabled' | i18n }}" *ngIf="disabledByPolicy">
{{ "personalVaultExportPolicyInEffect" | i18n }} {{ "personalVaultExportPolicyInEffect" | i18n }}
</bit-callout> </bit-callout>
@@ -110,9 +104,9 @@
<button <button
bitButton bitButton
bitFormButton
type="submit" type="submit"
buttonType="primary" buttonType="primary"
[loading]="form.loading"
[disabled]="disabledByPolicy" [disabled]="disabledByPolicy"
> >
{{ "confirmFormat" | i18n }} {{ "confirmFormat" | i18n }}

View File

@@ -1,8 +1,8 @@
import { Component } from "@angular/core"; import { Component } from "@angular/core";
import { UntypedFormBuilder } from "@angular/forms"; import { UntypedFormBuilder } from "@angular/forms";
import { firstValueFrom } from "rxjs";
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component"; import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
import { UserVerificationDialogComponent } from "@bitwarden/auth/angular";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
@@ -11,20 +11,14 @@ 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 { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { EncryptedExportType } from "@bitwarden/common/tools/enums/encrypted-export-type.enum";
import { DialogService } from "@bitwarden/components"; import { DialogService } from "@bitwarden/components";
import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core";
import { openUserVerificationPrompt } from "../../auth/shared/components/user-verification";
@Component({ @Component({
selector: "app-export", selector: "app-export",
templateUrl: "export.component.html", templateUrl: "export.component.html",
}) })
export class ExportComponent extends BaseExportComponent { export class ExportComponent extends BaseExportComponent {
encryptedExportType = EncryptedExportType;
protected showFilePassword: boolean;
constructor( constructor(
i18nService: I18nService, i18nService: I18nService,
platformUtilsService: PlatformUtilsService, platformUtilsService: PlatformUtilsService,
@@ -53,7 +47,7 @@ export class ExportComponent extends BaseExportComponent {
); );
} }
async submit() { submit = async () => {
if (this.isFileEncryptedExport && this.filePassword != this.confirmFilePassword) { if (this.isFileEncryptedExport && this.filePassword != this.confirmFilePassword) {
this.platformUtilsService.showToast( this.platformUtilsService.showToast(
"error", "error",
@@ -64,7 +58,7 @@ export class ExportComponent extends BaseExportComponent {
} }
this.exportForm.markAllAsTouched(); this.exportForm.markAllAsTouched();
if (!this.exportForm.valid) { if (this.exportForm.invalid) {
return; return;
} }
@@ -85,14 +79,14 @@ export class ExportComponent extends BaseExportComponent {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises // eslint-disable-next-line @typescript-eslint/no-floating-promises
this.doExport(); this.doExport();
} };
protected saved() { protected saved() {
super.saved(); super.saved();
this.platformUtilsService.showToast("success", null, this.i18nService.t("exportSuccess")); this.platformUtilsService.showToast("success", null, this.i18nService.t("exportSuccess"));
} }
private verifyUser() { private async verifyUser(): Promise<boolean> {
let confirmDescription = "exportWarningDesc"; let confirmDescription = "exportWarningDesc";
if (this.isFileEncryptedExport) { if (this.isFileEncryptedExport) {
confirmDescription = "fileEncryptedExportWarningDesc"; confirmDescription = "fileEncryptedExportWarningDesc";
@@ -100,32 +94,30 @@ export class ExportComponent extends BaseExportComponent {
confirmDescription = "encExportKeyWarningDesc"; confirmDescription = "encExportKeyWarningDesc";
} }
const ref = openUserVerificationPrompt(this.dialogService, { const result = await UserVerificationDialogComponent.open(this.dialogService, {
data: { clientSideOnlyVerification: true,
confirmDescription: confirmDescription, title: "confirmVaultExport",
confirmButtonText: "exportVault", bodyText: confirmDescription,
modalTitle: "confirmVaultExport", confirmButtonOptions: {
text: "exportVault",
type: "primary",
}, },
}); });
if (ref == null) { // Handle the result of the dialog based on user action and verification success
return; if (result.userAction === "cancel") {
// User cancelled the dialog
return false;
} }
return firstValueFrom(ref.closed); // User confirmed the dialog so check verification success
if (!result.verificationSuccess) {
if (result.noAvailableClientVerificationMethods) {
// No client-side verification methods are available
// Could send user to configure a verification method like PIN or biometrics
} }
return false;
get isFileEncryptedExport() {
return (
this.format === "encrypted_json" &&
this.fileEncryptionType === EncryptedExportType.FileEncrypted
);
} }
return true;
get isAccountEncryptedExport() {
return (
this.format === "encrypted_json" &&
this.fileEncryptionType === EncryptedExportType.AccountEncrypted
);
} }
} }

View File

@@ -25,8 +25,10 @@ export class ExportComponent implements OnInit, OnDestroy {
@Output() onSaved = new EventEmitter(); @Output() onSaved = new EventEmitter();
@ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent; @ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent;
encryptedExportType = EncryptedExportType;
protected showFilePassword: boolean;
filePasswordValue: string = null; filePasswordValue: string = null;
formPromise: Promise<string>;
private _disabledByPolicy = false; private _disabledByPolicy = false;
protected organizationId: string = null; protected organizationId: string = null;
@@ -126,10 +128,23 @@ export class ExportComponent implements OnInit, OnDestroy {
return this.format === "encrypted_json"; return this.format === "encrypted_json";
} }
get isFileEncryptedExport() {
return (
this.format === "encrypted_json" &&
this.fileEncryptionType === EncryptedExportType.FileEncrypted
);
}
get isAccountEncryptedExport() {
return (
this.format === "encrypted_json" &&
this.fileEncryptionType === EncryptedExportType.AccountEncrypted
);
}
protected async doExport() { protected async doExport() {
try { try {
this.formPromise = this.getExportData(); const data = await this.getExportData();
const data = await this.formPromise;
this.downloadFile(data); this.downloadFile(data);
this.saved(); this.saved();
await this.collectEvent(); await this.collectEvent();

View File

@@ -78,6 +78,6 @@ export const DefaultPasswordGenerationOptions: Partial<PasswordGenerationOptions
lowercase: true, lowercase: true,
number: true, number: true,
minNumber: 1, minNumber: 1,
special: true, special: false,
minSpecial: 1, minSpecial: 0,
}); });

View File

@@ -23,7 +23,7 @@ const DefaultOptions: PasswordGeneratorOptions = {
lowercase: true, lowercase: true,
minLowercase: 0, minLowercase: 0,
special: false, special: false,
minSpecial: 1, minSpecial: 0,
type: "password", type: "password",
numWords: 3, numWords: 3,
wordSeparator: "-", wordSeparator: "-",