mirror of
https://github.com/bitwarden/browser
synced 2025-12-22 03:03:43 +00:00
[PM-8524] Migrate password/username generation to CipherFormGenerationService
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Service responsible for generating random passwords and usernames.
|
||||||
|
*/
|
||||||
|
export abstract class CipherFormGenerationService {
|
||||||
|
/**
|
||||||
|
* Generates a random password. Called when the user clicks the "Generate Password" button in the UI.
|
||||||
|
*/
|
||||||
|
abstract generatePassword(): Promise<string | null>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random username. Called when the user clicks the "Generate Username" button in the UI.
|
||||||
|
*/
|
||||||
|
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>;
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
|
|
||||||
|
import { CipherFormGenerationService } from "./abstractions/cipher-form-generation.service";
|
||||||
import { CipherFormService } from "./abstractions/cipher-form.service";
|
import { CipherFormService } from "./abstractions/cipher-form.service";
|
||||||
import { CipherFormComponent } from "./components/cipher-form.component";
|
import { CipherFormComponent } from "./components/cipher-form.component";
|
||||||
|
import { DefaultCipherFormGenerationService } from "./services/default-cipher-form-generation.service";
|
||||||
import { DefaultCipherFormService } from "./services/default-cipher-form.service";
|
import { DefaultCipherFormService } from "./services/default-cipher-form.service";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -11,6 +13,10 @@ import { DefaultCipherFormService } from "./services/default-cipher-form.service
|
|||||||
provide: CipherFormService,
|
provide: CipherFormService,
|
||||||
useClass: DefaultCipherFormService,
|
useClass: DefaultCipherFormService,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: CipherFormGenerationService,
|
||||||
|
useClass: DefaultCipherFormGenerationService,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
exports: [CipherFormComponent],
|
exports: [CipherFormComponent],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
|||||||
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
|
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
|
||||||
import { AsyncActionsModule, ButtonModule, ToastService } from "@bitwarden/components";
|
import { AsyncActionsModule, ButtonModule, ToastService } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
PasswordGenerationServiceAbstraction,
|
CipherFormConfig,
|
||||||
UsernameGenerationServiceAbstraction,
|
CipherFormGenerationService,
|
||||||
} from "@bitwarden/generator-legacy";
|
PasswordRepromptService,
|
||||||
import { CipherFormConfig, PasswordRepromptService } from "@bitwarden/vault";
|
} from "@bitwarden/vault";
|
||||||
import { PreloadedEnglishI18nModule } from "@bitwarden/web-vault/src/app/core/tests";
|
import { PreloadedEnglishI18nModule } from "@bitwarden/web-vault/src/app/core/tests";
|
||||||
|
|
||||||
import { CipherFormService } from "./abstractions/cipher-form.service";
|
import { CipherFormService } from "./abstractions/cipher-form.service";
|
||||||
@@ -132,23 +132,17 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: PasswordGenerationServiceAbstraction,
|
provide: CipherFormGenerationService,
|
||||||
useValue: {
|
useValue: {
|
||||||
getOptions: () => Promise.resolve([{}, {}]),
|
generateInitialPassword: () => Promise.resolve("initial-password"),
|
||||||
generatePassword: () => Promise.resolve("random-password"),
|
generatePassword: () => Promise.resolve("random-password"),
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: UsernameGenerationServiceAbstraction,
|
|
||||||
useValue: {
|
|
||||||
getOptions: () => Promise.resolve({}),
|
|
||||||
generateUsername: () => Promise.resolve("random-username"),
|
generateUsername: () => Promise.resolve("random-username"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: TotpCaptureService,
|
provide: TotpCaptureService,
|
||||||
useValue: {
|
useValue: {
|
||||||
captureTotpFromTab: () => Promise.resolve("some-value"),
|
captureTotpSecret: () => Promise.resolve("some-value"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,11 +19,8 @@ import {
|
|||||||
ToastService,
|
ToastService,
|
||||||
TypographyModule,
|
TypographyModule,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
import {
|
|
||||||
PasswordGenerationServiceAbstraction,
|
|
||||||
UsernameGenerationServiceAbstraction,
|
|
||||||
} from "@bitwarden/generator-legacy";
|
|
||||||
|
|
||||||
|
import { CipherFormGenerationService } from "../../abstractions/cipher-form-generation.service";
|
||||||
import { TotpCaptureService } from "../../abstractions/totp-capture.service";
|
import { TotpCaptureService } from "../../abstractions/totp-capture.service";
|
||||||
import { CipherFormContainer } from "../../cipher-form-container";
|
import { CipherFormContainer } from "../../cipher-form-container";
|
||||||
|
|
||||||
@@ -88,8 +85,7 @@ export class LoginDetailsSectionComponent implements OnInit {
|
|||||||
private cipherFormContainer: CipherFormContainer,
|
private cipherFormContainer: CipherFormContainer,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private passwordGenerationService: PasswordGenerationServiceAbstraction,
|
private generationService: CipherFormGenerationService,
|
||||||
private usernameGenerationService: UsernameGenerationServiceAbstraction,
|
|
||||||
private auditService: AuditService,
|
private auditService: AuditService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
@Optional() private totpCaptureService?: TotpCaptureService,
|
@Optional() private totpCaptureService?: TotpCaptureService,
|
||||||
@@ -145,7 +141,9 @@ export class LoginDetailsSectionComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async initNewCipher() {
|
private async initNewCipher() {
|
||||||
this.loginDetailsForm.controls.password.patchValue(await this.generateNewPassword());
|
this.loginDetailsForm.controls.password.patchValue(
|
||||||
|
await this.generationService.generateInitialPassword(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
captureTotp = async () => {
|
captureTotp = async () => {
|
||||||
@@ -184,8 +182,11 @@ export class LoginDetailsSectionComponent implements OnInit {
|
|||||||
* TODO: Browser extension needs a means to cache the current form so values are not lost upon navigating to the generator.
|
* TODO: Browser extension needs a means to cache the current form so values are not lost upon navigating to the generator.
|
||||||
*/
|
*/
|
||||||
generatePassword = async () => {
|
generatePassword = async () => {
|
||||||
const newPassword = await this.generateNewPassword();
|
const newPassword = await this.generationService.generatePassword();
|
||||||
|
|
||||||
|
if (newPassword) {
|
||||||
this.loginDetailsForm.controls.password.patchValue(newPassword);
|
this.loginDetailsForm.controls.password.patchValue(newPassword);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,9 +194,10 @@ export class LoginDetailsSectionComponent implements OnInit {
|
|||||||
* TODO: Browser extension needs a means to cache the current form so values are not lost upon navigating to the generator.
|
* TODO: Browser extension needs a means to cache the current form so values are not lost upon navigating to the generator.
|
||||||
*/
|
*/
|
||||||
generateUsername = async () => {
|
generateUsername = async () => {
|
||||||
const options = await this.usernameGenerationService.getOptions();
|
const newUsername = await this.generationService.generateUsername();
|
||||||
const newUsername = await this.usernameGenerationService.generateUsername(options);
|
if (newUsername) {
|
||||||
this.loginDetailsForm.controls.username.patchValue(newUsername);
|
this.loginDetailsForm.controls.username.patchValue(newUsername);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,9 +226,4 @@ export class LoginDetailsSectionComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private async generateNewPassword() {
|
|
||||||
const [options] = await this.passwordGenerationService.getOptions();
|
|
||||||
return await this.passwordGenerationService.generatePassword(options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ export {
|
|||||||
OptionalInitialValues,
|
OptionalInitialValues,
|
||||||
} from "./abstractions/cipher-form-config.service";
|
} from "./abstractions/cipher-form-config.service";
|
||||||
export { TotpCaptureService } from "./abstractions/totp-capture.service";
|
export { TotpCaptureService } from "./abstractions/totp-capture.service";
|
||||||
|
export { CipherFormGenerationService } from "./abstractions/cipher-form-generation.service";
|
||||||
export { DefaultCipherFormConfigService } from "./services/default-cipher-form-config.service";
|
export { DefaultCipherFormConfigService } from "./services/default-cipher-form-config.service";
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
import {
|
||||||
|
PasswordGenerationServiceAbstraction,
|
||||||
|
UsernameGenerationServiceAbstraction,
|
||||||
|
} from "@bitwarden/generator-legacy";
|
||||||
|
|
||||||
|
import { CipherFormGenerationService } from "../abstractions/cipher-form-generation.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DefaultCipherFormGenerationService implements CipherFormGenerationService {
|
||||||
|
constructor(
|
||||||
|
private passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||||
|
private usernameGenerationService: UsernameGenerationServiceAbstraction,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async generatePassword(): Promise<string> {
|
||||||
|
const [options] = await this.passwordGenerationService.getOptions();
|
||||||
|
return await this.passwordGenerationService.generatePassword(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateUsername(): Promise<string> {
|
||||||
|
const options = await this.usernameGenerationService.getOptions();
|
||||||
|
return await this.usernameGenerationService.generateUsername(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateInitialPassword(): Promise<string> {
|
||||||
|
return await this.generatePassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user