1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-22 07:50:04 +02:00

forwarder component cleanup

This commit is contained in:
✨ Audrey ✨ 2024-10-17 15:16:34 -04:00
parent 98270c9124
commit 0cb3e809dd
No known key found for this signature in database
GPG Key ID: 0CF8B4C0D9088B97
3 changed files with 39 additions and 9 deletions

View File

@ -48,7 +48,7 @@
</bit-section-header> </bit-section-header>
<div class="tw-mb-4"> <div class="tw-mb-4">
<bit-card> <bit-card>
<form class="box" [formGroup]="username" class="tw-container"> <form [formGroup]="username" class="box tw-container">
<bit-form-field> <bit-form-field>
<bit-label>{{ "type" | i18n }}</bit-label> <bit-label>{{ "type" | i18n }}</bit-label>
<bit-select [items]="usernameOptions$ | async" formControlName="nav"> </bit-select> <bit-select [items]="usernameOptions$ | async" formControlName="nav"> </bit-select>
@ -57,9 +57,9 @@
}}</bit-hint> }}</bit-hint>
</bit-form-field> </bit-form-field>
</form> </form>
<form class="box" [formGroup]="forwarder" class="tw-container"> <form *ngIf="!!(showForwarder$ | async)" [formGroup]="forwarder" class="box tw-container">
<bit-form-field> <bit-form-field>
<bit-label>{{ "forwarder" | i18n }}</bit-label> <bit-label>{{ "service" | i18n }}</bit-label>
<bit-select [items]="forwarderOptions$ | async" formControlName="nav"> </bit-select> <bit-select [items]="forwarderOptions$ | async" formControlName="nav"> </bit-select>
</bit-form-field> </bit-form-field>
</form> </form>
@ -69,7 +69,7 @@
(onUpdated)="generate$.next()" (onUpdated)="generate$.next()"
/> />
<tools-forwarder-settings <tools-forwarder-settings
*ngIf="!!(forwarderId$ | async)" *ngIf="!!(showForwarder$ | async)"
[forwarder]="forwarderId$ | async" [forwarder]="forwarderId$ | async"
[userId]="this.userId$ | async" [userId]="this.userId$ | async"
/> />

View File

