[PM-10100] Remove auto password generation (#10355)

* [PM-10100] Remove initial password generation on new Login ciphers

* [PM-10100] Update password help text

* [PM-10100] Fix linter
This commit is contained in:
Shane Melton 2024-08-07 12:57:05 -07:00 committed by GitHub
parent 0b6701d3f8
commit 600c8de129
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 50 additions and 24 deletions

View File

@ -1815,6 +1815,17 @@
"useThisUsername": { "useThisUsername": {
"message": "Use this username" "message": "Use this username"
}, },
"securePasswordGenerated": {
"message": "Secure password generated! Don't forget to also update your password on the website."
},
"useGeneratorHelpTextPartOne": {
"message": "Use the generator",
"description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'"
},
"useGeneratorHelpTextPartTwo": {
"message": "to create a strong unique password",
"description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'"
},
"vaultTimeoutAction": { "vaultTimeoutAction": {
"message": "Vault timeout action" "message": "Vault timeout action"
}, },

View File

@ -39,7 +39,4 @@ export class BrowserCipherFormGenerationService implements CipherFormGenerationS
return result.generatedValue; return result.generatedValue;
} }
async generateInitialPassword(): Promise<string> {
return "";
}
} }

View File

@ -6050,6 +6050,26 @@
"randomWord": { "randomWord": {
"message": "Random word" "message": "Random word"
}, },
"usernameGenerator": {
"message": "Username generator"
},
"useThisPassword": {
"message": "Use this password"
},
"useThisUsername": {
"message": "Use this username"
},
"securePasswordGenerated": {
"message": "Secure password generated! Don't forget to also update your password on the website."
},
"useGeneratorHelpTextPartOne": {
"message": "Use the generator",
"description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'"
},
"useGeneratorHelpTextPartTwo": {
"message": "to create a strong unique password",
"description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'"
},
"service": { "service": {
"message": "Service" "message": "Service"
}, },

View File

@ -11,10 +11,4 @@ export abstract class CipherFormGenerationService {
* Generates a random username. Called when the user clicks the "Generate Username" button in the UI. * Generates a random username. Called when the user clicks the "Generate Username" button in the UI.
*/ */
abstract generateUsername(): Promise<string | null>; abstract generateUsername(): Promise<string | null>;
/**
* Generates an initial password for a new cipher. This should not involve any user interaction as it will
* be used to pre-fill the password field in the UI for new Login ciphers.
*/
abstract generateInitialPassword(): Promise<string | null>;
} }

View File

@ -1,5 +1,5 @@
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component, DestroyRef, EventEmitter, Input, Output } from "@angular/core"; import { Component, DestroyRef, EventEmitter, Input, OnChanges, Output } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { firstValueFrom, map, startWith, Subject, Subscription, switchMap, tap } from "rxjs"; import { firstValueFrom, map, startWith, Subject, Subscription, switchMap, tap } from "rxjs";
@ -42,7 +42,7 @@ import {
TypographyModule, TypographyModule,
], ],
}) })
export class CipherFormGeneratorComponent { export class CipherFormGeneratorComponent implements OnChanges {
/** /**
* The type of generator form to show. * The type of generator form to show.
*/ */

View File

@ -23,6 +23,16 @@
<bit-form-field> <bit-form-field>
<bit-label>{{ "password" | i18n }}</bit-label> <bit-label>{{ "password" | i18n }}</bit-label>
<input bitInput formControlName="password" type="password" /> <input bitInput formControlName="password" type="password" />
<bit-hint *ngIf="loginDetailsForm.controls.password.enabled">
<ng-container *ngIf="newPasswordGenerated">
{{ "securePasswordGenerated" | i18n }}
</ng-container>
<ng-container *ngIf="!newPasswordGenerated">
{{ "useGeneratorHelpTextPartOne" | i18n }}
<i class="bwi bwi-generate" aria-hidden="true"></i>
{{ "useGeneratorHelpTextPartTwo" | i18n }}
</ng-container>
</bit-hint>
<button <button
type="button" type="button"
bitIconButton="bwi-check-circle" bitIconButton="bwi-check-circle"

View File

@ -125,14 +125,6 @@ describe("LoginDetailsSectionComponent", () => {
}); });
}); });
it("initializes 'loginDetailsForm' with generated password when creating a new cipher", async () => {
generationService.generateInitialPassword.mockResolvedValue("generated-password");
await component.ngOnInit();
expect(component.loginDetailsForm.controls.password.value).toBe("generated-password");
});
describe("viewHiddenFields", () => { describe("viewHiddenFields", () => {
beforeEach(() => { beforeEach(() => {
(cipherFormContainer.originalCipherView as CipherView) = { (cipherFormContainer.originalCipherView as CipherView) = {

View File

@ -52,6 +52,11 @@ export class LoginDetailsSectionComponent implements OnInit {
totp: [""], totp: [""],
}); });
/**
* Flag indicating whether a new password has been generated for the current form.
*/
newPasswordGenerated: boolean;
/** /**
* Whether the TOTP field can be captured from the current tab. Only available in the browser extension. * Whether the TOTP field can be captured from the current tab. Only available in the browser extension.
*/ */
@ -148,7 +153,7 @@ export class LoginDetailsSectionComponent implements OnInit {
private async initNewCipher() { private async initNewCipher() {
this.loginDetailsForm.patchValue({ this.loginDetailsForm.patchValue({
username: this.cipherFormContainer.config.initialValues?.username || "", username: this.cipherFormContainer.config.initialValues?.username || "",
password: await this.generationService.generateInitialPassword(), password: "",
}); });
} }
@ -193,6 +198,7 @@ export class LoginDetailsSectionComponent implements OnInit {
if (newPassword) { if (newPassword) {
this.loginDetailsForm.controls.password.patchValue(newPassword); this.loginDetailsForm.controls.password.patchValue(newPassword);
this.newPasswordGenerated = true;
} }
}; };

View File

@ -23,8 +23,4 @@ export class DefaultCipherFormGenerationService implements CipherFormGenerationS
const options = await this.usernameGenerationService.getOptions(); const options = await this.usernameGenerationService.getOptions();
return await this.usernameGenerationService.generateUsername(options); return await this.usernameGenerationService.generateUsername(options);
} }
async generateInitialPassword(): Promise<string> {
return await this.generatePassword();
}
} }