mirror of
https://github.com/bitwarden/browser.git
synced 2024-10-22 07:50:04 +02:00
localize algorithm names and descriptions in the credential generator service
This commit is contained in:
parent
3aebbe9a64
commit
b79d4c12f1
@ -19,9 +19,9 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { Option } from "@bitwarden/components/src/select/option";
|
||||
import {
|
||||
AlgorithmInfo,
|
||||
CredentialAlgorithm,
|
||||
CredentialCategory,
|
||||
CredentialGeneratorInfo,
|
||||
CredentialGeneratorService,
|
||||
GeneratedCredential,
|
||||
Generators,
|
||||
@ -114,7 +114,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.algorithm$
|
||||
.pipe(
|
||||
map((a) => a?.descriptionKey && this.i18nService.t(a?.descriptionKey)),
|
||||
map((a) => a?.description),
|
||||
takeUntil(this.destroyed),
|
||||
)
|
||||
.subscribe((hint) => {
|
||||
@ -268,7 +268,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
|
||||
protected rootOptions$ = new BehaviorSubject<Option<RootNavValue>[]>([]);
|
||||
|
||||
/** tracks the currently selected credential type */
|
||||
protected algorithm$ = new ReplaySubject<CredentialGeneratorInfo>(1);
|
||||
protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1);
|
||||
|
||||
/** Emits hint key for the currently selected credential type */
|
||||
protected credentialTypeHint$ = new ReplaySubject<string>(1);
|
||||
@ -285,10 +285,10 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
|
||||
/** Emits when a new credential is requested */
|
||||
protected readonly generate$ = new Subject<void>();
|
||||
|
||||
private toOptions(algorithms: CredentialGeneratorInfo[]) {
|
||||
private toOptions(algorithms: AlgorithmInfo[]) {
|
||||
const options: Option<CredentialAlgorithm>[] = algorithms.map((algorithm) => ({
|
||||
value: algorithm.id,
|
||||
label: this.i18nService.t(algorithm.nameKey),
|
||||
label: this.i18nService.t(algorithm.name),
|
||||
}));
|
||||
|
||||
return options;
|
||||
|
@ -20,9 +20,9 @@ import {
|
||||
Generators,
|
||||
PasswordAlgorithm,
|
||||
GeneratedCredential,
|
||||
CredentialGeneratorInfo,
|
||||
CredentialAlgorithm,
|
||||
isPasswordAlgorithm,
|
||||
AlgorithmInfo,
|
||||
} from "@bitwarden/generator-core";
|
||||
|
||||
/** Options group for passwords */
|
||||
@ -174,12 +174,12 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy {
|
||||
protected passwordOptions$ = new BehaviorSubject<Option<CredentialAlgorithm>[]>([]);
|
||||
|
||||
/** tracks the currently selected credential type */
|
||||
protected algorithm$ = new ReplaySubject<CredentialGeneratorInfo>(1);
|
||||
protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1);
|
||||
|
||||
private toOptions(algorithms: CredentialGeneratorInfo[]) {
|
||||
private toOptions(algorithms: AlgorithmInfo[]) {
|
||||
const options: Option<CredentialAlgorithm>[] = algorithms.map((algorithm) => ({
|
||||
value: algorithm.id,
|
||||
label: this.i18nService.t(algorithm.nameKey),
|
||||
label: this.i18nService.t(algorithm.name),
|
||||
}));
|
||||
|
||||
return options;
|
||||
|
@ -17,8 +17,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { Option } from "@bitwarden/components/src/select/option";
|
||||
import {
|
||||
AlgorithmInfo,
|
||||
CredentialAlgorithm,
|
||||
CredentialGeneratorInfo,
|
||||
CredentialGeneratorService,
|
||||
GeneratedCredential,
|
||||
Generators,
|
||||
@ -97,7 +97,7 @@ export class UsernameGeneratorComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.algorithm$
|
||||
.pipe(
|
||||
map((a) => a?.descriptionKey && this.i18nService.t(a?.descriptionKey)),
|
||||
map((a) => a?.description),
|
||||
takeUntil(this.destroyed),
|
||||
)
|
||||
.subscribe((hint) => {
|
||||
@ -205,7 +205,7 @@ export class UsernameGeneratorComponent implements OnInit, OnDestroy {
|
||||
protected forwarderOptions$ = new BehaviorSubject<Option<CredentialAlgorithm>[]>([]);
|
||||
|
||||
/** tracks the currently selected credential type */
|
||||
protected algorithm$ = new ReplaySubject<CredentialGeneratorInfo>(1);
|
||||
protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1);
|
||||
|
||||
/** Emits hint key for the currently selected credential type */
|
||||
protected credentialTypeHint$ = new ReplaySubject<string>(1);
|
||||
@ -219,10 +219,10 @@ export class UsernameGeneratorComponent implements OnInit, OnDestroy {
|
||||
/** Emits when a new credential is requested */
|
||||
protected readonly generate$ = new Subject<void>();
|
||||
|
||||
private toOptions(algorithms: CredentialGeneratorInfo[]) {
|
||||
private toOptions(algorithms: AlgorithmInfo[]) {
|
||||
const options: Option<CredentialAlgorithm>[] = algorithms.map((algorithm) => ({
|
||||
value: algorithm.id,
|
||||
label: this.i18nService.t(algorithm.nameKey),
|
||||
label: this.i18nService.t(algorithm.name),
|
||||
}));
|
||||
|
||||
return options;
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
SingleUserDependency,
|
||||
UserDependency,
|
||||
} from "@bitwarden/common/tools/dependencies";
|
||||
import { IntegrationId } from "@bitwarden/common/tools/integration";
|
||||
import { IntegrationId, IntegrationMetadata } from "@bitwarden/common/tools/integration";
|
||||
import { RestClient } from "@bitwarden/common/tools/integration/rpc";
|
||||
import { isDynamic } from "@bitwarden/common/tools/state/state-constraints-dependency";
|
||||
import { UserStateSubject } from "@bitwarden/common/tools/state/user-state-subject";
|
||||
@ -43,12 +43,13 @@ import {
|
||||
CredentialAlgorithm,
|
||||
CredentialCategories,
|
||||
CredentialCategory,
|
||||
CredentialGeneratorInfo,
|
||||
AlgorithmInfo,
|
||||
CredentialPreference,
|
||||
isForwarderIntegration,
|
||||
} from "../types";
|
||||
import {
|
||||
CredentialGeneratorConfiguration as Configuration,
|
||||
CredentialGeneratorInfo,
|
||||
GeneratorDependencyProvider,
|
||||
} from "../types/credential-generator-configuration";
|
||||
import { GeneratorConstraints } from "../types/generator-constraints";
|
||||
@ -152,11 +153,11 @@ export class CredentialGeneratorService {
|
||||
algorithms$(
|
||||
category: CredentialCategory,
|
||||
dependencies?: Algorithms$Dependencies,
|
||||
): Observable<CredentialGeneratorInfo[]>;
|
||||
): Observable<AlgorithmInfo[]>;
|
||||
algorithms$(
|
||||
category: CredentialCategory[],
|
||||
dependencies?: Algorithms$Dependencies,
|
||||
): Observable<CredentialGeneratorInfo[]>;
|
||||
): Observable<AlgorithmInfo[]>;
|
||||
algorithms$(
|
||||
category: CredentialCategory | CredentialCategory[],
|
||||
dependencies?: Algorithms$Dependencies,
|
||||
@ -197,9 +198,9 @@ export class CredentialGeneratorService {
|
||||
* @param category the category or categories of interest
|
||||
* @returns A list containing the requested metadata.
|
||||
*/
|
||||
algorithms(category: CredentialCategory): CredentialGeneratorInfo[];
|
||||
algorithms(category: CredentialCategory[]): CredentialGeneratorInfo[];
|
||||
algorithms(category: CredentialCategory | CredentialCategory[]): CredentialGeneratorInfo[] {
|
||||
algorithms(category: CredentialCategory): AlgorithmInfo[];
|
||||
algorithms(category: CredentialCategory[]): AlgorithmInfo[];
|
||||
algorithms(category: CredentialCategory | CredentialCategory[]): AlgorithmInfo[] {
|
||||
const categories = Array.isArray(category) ? category : [category];
|
||||
const algorithms = categories
|
||||
.flatMap((c) => CredentialCategories[c])
|
||||
@ -213,18 +214,37 @@ export class CredentialGeneratorService {
|
||||
* @param id identifies the algorithm
|
||||
* @returns the requested metadata, or `null` if the metadata wasn't found.
|
||||
*/
|
||||
algorithm(id: CredentialAlgorithm): CredentialGeneratorInfo {
|
||||
if (isForwarderIntegration(id)) {
|
||||
const forwarder = getForwarderConfiguration(id.forwarder);
|
||||
if (!forwarder) {
|
||||
throw new Error(`Invalid forwarder id: ${id.forwarder}`);
|
||||
}
|
||||
algorithm(id: CredentialAlgorithm): AlgorithmInfo {
|
||||
let generator: CredentialGeneratorInfo = null;
|
||||
let integration: IntegrationMetadata = null;
|
||||
|
||||
const generator = toCredentialGeneratorConfiguration(forwarder);
|
||||
return generator;
|
||||
if (isForwarderIntegration(id)) {
|
||||
const forwarderConfig = getForwarderConfiguration(id.forwarder);
|
||||
integration = forwarderConfig;
|
||||
|
||||
if (forwarderConfig) {
|
||||
generator = toCredentialGeneratorConfiguration(forwarderConfig);
|
||||
}
|
||||
} else {
|
||||
return Generators[id];
|
||||
generator = Generators[id];
|
||||
}
|
||||
|
||||
if (!generator) {
|
||||
throw new Error(`Invalid credential algorithm: ${JSON.stringify(id)}`);
|
||||
}
|
||||
|
||||
const info: AlgorithmInfo = {
|
||||
id: generator.id,
|
||||
category: generator.category,
|
||||
name: integration ? integration.name : this.i18nService.t(generator.nameKey),
|
||||
onlyOnRequest: generator.onlyOnRequest,
|
||||
};
|
||||
|
||||
if (generator.descriptionKey) {
|
||||
info.description = this.i18nService.t(generator.descriptionKey);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/** Get the settings for the provided configuration
|
||||
|
@ -14,6 +14,33 @@ export type GeneratorDependencyProvider = {
|
||||
i18nService: I18nService;
|
||||
};
|
||||
|
||||
export type AlgorithmInfo = {
|
||||
/** Uniquely identifies the credential configuration
|
||||
* @example
|
||||
* // Use `isForwarderIntegration(algorithm: CredentialAlgorithm)`
|
||||
* // to pattern test whether the credential describes a forwarder algorithm
|
||||
* const meta : CredentialGeneratorInfo = // ...
|
||||
* const { forwarder } = isForwarderIntegration(meta.id) ? credentialId : {};
|
||||
*/
|
||||
id: CredentialAlgorithm;
|
||||
|
||||
/** The kind of credential generated by this configuration */
|
||||
category: CredentialCategory;
|
||||
|
||||
/** Localized algorithm name */
|
||||
name: string;
|
||||
|
||||
/** Localized algorithm description */
|
||||
description?: string;
|
||||
|
||||
/** When true, credential generation must be explicitly requested.
|
||||
* @remarks this property is useful when credential generation
|
||||
* carries side effects, such as configuring a service external
|
||||
* to Bitwarden.
|
||||
*/
|
||||
onlyOnRequest: boolean;
|
||||
};
|
||||
|
||||
/** Credential generator metadata common across credential generators */
|
||||
export type CredentialGeneratorInfo = {
|
||||
/** Uniquely identifies the credential configuration
|
||||
|
Loading…
Reference in New Issue
Block a user