mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 17:53:39 +00:00
[BEEEP] [PM-28239] Migrate generators to standalone (#17386)
* Migrate generators to use standalone and control flow * Resolve feedback * Add variable for account * Fix generators
This commit is contained in:
@@ -136,6 +136,7 @@ import {
|
|||||||
DialogService,
|
DialogService,
|
||||||
ToastService,
|
ToastService,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
|
import { GeneratorServicesModule } from "@bitwarden/generator-components";
|
||||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
||||||
import {
|
import {
|
||||||
BiometricsService,
|
BiometricsService,
|
||||||
@@ -743,7 +744,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [JslibServicesModule],
|
imports: [JslibServicesModule, GeneratorServicesModule],
|
||||||
declarations: [],
|
declarations: [],
|
||||||
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
||||||
providers: safeProviders,
|
providers: safeProviders,
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/s
|
|||||||
import { SyncService } from "@bitwarden/common/platform/sync";
|
import { SyncService } from "@bitwarden/common/platform/sync";
|
||||||
import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { DialogService, ToastService } from "@bitwarden/components";
|
import { DialogService, ToastService } from "@bitwarden/components";
|
||||||
|
import { GeneratorServicesModule } from "@bitwarden/generator-components";
|
||||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
||||||
import {
|
import {
|
||||||
KdfConfigService,
|
KdfConfigService,
|
||||||
@@ -499,7 +500,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [JslibServicesModule],
|
imports: [JslibServicesModule, GeneratorServicesModule],
|
||||||
declarations: [],
|
declarations: [],
|
||||||
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
||||||
providers: safeProviders,
|
providers: safeProviders,
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ import {
|
|||||||
} from "@bitwarden/common/platform/theming/theme-state.service";
|
} from "@bitwarden/common/platform/theming/theme-state.service";
|
||||||
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
|
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
|
||||||
import { DialogService, ToastService } from "@bitwarden/components";
|
import { DialogService, ToastService } from "@bitwarden/components";
|
||||||
|
import { GeneratorServicesModule } from "@bitwarden/generator-components";
|
||||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
||||||
import {
|
import {
|
||||||
KdfConfigService,
|
KdfConfigService,
|
||||||
@@ -484,7 +485,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [],
|
||||||
imports: [CommonModule, JslibServicesModule],
|
imports: [CommonModule, JslibServicesModule, GeneratorServicesModule],
|
||||||
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
||||||
providers: safeProviders,
|
providers: safeProviders,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { FormFieldModule } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CatchallGenerationOptions,
|
CatchallGenerationOptions,
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
/** Options group for catchall emails */
|
/** Options group for catchall emails */
|
||||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||||
@@ -24,7 +27,7 @@ import {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-catchall-settings",
|
selector: "tools-catchall-settings",
|
||||||
templateUrl: "catchall-settings.component.html",
|
templateUrl: "catchall-settings.component.html",
|
||||||
standalone: false,
|
imports: [ReactiveFormsModule, FormFieldModule, JslibModule, I18nPipe],
|
||||||
})
|
})
|
||||||
export class CatchallSettingsComponent implements OnInit, OnDestroy, OnChanges {
|
export class CatchallSettingsComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<bit-dialog #dialog background="alt">
|
<bit-dialog #dialog background="alt">
|
||||||
<span bitDialogTitle>{{ "generatorHistory" | i18n }}</span>
|
<span bitDialogTitle>{{ "generatorHistory" | i18n }}</span>
|
||||||
<ng-container bitDialogContent>
|
<ng-container bitDialogContent>
|
||||||
<bit-empty-credential-history *ngIf="!(hasHistory$ | async)" style="display: contents" />
|
@if (hasHistory$ | async) {
|
||||||
<bit-credential-generator-history [account]="account$ | async" *ngIf="hasHistory$ | async" />
|
<bit-credential-generator-history [account]="account$ | async" />
|
||||||
|
} @else {
|
||||||
|
<bit-empty-credential-history style="display: contents" />
|
||||||
|
}
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container bitDialogFooter>
|
<ng-container bitDialogFooter>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
<bit-item *ngFor="let credential of credentials$ | async">
|
@for (credential of credentials$ | async; track credential) {
|
||||||
<bit-item-content>
|
<bit-item>
|
||||||
<bit-color-password class="tw-font-mono" [password]="credential.credential" />
|
<bit-item-content>
|
||||||
<div slot="secondary">
|
<bit-color-password class="tw-font-mono" [password]="credential.credential" />
|
||||||
{{ credential.generationDate | date: "medium" }}
|
<div slot="secondary">
|
||||||
</div>
|
{{ credential.generationDate | date: "medium" }}
|
||||||
</bit-item-content>
|
</div>
|
||||||
<ng-container slot="end">
|
</bit-item-content>
|
||||||
<bit-item-action>
|
<ng-container slot="end">
|
||||||
<button
|
<bit-item-action>
|
||||||
type="button"
|
<button
|
||||||
bitIconButton="bwi-clone"
|
type="button"
|
||||||
[appCopyClick]="credential.credential"
|
bitIconButton="bwi-clone"
|
||||||
[valueLabel]="getGeneratedValueText(credential)"
|
[appCopyClick]="credential.credential"
|
||||||
[label]="getCopyText(credential)"
|
[valueLabel]="getGeneratedValueText(credential)"
|
||||||
showToast
|
[label]="getCopyText(credential)"
|
||||||
>
|
showToast
|
||||||
{{ getCopyText(credential) }}
|
>
|
||||||
</button>
|
{{ getCopyText(credential) }}
|
||||||
</bit-item-action>
|
</button>
|
||||||
</ng-container>
|
</bit-item-action>
|
||||||
</bit-item>
|
</ng-container>
|
||||||
|
</bit-item>
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
import { AlgorithmsByType, CredentialGeneratorService } from "@bitwarden/generator-core";
|
import { AlgorithmsByType, CredentialGeneratorService } from "@bitwarden/generator-core";
|
||||||
import { GeneratedCredential, GeneratorHistoryService } from "@bitwarden/generator-history";
|
import { GeneratedCredential, GeneratorHistoryService } from "@bitwarden/generator-history";
|
||||||
|
|
||||||
import { GeneratorModule } from "./generator.module";
|
|
||||||
import { translate } from "./util";
|
import { translate } from "./util";
|
||||||
|
|
||||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||||
@@ -32,13 +31,12 @@ import { translate } from "./util";
|
|||||||
selector: "bit-credential-generator-history",
|
selector: "bit-credential-generator-history",
|
||||||
templateUrl: "credential-generator-history.component.html",
|
templateUrl: "credential-generator-history.component.html",
|
||||||
imports: [
|
imports: [
|
||||||
ColorPasswordModule,
|
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
ColorPasswordModule,
|
||||||
IconButtonModule,
|
IconButtonModule,
|
||||||
NoItemsModule,
|
NoItemsModule,
|
||||||
JslibModule,
|
JslibModule,
|
||||||
ItemModule,
|
ItemModule,
|
||||||
GeneratorModule,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CredentialGeneratorHistoryComponent implements OnChanges, OnInit, OnDestroy {
|
export class CredentialGeneratorHistoryComponent implements OnChanges, OnInit, OnDestroy {
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
(selectedChange)="onRootChanged({ nav: $event })"
|
(selectedChange)="onRootChanged({ nav: $event })"
|
||||||
attr.aria-label="{{ 'type' | i18n }}"
|
attr.aria-label="{{ 'type' | i18n }}"
|
||||||
>
|
>
|
||||||
<bit-toggle *ngFor="let option of rootOptions$ | async" [value]="option.value">
|
@for (option of rootOptions$ | async; track option) {
|
||||||
{{ option.label }}
|
<bit-toggle [value]="option.value">
|
||||||
</bit-toggle>
|
{{ option.label }}
|
||||||
|
</bit-toggle>
|
||||||
|
}
|
||||||
</bit-toggle-group>
|
</bit-toggle-group>
|
||||||
|
|
||||||
<nudge-generator-spotlight></nudge-generator-spotlight>
|
<nudge-generator-spotlight></nudge-generator-spotlight>
|
||||||
@@ -40,69 +42,80 @@
|
|||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</bit-card>
|
</bit-card>
|
||||||
<tools-password-settings
|
@let showAlgorithm = showAlgorithm$ | async;
|
||||||
class="tw-mt-6"
|
@let account = account$ | async;
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.password"
|
@switch (showAlgorithm?.id) {
|
||||||
[account]="account$ | async"
|
@case (Algorithm.password) {
|
||||||
(onUpdated)="generate('password settings')"
|
<tools-password-settings
|
||||||
/>
|
class="tw-mt-6"
|
||||||
<tools-passphrase-settings
|
[account]="account"
|
||||||
class="tw-mt-6"
|
(onUpdated)="generate('password settings')"
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.passphrase"
|
/>
|
||||||
[account]="account$ | async"
|
}
|
||||||
(onUpdated)="generate('passphrase settings')"
|
@case (Algorithm.passphrase) {
|
||||||
/>
|
<tools-passphrase-settings
|
||||||
<bit-section *ngIf="(category$ | async) !== 'password'">
|
class="tw-mt-6"
|
||||||
<bit-section-header>
|
[account]="account"
|
||||||
<h2 bitTypography="h6">{{ "options" | i18n }}</h2>
|
(onUpdated)="generate('passphrase settings')"
|
||||||
</bit-section-header>
|
/>
|
||||||
<div class="tw-mb-4">
|
}
|
||||||
<bit-card>
|
}
|
||||||
<form [formGroup]="username" class="tw-container">
|
@if ((category$ | async) !== "password") {
|
||||||
<bit-form-field>
|
<bit-section>
|
||||||
<bit-label>{{ "type" | i18n }}</bit-label>
|
<bit-section-header>
|
||||||
<bit-select
|
<h2 bitTypography="h6">{{ "options" | i18n }}</h2>
|
||||||
[items]="usernameOptions$ | async"
|
</bit-section-header>
|
||||||
formControlName="nav"
|
<div class="tw-mb-4">
|
||||||
data-testid="username-type"
|
<bit-card>
|
||||||
>
|
<form [formGroup]="username" class="tw-container">
|
||||||
</bit-select>
|
<bit-form-field>
|
||||||
<bit-hint *ngIf="!!(credentialTypeHint$ | async)">{{
|
<bit-label>{{ "type" | i18n }}</bit-label>
|
||||||
credentialTypeHint$ | async
|
<bit-select
|
||||||
}}</bit-hint>
|
[items]="usernameOptions$ | async"
|
||||||
</bit-form-field>
|
formControlName="nav"
|
||||||
</form>
|
data-testid="username-type"
|
||||||
<form *ngIf="showForwarder$ | async" [formGroup]="forwarder" class="tw-container">
|
>
|
||||||
<bit-form-field>
|
</bit-select>
|
||||||
<bit-label>{{ "service" | i18n }}</bit-label>
|
@if (credentialTypeHint$ | async) {
|
||||||
<bit-select
|
<bit-hint>{{ credentialTypeHint$ | async }}</bit-hint>
|
||||||
[items]="forwarderOptions$ | async"
|
}
|
||||||
formControlName="nav"
|
</bit-form-field>
|
||||||
data-testid="email-forwarding-service"
|
</form>
|
||||||
>
|
@if (showForwarder$ | async) {
|
||||||
</bit-select>
|
<form [formGroup]="forwarder" class="tw-container">
|
||||||
</bit-form-field>
|
<bit-form-field>
|
||||||
</form>
|
<bit-label>{{ "service" | i18n }}</bit-label>
|
||||||
<tools-catchall-settings
|
<bit-select
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.catchall"
|
[items]="forwarderOptions$ | async"
|
||||||
[account]="account$ | async"
|
formControlName="nav"
|
||||||
(onUpdated)="generate('catchall settings')"
|
data-testid="email-forwarding-service"
|
||||||
/>
|
>
|
||||||
<tools-forwarder-settings
|
</bit-select>
|
||||||
*ngIf="!!(forwarderId$ | async)"
|
</bit-form-field>
|
||||||
[account]="account$ | async"
|
</form>
|
||||||
[forwarder]="forwarderId$ | async"
|
}
|
||||||
/>
|
@if (showAlgorithm?.id === Algorithm.catchall) {
|
||||||
<tools-subaddress-settings
|
<tools-catchall-settings
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.plusAddress"
|
[account]="account"
|
||||||
[account]="account$ | async"
|
(onUpdated)="generate('catchall settings')"
|
||||||
(onUpdated)="generate('subaddress settings')"
|
/>
|
||||||
/>
|
}
|
||||||
<tools-username-settings
|
@if (forwarderId$ | async; as forwarderId) {
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.username"
|
<tools-forwarder-settings [account]="account" [forwarder]="forwarderId" />
|
||||||
[account]="account$ | async"
|
}
|
||||||
(onUpdated)="generate('username settings')"
|
@if (showAlgorithm?.id === Algorithm.plusAddress) {
|
||||||
/>
|
<tools-subaddress-settings
|
||||||
</bit-card>
|
[account]="account"
|
||||||
</div>
|
(onUpdated)="generate('subaddress settings')"
|
||||||
</bit-section>
|
/>
|
||||||
|
}
|
||||||
|
@if (showAlgorithm?.id === Algorithm.username) {
|
||||||
|
<tools-username-settings
|
||||||
|
[account]="account"
|
||||||
|
(onUpdated)="generate('username settings')"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</bit-card>
|
||||||
|
</div>
|
||||||
|
</bit-section>
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
||||||
|
import { AsyncPipe } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@@ -10,7 +11,7 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
catchError,
|
catchError,
|
||||||
@@ -27,6 +28,7 @@ import {
|
|||||||
withLatestFrom,
|
withLatestFrom,
|
||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -37,7 +39,23 @@ import {
|
|||||||
ifEnabledSemanticLoggerProvider,
|
ifEnabledSemanticLoggerProvider,
|
||||||
} from "@bitwarden/common/tools/log";
|
} from "@bitwarden/common/tools/log";
|
||||||
import { UserId } from "@bitwarden/common/types/guid";
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import { ToastService, Option } from "@bitwarden/components";
|
import {
|
||||||
|
ToastService,
|
||||||
|
Option,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
ToggleGroupModule,
|
||||||
|
TypographyModule,
|
||||||
|
FormFieldModule,
|
||||||
|
SelectModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialType,
|
CredentialType,
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
@@ -55,7 +73,15 @@ import {
|
|||||||
Type,
|
Type,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
|
import { CatchallSettingsComponent } from "./catchall-settings.component";
|
||||||
|
import { ForwarderSettingsComponent } from "./forwarder-settings.component";
|
||||||
|
import { NudgeGeneratorSpotlightComponent } from "./nudge-generator-spotlight.component";
|
||||||
|
import { PassphraseSettingsComponent } from "./passphrase-settings.component";
|
||||||
|
import { PasswordSettingsComponent } from "./password-settings.component";
|
||||||
|
import { SubaddressSettingsComponent } from "./subaddress-settings.component";
|
||||||
|
import { UsernameSettingsComponent } from "./username-settings.component";
|
||||||
import { translate } from "./util";
|
import { translate } from "./util";
|
||||||
|
|
||||||
// constants used to identify navigation selections that are not
|
// constants used to identify navigation selections that are not
|
||||||
@@ -69,7 +95,32 @@ const NONE_SELECTED = "none";
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-credential-generator",
|
selector: "tools-credential-generator",
|
||||||
templateUrl: "credential-generator.component.html",
|
templateUrl: "credential-generator.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
ToggleGroupModule,
|
||||||
|
NudgeGeneratorSpotlightComponent,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
PasswordSettingsComponent,
|
||||||
|
PassphraseSettingsComponent,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormFieldModule,
|
||||||
|
SelectModule,
|
||||||
|
CatchallSettingsComponent,
|
||||||
|
ForwarderSettingsComponent,
|
||||||
|
SubaddressSettingsComponent,
|
||||||
|
UsernameSettingsComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class CredentialGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
export class CredentialGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
private readonly destroyed = new Subject<void>();
|
private readonly destroyed = new Subject<void>();
|
||||||
|
|||||||
@@ -1,28 +1,34 @@
|
|||||||
<form [formGroup]="settings" class="tw-container">
|
<form [formGroup]="settings" class="tw-container">
|
||||||
<bit-form-field *ngIf="displayDomain">
|
@if (displayDomain) {
|
||||||
<bit-label>{{ "forwarderDomainName" | i18n }}</bit-label>
|
<bit-form-field>
|
||||||
<input
|
<bit-label>{{ "forwarderDomainName" | i18n }}</bit-label>
|
||||||
bitInput
|
<input
|
||||||
formControlName="domain"
|
bitInput
|
||||||
type="text"
|
formControlName="domain"
|
||||||
placeholder="example.com"
|
type="text"
|
||||||
(change)="save('domain')"
|
placeholder="example.com"
|
||||||
/>
|
(change)="save('domain')"
|
||||||
<bit-hint>{{ "forwarderDomainNameHint" | i18n }}</bit-hint>
|
/>
|
||||||
</bit-form-field>
|
<bit-hint>{{ "forwarderDomainNameHint" | i18n }}</bit-hint>
|
||||||
<bit-form-field *ngIf="displayToken">
|
</bit-form-field>
|
||||||
<bit-label>{{ "apiKey" | i18n }}</bit-label>
|
}
|
||||||
<input bitInput formControlName="token" type="password" (change)="save('password')" />
|
@if (displayToken) {
|
||||||
<button
|
<bit-form-field>
|
||||||
type="button"
|
<bit-label>{{ "apiKey" | i18n }}</bit-label>
|
||||||
bitIconButton
|
<input bitInput formControlName="token" type="password" (change)="save('password')" />
|
||||||
bitSuffix
|
<button
|
||||||
bitPasswordInputToggle
|
type="button"
|
||||||
(change)="save('token')"
|
bitIconButton
|
||||||
></button>
|
bitSuffix
|
||||||
</bit-form-field>
|
bitPasswordInputToggle
|
||||||
<bit-form-field *ngIf="displayBaseUrl" disableMargin>
|
(change)="save('token')"
|
||||||
<bit-label>{{ "selfHostBaseUrl" | i18n }}</bit-label>
|
></button>
|
||||||
<input bitInput formControlName="baseUrl" type="text" (change)="save('baseUrl')" />
|
</bit-form-field>
|
||||||
</bit-form-field>
|
}
|
||||||
|
@if (displayBaseUrl) {
|
||||||
|
<bit-form-field disableMargin>
|
||||||
|
<bit-label>{{ "selfHostBaseUrl" | i18n }}</bit-label>
|
||||||
|
<input bitInput formControlName="baseUrl" type="text" (change)="save('baseUrl')" />
|
||||||
|
</bit-form-field>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -8,16 +8,24 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { map, ReplaySubject, skip, Subject, switchAll, takeUntil, withLatestFrom } from "rxjs";
|
import { map, ReplaySubject, skip, Subject, switchAll, takeUntil, withLatestFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { VendorId } from "@bitwarden/common/tools/extension";
|
import { VendorId } from "@bitwarden/common/tools/extension";
|
||||||
|
import {
|
||||||
|
FormFieldModule,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
ForwarderOptions,
|
ForwarderOptions,
|
||||||
GeneratorMetadata,
|
GeneratorMetadata,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
const Controls = Object.freeze({
|
const Controls = Object.freeze({
|
||||||
domain: "domain",
|
domain: "domain",
|
||||||
@@ -31,7 +39,15 @@ const Controls = Object.freeze({
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-forwarder-settings",
|
selector: "tools-forwarder-settings",
|
||||||
templateUrl: "forwarder-settings.component.html",
|
templateUrl: "forwarder-settings.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormFieldModule,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class ForwarderSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
export class ForwarderSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
@@ -1,67 +1,13 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
import { ReactiveFormsModule } from "@angular/forms";
|
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
|
||||||
import {
|
|
||||||
CardComponent,
|
|
||||||
ColorPasswordModule,
|
|
||||||
CheckboxModule,
|
|
||||||
FormFieldModule,
|
|
||||||
IconButtonModule,
|
|
||||||
InputModule,
|
|
||||||
ItemModule,
|
|
||||||
SectionComponent,
|
|
||||||
SectionHeaderComponent,
|
|
||||||
SelectModule,
|
|
||||||
ToggleGroupModule,
|
|
||||||
TypographyModule,
|
|
||||||
} from "@bitwarden/components";
|
|
||||||
|
|
||||||
import { CatchallSettingsComponent } from "./catchall-settings.component";
|
|
||||||
import { CredentialGeneratorComponent } from "./credential-generator.component";
|
import { CredentialGeneratorComponent } from "./credential-generator.component";
|
||||||
import { ForwarderSettingsComponent } from "./forwarder-settings.component";
|
|
||||||
import { GeneratorServicesModule } from "./generator-services.module";
|
|
||||||
import { NudgeGeneratorSpotlightComponent } from "./nudge-generator-spotlight.component";
|
|
||||||
import { PassphraseSettingsComponent } from "./passphrase-settings.component";
|
|
||||||
import { PasswordGeneratorComponent } from "./password-generator.component";
|
import { PasswordGeneratorComponent } from "./password-generator.component";
|
||||||
import { PasswordSettingsComponent } from "./password-settings.component";
|
|
||||||
import { SubaddressSettingsComponent } from "./subaddress-settings.component";
|
|
||||||
import { UsernameGeneratorComponent } from "./username-generator.component";
|
import { UsernameGeneratorComponent } from "./username-generator.component";
|
||||||
import { UsernameSettingsComponent } from "./username-settings.component";
|
|
||||||
|
|
||||||
/** Shared module containing generator component dependencies */
|
/** Shared module containing generator component dependencies */
|
||||||
|
/** @deprecated Use individual components instead. */
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [CredentialGeneratorComponent, PasswordGeneratorComponent, UsernameGeneratorComponent],
|
||||||
CardComponent,
|
|
||||||
ColorPasswordModule,
|
|
||||||
CheckboxModule,
|
|
||||||
CommonModule,
|
|
||||||
FormFieldModule,
|
|
||||||
GeneratorServicesModule,
|
|
||||||
IconButtonModule,
|
|
||||||
InputModule,
|
|
||||||
ItemModule,
|
|
||||||
JslibModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
SectionComponent,
|
|
||||||
SectionHeaderComponent,
|
|
||||||
SelectModule,
|
|
||||||
ToggleGroupModule,
|
|
||||||
TypographyModule,
|
|
||||||
NudgeGeneratorSpotlightComponent,
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
CatchallSettingsComponent,
|
|
||||||
CredentialGeneratorComponent,
|
|
||||||
ForwarderSettingsComponent,
|
|
||||||
SubaddressSettingsComponent,
|
|
||||||
PasswordGeneratorComponent,
|
|
||||||
PassphraseSettingsComponent,
|
|
||||||
PasswordSettingsComponent,
|
|
||||||
UsernameGeneratorComponent,
|
|
||||||
UsernameSettingsComponent,
|
|
||||||
],
|
|
||||||
exports: [CredentialGeneratorComponent, PasswordGeneratorComponent, UsernameGeneratorComponent],
|
exports: [CredentialGeneratorComponent, PasswordGeneratorComponent, UsernameGeneratorComponent],
|
||||||
})
|
})
|
||||||
export class GeneratorModule {
|
export class GeneratorModule {
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* This file contains the public interface for the generator components library.
|
||||||
|
*
|
||||||
|
* Be mindful of what you export here, as those components should be considered stable
|
||||||
|
* and part of the public API contract.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { CredentialGeneratorComponent } from "./credential-generator.component";
|
||||||
export { CredentialGeneratorHistoryComponent } from "./credential-generator-history.component";
|
export { CredentialGeneratorHistoryComponent } from "./credential-generator-history.component";
|
||||||
export { CredentialGeneratorHistoryDialogComponent } from "./credential-generator-history-dialog.component";
|
export { CredentialGeneratorHistoryDialogComponent } from "./credential-generator-history-dialog.component";
|
||||||
export { EmptyCredentialHistoryComponent } from "./empty-credential-history.component";
|
export { EmptyCredentialHistoryComponent } from "./empty-credential-history.component";
|
||||||
export { GeneratorModule } from "./generator.module";
|
export { GeneratorModule } from "./generator.module";
|
||||||
export { GeneratorServicesModule, SYSTEM_SERVICE_PROVIDER } from "./generator-services.module";
|
export { GeneratorServicesModule, SYSTEM_SERVICE_PROVIDER } from "./generator-services.module";
|
||||||
|
export { PasswordGeneratorComponent } from "./password-generator.component";
|
||||||
|
export { UsernameGeneratorComponent } from "./username-generator.component";
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
<div class="tw-mb-4" *ngIf="showGeneratorSpotlight$ | async">
|
@if (showGeneratorSpotlight$ | async) {
|
||||||
<bit-spotlight
|
<div class="tw-mb-4">
|
||||||
[title]="'generatorNudgeTitle' | i18n"
|
<bit-spotlight
|
||||||
(onDismiss)="dismissGeneratorSpotlight(NudgeType.GeneratorNudgeStatus)"
|
[title]="'generatorNudgeTitle' | i18n"
|
||||||
>
|
(onDismiss)="dismissGeneratorSpotlight(NudgeType.GeneratorNudgeStatus)"
|
||||||
<p class="tw-text-main tw-mb-0" bitTypography="body2">
|
>
|
||||||
<span class="tw-sr-only">
|
<p class="tw-text-main tw-mb-0" bitTypography="body2">
|
||||||
{{ "generatorNudgeBodyAria" | i18n }}
|
<span class="tw-sr-only">
|
||||||
</span>
|
{{ "generatorNudgeBodyAria" | i18n }}
|
||||||
<span aria-hidden="true">
|
</span>
|
||||||
{{ "generatorNudgeBodyOne" | i18n }} <i class="bwi bwi-generate"></i>
|
<span aria-hidden="true">
|
||||||
{{ "generatorNudgeBodyTwo" | i18n }}
|
{{ "generatorNudgeBodyOne" | i18n }} <i class="bwi bwi-generate"></i>
|
||||||
</span>
|
{{ "generatorNudgeBodyTwo" | i18n }}
|
||||||
</p>
|
</span>
|
||||||
</bit-spotlight>
|
</p>
|
||||||
</div>
|
</bit-spotlight>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<bit-section [disableMargin]="disableMargin">
|
<bit-section [disableMargin]="disableMargin">
|
||||||
<bit-section-header *ngIf="showHeader">
|
@if (showHeader) {
|
||||||
<h6 bitTypography="h6">{{ "options" | i18n }}</h6>
|
<bit-section-header>
|
||||||
</bit-section-header>
|
<h6 bitTypography="h6">{{ "options" | i18n }}</h6>
|
||||||
|
</bit-section-header>
|
||||||
|
}
|
||||||
<form [formGroup]="settings" class="tw-container">
|
<form [formGroup]="settings" class="tw-container">
|
||||||
<div class="tw-mb-4">
|
<div class="tw-mb-4">
|
||||||
<bit-card>
|
<bit-card>
|
||||||
@@ -51,7 +53,9 @@
|
|||||||
/>
|
/>
|
||||||
<bit-label>{{ "includeNumber" | i18n }}</bit-label>
|
<bit-label>{{ "includeNumber" | i18n }}</bit-label>
|
||||||
</bit-form-control>
|
</bit-form-control>
|
||||||
<p *ngIf="policyInEffect" bitTypography="helper">{{ "generatorPolicyInEffect" | i18n }}</p>
|
@if (policyInEffect) {
|
||||||
|
<p bitTypography="helper">{{ "generatorPolicyInEffect" | i18n }}</p>
|
||||||
|
}
|
||||||
</bit-card>
|
</bit-card>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
||||||
|
import { AsyncPipe } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
OnInit,
|
OnInit,
|
||||||
Input,
|
Input,
|
||||||
@@ -9,9 +10,10 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { skip, takeUntil, Subject, map, withLatestFrom, ReplaySubject, tap } from "rxjs";
|
import { skip, takeUntil, Subject, map, withLatestFrom, ReplaySubject, tap } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -20,11 +22,21 @@ import {
|
|||||||
disabledSemanticLoggerProvider,
|
disabledSemanticLoggerProvider,
|
||||||
ifEnabledSemanticLoggerProvider,
|
ifEnabledSemanticLoggerProvider,
|
||||||
} from "@bitwarden/common/tools/log";
|
} from "@bitwarden/common/tools/log";
|
||||||
|
import {
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
TypographyModule,
|
||||||
|
FormFieldModule,
|
||||||
|
CheckboxModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
PassphraseGenerationOptions,
|
PassphraseGenerationOptions,
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
const Controls = Object.freeze({
|
const Controls = Object.freeze({
|
||||||
numWords: "numWords",
|
numWords: "numWords",
|
||||||
@@ -39,7 +51,19 @@ const Controls = Object.freeze({
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-passphrase-settings",
|
selector: "tools-passphrase-settings",
|
||||||
templateUrl: "passphrase-settings.component.html",
|
templateUrl: "passphrase-settings.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
CheckboxModule,
|
||||||
|
AsyncPipe,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PassphraseSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
export class PassphraseSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
<bit-toggle-group
|
@if (showCredentialTypes$ | async) {
|
||||||
fullWidth
|
<bit-toggle-group
|
||||||
class="tw-mb-4"
|
fullWidth
|
||||||
[selected]="credentialType$ | async"
|
class="tw-mb-4"
|
||||||
(selectedChange)="onCredentialTypeChanged($event)"
|
[selected]="credentialType$ | async"
|
||||||
*ngIf="showCredentialTypes$ | async"
|
(selectedChange)="onCredentialTypeChanged($event)"
|
||||||
attr.aria-label="{{ 'type' | i18n }}"
|
attr.aria-label="{{ 'type' | i18n }}"
|
||||||
>
|
>
|
||||||
<bit-toggle *ngFor="let option of passwordOptions$ | async" [value]="option.value">
|
@for (option of passwordOptions$ | async; track option) {
|
||||||
{{ option.label }}
|
<bit-toggle [value]="option.value">
|
||||||
</bit-toggle>
|
{{ option.label }}
|
||||||
</bit-toggle-group>
|
</bit-toggle>
|
||||||
|
}
|
||||||
|
</bit-toggle-group>
|
||||||
|
}
|
||||||
<bit-card class="tw-flex tw-justify-between tw-mb-4">
|
<bit-card class="tw-flex tw-justify-between tw-mb-4">
|
||||||
<div class="tw-grow tw-flex tw-items-center tw-min-w-0">
|
<div class="tw-grow tw-flex tw-items-center tw-min-w-0">
|
||||||
<bit-color-password class="tw-font-mono" [password]="value$ | async"></bit-color-password>
|
<bit-color-password class="tw-font-mono" [password]="value$ | async"></bit-color-password>
|
||||||
@@ -37,17 +40,19 @@
|
|||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</bit-card>
|
</bit-card>
|
||||||
<tools-password-settings
|
@if ((algorithm$ | async)?.id === Algorithm.password) {
|
||||||
class="tw-mt-6"
|
<tools-password-settings
|
||||||
*ngIf="(algorithm$ | async)?.id === Algorithm.password"
|
class="tw-mt-6"
|
||||||
[account]="account$ | async"
|
[account]="account$ | async"
|
||||||
[disableMargin]="disableMargin"
|
[disableMargin]="disableMargin"
|
||||||
(onUpdated)="generate('password settings')"
|
(onUpdated)="generate('password settings')"
|
||||||
/>
|
/>
|
||||||
<tools-passphrase-settings
|
}
|
||||||
class="tw-mt-6"
|
@if ((algorithm$ | async)?.id === Algorithm.passphrase) {
|
||||||
*ngIf="(algorithm$ | async)?.id === Algorithm.passphrase"
|
<tools-passphrase-settings
|
||||||
[account]="account$ | async"
|
class="tw-mt-6"
|
||||||
(onUpdated)="generate('passphrase settings')"
|
[account]="account$ | async"
|
||||||
[disableMargin]="disableMargin"
|
(onUpdated)="generate('passphrase settings')"
|
||||||
/>
|
[disableMargin]="disableMargin"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
||||||
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
||||||
|
import { AsyncPipe } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@@ -24,6 +25,7 @@ import {
|
|||||||
withLatestFrom,
|
withLatestFrom,
|
||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -33,7 +35,18 @@ import {
|
|||||||
ifEnabledSemanticLoggerProvider,
|
ifEnabledSemanticLoggerProvider,
|
||||||
} from "@bitwarden/common/tools/log";
|
} from "@bitwarden/common/tools/log";
|
||||||
import { UserId } from "@bitwarden/common/types/guid";
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import { ToastService, Option } from "@bitwarden/components";
|
import {
|
||||||
|
ToastService,
|
||||||
|
Option,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
ToggleGroupModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
GeneratedCredential,
|
GeneratedCredential,
|
||||||
@@ -49,7 +62,10 @@ import {
|
|||||||
Profile,
|
Profile,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
|
import { PassphraseSettingsComponent } from "./passphrase-settings.component";
|
||||||
|
import { PasswordSettingsComponent } from "./password-settings.component";
|
||||||
import { toAlgorithmInfo, translate } from "./util";
|
import { toAlgorithmInfo, translate } from "./util";
|
||||||
|
|
||||||
/** Options group for passwords */
|
/** Options group for passwords */
|
||||||
@@ -58,7 +74,21 @@ import { toAlgorithmInfo, translate } from "./util";
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-password-generator",
|
selector: "tools-password-generator",
|
||||||
templateUrl: "password-generator.component.html",
|
templateUrl: "password-generator.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
ToggleGroupModule,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
PasswordSettingsComponent,
|
||||||
|
PassphraseSettingsComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PasswordGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
export class PasswordGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<bit-section [disableMargin]="disableMargin">
|
<bit-section [disableMargin]="disableMargin">
|
||||||
<bit-section-header *ngIf="showHeader">
|
@if (showHeader) {
|
||||||
<h2 bitTypography="h6">{{ "options" | i18n }}</h2>
|
<bit-section-header>
|
||||||
</bit-section-header>
|
<h2 bitTypography="h6">{{ "options" | i18n }}</h2>
|
||||||
|
</bit-section-header>
|
||||||
|
}
|
||||||
<form [formGroup]="settings" class="tw-container">
|
<form [formGroup]="settings" class="tw-container">
|
||||||
<div class="tw-mb-4">
|
<div class="tw-mb-4">
|
||||||
<bit-card>
|
<bit-card>
|
||||||
@@ -62,9 +64,9 @@
|
|||||||
(change)="save('special')"
|
(change)="save('special')"
|
||||||
/>
|
/>
|
||||||
<!-- hard-coded the special characters string because `$` indicates an i18n interpolation,
|
<!-- hard-coded the special characters string because `$` indicates an i18n interpolation,
|
||||||
and is handled inconsistently across browsers. Angular template syntax is used to
|
and is handled inconsistently across browsers. Angular template syntax is used to
|
||||||
ensure special characters are entity-encoded.
|
ensure special characters are entity-encoded.
|
||||||
-->
|
-->
|
||||||
<bit-label>{{ "!@#$%^&*" }}</bit-label>
|
<bit-label>{{ "!@#$%^&*" }}</bit-label>
|
||||||
</bit-form-control>
|
</bit-form-control>
|
||||||
</div>
|
</div>
|
||||||
@@ -97,7 +99,9 @@
|
|||||||
/>
|
/>
|
||||||
<bit-label>{{ "avoidAmbiguous" | i18n }}</bit-label>
|
<bit-label>{{ "avoidAmbiguous" | i18n }}</bit-label>
|
||||||
</bit-form-control>
|
</bit-form-control>
|
||||||
<p *ngIf="policyInEffect" bitTypography="helper">{{ "generatorPolicyInEffect" | i18n }}</p>
|
@if (policyInEffect) {
|
||||||
|
<p bitTypography="helper">{{ "generatorPolicyInEffect" | i18n }}</p>
|
||||||
|
}
|
||||||
</bit-card>
|
</bit-card>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
||||||
|
import { AsyncPipe } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
OnInit,
|
OnInit,
|
||||||
Input,
|
Input,
|
||||||
@@ -9,16 +10,27 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { takeUntil, Subject, map, filter, tap, skip, ReplaySubject, withLatestFrom } from "rxjs";
|
import { takeUntil, Subject, map, filter, tap, skip, ReplaySubject, withLatestFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import {
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
TypographyModule,
|
||||||
|
CheckboxModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
PasswordGenerationOptions,
|
PasswordGenerationOptions,
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
import { hasRangeOfValues } from "./util";
|
import { hasRangeOfValues } from "./util";
|
||||||
|
|
||||||
@@ -39,7 +51,19 @@ const Controls = Object.freeze({
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-password-settings",
|
selector: "tools-password-settings",
|
||||||
templateUrl: "password-settings.component.html",
|
templateUrl: "password-settings.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
CheckboxModule,
|
||||||
|
AsyncPipe,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PasswordSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
export class PasswordSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { FormFieldModule } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
SubaddressGenerationOptions,
|
SubaddressGenerationOptions,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
/** Options group for plus-addressed emails */
|
/** Options group for plus-addressed emails */
|
||||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||||
@@ -24,7 +27,7 @@ import {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-subaddress-settings",
|
selector: "tools-subaddress-settings",
|
||||||
templateUrl: "subaddress-settings.component.html",
|
templateUrl: "subaddress-settings.component.html",
|
||||||
standalone: false,
|
imports: [ReactiveFormsModule, FormFieldModule, JslibModule, I18nPipe],
|
||||||
})
|
})
|
||||||
export class SubaddressSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
export class SubaddressSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
@@ -42,42 +42,41 @@
|
|||||||
data-testid="username-type"
|
data-testid="username-type"
|
||||||
>
|
>
|
||||||
</bit-select>
|
</bit-select>
|
||||||
<bit-hint *ngIf="!!(credentialTypeHint$ | async)">{{
|
@if (credentialTypeHint$ | async) {
|
||||||
credentialTypeHint$ | async
|
<bit-hint>{{ credentialTypeHint$ | async }}</bit-hint>
|
||||||
}}</bit-hint>
|
}
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
</form>
|
</form>
|
||||||
<form *ngIf="showForwarder$ | async" [formGroup]="forwarder" class="tw-container">
|
@if (showForwarder$ | async) {
|
||||||
<bit-form-field>
|
<form [formGroup]="forwarder" class="tw-container">
|
||||||
<bit-label>{{ "service" | i18n }}</bit-label>
|
<bit-form-field>
|
||||||
<bit-select
|
<bit-label>{{ "service" | i18n }}</bit-label>
|
||||||
[items]="forwarderOptions$ | async"
|
<bit-select
|
||||||
formControlName="nav"
|
[items]="forwarderOptions$ | async"
|
||||||
data-testid="email-forwarding-service"
|
formControlName="nav"
|
||||||
>
|
data-testid="email-forwarding-service"
|
||||||
</bit-select>
|
>
|
||||||
</bit-form-field>
|
</bit-select>
|
||||||
</form>
|
</bit-form-field>
|
||||||
<tools-catchall-settings
|
</form>
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.catchall"
|
}
|
||||||
[account]="account$ | async"
|
@let showAlgorithm = showAlgorithm$ | async;
|
||||||
(onUpdated)="generate('catchall settings')"
|
@let account = account$ | async;
|
||||||
/>
|
@if (showAlgorithm?.id === Algorithm.catchall) {
|
||||||
<tools-forwarder-settings
|
<tools-catchall-settings [account]="account" (onUpdated)="generate('catchall settings')" />
|
||||||
*ngIf="!!(forwarderId$ | async)"
|
}
|
||||||
[forwarder]="forwarderId$ | async"
|
@if (forwarderId$ | async; as forwarderId) {
|
||||||
[account]="account$ | async"
|
<tools-forwarder-settings [forwarder]="forwarderId" [account]="account" />
|
||||||
/>
|
}
|
||||||
<tools-subaddress-settings
|
@if (showAlgorithm?.id === Algorithm.plusAddress) {
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.plusAddress"
|
<tools-subaddress-settings
|
||||||
[account]="account$ | async"
|
[account]="account"
|
||||||
(onUpdated)="generate('subaddress settings')"
|
(onUpdated)="generate('subaddress settings')"
|
||||||
/>
|
/>
|
||||||
<tools-username-settings
|
}
|
||||||
*ngIf="(showAlgorithm$ | async)?.id === Algorithm.username"
|
@if (showAlgorithm?.id === Algorithm.username) {
|
||||||
[account]="account$ | async"
|
<tools-username-settings [account]="account" (onUpdated)="generate('username settings')" />
|
||||||
(onUpdated)="generate('username settings')"
|
}
|
||||||
/>
|
|
||||||
</bit-card>
|
</bit-card>
|
||||||
</div>
|
</div>
|
||||||
</bit-section>
|
</bit-section>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
import { LiveAnnouncer } from "@angular/cdk/a11y";
|
||||||
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
import { coerceBooleanProperty } from "@angular/cdk/coercion";
|
||||||
|
import { NgClass, AsyncPipe } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@@ -11,7 +12,7 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
catchError,
|
catchError,
|
||||||
@@ -28,6 +29,7 @@ import {
|
|||||||
withLatestFrom,
|
withLatestFrom,
|
||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -38,7 +40,22 @@ import {
|
|||||||
ifEnabledSemanticLoggerProvider,
|
ifEnabledSemanticLoggerProvider,
|
||||||
} from "@bitwarden/common/tools/log";
|
} from "@bitwarden/common/tools/log";
|
||||||
import { UserId } from "@bitwarden/common/types/guid";
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import { ToastService, Option } from "@bitwarden/components";
|
import {
|
||||||
|
ToastService,
|
||||||
|
Option,
|
||||||
|
AriaDisableDirective,
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
TooltipDirective,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
SelectComponent,
|
||||||
|
TypographyModule,
|
||||||
|
FormFieldModule,
|
||||||
|
} from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
AlgorithmInfo,
|
AlgorithmInfo,
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
@@ -55,7 +72,12 @@ import {
|
|||||||
Algorithm,
|
Algorithm,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
import { GeneratorHistoryService } from "@bitwarden/generator-history";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
|
import { CatchallSettingsComponent } from "./catchall-settings.component";
|
||||||
|
import { ForwarderSettingsComponent } from "./forwarder-settings.component";
|
||||||
|
import { SubaddressSettingsComponent } from "./subaddress-settings.component";
|
||||||
|
import { UsernameSettingsComponent } from "./username-settings.component";
|
||||||
import { toAlgorithmInfo, translate } from "./util";
|
import { toAlgorithmInfo, translate } from "./util";
|
||||||
|
|
||||||
// constants used to identify navigation selections that are not
|
// constants used to identify navigation selections that are not
|
||||||
@@ -69,7 +91,29 @@ const NONE_SELECTED = "none";
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-username-generator",
|
selector: "tools-username-generator",
|
||||||
templateUrl: "username-generator.component.html",
|
templateUrl: "username-generator.component.html",
|
||||||
standalone: false,
|
imports: [
|
||||||
|
BaseCardDirective,
|
||||||
|
CardComponent,
|
||||||
|
ColorPasswordComponent,
|
||||||
|
AriaDisableDirective,
|
||||||
|
TooltipDirective,
|
||||||
|
BitIconButtonComponent,
|
||||||
|
CopyClickDirective,
|
||||||
|
SectionComponent,
|
||||||
|
SectionHeaderComponent,
|
||||||
|
TypographyModule,
|
||||||
|
NgClass,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
SelectComponent,
|
||||||
|
FormFieldModule,
|
||||||
|
CatchallSettingsComponent,
|
||||||
|
ForwarderSettingsComponent,
|
||||||
|
SubaddressSettingsComponent,
|
||||||
|
UsernameSettingsComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
JslibModule,
|
||||||
|
I18nPipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class UsernameGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
export class UsernameGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the username generator
|
/** Instantiates the username generator
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
import { map, ReplaySubject, skip, Subject, takeUntil, withLatestFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
import { Account } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { FormFieldModule, CheckboxModule } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
CredentialGeneratorService,
|
CredentialGeneratorService,
|
||||||
EffUsernameGenerationOptions,
|
EffUsernameGenerationOptions,
|
||||||
BuiltIn,
|
BuiltIn,
|
||||||
} from "@bitwarden/generator-core";
|
} from "@bitwarden/generator-core";
|
||||||
|
import { I18nPipe } from "@bitwarden/ui-common";
|
||||||
|
|
||||||
/** Options group for usernames */
|
/** Options group for usernames */
|
||||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||||
@@ -24,7 +27,7 @@ import {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: "tools-username-settings",
|
selector: "tools-username-settings",
|
||||||
templateUrl: "username-settings.component.html",
|
templateUrl: "username-settings.component.html",
|
||||||
standalone: false,
|
imports: [ReactiveFormsModule, FormFieldModule, CheckboxModule, JslibModule, I18nPipe],
|
||||||
})
|
})
|
||||||
export class UsernameSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
export class UsernameSettingsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
/** Instantiates the component
|
/** Instantiates the component
|
||||||
|
|||||||
Reference in New Issue
Block a user