mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 06:13:38 +00:00
[PM-328] Move generator to tools (#4980)
* Move generator to tools libs/angular: - Move generator.component to tools libs/common: - Move password generation to tools - Move username generation including email-forwarders to tools apps/* - create tools-subfolder and move files regarding generator functionality - Update all the imports .github/: - Cleaned up whitelist-capital-letters.txt - Added team-tools-dev folders to CODEOWNERS * Remove unused barrel file
This commit is contained in:
committed by
GitHub
parent
e9d0f75b8a
commit
d4c812160f
@@ -1,256 +0,0 @@
|
||||
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { UsernameGenerationService } from "@bitwarden/common/abstractions/usernameGeneration.service";
|
||||
import { PasswordGeneratorPolicyOptions } from "@bitwarden/common/models/domain/password-generator-policy-options";
|
||||
|
||||
@Directive()
|
||||
export class GeneratorComponent implements OnInit {
|
||||
@Input() comingFromAddEdit = false;
|
||||
@Input() type: string;
|
||||
@Output() onSelected = new EventEmitter<string>();
|
||||
|
||||
usernameGeneratingPromise: Promise<string>;
|
||||
typeOptions: any[];
|
||||
passTypeOptions: any[];
|
||||
usernameTypeOptions: any[];
|
||||
subaddressOptions: any[];
|
||||
catchallOptions: any[];
|
||||
forwardOptions: any[];
|
||||
usernameOptions: any = {};
|
||||
passwordOptions: any = {};
|
||||
username = "-";
|
||||
password = "-";
|
||||
showOptions = false;
|
||||
avoidAmbiguous = false;
|
||||
enforcedPasswordPolicyOptions: PasswordGeneratorPolicyOptions;
|
||||
usernameWebsite: string = null;
|
||||
|
||||
constructor(
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected usernameGenerationService: UsernameGenerationService,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected stateService: StateService,
|
||||
protected i18nService: I18nService,
|
||||
protected logService: LogService,
|
||||
protected route: ActivatedRoute,
|
||||
private win: Window
|
||||
) {
|
||||
this.typeOptions = [
|
||||
{ name: i18nService.t("password"), value: "password" },
|
||||
{ name: i18nService.t("username"), value: "username" },
|
||||
];
|
||||
this.passTypeOptions = [
|
||||
{ name: i18nService.t("password"), value: "password" },
|
||||
{ name: i18nService.t("passphrase"), value: "passphrase" },
|
||||
];
|
||||
this.usernameTypeOptions = [
|
||||
{
|
||||
name: i18nService.t("plusAddressedEmail"),
|
||||
value: "subaddress",
|
||||
desc: i18nService.t("plusAddressedEmailDesc"),
|
||||
},
|
||||
{
|
||||
name: i18nService.t("catchallEmail"),
|
||||
value: "catchall",
|
||||
desc: i18nService.t("catchallEmailDesc"),
|
||||
},
|
||||
{
|
||||
name: i18nService.t("forwardedEmail"),
|
||||
value: "forwarded",
|
||||
desc: i18nService.t("forwardedEmailDesc"),
|
||||
},
|
||||
{ name: i18nService.t("randomWord"), value: "word" },
|
||||
];
|
||||
this.subaddressOptions = [{ name: i18nService.t("random"), value: "random" }];
|
||||
this.catchallOptions = [{ name: i18nService.t("random"), value: "random" }];
|
||||
this.initForwardOptions();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
// eslint-disable-next-line rxjs/no-async-subscribe
|
||||
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
||||
const passwordOptionsResponse = await this.passwordGenerationService.getOptions();
|
||||
this.passwordOptions = passwordOptionsResponse[0];
|
||||
this.enforcedPasswordPolicyOptions = passwordOptionsResponse[1];
|
||||
this.avoidAmbiguous = !this.passwordOptions.ambiguous;
|
||||
this.passwordOptions.type =
|
||||
this.passwordOptions.type === "passphrase" ? "passphrase" : "password";
|
||||
|
||||
this.usernameOptions = await this.usernameGenerationService.getOptions();
|
||||
if (this.usernameOptions.type == null) {
|
||||
this.usernameOptions.type = "word";
|
||||
}
|
||||
if (
|
||||
this.usernameOptions.subaddressEmail == null ||
|
||||
this.usernameOptions.subaddressEmail === ""
|
||||
) {
|
||||
this.usernameOptions.subaddressEmail = await this.stateService.getEmail();
|
||||
}
|
||||
if (this.usernameWebsite == null) {
|
||||
this.usernameOptions.subaddressType = this.usernameOptions.catchallType = "random";
|
||||
} else {
|
||||
this.usernameOptions.website = this.usernameWebsite;
|
||||
const websiteOption = { name: this.i18nService.t("websiteName"), value: "website-name" };
|
||||
this.subaddressOptions.push(websiteOption);
|
||||
this.catchallOptions.push(websiteOption);
|
||||
}
|
||||
|
||||
if (this.type !== "username" && this.type !== "password") {
|
||||
if (qParams.type === "username" || qParams.type === "password") {
|
||||
this.type = qParams.type;
|
||||
} else {
|
||||
const generatorOptions = await this.stateService.getGeneratorOptions();
|
||||
this.type = generatorOptions?.type ?? "password";
|
||||
}
|
||||
}
|
||||
if (this.regenerateWithoutButtonPress()) {
|
||||
await this.regenerate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async typeChanged() {
|
||||
await this.stateService.setGeneratorOptions({ type: this.type });
|
||||
if (this.regenerateWithoutButtonPress()) {
|
||||
await this.regenerate();
|
||||
}
|
||||
}
|
||||
|
||||
async regenerate() {
|
||||
if (this.type === "password") {
|
||||
await this.regeneratePassword();
|
||||
} else if (this.type === "username") {
|
||||
await this.regenerateUsername();
|
||||
}
|
||||
}
|
||||
|
||||
async sliderChanged() {
|
||||
this.savePasswordOptions(false);
|
||||
await this.passwordGenerationService.addHistory(this.password);
|
||||
}
|
||||
|
||||
async sliderInput() {
|
||||
this.normalizePasswordOptions();
|
||||
this.password = await this.passwordGenerationService.generatePassword(this.passwordOptions);
|
||||
}
|
||||
|
||||
async savePasswordOptions(regenerate = true) {
|
||||
this.normalizePasswordOptions();
|
||||
await this.passwordGenerationService.saveOptions(this.passwordOptions);
|
||||
|
||||
if (regenerate && this.regenerateWithoutButtonPress()) {
|
||||
await this.regeneratePassword();
|
||||
}
|
||||
}
|
||||
|
||||
async saveUsernameOptions(regenerate = true) {
|
||||
await this.usernameGenerationService.saveOptions(this.usernameOptions);
|
||||
if (this.usernameOptions.type === "forwarded") {
|
||||
this.username = "-";
|
||||
}
|
||||
if (regenerate && this.regenerateWithoutButtonPress()) {
|
||||
await this.regenerateUsername();
|
||||
}
|
||||
}
|
||||
|
||||
async regeneratePassword() {
|
||||
this.password = await this.passwordGenerationService.generatePassword(this.passwordOptions);
|
||||
await this.passwordGenerationService.addHistory(this.password);
|
||||
}
|
||||
|
||||
regenerateUsername() {
|
||||
return this.generateUsername();
|
||||
}
|
||||
|
||||
async generateUsername() {
|
||||
try {
|
||||
this.usernameGeneratingPromise = this.usernameGenerationService.generateUsername(
|
||||
this.usernameOptions
|
||||
);
|
||||
this.username = await this.usernameGeneratingPromise;
|
||||
if (this.username === "" || this.username === null) {
|
||||
this.username = "-";
|
||||
}
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
copy() {
|
||||
const password = this.type === "password";
|
||||
const copyOptions = this.win != null ? { window: this.win } : null;
|
||||
this.platformUtilsService.copyToClipboard(
|
||||
password ? this.password : this.username,
|
||||
copyOptions
|
||||
);
|
||||
this.platformUtilsService.showToast(
|
||||
"info",
|
||||
null,
|
||||
this.i18nService.t("valueCopied", this.i18nService.t(password ? "password" : "username"))
|
||||
);
|
||||
}
|
||||
|
||||
select() {
|
||||
this.onSelected.emit(this.type === "password" ? this.password : this.username);
|
||||
}
|
||||
|
||||
toggleOptions() {
|
||||
this.showOptions = !this.showOptions;
|
||||
}
|
||||
|
||||
regenerateWithoutButtonPress() {
|
||||
return this.type !== "username" || this.usernameOptions.type !== "forwarded";
|
||||
}
|
||||
|
||||
private normalizePasswordOptions() {
|
||||
// Application level normalize options depedent on class variables
|
||||
this.passwordOptions.ambiguous = !this.avoidAmbiguous;
|
||||
|
||||
if (
|
||||
!this.passwordOptions.uppercase &&
|
||||
!this.passwordOptions.lowercase &&
|
||||
!this.passwordOptions.number &&
|
||||
!this.passwordOptions.special
|
||||
) {
|
||||
this.passwordOptions.lowercase = true;
|
||||
if (this.win != null) {
|
||||
const lowercase = this.win.document.querySelector("#lowercase") as HTMLInputElement;
|
||||
if (lowercase) {
|
||||
lowercase.checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.passwordGenerationService.normalizeOptions(
|
||||
this.passwordOptions,
|
||||
this.enforcedPasswordPolicyOptions
|
||||
);
|
||||
}
|
||||
|
||||
private async initForwardOptions() {
|
||||
this.forwardOptions = [
|
||||
{ name: "AnonAddy", value: "anonaddy" },
|
||||
{ name: "DuckDuckGo", value: "duckduckgo" },
|
||||
{ name: "Fastmail", value: "fastmail" },
|
||||
{ name: "Firefox Relay", value: "firefoxrelay" },
|
||||
{ name: "SimpleLogin", value: "simplelogin" },
|
||||
];
|
||||
|
||||
this.usernameOptions = await this.usernameGenerationService.getOptions();
|
||||
if (
|
||||
this.usernameOptions.forwardedService == null ||
|
||||
this.usernameOptions.forwardedService === ""
|
||||
) {
|
||||
this.forwardOptions.push({ name: "", value: null });
|
||||
}
|
||||
|
||||
this.forwardOptions = this.forwardOptions.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Directive, OnInit } from "@angular/core";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { GeneratedPasswordHistory } from "@bitwarden/common/models/domain/generated-password-history";
|
||||
|
||||
@Directive()
|
||||
export class PasswordGeneratorHistoryComponent implements OnInit {
|
||||
history: GeneratedPasswordHistory[] = [];
|
||||
|
||||
constructor(
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected i18nService: I18nService,
|
||||
private win: Window
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.history = await this.passwordGenerationService.getHistory();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.history = [];
|
||||
this.passwordGenerationService.clear();
|
||||
}
|
||||
|
||||
copy(password: string) {
|
||||
const copyOptions = this.win != null ? { window: this.win } : null;
|
||||
this.platformUtilsService.copyToClipboard(password, copyOptions);
|
||||
this.platformUtilsService.showToast(
|
||||
"info",
|
||||
null,
|
||||
this.i18nService.t("valueCopied", this.i18nService.t("password"))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
} from "@bitwarden/common/abstractions/formValidationErrors.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
@@ -23,6 +22,7 @@ import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||
import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request";
|
||||
import { RegisterRequest } from "@bitwarden/common/models/request/register.request";
|
||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
|
||||
|
||||
import { CaptchaProtectedComponent } from "../auth/components/captcha-protected.component";
|
||||
import { PasswordColorText } from "../shared/components/password-strength/password-strength.component";
|
||||
@@ -87,7 +87,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
|
||||
protected apiService: ApiService,
|
||||
protected stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||
environmentService: EnvironmentService,
|
||||
protected logService: LogService,
|
||||
protected auditService: AuditService
|
||||
|
||||
@@ -9,7 +9,6 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi
|
||||
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
||||
import { OrganizationUserResetPasswordEnrollmentRequest } from "@bitwarden/common/abstractions/organization-user/requests";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
|
||||
@@ -21,6 +20,7 @@ import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetric-crypto-key";
|
||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
|
||||
import { ChangePasswordComponent as BaseChangePasswordComponent } from "../auth/components/change-password.component";
|
||||
@@ -41,7 +41,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||
i18nService: I18nService,
|
||||
cryptoService: CryptoService,
|
||||
messagingService: MessagingService,
|
||||
passwordGenerationService: PasswordGenerationService,
|
||||
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
private policyApiService: PolicyApiServiceAbstraction,
|
||||
policyService: PolicyService,
|
||||
|
||||
Reference in New Issue
Block a user