@ -8,6 +8,7 @@ import {
map, map,
of, of,
ReplaySubject, ReplaySubject,
startWith,
Subject, Subject,
switchMap, switchMap,
takeUntil, takeUntil,
@ -49,6 +50,8 @@ type UsernameNavValue = UsernameAlgorithm | EmailAlgorithm | typeof FORWARDER;
const NONE_SELECTED = "none"; const NONE_SELECTED = "none";
type ForwarderNavValue = ForwarderIntegration | typeof NONE_SELECTED; type ForwarderNavValue = ForwarderIntegration | typeof NONE_SELECTED;
const FORWARDER_INITIALIZED = new GeneratedCredential("-", null, Date.now());
@Component({ @Component({
selector: "tools-credential-generator", selector: "tools-credential-generator",
templateUrl: "credential-generator.component.html", templateUrl: "credential-generator.component.html",
@ -112,7 +115,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
map((algorithms) => { map((algorithms) => {
const usernames = algorithms.filter((a) => !isForwarderIntegration(a.id)); const usernames = algorithms.filter((a) => !isForwarderIntegration(a.id));
const usernameOptions = this.toOptions(usernames) as Option<UsernameNavValue>[]; const usernameOptions = this.toOptions(usernames) as Option<UsernameNavValue>[];
usernameOptions.push({ value: FORWARDER, label: this.i18nService.t("forwarder") }); usernameOptions.push({ value: FORWARDER, label: this.i18nService.t("forwardedEmail") });
const forwarders = algorithms.filter((a) => isForwarderIntegration(a.id)); const forwarders = algorithms.filter((a) => isForwarderIntegration(a.id));
const forwarderOptions = this.toOptions(forwarders) as Option<ForwarderNavValue>[]; const forwarderOptions = this.toOptions(forwarders) as Option<ForwarderNavValue>[];
@ -226,12 +229,20 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
} else if (isPasswordAlgorithm(algorithm)) { } else if (isPasswordAlgorithm(algorithm)) {
setPreference("password"); setPreference("password");
} else { } else {
this.showForwarder$.next(false);
return; return;
} }
preferences.next(preference); preferences.next(preference);
}); });
this.username.valueChanges
.pipe(
map(({ nav }) => nav === FORWARDER),
takeUntil(this.destroyed),
)
.subscribe(this.showForwarder$);
// populate the form with the user's preferences to kick off interactivity // populate the form with the user's preferences to kick off interactivity
preferences.pipe(takeUntil(this.destroyed)).subscribe(({ email, username, password }) => { preferences.pipe(takeUntil(this.destroyed)).subscribe(({ email, username, password }) => {
// the last preference set by the user "wins" // the last preference set by the user "wins"
@ -305,7 +316,9 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
if (isForwarderIntegration(type)) { if (isForwarderIntegration(type)) {
const forwarder = getForwarderConfiguration(type.forwarder); const forwarder = getForwarderConfiguration(type.forwarder);
const configuration = toCredentialGeneratorConfiguration(forwarder); const configuration = toCredentialGeneratorConfiguration(forwarder);
return this.generatorService.generate$(configuration, dependencies); const generator = this.generatorService.generate$(configuration, dependencies);
return generator.pipe(startWith(FORWARDER_INITIALIZED));
} }
throw new Error(`Invalid generator type: "${type}"`); throw new Error(`Invalid generator type: "${type}"`);
@ -323,6 +336,9 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
/** Tracks the currently selected forwarder. */ /** Tracks the currently selected forwarder. */
protected forwarderId$ = new BehaviorSubject<IntegrationId>(null); protected forwarderId$ = new BehaviorSubject<IntegrationId>(null);
/** Tracks forwarder control visibility */
protected showForwarder$ = new BehaviorSubject<boolean>(false);
/** tracks the currently selected credential type */ /** tracks the currently selected credential type */
protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1); protected algorithm$ = new ReplaySubject<AlgorithmInfo>(1);
@ -344,7 +360,7 @@ export class CredentialGeneratorComponent implements OnInit, OnDestroy {
private toOptions(algorithms: AlgorithmInfo[]) { private toOptions(algorithms: AlgorithmInfo[]) {
const options: Option<CredentialAlgorithm>[] = algorithms.map((algorithm) => ({ const options: Option<CredentialAlgorithm>[] = algorithms.map((algorithm) => ({
value: algorithm.id, value: algorithm.id,
label: this.i18nService.t(algorithm.name), label: algorithm.name,
})); }));
return options; return options;

View File

@ -43,7 +43,12 @@ import { UserStateSubject } from "@bitwarden/common/tools/state/user-state-subje
import { UserId } from "@bitwarden/common/types/guid"; import { UserId } from "@bitwarden/common/types/guid";
import { Randomizer } from "../abstractions"; import { Randomizer } from "../abstractions";
import { Generators, getForwarderConfiguration, toCredentialGeneratorConfiguration } from "../data"; import {
Generators,
getForwarderConfiguration,
Integrations,
toCredentialGeneratorConfiguration,
} from "../data";
import { availableAlgorithms } from "../policies/available-algorithms-policy"; import { availableAlgorithms } from "../policies/available-algorithms-policy";
import { mapPolicyToConstraints } from "../rx"; import { mapPolicyToConstraints } from "../rx";
import { import {
@ -53,6 +58,7 @@ import {
AlgorithmInfo, AlgorithmInfo,
CredentialPreference, CredentialPreference,
isForwarderIntegration, isForwarderIntegration,
ForwarderIntegration,
} from "../types"; } from "../types";
import { import {
CredentialGeneratorConfiguration as Configuration, CredentialGeneratorConfiguration as Configuration,
@ -208,12 +214,20 @@ export class CredentialGeneratorService {
algorithms(category: CredentialCategory[]): AlgorithmInfo[]; algorithms(category: CredentialCategory[]): AlgorithmInfo[];
algorithms(category: CredentialCategory | CredentialCategory[]): AlgorithmInfo[] { algorithms(category: CredentialCategory | CredentialCategory[]): AlgorithmInfo[] {
const categories: CredentialCategory[] = Array.isArray(category) ? category : [category]; const categories: CredentialCategory[] = Array.isArray(category) ? category : [category];
const algorithms = categories const algorithms = categories
.flatMap((c) => CredentialCategories[c] as CredentialAlgorithm[]) .flatMap((c) => CredentialCategories[c] as CredentialAlgorithm[])
.map((id) => this.algorithm(id)) .map((id) => this.algorithm(id))
.filter((info) => info !== null); .filter((info) => info !== null);
return algorithms; const forwarders = Object.keys(Integrations)
.map((key: keyof typeof Integrations) => {
const forwarder: ForwarderIntegration = { forwarder: Integrations[key].id };
return this.algorithm(forwarder);
})
.filter((forwarder) => categories.includes(forwarder.category));
return algorithms.concat(forwarders);
} }
/** Look up the metadata for a specific generator algorithm /** Look up the metadata for a specific generator algorithm