1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 08:43:33 +00:00

[PM-7608] Account Security Settings V2 (#10441)

* Implement account security settings v2

* Increase await dialog delay to 500 msec

* Update messages

* Replace platformservice with biometricsservice

* Cleanup

* Cleanup

* Fix account security component according to feedback

* Re-add old message

* Re-add old error message

* Fix minimum timeout message

* Fix screen-reader on custom timeout

* Remove debugging configurations

* Fix incorrectly changed message

* Remove custom vault timeout text

* Restore vaultTimeoutPolicyInEffect i18n message in web

* Change text to use vaultTimeoutPolicyInEffect1

* Fix tests
This commit is contained in:
Bernd Schoolmann
2024-09-16 17:40:08 +02:00
committed by GitHub
parent d34b40797e
commit 15610906d2
14 changed files with 1122 additions and 297 deletions

View File

@@ -1,8 +1,10 @@
<bit-simple-dialog>
<i bitDialogIcon class="bwi bwi-info-circle tw-text-3xl" aria-hidden="true"></i>
<span bitDialogTitle>{{ "yourAccountsFingerprint" | i18n }}:</span>
<span bitDialogTitle
><strong>{{ "yourAccountsFingerprint" | i18n }}:</strong></span
>
<span bitDialogContent>
<strong>{{ data.fingerprint.join("-") }}</strong>
{{ data.fingerprint.join("-") }}
</span>
<ng-container bitDialogFooter>
<a

View File

@@ -1,29 +1,47 @@
<div [formGroup]="form">
<bit-form-field>
<bit-label>{{ "vaultTimeout" | i18n }}</bit-label>
<div [formGroup]="form" class="tw-mb-4">
<bit-form-field [disableMargin]="!showCustom">
<bit-label>{{ "vaultTimeout1" | i18n }}</bit-label>
<bit-select formControlName="vaultTimeout">
<bit-option
*ngFor="let o of vaultTimeoutOptions"
*ngFor="let o of filteredVaultTimeoutOptions"
[value]="o.value"
[label]="o.name"
></bit-option>
</bit-select>
<bit-hint class="tw-text-sm">{{
((canLockVault$ | async) ? "vaultTimeoutDesc" : "vaultTimeoutLogoutDesc") | i18n
}}</bit-hint>
</bit-form-field>
<div class="tw-grid tw-grid-cols-12 tw-gap-4" *ngIf="showCustom" formGroupName="custom">
<bit-form-field class="tw-col-span-6">
<bit-label>{{ "customVaultTimeout" | i18n }}</bit-label>
<input bitInput type="number" min="0" formControlName="hours" />
<bit-hint>{{ "hours" | i18n }}</bit-hint>
<bit-form-field class="tw-col-span-6" disableMargin>
<input
bitInput
type="number"
min="0"
formControlName="hours"
aria-labelledby="maximum-error"
/>
<bit-label>{{ "hours" | i18n }}</bit-label>
</bit-form-field>
<bit-form-field class="tw-col-span-6 tw-self-end">
<input bitInput type="number" min="0" name="minutes" formControlName="minutes" />
<bit-hint>{{ "minutes" | i18n }}</bit-hint>
<bit-form-field class="tw-col-span-6 tw-self-end" disableMargin>
<input
bitInput
type="number"
min="0"
name="minutes"
formControlName="minutes"
aria-labelledby="maximum-error"
/>
<bit-label>{{ "minutes" | i18n }}</bit-label>
</bit-form-field>
</div>
<small *ngIf="!exceedsMinimumTimout" class="tw-text-danger">
<bit-hint *ngIf="vaultTimeoutPolicy != null && !exceedsMaximumTimeout">
{{ "vaultTimeoutPolicyInEffect1" | i18n: vaultTimeoutPolicyHours : vaultTimeoutPolicyMinutes }}
</bit-hint>
<small *ngIf="!exceedsMinimumTimeout" class="tw-text-danger">
<i class="bwi bwi-error" aria-hidden="true"></i> {{ "vaultCustomTimeoutMinimum" | i18n }}
</small>
<small class="tw-text-danger" *ngIf="exceedsMaximumTimeout" id="maximum-error">
<i class="bwi bwi-error" aria-hidden="true"></i>
{{
"vaultTimeoutPolicyMaximumError" | i18n: vaultTimeoutPolicyHours : vaultTimeoutPolicyMinutes
}}
</small>
</div>

View File

@@ -55,16 +55,41 @@ type VaultTimeoutFormValue = VaultTimeoutForm["value"];
export class VaultTimeoutInputComponent
implements ControlValueAccessor, Validator, OnInit, OnDestroy, OnChanges
{
protected readonly VaultTimeoutAction = VaultTimeoutAction;
get showCustom() {
return this.form.get("vaultTimeout").value === VaultTimeoutInputComponent.CUSTOM_VALUE;
}
get exceedsMinimumTimout(): boolean {
get exceedsMinimumTimeout(): boolean {
return (
!this.showCustom || this.customTimeInMinutes() > VaultTimeoutInputComponent.MIN_CUSTOM_MINUTES
);
}
get exceedsMaximumTimeout(): boolean {
return (
this.showCustom &&
this.customTimeInMinutes() >
this.vaultTimeoutPolicyMinutes + 60 * this.vaultTimeoutPolicyHours
);
}
get filteredVaultTimeoutOptions(): VaultTimeoutOption[] {
// by policy max value
if (this.vaultTimeoutPolicy == null || this.vaultTimeoutPolicy.data == null) {
return this.vaultTimeoutOptions;
}
return this.vaultTimeoutOptions.filter((option) => {
if (typeof option.value === "number") {
return option.value <= this.vaultTimeoutPolicy.data.minutes;
}
return false;
});
}
static CUSTOM_VALUE = -100;
static MIN_CUSTOM_MINUTES = 0;
@@ -77,6 +102,7 @@ export class VaultTimeoutInputComponent
});
@Input() vaultTimeoutOptions: VaultTimeoutOption[];
vaultTimeoutPolicy: Policy;
vaultTimeoutPolicyHours: number;
vaultTimeoutPolicyMinutes: number;
@@ -207,7 +233,7 @@ export class VaultTimeoutInputComponent
return { policyError: true };
}
if (!this.exceedsMinimumTimout) {
if (!this.exceedsMinimumTimeout) {
return { minTimeoutError: true };
}