1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-11 14:48:46 +01:00
bitwarden-browser/angular/src/components/password-generator.component.ts

213 lines
7.0 KiB
TypeScript
Raw Normal View History

2021-12-16 13:36:21 +01:00
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { first } from "rxjs/operators";
2018-04-06 04:21:18 +02:00
2021-12-16 13:36:21 +01:00
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { UsernameGenerationService } from "jslib-common/abstractions/usernameGeneration.service";
2021-12-16 13:36:21 +01:00
import { PasswordGeneratorPolicyOptions } from "jslib-common/models/domain/passwordGeneratorPolicyOptions";
@Directive()
2018-04-06 04:21:18 +02:00
export class PasswordGeneratorComponent implements OnInit {
2022-02-22 15:39:11 +01:00
@Input() showSelect = false;
@Input() type = "password";
2021-12-16 13:36:21 +01:00
@Output() onSelected = new EventEmitter<string>();
typeOptions: any[];
2021-12-16 13:36:21 +01:00
passTypeOptions: any[];
usernameTypeOptions: any[];
subaddressOptions: any[];
catchallOptions: any[];
forwardOptions: any[];
usernameOptions: any = {};
passwordOptions: any = {};
username = "-";
2022-02-22 15:39:11 +01:00
password = "-";
2021-12-16 13:36:21 +01:00
showOptions = false;
avoidAmbiguous = false;
showWebsiteOption = false;
enforcedPasswordPolicyOptions: PasswordGeneratorPolicyOptions;
2021-12-16 13:36:21 +01:00
constructor(
protected passwordGenerationService: PasswordGenerationService,
protected usernameGenerationService: UsernameGenerationService,
2021-12-16 13:36:21 +01:00
protected platformUtilsService: PlatformUtilsService,
protected stateService: StateService,
2021-12-16 13:36:21 +01:00
protected i18nService: I18nService,
protected route: ActivatedRoute,
2021-12-16 13:36:21 +01:00
private win: Window
) {
this.typeOptions = [
{ name: i18nService.t("password"), value: "password" },
{ name: i18nService.t("username"), value: "username" },
];
2021-12-16 13:36:21 +01:00
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("randomWord"), value: "word" },
];
this.subaddressOptions = [{ name: i18nService.t("random"), value: "random" }];
this.catchallOptions = [{ name: i18nService.t("random"), value: "random" }];
this.forwardOptions = [
{ name: "SimpleLogin", value: "simplelogin" },
{ name: "FastMail", value: "fastmail" },
];
2021-12-16 13:36:21 +01:00
}
async ngOnInit() {
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";
if (this.showWebsiteOption) {
const websiteOption = { name: this.i18nService.t("websiteName"), value: "website-name" };
this.subaddressOptions.push(websiteOption);
this.catchallOptions.push(websiteOption);
}
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.showWebsiteOption) {
this.usernameOptions.subaddressType = this.usernameOptions.catchallType = "random";
}
if (qParams.type === "username" || qParams.type === "password") {
this.type = qParams.type;
} else {
const generatorOptions = await this.stateService.getGeneratorOptions();
if (generatorOptions != null && generatorOptions.type != null) {
this.type = generatorOptions.type;
}
}
await this.regenerate();
});
}
async typeChanged() {
await this.stateService.setGeneratorOptions({ type: this.type });
await this.regenerate();
}
async regenerate() {
if (this.type === "password") {
await this.regeneratePassword();
} else if (this.type === "username") {
await this.regenerateUsername();
}
2021-12-16 13:36:21 +01:00
}
async sliderChanged() {
this.savePasswordOptions(false);
2021-12-16 13:36:21 +01:00
await this.passwordGenerationService.addHistory(this.password);
}
async sliderInput() {
this.normalizePasswordOptions();
this.password = await this.passwordGenerationService.generatePassword(this.passwordOptions);
2021-12-16 13:36:21 +01:00
}
async savePasswordOptions(regenerate = true) {
this.normalizePasswordOptions();
await this.passwordGenerationService.saveOptions(this.passwordOptions);
2021-12-16 13:36:21 +01:00
if (regenerate) {
await this.regeneratePassword();
2018-04-06 04:21:18 +02:00
}
2021-12-16 13:36:21 +01:00
}
async saveUsernameOptions(regenerate = true) {
await this.usernameGenerationService.saveOptions(this.usernameOptions);
if (regenerate) {
await this.regenerateUsername();
}
}
async regeneratePassword() {
this.password = await this.passwordGenerationService.generatePassword(this.passwordOptions);
2021-12-16 13:36:21 +01:00
await this.passwordGenerationService.addHistory(this.password);
}
regenerateUsername() {
return this.generateUsername();
}
async generateUsername() {
this.username = await this.usernameGenerationService.generateUsername(this.usernameOptions);
if (this.username === "" || this.username === null) {
this.username = "-";
}
}
2021-12-16 13:36:21 +01:00
copy() {
const password = this.type === "password";
2021-12-16 13:36:21 +01:00
const copyOptions = this.win != null ? { window: this.win } : null;
this.platformUtilsService.copyToClipboard(
password ? this.password : this.username,
copyOptions
);
2021-12-16 13:36:21 +01:00
this.platformUtilsService.showToast(
"info",
null,
this.i18nService.t("valueCopied", this.i18nService.t(password ? "password" : "username"))
2021-12-16 13:36:21 +01:00
);
}
select() {
this.onSelected.emit(this.type === "password" ? this.password : this.username);
2021-12-16 13:36:21 +01:00
}
toggleOptions() {
this.showOptions = !this.showOptions;
}
private normalizePasswordOptions() {
2021-12-16 13:36:21 +01:00
// Application level normalize options depedent on class variables
this.passwordOptions.ambiguous = !this.avoidAmbiguous;
2021-12-16 13:36:21 +01:00
if (
!this.passwordOptions.uppercase &&
!this.passwordOptions.lowercase &&
!this.passwordOptions.number &&
!this.passwordOptions.special
2021-12-16 13:36:21 +01:00
) {
this.passwordOptions.lowercase = true;
2021-12-16 13:36:21 +01:00
if (this.win != null) {
const lowercase = this.win.document.querySelector("#lowercase") as HTMLInputElement;
if (lowercase) {
lowercase.checked = true;
2018-04-06 04:21:18 +02:00
}
2021-12-16 13:36:21 +01:00
}
2018-04-06 04:21:18 +02:00
}
this.passwordGenerationService.normalizeOptions(
this.passwordOptions,
this.enforcedPasswordPolicyOptions
);
2021-12-16 13:36:21 +01:00
}
2018-04-06 04:21:18 +02:00
}