[PM-9118] fix duplicate website name (#9782)
This commit is contained in:
parent
b9cb1644ec
commit
52f6b24020
|
@ -151,9 +151,6 @@ export class GeneratorComponent implements OnInit, OnDestroy {
|
||||||
this.usernameOptions.subaddressType = this.usernameOptions.catchallType = "random";
|
this.usernameOptions.subaddressType = this.usernameOptions.catchallType = "random";
|
||||||
} else {
|
} else {
|
||||||
this.usernameOptions.website = this.usernameWebsite;
|
this.usernameOptions.website = this.usernameWebsite;
|
||||||
const websiteOption = { name: this.i18nService.t("websiteName"), value: "website-name" };
|
|
||||||
this.subaddressOptions.push(websiteOption);
|
|
||||||
this.catchallOptions.push(websiteOption);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +198,12 @@ export class GeneratorComponent implements OnInit, OnDestroy {
|
||||||
takeUntil(this.destroy$),
|
takeUntil(this.destroy$),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this.usernameWebsite !== null) {
|
||||||
|
const websiteOption = { name: this.i18nService.t("websiteName"), value: "website-name" };
|
||||||
|
this.subaddressOptions.push(websiteOption);
|
||||||
|
this.catchallOptions.push(websiteOption);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
|
|
@ -638,6 +638,10 @@ describe("LegacyUsernameGenerationService", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("saveOptions", () => {
|
describe("saveOptions", () => {
|
||||||
|
// this test is awful, but the coupling of the legacy username generator
|
||||||
|
// would cause the test file's size to bloat to ~2000 loc. Since the legacy
|
||||||
|
// generators are actively being rewritten, this heinous test seemed the lesser
|
||||||
|
// of two evils.
|
||||||
it("saves option sets to its inner generators", async () => {
|
it("saves option sets to its inner generators", async () => {
|
||||||
const account = mockAccountServiceWith(SomeUser);
|
const account = mockAccountServiceWith(SomeUser);
|
||||||
const navigation = createNavigationGenerator({ type: "password" });
|
const navigation = createNavigationGenerator({ type: "password" });
|
||||||
|
@ -665,7 +669,7 @@ describe("LegacyUsernameGenerationService", () => {
|
||||||
simpleLogin,
|
simpleLogin,
|
||||||
);
|
);
|
||||||
|
|
||||||
await generator.saveOptions({
|
const options: UsernameGeneratorOptions = {
|
||||||
type: "catchall",
|
type: "catchall",
|
||||||
wordCapitalize: true,
|
wordCapitalize: true,
|
||||||
wordIncludeNumber: false,
|
wordIncludeNumber: false,
|
||||||
|
@ -685,7 +689,9 @@ describe("LegacyUsernameGenerationService", () => {
|
||||||
forwardedSimpleLoginApiKey: "simpleLoginToken",
|
forwardedSimpleLoginApiKey: "simpleLoginToken",
|
||||||
forwardedSimpleLoginBaseUrl: "https://simplelogin.api.example.com",
|
forwardedSimpleLoginBaseUrl: "https://simplelogin.api.example.com",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(navigation.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(navigation.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
type: "password",
|
type: "password",
|
||||||
|
@ -699,18 +705,28 @@ describe("LegacyUsernameGenerationService", () => {
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "word";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(effUsername.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(effUsername.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
wordCapitalize: true,
|
wordCapitalize: true,
|
||||||
wordIncludeNumber: false,
|
wordIncludeNumber: false,
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "subaddress";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(subaddress.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(subaddress.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
subaddressType: "random",
|
subaddressType: "random",
|
||||||
subaddressEmail: "foo@example.com",
|
subaddressEmail: "foo@example.com",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "anonaddy";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(addyIo.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(addyIo.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "addyIoToken",
|
token: "addyIoToken",
|
||||||
domain: "addyio.example.com",
|
domain: "addyio.example.com",
|
||||||
|
@ -718,27 +734,47 @@ describe("LegacyUsernameGenerationService", () => {
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "duckduckgo";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(duckDuckGo.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(duckDuckGo.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "ddgToken",
|
token: "ddgToken",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "fastmail";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(fastmail.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(fastmail.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "fastmailToken",
|
token: "fastmailToken",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "firefoxrelay";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(firefoxRelay.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(firefoxRelay.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "firefoxToken",
|
token: "firefoxToken",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "forwardemail";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(forwardEmail.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(forwardEmail.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "forwardEmailToken",
|
token: "forwardEmailToken",
|
||||||
domain: "example.com",
|
domain: "example.com",
|
||||||
website: null,
|
website: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.type = "forwarded";
|
||||||
|
options.forwardedService = "simplelogin";
|
||||||
|
await generator.saveOptions(options);
|
||||||
|
|
||||||
expect(simpleLogin.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
expect(simpleLogin.saveOptions).toHaveBeenCalledWith(SomeUser, {
|
||||||
token: "simpleLoginToken",
|
token: "simpleLoginToken",
|
||||||
baseUrl: "https://simplelogin.api.example.com",
|
baseUrl: "https://simplelogin.api.example.com",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { zip, firstValueFrom, map, concatMap, combineLatest } from "rxjs";
|
import { zip, firstValueFrom, map, concatMap, combineLatest } from "rxjs";
|
||||||
|
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import {
|
import {
|
||||||
ApiOptions,
|
ApiOptions,
|
||||||
EmailDomainOptions,
|
EmailDomainOptions,
|
||||||
|
@ -13,6 +14,8 @@ import {
|
||||||
EffUsernameGenerationOptions,
|
EffUsernameGenerationOptions,
|
||||||
Forwarders,
|
Forwarders,
|
||||||
SubaddressGenerationOptions,
|
SubaddressGenerationOptions,
|
||||||
|
UsernameGeneratorType,
|
||||||
|
ForwarderId,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
import { GeneratorNavigationService, GeneratorNavigation } from "@bitwarden/generator-navigation";
|
import { GeneratorNavigationService, GeneratorNavigation } from "@bitwarden/generator-navigation";
|
||||||
|
|
||||||
|
@ -178,28 +181,76 @@ export class LegacyUsernameGenerationService implements UsernameGenerationServic
|
||||||
const stored = this.toStoredOptions(options);
|
const stored = this.toStoredOptions(options);
|
||||||
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
|
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
|
||||||
|
|
||||||
|
const saved = await this.saveGeneratorOptions(activeAccount.id, options.type, stored);
|
||||||
|
if (!saved) {
|
||||||
|
await this.saveForwarderOptions(activeAccount.id, options.forwardedService, stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run navigation options 2nd so that navigation options update doesn't race the `saved options`
|
||||||
|
// update in Firefox.
|
||||||
|
await this.saveNavigationOptions(activeAccount.id, stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveNavigationOptions(account: UserId, options: MappedOptions) {
|
||||||
// generator settings needs to preserve whether password or passphrase is selected,
|
// generator settings needs to preserve whether password or passphrase is selected,
|
||||||
// so `navigationOptions` is mutated.
|
// so `navigationOptions` is mutated.
|
||||||
const navigationOptions$ = zip(
|
const navigationOptions$ = zip(
|
||||||
this.navigation.options$(activeAccount.id),
|
this.navigation.options$(account),
|
||||||
this.navigation.defaults$(activeAccount.id),
|
this.navigation.defaults$(account),
|
||||||
).pipe(map(([options, defaults]) => options ?? defaults));
|
).pipe(map(([options, defaults]) => options ?? defaults));
|
||||||
let navigationOptions = await firstValueFrom(navigationOptions$);
|
|
||||||
navigationOptions = Object.assign(navigationOptions, stored.generator);
|
|
||||||
await this.navigation.saveOptions(activeAccount.id, navigationOptions);
|
|
||||||
|
|
||||||
// overwrite all other settings with latest values
|
let navigationOptions = await firstValueFrom(navigationOptions$);
|
||||||
await Promise.all([
|
navigationOptions = Object.assign(navigationOptions, options.generator);
|
||||||
this.catchall.saveOptions(activeAccount.id, stored.algorithms.catchall),
|
await this.navigation.saveOptions(account, navigationOptions);
|
||||||
this.effUsername.saveOptions(activeAccount.id, stored.algorithms.effUsername),
|
}
|
||||||
this.subaddress.saveOptions(activeAccount.id, stored.algorithms.subaddress),
|
|
||||||
this.addyIo.saveOptions(activeAccount.id, stored.forwarders.addyIo),
|
private async saveGeneratorOptions(
|
||||||
this.duckDuckGo.saveOptions(activeAccount.id, stored.forwarders.duckDuckGo),
|
account: UserId,
|
||||||
this.fastmail.saveOptions(activeAccount.id, stored.forwarders.fastmail),
|
type: UsernameGeneratorType,
|
||||||
this.firefoxRelay.saveOptions(activeAccount.id, stored.forwarders.firefoxRelay),
|
options: MappedOptions,
|
||||||
this.forwardEmail.saveOptions(activeAccount.id, stored.forwarders.forwardEmail),
|
) {
|
||||||
this.simpleLogin.saveOptions(activeAccount.id, stored.forwarders.simpleLogin),
|
switch (type) {
|
||||||
]);
|
case "word":
|
||||||
|
await this.effUsername.saveOptions(account, options.algorithms.effUsername);
|
||||||
|
return true;
|
||||||
|
case "subaddress":
|
||||||
|
await this.subaddress.saveOptions(account, options.algorithms.subaddress);
|
||||||
|
return true;
|
||||||
|
case "catchall":
|
||||||
|
await this.catchall.saveOptions(account, options.algorithms.catchall);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveForwarderOptions(
|
||||||
|
account: UserId,
|
||||||
|
forwarder: ForwarderId | "",
|
||||||
|
options: MappedOptions,
|
||||||
|
) {
|
||||||
|
switch (forwarder) {
|
||||||
|
case "anonaddy":
|
||||||
|
await this.addyIo.saveOptions(account, options.forwarders.addyIo);
|
||||||
|
return true;
|
||||||
|
case "duckduckgo":
|
||||||
|
await this.duckDuckGo.saveOptions(account, options.forwarders.duckDuckGo);
|
||||||
|
return true;
|
||||||
|
case "fastmail":
|
||||||
|
await this.fastmail.saveOptions(account, options.forwarders.fastmail);
|
||||||
|
return true;
|
||||||
|
case "firefoxrelay":
|
||||||
|
await this.firefoxRelay.saveOptions(account, options.forwarders.firefoxRelay);
|
||||||
|
return true;
|
||||||
|
case "forwardemail":
|
||||||
|
await this.forwardEmail.saveOptions(account, options.forwarders.forwardEmail);
|
||||||
|
return true;
|
||||||
|
case "simplelogin":
|
||||||
|
await this.simpleLogin.saveOptions(account, options.forwarders.simpleLogin);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private toStoredOptions(options: UsernameGeneratorOptions) {
|
private toStoredOptions(options: UsernameGeneratorOptions) {
|
||||||
|
|
Loading…
Reference in New Issue