[SM-252] Enable strict templates (#3601)

This commit is contained in:
Oscar Hinton 2022-11-28 18:59:46 +01:00 committed by GitHub
parent b312f6b925
commit d994faa8a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
97 changed files with 302 additions and 301 deletions

View File

@ -39,13 +39,10 @@
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPassword"
>{{ "masterPass" | i18n }}
<strong
class="sub-label text-{{ passwordStrengthComponent?.masterPasswordScoreColor }}"
*ngIf="passwordStrengthComponent?.masterPasswordScoreText"
>
{{ passwordStrengthComponent?.masterPasswordScoreText }}
<label for="masterPassword">
{{ "masterPass" | i18n }}
<strong class="sub-label text-{{ color }}" *ngIf="text">
{{ text }}
</strong>
</label>
<input

View File

@ -86,7 +86,9 @@
</div>
</ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn && !webAuthnNewTab">
<div id="web-authn-frame"><iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe></div>
<div id="web-authn-frame">
<iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>

View File

@ -57,11 +57,11 @@
appStopClick
appA11yTitle="{{ 'regenerateUsername' | i18n }}"
(click)="regenerate()"
[disabled]="form.loading"
[disabled]="$any(form).loading"
>
<i
class="bwi bwi-lg bwi-generate"
[ngClass]="form.loading ? 'bwi-spin' : ''"
[ngClass]="$any(form).loading ? 'bwi-spin' : ''"
aria-hidden="true"
></i>
</button>

View File

@ -305,8 +305,11 @@
>
<div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i>
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div>
<span>{{ "deleteSend" | i18n }}</span>
</div>

View File

@ -40,8 +40,11 @@
>
<div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i>
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div>
<span>{{ "deleteFolder" | i18n }}</span>
</div>

View File

@ -49,14 +49,14 @@
#refreshBtn
type="button"
(click)="refresh()"
[disabled]="refreshBtn.loading"
[disabled]="$any(refreshBtn).loading"
[appApiAction]="refreshPromise"
class="btn link block"
>
<span [hidden]="refreshBtn.loading">{{ "premiumRefresh" | i18n }}</span>
<span [hidden]="$any(refreshBtn).loading">{{ "premiumRefresh" | i18n }}</span>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!refreshBtn.loading"
[hidden]="!$any(refreshBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -17,11 +17,15 @@
class="btn block primary"
(click)="sync()"
#syncBtn
[disabled]="syncBtn.loading"
[disabled]="$any(syncBtn).loading"
[appApiAction]="syncPromise"
>
<span [hidden]="syncBtn.loading">{{ "syncVaultNow" | i18n }}</span>
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!syncBtn.loading" aria-hidden="true"></i>
<span [hidden]="$any(syncBtn).loading">{{ "syncVaultNow" | i18n }}</span>
<i
class="bwi bwi-spinner bwi-lg bwi-spin"
[hidden]="!$any(syncBtn).loading"
aria-hidden="true"
></i>
</button>
<p class="text-center text-muted small">{{ "lastSync" | i18n }} {{ lastSync }}</p>
</div>

View File

@ -81,8 +81,8 @@
[(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean"
appTrueFalseValue
trueValue="true"
falseValue="false"
[trueValue]="true"
[falseValue]="false"
attr.aria-describedby="fieldName{{ i }}"
[readonly]="!cipher.edit && editMode"
/>

View File

@ -88,17 +88,17 @@
appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()"
[appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading"
[disabled]="$any(checkPasswordBtn).loading"
*ngIf="cipher.viewPassword"
>
<i
class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading"
[hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading"
[hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
</button>
@ -487,7 +487,7 @@
type="text"
name="Login.Uris[{{ i }}].Uri"
[(ngModel)]="u.uri"
[hidden]="u.showUriOptionsInput === true"
[hidden]="$any(u).showUriOptionsInput === true"
placeholder="{{ 'ex' | i18n }} https://google.com"
inputmode="url"
appInputVerbatim
@ -500,7 +500,7 @@
id="currentUris{{ i }}"
name="Login.Uris[{{ i }}].CurrentUris"
[(ngModel)]="u.uri"
[hidden]="!u.showCurrentUris"
[hidden]="!$any(u).showCurrentUris"
>
<option [ngValue]="null">-- {{ "select" | i18n }} --</option>
<option *ngFor="let u of currentUris" [ngValue]="u">{{ u }}</option>
@ -512,7 +512,9 @@
id="loginUriMatch{{ i }}"
name="Login.Uris[{{ i }}].Match"
[(ngModel)]="u.match"
[hidden]="u.showOptions === false || (u.showOptions == null && u.match == null)"
[hidden]="
$any(u).showOptions === false || ($any(u).showOptions == null && u.match == null)
"
(change)="loginUriMatchChanged(u)"
>
<option *ngFor="let o of uriMatchOptions" [ngValue]="o.value">{{ o.name }}</option>
@ -526,7 +528,7 @@
appStopClick
appA11yTitle="{{ 'toggleCurrentUris' | i18n }}"
(click)="toggleUriInput(u)"
[attr.aria-pressed]="u.showCurrentUris === true"
[attr.aria-pressed]="$any(u).showCurrentUris === true"
>
<i aria-hidden="true" class="bwi bwi-lg bwi-list"></i>
</button>
@ -536,7 +538,7 @@
appStopClick
appA11yTitle="{{ 'toggleOptions' | i18n }}"
(click)="toggleUriOptions(u)"
[attr.aria-pressed]="u.showOptions === true"
[attr.aria-pressed]="$any(u).showOptions === true"
>
<i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i>
</button>
@ -695,7 +697,7 @@
<input
id="collection_{{ i }}"
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
/>
</div>
@ -713,8 +715,11 @@
>
<div class="row-main text-danger">
<div class="icon text-danger" aria-hidden="true">
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading"></i>
<i class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw" [hidden]="!deleteBtn.loading"></i>
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="$any(deleteBtn).loading"></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!$any(deleteBtn).loading"
></i>
</div>
<span>{{ "deleteItem" | i18n }}</span>
</div>

View File

@ -37,16 +37,16 @@
(click)="delete(a)"
#deleteBtn
[appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -33,7 +33,7 @@
<input
id="collection_{{ i }}"
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
/>
</div>

View File

@ -200,7 +200,7 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
}
}
private async load() {
protected async load() {
this.isLoading = false;
this.tab = await BrowserApi.getTabFromCurrentWindow();
if (this.tab != null) {

View File

@ -27,11 +27,7 @@
role="dialog"
aria-modal="true"
>
<button
appStopClick
(click)="selectAllVaults()"
[ngClass]="{ active: !myVaultOnly && !selectOrganizationId }"
>
<button appStopClick (click)="selectAllVaults()">
<i class="bwi bwi-fw bwi-filter" aria-hidden="true"></i>
&nbsp;{{ "allVaults" | i18n }}
</button>
@ -60,7 +56,7 @@
<i
*ngIf="!organization.enabled"
class="bwi bwi-fw bwi-exclamation-triangle text-danger"
aria-label="{{ 'organizationIsDisabled' | i18n }}"
attr.aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i>
</button>

View File

@ -88,17 +88,17 @@
appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()"
[appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading"
[disabled]="$any(checkPasswordBtn).loading"
*ngIf="cipher.viewPassword"
>
<i
class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading"
[hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading"
[hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
</button>
@ -537,12 +537,12 @@
<small class="row-sub-label">{{ attachment.sizeName }}</small>
<i
class="bwi bwi-download bwi-fw row-sub-icon"
*ngIf="!attachment.downloading"
*ngIf="!$any(attachment).downloading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon"
*ngIf="attachment.downloading"
*ngIf="$any(attachment).downloading"
aria-hidden="true"
></i>
</button>

View File

@ -15,6 +15,7 @@
}
},
"angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true
},
"include": ["src", "../../libs/common/src/services/**/*.worker.ts"]

View File

@ -57,7 +57,7 @@
class="primary"
(click)="purchase()"
*ngIf="!isPremium"
[disabled]="purchaseBtn.loading"
[disabled]="$any(purchaseBtn).loading"
>
<b>{{ "premiumPurchase" | i18n }}</b>
</button>
@ -67,18 +67,18 @@
#refreshBtn
type="button"
(click)="refresh()"
[disabled]="refreshBtn.loading"
[disabled]="$any(refreshBtn).loading"
appA11yTitle="{{ 'premiumRefresh' | i18n }}"
[appApiAction]="refreshPromise"
>
<i
class="bwi bwi-refresh bwi-lg bwi-fw"
[hidden]="refreshBtn.loading"
[hidden]="$any(refreshBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!refreshBtn.loading"
[hidden]="!$any(refreshBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -65,7 +65,7 @@
</ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn">
<div id="web-authn-frame">
<iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe>
<iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div>
<div class="box first">
<div class="box-content">

View File

@ -5,12 +5,7 @@ import { Utils } from "@bitwarden/common/misc/utils";
@Component({
selector: "app-avatar",
template: `<img
*ngIf="src"
[src]="src"
title="{{ data }}"
[ngClass]="{ 'rounded-circle': circle }"
/>`,
template: `<img *ngIf="src" [src]="src" [ngClass]="{ 'rounded-circle': circle }" />`,
})
export class AvatarComponent implements OnChanges, OnInit {
@Input() size = 45;
@ -20,7 +15,7 @@ export class AvatarComponent implements OnChanges, OnInit {
@Input() circle = false;
@Input() color?: string;
@Input() id?: number;
@Input() id?: string;
@Input() text?: string;
private svgCharCount = 2;

View File

@ -12,7 +12,7 @@
<app-avatar
[text]="activeAccount.name"
[id]="activeAccount.id"
size="25"
[size]="25"
[circle]="true"
[fontSize]="14"
[dynamic]="true"
@ -61,7 +61,7 @@
<app-avatar
[text]="a.value.profile.name ?? a.value.profile.email"
[id]="a.value.profile.userId"
size="25"
[size]="25"
[circle]="true"
[fontSize]="14"
[dynamic]="true"

View File

@ -35,7 +35,7 @@
name="Type_{{ o.value }}"
id="type_{{ o.value }}"
[value]="o.value"
(change)="typeChanged(o)"
(change)="typeChanged()"
[checked]="send.type === o.value"
[disabled]="disableSend"
/>
@ -280,10 +280,14 @@
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
>
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -46,7 +46,6 @@
formControlName="defaultExpirationDateTime"
required
placeholder="MM/DD/YYYY HH:MM AM/PM"
[readOnly]="disableSend"
/>
<small *ngIf="editMode" class="help-block">{{ "expirationDateDesc" | i18n }}</small>
</div>

View File

@ -79,8 +79,8 @@
[(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean"
appTrueFalseValue
trueValue="true"
falseValue="false"
[trueValue]="true"
[falseValue]="false"
attr.aria-describedby="fieldName{{ i }}"
[readonly]="!cipher.edit && editMode"
/>

View File

@ -75,16 +75,16 @@
appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()"
[appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading"
[disabled]="$any(checkPasswordBtn).loading"
>
<i
class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading"
[hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading"
[hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
</button>
@ -485,7 +485,10 @@
id="loginUriMatch{{ i }}"
name="Login.Uris[{{ i }}].Match"
[(ngModel)]="u.match"
[hidden]="u.showOptions === false || (u.showOptions == null && u.match == null)"
[hidden]="
$any(u).showOptions === false ||
($any(u).showOptions == null && u.match == null)
"
(change)="loginUriMatchChanged(u)"
>
<option *ngFor="let o of uriMatchOptions" [ngValue]="o.value">
@ -501,7 +504,10 @@
appA11yTitle="{{ 'toggleOptions' | i18n }}"
(click)="toggleUriOptions(u)"
[attr.aria-expanded]="
!(u.showOptions === false || (u.showOptions == null && u.match == null))
!(
$any(u).showOptions === false ||
($any(u).showOptions == null && u.match == null)
)
"
>
<i class="bwi bwi-lg bwi-cog" aria-hidden="true"></i>
@ -634,7 +640,7 @@
<input
id="collection_{{ i }}"
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
/>
</div>
@ -647,12 +653,16 @@
type="submit"
class="primary"
appA11yTitle="{{ 'save' | i18n }}"
[disabled]="form.loading"
[disabled]="$any(form).loading"
>
<i class="bwi bwi-save-changes bwi-lg bwi-fw" [hidden]="form.loading" aria-hidden="true"></i>
<i
class="bwi bwi-save-changes bwi-lg bwi-fw"
[hidden]="$any(form).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!form.loading"
[hidden]="!$any(form).loading"
aria-hidden="true"
></i>
</button>
@ -675,13 +685,17 @@
class="danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode && !cloneMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i class="bwi bwi-trash bwi-lg bwi-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -21,16 +21,16 @@
(click)="delete(a)"
#deleteBtn
[appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -19,7 +19,7 @@
<input
id="collection_{{ i }}"
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
/>
</div>

View File

@ -47,17 +47,17 @@
class="danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
></i>
</button>

View File

@ -52,11 +52,11 @@
appStopClick
appA11yTitle="{{ 'regenerateUsername' | i18n }}"
(click)="regenerate()"
[disabled]="form.loading"
[disabled]="$any(form).loading"
>
<i
class="bwi bwi-lg bwi-generate"
[ngClass]="form.loading ? 'bwi-spin' : ''"
[ngClass]="$any(form).loading ? 'bwi-spin' : ''"
aria-hidden="true"
></i>
</button>

View File

@ -112,7 +112,6 @@
<i
*ngIf="!organization.enabled"
class="bwi bwi-fw bwi-exclamation-triangle text-danger mr-auto"
aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i>
</span>

View File

@ -64,16 +64,16 @@
appA11yTitle="{{ 'checkPassword' | i18n }}"
(click)="checkPassword()"
[appApiAction]="checkPasswordPromise"
[disabled]="checkPasswordBtn.loading"
[disabled]="$any(checkPasswordBtn).loading"
>
<i
class="bwi bwi-lg bwi-check-circle"
[hidden]="checkPasswordBtn.loading"
[hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-lg bwi-spinner bwi-spin"
[hidden]="!checkPasswordBtn.loading"
[hidden]="!$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
</button>
@ -472,12 +472,12 @@
<small class="row-sub-label">{{ attachment.sizeName }}</small>
<i
class="bwi bwi-download bwi-fw row-sub-icon"
*ngIf="!attachment.downloading"
*ngIf="!$any(attachment).downloading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-fw bwi-spin row-sub-icon"
*ngIf="attachment.downloading"
*ngIf="$any(attachment).downloading"
aria-hidden="true"
></i>
</button>

View File

@ -16,6 +16,7 @@
}
},
"angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true
},
"include": ["src", "../../libs/common/src/services/**/*.worker.ts"]

View File

@ -55,7 +55,7 @@
<!-- Teams & Enterprise Body -->
<div *ngIf="layout === 'teams1' || layout === 'teams2' || layout === 'enterprise2'">
<h1>
Start Your <span *ngIf="layout === 'teams1' || layout === 'teams1'">Teams<br /></span
Start Your <span *ngIf="layout === 'teams1'">Teams<br /></span
><span *ngIf="layout === 'enterprise2'">Enterprise</span> Free Trial Now
</h1>
<h2>

View File

@ -1,5 +1,7 @@
import { CdkStepper } from "@angular/cdk/stepper";
import { Component, Input } from "@angular/core";
import { Component, Input, QueryList } from "@angular/core";
import { VerticalStep } from "./vertical-step.component";
@Component({
selector: "app-vertical-stepper",
@ -7,6 +9,8 @@ import { Component, Input } from "@angular/core";
providers: [{ provide: CdkStepper, useExisting: VerticalStepperComponent }],
})
export class VerticalStepperComponent extends CdkStepper {
readonly steps: QueryList<VerticalStep>;
@Input()
activeClass = "active";

View File

@ -80,7 +80,7 @@
</ng-container>
<ng-container *ngIf="selectedProviderType === providerType.WebAuthn">
<div id="web-authn-frame" class="mb-3">
<iframe id="webauthn_iframe" [allow]="webAuthnAllow"></iframe>
<iframe id="webauthn_iframe" [attr.allow]="webAuthnAllow"></iframe>
</div>
</ng-container>
<ng-container

View File

@ -0,0 +1,23 @@
import { animate, style, transition, trigger } from "@angular/animations";
import { Component } from "@angular/core";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { UserVerificationComponent as BaseComponent } from "@bitwarden/angular/components/user-verification.component";
@Component({
selector: "app-user-verification",
templateUrl: "user-verification.component.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: UserVerificationComponent,
},
],
animations: [
trigger("sent", [
transition(":enter", [style({ opacity: 0 }), animate("100ms", style({ opacity: 1 }))]),
]),
],
})
export class UserVerificationComponent extends BaseComponent {}

View File

@ -44,7 +44,7 @@
class="btn btn-outline-secondary btn-submit"
(click)="reinstate()"
[appApiAction]="reinstatePromise"
[disabled]="reinstateBtn.loading"
[disabled]="$any(reinstateBtn).loading"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "reinstateSubscription" | i18n }}</span>
@ -113,8 +113,8 @@
</button>
<app-change-plan
[organizationId]="organizationId"
(onChanged)="closeChangePlan(true)"
(onCanceled)="closeChangePlan(false)"
(onChanged)="closeChangePlan()"
(onCanceled)="closeChangePlan()"
*ngIf="showChangePlan"
></app-change-plan>
</ng-container>
@ -143,7 +143,7 @@
class="btn btn-outline-danger btn-submit"
(click)="removeSponsorship()"
[appApiAction]="removeSponsorshipPromise"
[disabled]="removeSponsorshipBtn.loading"
[disabled]="$any(removeSponsorshipBtn).loading"
*ngIf="isSponsoredSubscription"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
@ -230,7 +230,7 @@
class="btn btn-outline-danger btn-submit ml-1"
(click)="cancel()"
[appApiAction]="cancelPromise"
[disabled]="cancelBtn.loading"
[disabled]="$any(cancelBtn).loading"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@ -53,11 +53,13 @@
<div class="tw-flex tw-flex-col">
<div class="tw-text-sm">
{{ item.labelName }}
<span *ngIf="item.status == 0" bitBadge badgeType="secondary">
<span *ngIf="$any(item).status == 0" bitBadge badgeType="secondary">
{{ "invited" | i18n }}
</span>
</div>
<div class="tw-text-xs tw-text-muted" *ngIf="item.status != 0">{{ item.email }}</div>
<div class="tw-text-xs tw-text-muted" *ngIf="$any(item).status != 0">
{{ $any(item).email }}
</div>
</div>
</div>
@ -110,11 +112,11 @@
</td>
<td bitCell *ngIf="showMemberRoles">
{{ item.role | userType: "-" }}
{{ $any(item).role | userType: "-" }}
</td>
<td bitCell *ngIf="showGroupColumn">
{{ item.viaGroupName ?? "-" }}
{{ $any(item).viaGroupName ?? "-" }}
</td>
<td bitCell>

View File

@ -81,7 +81,7 @@
<td class="table-list-checkbox" (click)="check(g)">
<input
type="checkbox"
[(ngModel)]="g.checked"
[(ngModel)]="$any(g).checked"
name="Groups[{{ i }}].Checked"
[disabled]="g.accessAll || !this.canSave"
appStopProp
@ -101,17 +101,17 @@
<td class="text-center">
<input
type="checkbox"
[(ngModel)]="g.hidePasswords"
[(ngModel)]="$any(g).hidePasswords"
name="Groups[{{ i }}].HidePasswords"
[disabled]="!g.checked || g.accessAll || !this.canSave"
[disabled]="!$any(g).checked || g.accessAll || !this.canSave"
/>
</td>
<td class="text-center">
<input
type="checkbox"
[(ngModel)]="g.readOnly"
[(ngModel)]="$any(g).readOnly"
name="Groups[{{ i }}].ReadOnly"
[disabled]="!g.checked || g.accessAll || !this.canSave"
[disabled]="!$any(g).checked || g.accessAll || !this.canSave"
/>
</td>
</tr>
@ -140,17 +140,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -52,11 +52,11 @@
type="button"
class="btn btn-sm btn-outline-primary ml-3"
(click)="loadEvents(true)"
[disabled]="loaded && refreshBtn.loading"
[disabled]="loaded && $any(refreshBtn).loading"
>
<i
class="bwi bwi-refresh bwi-fw"
[ngClass]="{ 'bwi-spin': loaded && refreshBtn.loading }"
[ngClass]="{ 'bwi-spin': loaded && $any(refreshBtn).loading }"
aria-hidden="true"
></i>
{{ "refresh" | i18n }}
@ -101,7 +101,7 @@
type="button"
class="btn btn-block btn-link btn-submit"
(click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading"
[disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@ -95,7 +95,7 @@
bitButton
buttonType="primary"
(click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading"
[disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken"
>
<i

View File

@ -119,7 +119,7 @@
<td class="table-list-checkbox" (click)="check(c)">
<input
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
/>
@ -132,7 +132,7 @@
type="checkbox"
[(ngModel)]="c.hidePasswords"
name="Collection[{{ i }}].HidePasswords"
[disabled]="!c.checked"
[disabled]="!$any(c).checked"
/>
</td>
<td class="text-center">
@ -140,7 +140,7 @@
type="checkbox"
[(ngModel)]="c.readOnly"
name="Collection[{{ i }}].ReadOnly"
[disabled]="!c.checked"
[disabled]="!$any(c).checked"
/>
</td>
</tr>
@ -164,17 +164,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
aria-hidden="true"
title="{{ 'loading' | i18n }}"
></i>

View File

@ -341,7 +341,7 @@
<td class="table-list-checkbox" (click)="check(c)">
<input
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
/>
@ -354,7 +354,7 @@
type="checkbox"
[(ngModel)]="c.hidePasswords"
name="Collection[{{ i }}].HidePasswords"
[disabled]="!c.checked"
[disabled]="!$any(c).checked"
/>
</td>
<td class="text-center">
@ -362,7 +362,7 @@
type="checkbox"
[(ngModel)]="c.readOnly"
name="Collection[{{ i }}].ReadOnly"
[disabled]="!c.checked"
[disabled]="!$any(c).checked"
/>
</td>
</tr>
@ -416,17 +416,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -34,7 +34,7 @@
<td class="table-list-checkbox" (click)="check(g)">
<input
type="checkbox"
[(ngModel)]="g.checked"
[(ngModel)]="$any(g).checked"
name="Groups[{{ i }}].Checked"
appStopProp
/>

View File

@ -29,7 +29,7 @@ export class PoliciesComponent implements OnInit {
organization: Organization;
private orgPolicies: PolicyResponse[];
private policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
protected policiesEnabledMap: Map<PolicyType, boolean> = new Map<PolicyType, boolean>();
constructor(
private route: ActivatedRoute,

View File

@ -18,7 +18,6 @@ import { StateService } from "@bitwarden/common/abstractions/state.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { CipherData } from "@bitwarden/common/models/data/cipher.data";
import { Cipher } from "@bitwarden/common/models/domain/cipher";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherCreateRequest } from "@bitwarden/common/models/request/cipher-create.request";
import { CipherRequest } from "@bitwarden/common/models/request/cipher.request";
@ -29,7 +28,6 @@ import { AddEditComponent as BaseAddEditComponent } from "../../vault/add-edit.c
templateUrl: "../../vault/add-edit.component.html",
})
export class AddEditComponent extends BaseAddEditComponent {
organization: Organization;
originalCipher: Cipher = null;
constructor(

View File

@ -12,7 +12,6 @@ import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { TokenService } from "@bitwarden/common/abstractions/token.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { VaultItemsComponent as BaseVaultItemsComponent } from "../../vault/vault-items.component";
@ -24,9 +23,6 @@ import { VaultItemsComponent as BaseVaultItemsComponent } from "../../vault/vaul
export class VaultItemsComponent extends BaseVaultItemsComponent {
@Output() onEventsClicked = new EventEmitter<CipherView>();
organization: Organization;
accessEvents = false;
protected allCiphers: CipherView[] = [];
constructor(
@ -86,6 +82,7 @@ export class VaultItemsComponent extends BaseVaultItemsComponent {
async search(timeout: number = null) {
await super.search(timeout, this.allCiphers);
}
events(c: CipherView) {
this.onEventsClicked.emit(c);
}

View File

@ -19,7 +19,7 @@
<h1>
{{ "vaultItems" | i18n }}
<small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise">
<ng-container *ngIf="actionSpinner.loading">
<ng-container *ngIf="$any(actionSpinner).loading">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"

View File

@ -1,5 +1,6 @@
import { NgModule } from "@angular/core";
import { OrganizationBadgeModule } from "../../vault/organization-badge/organization-badge.module";
import { VaultSharedModule } from "../../vault/shared/vault-shared.module";
import { VaultFilterModule } from "./vault-filter/vault-filter.module";
@ -8,7 +9,7 @@ import { VaultRoutingModule } from "./vault-routing.module";
import { VaultComponent } from "./vault.component";
@NgModule({
imports: [VaultSharedModule, VaultRoutingModule, VaultFilterModule],
imports: [VaultSharedModule, VaultRoutingModule, VaultFilterModule, OrganizationBadgeModule],
declarations: [VaultComponent, VaultItemsComponent],
exports: [VaultComponent],
})

View File

@ -8,6 +8,7 @@ import { PasswordRepromptService } from "@bitwarden/common/abstractions/password
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { CipherType } from "@bitwarden/common/enums/cipherType";
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { BadgeTypes } from "@bitwarden/components";
import { CipherReportComponent } from "./cipher-report.component";
@ -16,7 +17,7 @@ import { CipherReportComponent } from "./cipher-report.component";
templateUrl: "weak-passwords-report.component.html",
})
export class WeakPasswordsReportComponent extends CipherReportComponent implements OnInit {
passwordStrengthMap = new Map<string, [string, string]>();
passwordStrengthMap = new Map<string, [string, BadgeTypes]>();
private passwordStrengthCache = new Map<string, number>();
@ -110,7 +111,7 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen
return true;
}
private scoreKey(score: number): [string, string] {
private scoreKey(score: number): [string, BadgeTypes] {
switch (score) {
case 4:
return ["strong", "success"];

View File

@ -1,5 +1,7 @@
import { Component, Input } from "@angular/core";
import { Icon } from "@bitwarden/components";
import { ReportVariant } from "../models/report-variant";
@Component({
@ -10,7 +12,7 @@ export class ReportCardComponent {
@Input() title: string;
@Input() description: string;
@Input() route: string;
@Input() icon: string;
@Input() icon: Icon;
@Input() variant: ReportVariant;
protected get disabled() {

View File

@ -81,7 +81,7 @@
id="text"
rows="8"
name="Text"
[(ngModel)]="sendText"
[ngModel]="sendText"
class="form-control"
readonly
></textarea>

View File

@ -55,7 +55,7 @@
name="Type_{{ o.value }}"
id="type_{{ o.value }}"
[value]="o.value"
(change)="typeChanged(o)"
(change)="typeChanged()"
[checked]="send.type === o.value"
/>
<label class="form-check-label" for="type_{{ o.value }}">
@ -120,14 +120,7 @@
<h3 class="mt-5">{{ "share" | i18n }}</h3>
<div class="form-group" *ngIf="link">
<label for="link">{{ "sendLinkLabel" | i18n }}</label>
<input
type="text"
readonly
id="link"
name="Link"
[(ngModel)]="link"
class="form-control"
/>
<input type="text" readonly id="link" name="Link" [ngModel]="link" class="form-control" />
</div>
<div class="form-group">
<div class="form-check">
@ -286,17 +279,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -13,7 +13,6 @@
formControlName="fallbackDeletionDate"
required
placeholder="MM/DD/YYYY"
[readOnly]="disableSend"
data-date-format="mm/dd/yyyy"
/>
<input
@ -24,7 +23,6 @@
formControlName="fallbackDeletionTime"
required
placeholder="HH:MM AM/PM"
[readOnly]="disableSend"
/>
</div>
</ng-container>
@ -38,7 +36,6 @@
formControlName="fallbackDeletionDate"
required
placeholder="MM/DD/YYYY"
[readOnly]="disableSend"
data-date-format="mm/dd/yyyy"
/>
<select

View File

@ -59,7 +59,7 @@
<h1>
{{ "send" | i18n }}
<small #actionSpinner [appApiAction]="actionPromise">
<ng-container *ngIf="actionSpinner.loading">
<ng-container *ngIf="$any(actionSpinner).loading">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"

View File

@ -121,16 +121,16 @@
(click)="delete()"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -240,14 +240,6 @@
{{ "monthAbbr" | i18n }} =
{{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "year" | i18n }}
</small>
<small *ngIf="selectablePlan.hasPremiumAccessOption && premiumAccessAddon">
{{ "premiumAccess" | i18n }}:
{{ selectablePlan.premiumAccessOptionCost / 12 | currency: "$" }} &times; 12
{{ "monthAbbr" | i18n }}
=
{{ 40 | currency: "$" }}
/{{ "year" | i18n }}
</small>
</ng-container>
<ng-container *ngIf="!selectablePlan.isAnnual">
{{ "monthly" | i18n }}
@ -272,17 +264,6 @@
{{ "monthAbbr" | i18n }} =
{{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "month" | i18n }}
</small>
<small
*ngIf="
selectablePlan.hasPremiumAccessOption &&
formGroup.controls['premiumAccessAddon'].value
"
>
{{ "premiumAccess" | i18n }}:
{{ selectablePlan.premiumAccessOptionCost | currency: "$" }} {{ "monthAbbr" | i18n }} =
{{ 40 | currency: "$" }}
/{{ "month" | i18n }}
</small>
</ng-container>
</label>
</div>

View File

@ -25,7 +25,7 @@
*ngIf="!isSelfHosted && !sponsoringOrg.familySponsorshipValidUntil"
[appApiAction]="resendEmailPromise"
class="dropdown-item btn-submit"
[disabled]="resendEmailBtn.loading"
[disabled]="$any(resendEmailBtn).loading"
(click)="resendEmail()"
[attr.aria-label]="'resendEmailLabel' | i18n: sponsoringOrg.familySponsorshipFriendlyName"
>
@ -36,7 +36,7 @@
#revokeSponsorshipBtn
[appApiAction]="revokeSponsorshipPromise"
class="dropdown-item text-danger btn-submit"
[disabled]="revokeSponsorshipBtn.loading"
[disabled]="$any(revokeSponsorshipBtn).loading"
(click)="revokeSponsorship()"
[attr.aria-label]="'revokeAccount' | i18n: sponsoringOrg.familySponsorshipFriendlyName"
>

View File

@ -18,7 +18,7 @@
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
(onAuthed)="auth($any($event))"
*ngIf="!authed"
>
</app-two-factor-verify>

View File

@ -18,7 +18,7 @@
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
(onAuthed)="auth($any($event))"
*ngIf="!authed"
>
</app-two-factor-verify>

View File

@ -18,7 +18,7 @@
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
(onAuthed)="auth($any($event))"
*ngIf="!authed"
>
</app-two-factor-verify>
@ -61,7 +61,7 @@
class="btn btn-outline-primary btn-sm btn-submit align-self-start"
(click)="sendEmail()"
[appApiAction]="emailPromise"
[disabled]="sendBtn.loading"
[disabled]="$any(sendBtn).loading"
>
<i
class="bwi bwi-spinner bwi-spin"

View File

@ -15,12 +15,7 @@
<span aria-hidden="true">&times;</span>
</button>
</div>
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
*ngIf="!authed"
>
<app-two-factor-verify [type]="type" (onAuthed)="auth($event)" *ngIf="!authed">
</app-two-factor-verify>
<ng-container *ngIf="authed">
<div class="modal-body text-center">

View File

@ -18,7 +18,7 @@
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
(onAuthed)="auth($any($event))"
*ngIf="!authed"
>
</app-two-factor-verify>
@ -54,7 +54,7 @@
<i class="bwi bwi-li bwi-key"></i>
<strong *ngIf="!k.configured || !k.name">{{ "webAuthnkeyX" | i18n: i + 1 }}</strong>
<strong *ngIf="k.configured && k.name">{{ k.name }}</strong>
<ng-container *ngIf="k.configured && !removeKeyBtn.loading">
<ng-container *ngIf="k.configured && !$any(removeKeyBtn).loading">
<ng-container *ngIf="k.migrated">
<span>{{ "webAuthnMigrated" | i18n }}</span>
</ng-container>
@ -63,7 +63,7 @@
<i
class="bwi bwi-spin bwi-spinner text-muted bwi-fw"
title="{{ 'loading' | i18n }}"
*ngIf="removeKeyBtn.loading"
*ngIf="$any(removeKeyBtn).loading"
aria-hidden="true"
></i>
-
@ -96,16 +96,16 @@
type="button"
(click)="readKey()"
class="btn btn-outline-secondary mr-2"
[disabled]="readKeyBtn.loading || webAuthnListening || !keyIdAvailable"
[disabled]="$any(readKeyBtn).loading || webAuthnListening || !keyIdAvailable"
#readKeyBtn
[appApiAction]="challengePromise"
>
{{ "readKey" | i18n }}
</button>
<ng-container *ngIf="readKeyBtn.loading">
<ng-container *ngIf="$any(readKeyBtn).loading">
<i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i>
</ng-container>
<ng-container *ngIf="!readKeyBtn.loading">
<ng-container *ngIf="!$any(readKeyBtn).loading">
<ng-container *ngIf="webAuthnListening">
<i class="bwi bwi-spinner bwi-spin text-muted" aria-hidden="true"></i>
{{ "twoFactorU2fWaiting" | i18n }}...
@ -138,8 +138,7 @@
#disableBtn
type="button"
class="btn btn-outline-secondary btn-submit"
[appApiAction]="disablePromise"
[disabled]="disableBtn.loading"
[disabled]="$any(disableBtn).loading"
(click)="disable()"
*ngIf="enabled"
>

View File

@ -18,7 +18,7 @@
<app-two-factor-verify
[organizationId]="organizationId"
[type]="type"
(onAuthed)="auth($event)"
(onAuthed)="auth($any($event))"
*ngIf="!authed"
>
</app-two-factor-verify>
@ -104,7 +104,7 @@
type="button"
class="btn btn-outline-secondary btn-submit"
[appApiAction]="disablePromise"
[disabled]="disableBtn.loading"
[disabled]="$any(disableBtn).loading"
(click)="disable()"
*ngIf="enabled"
>

View File

@ -46,7 +46,7 @@
class="btn-submit"
(click)="reinstate()"
[appApiAction]="reinstatePromise"
[disabled]="reinstateBtn.loading"
[disabled]="$any(reinstateBtn).loading"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "reinstateSubscription" | i18n }}</span>
@ -147,7 +147,7 @@
class="btn-submit tw-ml-auto"
(click)="cancel()"
[appApiAction]="cancelPromise"
[disabled]="cancelBtn.loading"
[disabled]="$any(cancelBtn).loading"
*ngIf="subscription && !subscription.cancelled && !subscriptionMarkedForCancel"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@ -9,7 +9,7 @@
class="btn btn-block btn-outline-secondary btn-submit"
#sendBtn
[appApiAction]="actionPromise"
[disabled]="sendBtn.loading"
[disabled]="$any(sendBtn).loading"
(click)="send()"
>
<i class="bwi bwi-spin bwi-spinner" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@ -1,7 +1,5 @@
import { NgModule } from "@angular/core";
import { UserVerificationComponent } from "@bitwarden/angular/components/user-verification.component";
import { AcceptEmergencyComponent } from "../accounts/accept-emergency.component";
import { AcceptOrganizationComponent } from "../accounts/accept-organization.component";
import { HintComponent } from "../accounts/hint.component";
@ -24,6 +22,7 @@ import { OrganizationSwitcherComponent } from "../components/organization-switch
import { PasswordRepromptComponent } from "../components/password-reprompt.component";
import { PremiumBadgeComponent } from "../components/premium-badge.component";
import { UserVerificationPromptComponent } from "../components/user-verification-prompt.component";
import { UserVerificationComponent } from "../components/user-verification.component";
import { FooterComponent } from "../layouts/footer.component";
import { FrontendLayoutComponent } from "../layouts/frontend-layout.component";
import { NavbarComponent } from "../layouts/navbar.component";
@ -124,7 +123,6 @@ import { BulkRestoreComponent } from "../vault/bulk-restore.component";
import { BulkShareComponent } from "../vault/bulk-share.component";
import { CollectionsComponent } from "../vault/collections.component";
import { FolderAddEditComponent } from "../vault/folder-add-edit.component";
import { OrganizationBadgeModule } from "../vault/organization-badge/organization-badge.module";
import { ShareComponent } from "../vault/share.component";
import { VaultFilterModule } from "../vault/vault-filter/vault-filter.module";
@ -133,13 +131,7 @@ import { SharedModule } from ".";
// Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left.
// If you are building new functionality, please create or extend a feature module instead.
@NgModule({
imports: [
SharedModule,
VaultFilterModule,
OrganizationBadgeModule,
OrganizationCreateModule,
RegisterFormModule,
],
imports: [SharedModule, VaultFilterModule, OrganizationCreateModule, RegisterFormModule],
declarations: [
PremiumBadgeComponent,
AcceptEmergencyComponent,

View File

@ -408,7 +408,7 @@
type="button"
class="btn btn-submit btn-primary"
(click)="regenerate()"
[disabled]="form.loading"
[disabled]="$any(form).loading"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "regenerateUsername" | i18n }}</span>

View File

@ -157,7 +157,8 @@
<button
type="submit"
class="btn btn-primary btn-submit"
[disabled]="form.loading || disabled"
[disabled]="form.loading || disabledByPolicy"
[ngClass]="{ manual: disabledByPolicy }"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "confirmFormat" | i18n }}</span>

View File

@ -80,11 +80,13 @@
right) and select "Settings". Go to "Export" and find the "Export to .csv File" option. Click
"Export" to save the CSV file.
</ng-container>
<!--
<ng-container *ngIf="format === 'keeperjson'">
Log into the Keeper web vault (keepersecurity.com/vault). Click on your "account email" (top
right) and select "Settings". Go to "Export" and find the "Export to .json File" option. Click
"Export" to save the JSON file.
</ng-container>
-->
<ng-container
*ngIf="format === 'chromecsv' || format === 'operacsv' || format === 'vivaldicsv'"
>

View File

@ -122,8 +122,8 @@
[(ngModel)]="f.value"
*ngIf="f.type === fieldType.Boolean"
appTrueFalseValue
trueValue="true"
falseValue="false"
[trueValue]="true"
[falseValue]="false"
[disabled]="cipher.isDeleted || viewOnly"
attr.aria-describedby="fieldName{{ i }}"
/>

View File

@ -118,13 +118,13 @@
>
<i
class="bwi bwi-lg bwi-fw bwi-check-circle"
[hidden]="checkPasswordBtn.loading"
[hidden]="$any(checkPasswordBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-lg bwi-fw bwi-spinner bwi-spin"
aria-hidden="true"
[hidden]="!checkPasswordBtn.loading"
[hidden]="!$any(checkPasswordBtn).loading"
title="{{ 'loading' | i18n }}"
></i>
</a>
@ -838,7 +838,7 @@
<input
class="form-check-input"
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
id="collection-{{ i }}"
name="Collection[{{ i }}].Checked"
[disabled]="cipher.isDeleted || viewOnly"
@ -935,17 +935,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ (cipher.isDeleted ? 'permanentlyDelete' : 'delete') | i18n }}"
*ngIf="editMode && !cloneMode && !(!cipher.edit && editMode)"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -26,10 +26,14 @@
<tbody>
<tr *ngFor="let a of cipher.attachments">
<td class="table-list-icon">
<i class="bwi bwi-fw bwi-lg bwi-file" *ngIf="!a.downloading" aria-hidden="true"></i>
<i
class="bwi bwi-fw bwi-lg bwi-file"
*ngIf="!$any(a).downloading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-lg bwi-fw bwi-spin"
*ngIf="a.downloading"
*ngIf="$any(a).downloading"
aria-hidden="true"
></i>
</td>
@ -55,7 +59,7 @@
(click)="reupload(a)"
#reuploadBtn
[appApiAction]="reuploadPromises[a.id]"
[disabled]="reuploadBtn.loading"
[disabled]="$any(reuploadBtn).loading"
>
{{ "fix" | i18n }}
</button>
@ -72,16 +76,16 @@
(click)="delete(a)"
#deleteBtn
[appApiAction]="deletePromises[a.id]"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -54,7 +54,7 @@
<td class="table-list-checkbox">
<input
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
/>

View File

@ -37,7 +37,7 @@
<td class="table-list-checkbox">
<input
type="checkbox"
[(ngModel)]="c.checked"
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
/>

View File

@ -46,17 +46,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -167,7 +167,6 @@
<i
*ngIf="!organization.enabled"
class="org-options bwi bwi-fw bwi-exclamation-triangle text-danger"
aria-label="{{ 'organizationIsDisabled' | i18n }}"
appA11yTitle="{{ 'organizationIsDisabled' | i18n }}"
></i
><button [bitMenuTriggerFor]="orgMenu" class="org-options">

View File

@ -1,6 +1,9 @@
import { NgModule } from "@angular/core";
import { SharedModule } from "../../../shared";
import { LinkSsoComponent } from "../organization-filter/link-sso.component";
import { OrganizationFilterComponent } from "../organization-filter/organization-filter.component";
import { OrganizationOptionsComponent } from "../organization-filter/organization-options.component";
import { CollectionFilterComponent } from "./collection-filter/collection-filter.component";
import { FolderFilterComponent } from "./folder-filter/folder-filter.component";
@ -15,6 +18,9 @@ import { VaultFilterService } from "./vault-filter.service";
FolderFilterComponent,
StatusFilterComponent,
TypeFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
],
exports: [
SharedModule,
@ -22,6 +28,9 @@ import { VaultFilterService } from "./vault-filter.service";
FolderFilterComponent,
StatusFilterComponent,
TypeFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
],
providers: [VaultFilterService],
})

View File

@ -1,19 +1,11 @@
import { NgModule } from "@angular/core";
import { LinkSsoComponent } from "./organization-filter/link-sso.component";
import { OrganizationFilterComponent } from "./organization-filter/organization-filter.component";
import { OrganizationOptionsComponent } from "./organization-filter/organization-options.component";
import { VaultFilterSharedModule } from "./shared/vault-filter-shared.module";
import { VaultFilterComponent } from "./vault-filter.component";
@NgModule({
imports: [VaultFilterSharedModule],
declarations: [
VaultFilterComponent,
OrganizationFilterComponent,
OrganizationOptionsComponent,
LinkSsoComponent,
],
declarations: [VaultFilterComponent],
exports: [VaultFilterComponent],
})
export class VaultFilterModule {}

View File

@ -10,7 +10,7 @@
<tbody>
<tr *ngFor="let c of filteredCiphers">
<td (click)="checkCipher(c)" class="table-list-checkbox">
<input type="checkbox" [(ngModel)]="c.checked" appStopProp />
<input type="checkbox" [(ngModel)]="$any(c).checked" appStopProp />
</td>
<td (click)="checkCipher(c)" class="table-list-icon">
<app-vault-icon [cipher]="c"></app-vault-icon>

View File

@ -289,6 +289,10 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnDe
this.onOrganzationBadgeClicked.emit(organizationId);
}
events(c: CipherView) {
// TODO: This should be removed but is needed since we reuse the same template
}
protected deleteCipher(id: string, permanent: boolean) {
return permanent
? this.cipherService.deleteWithServer(id)

View File

@ -21,7 +21,7 @@
<h1>
{{ "vaultItems" | i18n }}
<small #actionSpinner [appApiAction]="vaultItemsComponent.actionPromise">
<ng-container *ngIf="actionSpinner.loading">
<ng-container *ngIf="$any(actionSpinner).loading">
<i
class="bwi bwi-spinner bwi-spin text-muted"
title="{{ 'loading' | i18n }}"

View File

@ -12,6 +12,7 @@
}
},
"angularCompilerOptions": {
"strictTemplates": true,
"preserveWhitespaces": true
},
"files": ["src/polyfills.ts", "src/main.ts", "../../bitwarden_license/bit-web/src/main.ts"],

View File

@ -70,7 +70,7 @@
</ng-container>
<ng-container #rotateButton [appApiAction]="rotatePromise">
<button
[disabled]="rotateButton.loading"
[disabled]="$any(rotateButton).loading"
type="button"
bitSuffix
bitButton
@ -80,7 +80,7 @@
<i
aria-hidden="true"
class="bwi bwi-lg bwi-generate"
[ngClass]="{ 'bwi-spin': rotateButton.loading }"
[ngClass]="{ 'bwi-spin': $any(rotateButton).loading }"
></i>
</button>
</ng-container>

View File

@ -97,13 +97,13 @@ export class SsoComponent implements OnInit, OnDestroy {
spMetadataUrl: string;
spAcsUrl: string;
private enabled = this.formBuilder.control(false);
protected enabled = this.formBuilder.control(false);
private ssoIdentifier = this.formBuilder.control("", {
protected ssoIdentifier = this.formBuilder.control("", {
validators: [Validators.maxLength(50), Validators.required],
});
private openIdForm = this.formBuilder.group<ControlsOf<SsoConfigView["openId"]>>(
protected openIdForm = this.formBuilder.group<ControlsOf<SsoConfigView["openId"]>>(
{
authority: new FormControl("", Validators.required),
clientId: new FormControl("", Validators.required),
@ -126,7 +126,7 @@ export class SsoComponent implements OnInit, OnDestroy {
}
);
private samlForm = this.formBuilder.group<ControlsOf<SsoConfigView["saml"]>>(
protected samlForm = this.formBuilder.group<ControlsOf<SsoConfigView["saml"]>>(
{
spNameIdFormat: new FormControl(Saml2NameIdFormat.NotConfigured),
spOutboundSigningAlgorithm: new FormControl(defaultSigningAlgorithm),
@ -150,7 +150,7 @@ export class SsoComponent implements OnInit, OnDestroy {
}
);
private ssoConfigForm = this.formBuilder.group<ControlsOf<SsoConfigView>>({
protected ssoConfigForm = this.formBuilder.group<ControlsOf<SsoConfigView>>({
configType: new FormControl(SsoType.None),
keyConnectorEnabled: new FormControl(false),
keyConnectorUrl: new FormControl(""),

View File

@ -98,7 +98,7 @@
type="button"
class="btn btn-block btn-link btn-submit"
(click)="loadEvents(false)"
[disabled]="loaded && moreBtn.loading"
[disabled]="loaded && $any(moreBtn).loading"
*ngIf="continuationToken"
>
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>

View File

@ -149,7 +149,6 @@
<td>
<span *ngIf="u.type === userType.ProviderAdmin">{{ "providerAdmin" | i18n }}</span>
<span *ngIf="u.type === userType.ServiceUser">{{ "serviceUser" | i18n }}</span>
<span *ngIf="u.type === userType.Custom">{{ "custom" | i18n }}</span>
</td>
<td class="table-list-options">
<div class="dropdown" appListDropdown>
@ -184,16 +183,6 @@
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
{{ "confirm" | i18n }}
</a>
<a
class="dropdown-item"
href="#"
appStopClick
(click)="groups(u)"
*ngIf="accessGroups"
>
<i class="bwi bwi-fw bwi-sitemap" aria-hidden="true"></i>
{{ "groups" | i18n }}
</a>
<a
class="dropdown-item"
href="#"

View File

@ -102,17 +102,17 @@
class="btn btn-outline-danger"
appA11yTitle="{{ 'delete' | i18n }}"
*ngIf="editMode"
[disabled]="deleteBtn.loading"
[disabled]="$any(deleteBtn).loading"
[appApiAction]="deletePromise"
>
<i
class="bwi bwi-trash bwi-lg bwi-fw"
[hidden]="deleteBtn.loading"
[hidden]="$any(deleteBtn).loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!deleteBtn.loading"
[hidden]="!$any(deleteBtn).loading"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>

View File

@ -30,9 +30,6 @@
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "submit" | i18n }}</span>
</button>
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" *ngIf="showCancel">
{{ "cancel" | i18n }}
</button>
</div>
</form>
</div>

View File

@ -23,6 +23,7 @@ import { SecureNoteType } from "@bitwarden/common/enums/secureNoteType";
import { UriMatchType } from "@bitwarden/common/enums/uriMatchType";
import { Utils } from "@bitwarden/common/misc/utils";
import { Cipher } from "@bitwarden/common/models/domain/cipher";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CardView } from "@bitwarden/common/models/view/card.view";
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
import { CollectionView } from "@bitwarden/common/models/view/collection.view";
@ -74,6 +75,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
allowPersonal = true;
reprompt = false;
canUseReprompt = true;
organization: Organization;
protected destroy$ = new Subject<void>();
protected writeableCollections: CollectionView[];

View File

@ -292,4 +292,8 @@ export class AttachmentsComponent implements OnInit {
protected deleteCipherAttachment(attachmentId: string) {
return this.cipherService.deleteAttachmentWithServer(this.cipher.id, attachmentId);
}
protected async reupload(attachment: AttachmentView) {
// TODO: This should be removed but is needed since we re-use the same template
}
}

View File

@ -1,6 +1,5 @@
import { animate, style, transition, trigger } from "@angular/animations";
import { Component, OnInit } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormControl } from "@angular/forms";
import { Directive, OnInit } from "@angular/core";
import { ControlValueAccessor, FormControl } from "@angular/forms";
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
@ -14,21 +13,8 @@ import { Verification } from "@bitwarden/common/types/verification";
* This is exposed to the parent component via the ControlValueAccessor interface (e.g. bind it to a FormControl).
* Use UserVerificationService to verify the user's input.
*/
@Component({
@Directive({
selector: "app-user-verification",
templateUrl: "user-verification.component.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: UserVerificationComponent,
},
],
animations: [
trigger("sent", [
transition(":enter", [style({ opacity: 0 }), animate("100ms", style({ opacity: 1 }))]),
]),
],
})
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
export class UserVerificationComponent implements ControlValueAccessor, OnInit {

View File

@ -1,6 +1,7 @@
import { Directive, EventEmitter, Input, Output } from "@angular/core";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { Organization } from "@bitwarden/common/models/domain/organization";
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
@Directive()
@ -17,6 +18,8 @@ export class VaultItemsComponent {
searchPlaceholder: string = null;
filter: (cipher: CipherView) => boolean = null;
deleted = false;
organization: Organization;
accessEvents = false;
protected searchPending = false;

View File

@ -8,7 +8,7 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
export class I18nPipe implements PipeTransform {
constructor(private i18nService: I18nService) {}
transform(id: string, p1?: string, p2?: string, p3?: string): string {
transform(id: string, p1?: string | number, p2?: string | number, p3?: string | number): string {
return this.i18nService.t(id, p1, p2, p3);
}
}

View File

@ -6,6 +6,6 @@ export abstract class I18nService {
translationLocale: string;
collator: Intl.Collator;
localeNames: Map<string, string>;
t: (id: string, p1?: string, p2?: string, p3?: string) => string;
t: (id: string, p1?: string | number, p2?: string | number, p3?: string | number) => string;
translate: (id: string, p1?: string, p2?: string, p3?: string) => string;
}

View File

@ -122,7 +122,7 @@ export class I18nService implements I18nServiceAbstraction {
return this.translate(id, p1, p2, p3);
}
translate(id: string, p1?: string, p2?: string, p3?: string): string {
translate(id: string, p1?: string | number, p2?: string | number, p3?: string | number): string {
let result: string;
// eslint-disable-next-line
if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) {
@ -136,13 +136,13 @@ export class I18nService implements I18nServiceAbstraction {
if (result !== "") {
if (p1 != null) {
result = result.split("__$1__").join(p1);
result = result.split("__$1__").join(p1.toString());
}
if (p2 != null) {
result = result.split("__$2__").join(p2);
result = result.split("__$2__").join(p2.toString());
}
if (p3 != null) {
result = result.split("__$3__").join(p3);
result = result.split("__$3__").join(p3.toString());
}
}

View File

@ -1,6 +1,6 @@
import { Directive, ElementRef, HostBinding, Input } from "@angular/core";
type BadgeTypes = "primary" | "secondary" | "success" | "danger" | "warning" | "info";
export type BadgeTypes = "primary" | "secondary" | "success" | "danger" | "warning" | "info";
const styles: Record<BadgeTypes, string[]> = {
primary: ["tw-bg-primary-500"],