mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-02 18:17:46 +01:00
[PM-15921] Remove v1 generator and generator history (#12345)
* Remove v1 generator, generator history page and extension refresh conditional routing * Remove unused keys from en/messages.json --------- Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
parent
d209da4c94
commit
ce5ae478a8
@ -454,9 +454,6 @@
|
|||||||
"length": {
|
"length": {
|
||||||
"message": "Length"
|
"message": "Length"
|
||||||
},
|
},
|
||||||
"passwordMinLength": {
|
|
||||||
"message": "Minimum password length"
|
|
||||||
},
|
|
||||||
"uppercase": {
|
"uppercase": {
|
||||||
"message": "Uppercase (A-Z)",
|
"message": "Uppercase (A-Z)",
|
||||||
"description": "deprecated. Use uppercaseLabel instead."
|
"description": "deprecated. Use uppercaseLabel instead."
|
||||||
@ -528,10 +525,6 @@
|
|||||||
"minSpecial": {
|
"minSpecial": {
|
||||||
"message": "Minimum special"
|
"message": "Minimum special"
|
||||||
},
|
},
|
||||||
"avoidAmbChar": {
|
|
||||||
"message": "Avoid ambiguous characters",
|
|
||||||
"description": "deprecated. Use avoidAmbiguous instead."
|
|
||||||
},
|
|
||||||
"avoidAmbiguous": {
|
"avoidAmbiguous": {
|
||||||
"message": "Avoid ambiguous characters",
|
"message": "Avoid ambiguous characters",
|
||||||
"description": "Label for the avoid ambiguous characters checkbox."
|
"description": "Label for the avoid ambiguous characters checkbox."
|
||||||
@ -2047,9 +2040,6 @@
|
|||||||
"clone": {
|
"clone": {
|
||||||
"message": "Clone"
|
"message": "Clone"
|
||||||
},
|
},
|
||||||
"passwordGeneratorPolicyInEffect": {
|
|
||||||
"message": "One or more organization policies are affecting your generator settings."
|
|
||||||
},
|
|
||||||
"passwordGenerator": {
|
"passwordGenerator": {
|
||||||
"message": "Password generator"
|
"message": "Password generator"
|
||||||
},
|
},
|
||||||
@ -2884,9 +2874,6 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"message": "Error"
|
"message": "Error"
|
||||||
},
|
},
|
||||||
"regenerateUsername": {
|
|
||||||
"message": "Regenerate username"
|
|
||||||
},
|
|
||||||
"generateUsername": {
|
"generateUsername": {
|
||||||
"message": "Generate username"
|
"message": "Generate username"
|
||||||
},
|
},
|
||||||
@ -2927,9 +2914,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"usernameType": {
|
|
||||||
"message": "Username type"
|
|
||||||
},
|
|
||||||
"plusAddressedEmail": {
|
"plusAddressedEmail": {
|
||||||
"message": "Plus addressed email",
|
"message": "Plus addressed email",
|
||||||
"description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com"
|
"description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com"
|
||||||
@ -2952,12 +2936,6 @@
|
|||||||
"websiteName": {
|
"websiteName": {
|
||||||
"message": "Website name"
|
"message": "Website name"
|
||||||
},
|
},
|
||||||
"whatWouldYouLikeToGenerate": {
|
|
||||||
"message": "What would you like to generate?"
|
|
||||||
},
|
|
||||||
"passwordType": {
|
|
||||||
"message": "Password type"
|
|
||||||
},
|
|
||||||
"service": {
|
"service": {
|
||||||
"message": "Service"
|
"message": "Service"
|
||||||
},
|
},
|
||||||
|
@ -86,8 +86,6 @@ import BrowserPopupUtils from "../platform/popup/browser-popup-utils";
|
|||||||
import { popupRouterCacheGuard } from "../platform/popup/view-cache/popup-router-cache.service";
|
import { popupRouterCacheGuard } from "../platform/popup/view-cache/popup-router-cache.service";
|
||||||
import { CredentialGeneratorHistoryComponent } from "../tools/popup/generator/credential-generator-history.component";
|
import { CredentialGeneratorHistoryComponent } from "../tools/popup/generator/credential-generator-history.component";
|
||||||
import { CredentialGeneratorComponent } from "../tools/popup/generator/credential-generator.component";
|
import { CredentialGeneratorComponent } from "../tools/popup/generator/credential-generator.component";
|
||||||
import { GeneratorComponent } from "../tools/popup/generator/generator.component";
|
|
||||||
import { PasswordGeneratorHistoryComponent } from "../tools/popup/generator/password-generator-history.component";
|
|
||||||
import { SendAddEditComponent } from "../tools/popup/send/send-add-edit.component";
|
import { SendAddEditComponent } from "../tools/popup/send/send-add-edit.component";
|
||||||
import { SendGroupingsComponent } from "../tools/popup/send/send-groupings.component";
|
import { SendGroupingsComponent } from "../tools/popup/send/send-groupings.component";
|
||||||
import { SendTypeComponent } from "../tools/popup/send/send-type.component";
|
import { SendTypeComponent } from "../tools/popup/send/send-type.component";
|
||||||
@ -330,15 +328,16 @@ const routes: Routes = [
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
path: "generator",
|
path: "generator",
|
||||||
component: GeneratorComponent,
|
component: CredentialGeneratorComponent,
|
||||||
canActivate: [authGuard],
|
canActivate: [authGuard],
|
||||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||||
},
|
},
|
||||||
...extensionRefreshSwap(PasswordGeneratorHistoryComponent, CredentialGeneratorHistoryComponent, {
|
{
|
||||||
path: "generator-history",
|
path: "generator-history",
|
||||||
|
component: CredentialGeneratorHistoryComponent,
|
||||||
canActivate: [authGuard],
|
canActivate: [authGuard],
|
||||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||||
}),
|
},
|
||||||
{
|
{
|
||||||
path: "import",
|
path: "import",
|
||||||
component: ImportBrowserV2Component,
|
component: ImportBrowserV2Component,
|
||||||
@ -757,11 +756,12 @@ const routes: Routes = [
|
|||||||
canDeactivate: [clearVaultStateGuard],
|
canDeactivate: [clearVaultStateGuard],
|
||||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||||
},
|
},
|
||||||
...extensionRefreshSwap(GeneratorComponent, CredentialGeneratorComponent, {
|
{
|
||||||
path: "generator",
|
path: "generator",
|
||||||
|
component: CredentialGeneratorComponent,
|
||||||
canActivate: [authGuard],
|
canActivate: [authGuard],
|
||||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||||
}),
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: "settings",
|
||||||
component: SettingsV2Component,
|
component: SettingsV2Component,
|
||||||
|
@ -56,8 +56,6 @@ import { PopupHeaderComponent } from "../platform/popup/layout/popup-header.comp
|
|||||||
import { PopupPageComponent } from "../platform/popup/layout/popup-page.component";
|
import { PopupPageComponent } from "../platform/popup/layout/popup-page.component";
|
||||||
import { PopupTabNavigationComponent } from "../platform/popup/layout/popup-tab-navigation.component";
|
import { PopupTabNavigationComponent } from "../platform/popup/layout/popup-tab-navigation.component";
|
||||||
import { FilePopoutCalloutComponent } from "../tools/popup/components/file-popout-callout.component";
|
import { FilePopoutCalloutComponent } from "../tools/popup/components/file-popout-callout.component";
|
||||||
import { GeneratorComponent } from "../tools/popup/generator/generator.component";
|
|
||||||
import { PasswordGeneratorHistoryComponent } from "../tools/popup/generator/password-generator-history.component";
|
|
||||||
import { SendListComponent } from "../tools/popup/send/components/send-list.component";
|
import { SendListComponent } from "../tools/popup/send/components/send-list.component";
|
||||||
import { SendAddEditComponent } from "../tools/popup/send/send-add-edit.component";
|
import { SendAddEditComponent } from "../tools/popup/send/send-add-edit.component";
|
||||||
import { SendGroupingsComponent } from "../tools/popup/send/send-groupings.component";
|
import { SendGroupingsComponent } from "../tools/popup/send/send-groupings.component";
|
||||||
@ -160,8 +158,6 @@ import "../platform/popup/locales";
|
|||||||
LoginDecryptionOptionsComponentV1,
|
LoginDecryptionOptionsComponentV1,
|
||||||
NotificationsSettingsV1Component,
|
NotificationsSettingsV1Component,
|
||||||
AppearanceComponent,
|
AppearanceComponent,
|
||||||
GeneratorComponent,
|
|
||||||
PasswordGeneratorHistoryComponent,
|
|
||||||
PasswordHistoryComponent,
|
PasswordHistoryComponent,
|
||||||
PremiumComponent,
|
PremiumComponent,
|
||||||
RegisterComponent,
|
RegisterComponent,
|
||||||
|
@ -1,588 +0,0 @@
|
|||||||
<app-header [hideAccountSwitcher]="comingFromAddEdit">
|
|
||||||
<div class="left">
|
|
||||||
<app-pop-out [show]="!comingFromAddEdit"></app-pop-out>
|
|
||||||
<button type="button" (click)="close()" *ngIf="comingFromAddEdit">
|
|
||||||
{{ "cancel" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<h1 class="center">
|
|
||||||
<span class="title">{{ "generator" | i18n }}</span>
|
|
||||||
</h1>
|
|
||||||
<div class="right">
|
|
||||||
<button type="button" (click)="select()" *ngIf="comingFromAddEdit">
|
|
||||||
{{ "select" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</app-header>
|
|
||||||
<main tabindex="-1">
|
|
||||||
<app-callout type="info" *ngIf="enforcedPasswordPolicyOptions?.inEffect() && type === 'password'">
|
|
||||||
{{ "passwordGeneratorPolicyInEffect" | i18n }}
|
|
||||||
</app-callout>
|
|
||||||
<div class="generated-block" *ngIf="type === 'password'">
|
|
||||||
<div
|
|
||||||
class="generated-wrapper"
|
|
||||||
[innerHTML]="password | colorPassword"
|
|
||||||
[appCopyText]="password"
|
|
||||||
></div>
|
|
||||||
<div class="action-buttons">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="row-btn"
|
|
||||||
appStopClick
|
|
||||||
appA11yTitle="{{ 'copyPassword' | i18n }}"
|
|
||||||
(click)="copy()"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
appStopClick
|
|
||||||
appA11yTitle="{{ 'regeneratePassword' | i18n }}"
|
|
||||||
(click)="regenerate()"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-lg bwi-generate" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="generated-block" *ngIf="type === 'username'">
|
|
||||||
<div
|
|
||||||
class="generated-wrapper"
|
|
||||||
[innerHTML]="username | colorPassword"
|
|
||||||
[appCopyText]="username"
|
|
||||||
></div>
|
|
||||||
<div class="action-buttons" #form [appApiAction]="usernameGeneratingPromise">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="row-btn"
|
|
||||||
appStopClick
|
|
||||||
appA11yTitle="{{ 'copyUsername' | i18n }}"
|
|
||||||
(click)="copy()"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
appStopClick
|
|
||||||
appA11yTitle="{{ 'regenerateUsername' | i18n }}"
|
|
||||||
(click)="$any(form).loading ? false : regenerate()"
|
|
||||||
[attr.aria-disabled]="$any(form).loading ? 'true' : null"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="bwi bwi-lg bwi-generate"
|
|
||||||
[ngClass]="$any(form).loading ? 'bwi-spin' : ''"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="!comingFromAddEdit">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" role="radiogroup" aria-labelledby="typeHeading">
|
|
||||||
<label id="typeHeading" class="radio-header">{{
|
|
||||||
"whatWouldYouLikeToGenerate" | i18n
|
|
||||||
}}</label>
|
|
||||||
<div class="radio-group text-default" appBoxRow *ngFor="let o of typeOptions">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
[(ngModel)]="type"
|
|
||||||
name="Type"
|
|
||||||
id="type_{{ o.value }}"
|
|
||||||
[value]="o.value"
|
|
||||||
(change)="typeChanged()"
|
|
||||||
[checked]="type === o.value"
|
|
||||||
/>
|
|
||||||
<label for="type_{{ o.value }}">
|
|
||||||
{{ o.name }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="type === 'password'">
|
|
||||||
<div class="box">
|
|
||||||
<h2 class="box-header">
|
|
||||||
{{ "options" | i18n }}
|
|
||||||
</h2>
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" role="radiogroup" aria-labelledby="passwordTypeHeading">
|
|
||||||
<label id="passwordTypeHeading" class="radio-header">{{ "passwordType" | i18n }}</label>
|
|
||||||
<div class="radio-group text-default" appBoxRow *ngFor="let o of passTypeOptions">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
[(ngModel)]="passwordOptions.type"
|
|
||||||
name="PasswordType"
|
|
||||||
id="passwordtype_{{ o.value }}"
|
|
||||||
[value]="o.value"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
[checked]="passwordOptions.type === o.value"
|
|
||||||
/>
|
|
||||||
<label for="passwordtype_{{ o.value }}">
|
|
||||||
{{ o.name }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="passwordOptions.type === 'passphrase'">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row box-content-row-input" appBoxRow>
|
|
||||||
<label for="num-words">{{ "numWords" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="num-words"
|
|
||||||
type="number"
|
|
||||||
min="3"
|
|
||||||
max="20"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
[(ngModel)]="passwordOptions.numWords"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-input" appBoxRow>
|
|
||||||
<label for="word-separator">{{ "wordSeparator" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="word-separator"
|
|
||||||
type="text"
|
|
||||||
maxlength="1"
|
|
||||||
(input)="savePasswordOptions()"
|
|
||||||
[(ngModel)]="passwordOptions.wordSeparator"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="capitalize">{{ "capitalize" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="capitalize"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
[(ngModel)]="passwordOptions.capitalize"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions?.capitalize"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="include-number">{{ "includeNumber" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="include-number"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
[(ngModel)]="passwordOptions.includeNumber"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions?.includeNumber"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="passwordOptions.type === 'password'">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row box-content-row-slider" appBoxRow>
|
|
||||||
<label for="length">{{ "length" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="length"
|
|
||||||
type="number"
|
|
||||||
[min]="passwordOptions.minLength"
|
|
||||||
max="128"
|
|
||||||
[(ngModel)]="passwordOptions.length"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
id="lengthRange"
|
|
||||||
type="range"
|
|
||||||
[min]="passwordOptions.minLength"
|
|
||||||
max="128"
|
|
||||||
step="1"
|
|
||||||
[(ngModel)]="passwordOptions.length"
|
|
||||||
(change)="sliderChanged()"
|
|
||||||
(input)="sliderInput()"
|
|
||||||
attr.aria-label="{{ 'length' | i18n }}"
|
|
||||||
tabindex="-1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<span>{{ "passwordMinLength" | i18n }}</span>
|
|
||||||
<span
|
|
||||||
class="sr-only"
|
|
||||||
attr.aria-label="{{ 'passwordMinLength' | i18n }}"
|
|
||||||
role="status"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
{{ passwordOptionsMinLengthForReader$ | async }}
|
|
||||||
</span>
|
|
||||||
<span class="txt-right">{{ passwordOptions.minLength }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="uppercase">A-Z</label>
|
|
||||||
<input
|
|
||||||
id="uppercase"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
attr.aria-label="{{ 'uppercase' | i18n }}"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions.useUppercase"
|
|
||||||
[(ngModel)]="passwordOptions.uppercase"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="lowercase">a-z</label>
|
|
||||||
<input
|
|
||||||
id="lowercase"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
attr.aria-label="{{ 'lowercase' | i18n }}"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions.useLowercase"
|
|
||||||
[(ngModel)]="passwordOptions.lowercase"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="numbers">0-9</label>
|
|
||||||
<input
|
|
||||||
id="numbers"
|
|
||||||
type="checkbox"
|
|
||||||
attr.aria-label="{{ 'numbers' | i18n }}"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions.useNumbers"
|
|
||||||
[ngModel]="passwordOptions.number"
|
|
||||||
(ngModelChange)="setPasswordOptionsNumber($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="special">!@#$%^&*</label>
|
|
||||||
<input
|
|
||||||
id="special"
|
|
||||||
type="checkbox"
|
|
||||||
attr.aria-label="{{ 'specialCharacters' | i18n }}"
|
|
||||||
[disabled]="enforcedPasswordPolicyOptions.useSpecial"
|
|
||||||
[ngModel]="passwordOptions.special"
|
|
||||||
(ngModelChange)="setPasswordOptionsSpecial($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row box-content-row-input" appBoxRow>
|
|
||||||
<label for="min-number">{{ "minNumbers" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="min-number"
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="9"
|
|
||||||
[(ngModel)]="passwordOptions.minNumber"
|
|
||||||
(input)="onPasswordOptionsMinNumberInput($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-input" appBoxRow>
|
|
||||||
<label for="min-special">{{ "minSpecial" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="min-special"
|
|
||||||
type="number"
|
|
||||||
min="0"
|
|
||||||
max="9"
|
|
||||||
[(ngModel)]="passwordOptions.minSpecial"
|
|
||||||
(input)="onPasswordOptionsMinSpecialInput($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="ambiguous">{{ "avoidAmbChar" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="ambiguous"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="savePasswordOptions()"
|
|
||||||
[(ngModel)]="avoidAmbiguous"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<div class="box list">
|
|
||||||
<div class="box-content single-line">
|
|
||||||
<a class="box-content-row box-content-row-flex" routerLink="/generator-history">
|
|
||||||
<div class="row-main">{{ "passwordHistory" | i18n }}</div>
|
|
||||||
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="type === 'username'">
|
|
||||||
<div class="box">
|
|
||||||
<h2 class="box-header">
|
|
||||||
{{ "options" | i18n }}
|
|
||||||
</h2>
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" role="radiogroup" aria-labelledby="usernameTypeHeading">
|
|
||||||
<label id="usernameTypeHeading" class="radio-header">
|
|
||||||
{{ "usernameType" | i18n }}
|
|
||||||
<a
|
|
||||||
href="https://bitwarden.com/help/generator/#username-types"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
appA11yTitle="{{ 'learnMore' | i18n }}"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</label>
|
|
||||||
<div
|
|
||||||
class="radio-group align-start text-default"
|
|
||||||
appBoxRow
|
|
||||||
*ngFor="let o of usernameTypeOptions"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
[(ngModel)]="usernameOptions.type"
|
|
||||||
name="UsernameType"
|
|
||||||
id="type_{{ o.value }}"
|
|
||||||
[value]="o.value"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
[checked]="usernameOptions.type === o.value"
|
|
||||||
/>
|
|
||||||
<label for="type_{{ o.value }}">
|
|
||||||
{{ o.name }}
|
|
||||||
<div class="small text-muted" *ngIf="o.desc">
|
|
||||||
{{ o.desc }}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'forwarded'">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" role="listbox" aria-labelledby="forwardTypeHeading">
|
|
||||||
<label id="forwardTypeHeading">{{ "service" | i18n }}</label>
|
|
||||||
<select
|
|
||||||
id="ForwardTypeDropdown"
|
|
||||||
name="ForwardType"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedService"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
>
|
|
||||||
<option *ngFor="let o of forwardOptions" [ngValue]="o.value" role="option">
|
|
||||||
{{ o.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'simplelogin'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="simplelogin-apikey">{{ "apiKey" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="simplelogin-apikey"
|
|
||||||
type="password"
|
|
||||||
name="SimpleLoginApiKey"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedSimpleLoginApiKey"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="simplelogin-baseUrl">{{ "baseUrl" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="simplelogin-baseUrl"
|
|
||||||
type="text"
|
|
||||||
name="SimpleLoginDomain"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedSimpleLoginBaseUrl"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'duckduckgo'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="duckduckgo-apikey">{{ "apiKey" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="duckduckgo-apikey"
|
|
||||||
type="password"
|
|
||||||
name="DuckDuckGoApiKey"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedDuckDuckGoToken"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'anonaddy'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="anonaddy-accessToken">{{ "apiAccessToken" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="anonaddy-accessToken"
|
|
||||||
type="password"
|
|
||||||
name="AnonAddyAccessToken"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedAnonAddyApiToken"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="anonaddy-domain">{{ "aliasDomain" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="anonaddy-domain"
|
|
||||||
type="text"
|
|
||||||
name="AnonAddyDomain"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedAnonAddyDomain"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="anonaddy-baseUrl">{{ "baseUrl" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="anonaddy-baseUrl"
|
|
||||||
type="text"
|
|
||||||
name="AnonAddyDomain"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedAnonAddyBaseUrl"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'firefoxrelay'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="firefox-apikey">{{ "apiAccessToken" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="firefox-apikey"
|
|
||||||
type="password"
|
|
||||||
name="FirefoxApiKey"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedFirefoxApiToken"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'fastmail'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="fastmail-apiToken">{{ "apiAccessToken" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="fastmail-apiToken"
|
|
||||||
type="password"
|
|
||||||
name="FastmailApiToken"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedFastmailApiToken"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="usernameOptions.forwardedService === 'forwardemail'">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="forwardemail-accessToken">{{ "apiAccessToken" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="forwardemail-accessToken"
|
|
||||||
type="password"
|
|
||||||
name="ForwardEmailAccessToken"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedForwardEmailApiToken"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="forwardemail-domain">{{ "aliasDomain" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="forwardemail-domain"
|
|
||||||
type="text"
|
|
||||||
name="ForwardEmailDomain"
|
|
||||||
[(ngModel)]="usernameOptions.forwardedForwardEmailDomain"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'subaddress'">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="subaddress-email">{{ "emailAddress" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="subaddress-email"
|
|
||||||
type="text"
|
|
||||||
name="SubaddressEmail"
|
|
||||||
[(ngModel)]="usernameOptions.subaddressEmail"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="box-content-row"
|
|
||||||
role="radiogroup"
|
|
||||||
aria-labelledby="subaddressTypeHeading"
|
|
||||||
*ngIf="subaddressOptions.length > 1"
|
|
||||||
>
|
|
||||||
<label id="subaddressTypeHeading" class="radio-header">{{ "type" | i18n }}</label>
|
|
||||||
<div class="radio-group text-default" appBoxRow *ngFor="let o of subaddressOptions">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
[(ngModel)]="usernameOptions.subaddressType"
|
|
||||||
name="SubaddressType"
|
|
||||||
id="subaddresstype_{{ o.value }}"
|
|
||||||
[value]="o.value"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
[checked]="usernameOptions.subaddressType === o.value"
|
|
||||||
/>
|
|
||||||
<label for="subaddresstype_{{ o.value }}">
|
|
||||||
{{ o.name }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow *ngIf="usernameWebsite">
|
|
||||||
<label for="subaddress-website">{{ "website" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="subaddress-website"
|
|
||||||
type="text"
|
|
||||||
name="SubaddressWebsite"
|
|
||||||
[value]="usernameOptions.website"
|
|
||||||
disabled
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'catchall'">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row" appBoxRow>
|
|
||||||
<label for="catchall-domain">{{ "domainName" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="catchall-domain"
|
|
||||||
type="text"
|
|
||||||
name="CatchallDomain"
|
|
||||||
[(ngModel)]="usernameOptions.catchallDomain"
|
|
||||||
(blur)="saveUsernameOptions()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="box-content-row"
|
|
||||||
role="radiogroup"
|
|
||||||
aria-labelledby="catchallTypeHeading"
|
|
||||||
*ngIf="catchallOptions.length > 1"
|
|
||||||
>
|
|
||||||
<label id="catchallTypeHeading" class="radio-header">{{ "type" | i18n }}</label>
|
|
||||||
<div class="radio-group text-default" appBoxRow *ngFor="let o of catchallOptions">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
[(ngModel)]="usernameOptions.catchallType"
|
|
||||||
name="CatchallType"
|
|
||||||
id="catchalltype_{{ o.value }}"
|
|
||||||
[value]="o.value"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
[checked]="usernameOptions.catchallType === o.value"
|
|
||||||
/>
|
|
||||||
<label for="catchalltype_{{ o.value }}">
|
|
||||||
{{ o.name }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row" appBoxRow *ngIf="usernameWebsite">
|
|
||||||
<label for="catchall-website">{{ "website" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="catchall-website"
|
|
||||||
type="text"
|
|
||||||
name="CatchallWebsite"
|
|
||||||
[value]="usernameOptions.website"
|
|
||||||
disabled
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box" *ngIf="usernameOptions.type === 'word'">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="capitalize">{{ "capitalize" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="capitalize"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
[(ngModel)]="usernameOptions.wordCapitalize"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
|
||||||
<label for="include-number">{{ "includeNumber" | i18n }}</label>
|
|
||||||
<input
|
|
||||||
id="include-number"
|
|
||||||
type="checkbox"
|
|
||||||
(change)="saveUsernameOptions()"
|
|
||||||
[(ngModel)]="usernameOptions.wordIncludeNumber"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</main>
|
|
@ -1,88 +0,0 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
|
||||||
// @ts-strict-ignore
|
|
||||||
import { Location } from "@angular/common";
|
|
||||||
import { Component, NgZone, OnInit } from "@angular/core";
|
|
||||||
import { ActivatedRoute } from "@angular/router";
|
|
||||||
import { firstValueFrom } from "rxjs";
|
|
||||||
|
|
||||||
import { GeneratorComponent as BaseGeneratorComponent } from "@bitwarden/angular/tools/generator/components/generator.component";
|
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
|
||||||
import { AddEditCipherInfo } from "@bitwarden/common/vault/types/add-edit-cipher-info";
|
|
||||||
import { ToastService } from "@bitwarden/components";
|
|
||||||
import {
|
|
||||||
PasswordGenerationServiceAbstraction,
|
|
||||||
UsernameGenerationServiceAbstraction,
|
|
||||||
} from "@bitwarden/generator-legacy";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-generator",
|
|
||||||
templateUrl: "generator.component.html",
|
|
||||||
})
|
|
||||||
export class GeneratorComponent extends BaseGeneratorComponent implements OnInit {
|
|
||||||
private addEditCipherInfo: AddEditCipherInfo;
|
|
||||||
private cipherState: CipherView;
|
|
||||||
private cipherService: CipherService;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
|
||||||
usernameGenerationService: UsernameGenerationServiceAbstraction,
|
|
||||||
platformUtilsService: PlatformUtilsService,
|
|
||||||
i18nService: I18nService,
|
|
||||||
accountService: AccountService,
|
|
||||||
cipherService: CipherService,
|
|
||||||
route: ActivatedRoute,
|
|
||||||
logService: LogService,
|
|
||||||
ngZone: NgZone,
|
|
||||||
private location: Location,
|
|
||||||
toastService: ToastService,
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
passwordGenerationService,
|
|
||||||
usernameGenerationService,
|
|
||||||
platformUtilsService,
|
|
||||||
accountService,
|
|
||||||
i18nService,
|
|
||||||
logService,
|
|
||||||
route,
|
|
||||||
ngZone,
|
|
||||||
window,
|
|
||||||
toastService,
|
|
||||||
);
|
|
||||||
this.cipherService = cipherService;
|
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
|
||||||
this.addEditCipherInfo = await firstValueFrom(this.cipherService.addEditCipherInfo$);
|
|
||||||
if (this.addEditCipherInfo != null) {
|
|
||||||
this.cipherState = this.addEditCipherInfo.cipher;
|
|
||||||
}
|
|
||||||
this.comingFromAddEdit = this.cipherState != null;
|
|
||||||
if (this.cipherState?.login?.hasUris) {
|
|
||||||
this.usernameWebsite = this.cipherState.login.uris[0].hostname;
|
|
||||||
}
|
|
||||||
await super.ngOnInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
select() {
|
|
||||||
super.select();
|
|
||||||
if (this.type === "password") {
|
|
||||||
this.cipherState.login.password = this.password;
|
|
||||||
} else if (this.type === "username") {
|
|
||||||
this.cipherState.login.username = this.username;
|
|
||||||
}
|
|
||||||
this.addEditCipherInfo.cipher = this.cipherState;
|
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
||||||
this.cipherService.setAddEditCipherInfo(this.addEditCipherInfo);
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.location.back();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
<header>
|
|
||||||
<div class="left">
|
|
||||||
<button type="button" type="button" (click)="close()">
|
|
||||||
<span class="header-icon" aria-hidden="true"><i class="bwi bwi-angle-left"></i></span>
|
|
||||||
<span>{{ "back" | i18n }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<h1 class="center">
|
|
||||||
<span class="title">{{ "passwordHistory" | i18n }}</span>
|
|
||||||
</h1>
|
|
||||||
<div class="right">
|
|
||||||
<button type="button" type="button" (click)="clear()">
|
|
||||||
{{ "clear" | i18n }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<main tabindex="-1">
|
|
||||||
<div class="box list full-list" *ngIf="history && history.length">
|
|
||||||
<div class="box-content">
|
|
||||||
<div class="box-content-row box-content-row-flex" *ngFor="let h of history">
|
|
||||||
<div class="row-main">
|
|
||||||
<div class="row-main-content">
|
|
||||||
<div
|
|
||||||
class="monospaced password-wrapper"
|
|
||||||
[appCopyText]="h.password"
|
|
||||||
[innerHTML]="h.password | colorPassword"
|
|
||||||
></div>
|
|
||||||
<span class="detail">{{ h.date | date: "medium" }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="action-buttons">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="row-btn"
|
|
||||||
appStopClick
|
|
||||||
appA11yTitle="{{ 'copyPassword' | i18n }}"
|
|
||||||
(click)="copy(h.password)"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-lg bwi-clone" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="no-items" *ngIf="!history || !history.length">
|
|
||||||
<p>{{ "noPasswordsInList" | i18n }}</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
@ -1,28 +0,0 @@
|
|||||||
import { Location } from "@angular/common";
|
|
||||||
import { Component } from "@angular/core";
|
|
||||||
|
|
||||||
import { PasswordGeneratorHistoryComponent as BasePasswordGeneratorHistoryComponent } from "@bitwarden/angular/tools/generator/components/password-generator-history.component";
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
||||||
import { ToastService } from "@bitwarden/components";
|
|
||||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-password-generator-history",
|
|
||||||
templateUrl: "password-generator-history.component.html",
|
|
||||||
})
|
|
||||||
export class PasswordGeneratorHistoryComponent extends BasePasswordGeneratorHistoryComponent {
|
|
||||||
constructor(
|
|
||||||
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
|
||||||
platformUtilsService: PlatformUtilsService,
|
|
||||||
i18nService: I18nService,
|
|
||||||
private location: Location,
|
|
||||||
toastService: ToastService,
|
|
||||||
) {
|
|
||||||
super(passwordGenerationService, platformUtilsService, i18nService, window, toastService);
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.location.back();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user