mirror of
https://github.com/bitwarden/browser
synced 2026-01-29 07:43:28 +00:00
Remove legacy components
This commit is contained in:
@@ -1,90 +0,0 @@
|
||||
<app-header></app-header>
|
||||
|
||||
<bit-container>
|
||||
<p bitTypography="body1">{{ "preferencesDesc" | i18n }}</p>
|
||||
<form [formGroup]="form" [bitSubmit]="submit" class="tw-w-full tw-max-w-md">
|
||||
<bit-callout type="info" *ngIf="vaultTimeoutPolicyCallout | async as policy">
|
||||
<span *ngIf="policy.timeout && policy.action">
|
||||
{{
|
||||
"vaultTimeoutPolicyWithActionInEffect"
|
||||
| i18n: policy.timeout.hours : policy.timeout.minutes : (policy.action | i18n)
|
||||
}}
|
||||
</span>
|
||||
<span *ngIf="policy.timeout && !policy.action">
|
||||
{{ "vaultTimeoutPolicyInEffect" | i18n: policy.timeout.hours : policy.timeout.minutes }}
|
||||
</span>
|
||||
<span *ngIf="!policy.timeout && policy.action">
|
||||
{{ "vaultTimeoutActionPolicyInEffect" | i18n: (policy.action | i18n) }}
|
||||
</span>
|
||||
</bit-callout>
|
||||
<bit-session-timeout-input-legacy
|
||||
[vaultTimeoutOptions]="vaultTimeoutOptions"
|
||||
[formControl]="form.controls.vaultTimeout"
|
||||
ngDefaultControl
|
||||
>
|
||||
</bit-session-timeout-input-legacy>
|
||||
<ng-container *ngIf="availableVaultTimeoutActions$ | async as availableVaultTimeoutActions">
|
||||
<bit-radio-group
|
||||
formControlName="vaultTimeoutAction"
|
||||
*ngIf="availableVaultTimeoutActions.length > 1"
|
||||
>
|
||||
<bit-label>{{ "vaultTimeoutAction" | i18n }}</bit-label>
|
||||
<bit-radio-button
|
||||
*ngIf="availableVaultTimeoutActions.includes(VaultTimeoutAction.Lock)"
|
||||
id="vaultTimeoutActionLock"
|
||||
[value]="VaultTimeoutAction.Lock"
|
||||
>
|
||||
<bit-label>{{ "lock" | i18n }}</bit-label>
|
||||
<bit-hint>{{ "vaultTimeoutActionLockDesc" | i18n }}</bit-hint>
|
||||
</bit-radio-button>
|
||||
<bit-radio-button
|
||||
*ngIf="availableVaultTimeoutActions.includes(VaultTimeoutAction.LogOut)"
|
||||
id="vaultTimeoutActionLogOut"
|
||||
[value]="VaultTimeoutAction.LogOut"
|
||||
>
|
||||
<bit-label>{{ "logOut" | i18n }}</bit-label>
|
||||
<bit-hint>{{ "vaultTimeoutActionLogOutDesc" | i18n }}</bit-hint>
|
||||
</bit-radio-button>
|
||||
</bit-radio-group>
|
||||
</ng-container>
|
||||
<bit-form-field>
|
||||
<bit-label>
|
||||
{{ "language" | i18n }}
|
||||
<a
|
||||
bitLink
|
||||
class="tw-float-right"
|
||||
href="https://bitwarden.com/help/localization/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
appA11yTitle="{{ 'learnMoreAboutLocalization' | i18n }}"
|
||||
slot="end"
|
||||
>
|
||||
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
|
||||
</a>
|
||||
</bit-label>
|
||||
<bit-select formControlName="locale" id="locale">
|
||||
<bit-option *ngFor="let o of localeOptions" [value]="o.value" [label]="o.name"></bit-option>
|
||||
</bit-select>
|
||||
<bit-hint>{{ "languageDesc" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
<div class="tw-flex tw-items-start tw-gap-1.5">
|
||||
<bit-form-control>
|
||||
<input type="checkbox" bitCheckbox formControlName="enableFavicons" />
|
||||
<bit-label>
|
||||
{{ "showIconsChangePasswordUrls" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
<div class="-tw-mt-0.5">
|
||||
<vault-permit-cipher-details-popover></vault-permit-cipher-details-popover>
|
||||
</div>
|
||||
</div>
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "theme" | i18n }}</bit-label>
|
||||
<bit-select formControlName="theme" id="theme">
|
||||
<bit-option *ngFor="let o of themeOptions" [value]="o.value" [label]="o.name"></bit-option>
|
||||
</bit-select>
|
||||
<bit-hint>{{ "themeDesc" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
<button bitButton bitFormButton type="submit" buttonType="primary">{{ "save" | i18n }}</button>
|
||||
</form>
|
||||
</bit-container>
|
||||
@@ -1,239 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import {
|
||||
concatMap,
|
||||
filter,
|
||||
firstValueFrom,
|
||||
map,
|
||||
Observable,
|
||||
Subject,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
tap,
|
||||
} from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import {
|
||||
VaultTimeout,
|
||||
VaultTimeoutAction,
|
||||
VaultTimeoutOption,
|
||||
VaultTimeoutSettingsService,
|
||||
VaultTimeoutStringType,
|
||||
} from "@bitwarden/common/key-management/vault-timeout";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { SessionTimeoutInputLegacyComponent } from "@bitwarden/key-management-ui";
|
||||
import { PermitCipherDetailsPopoverComponent } from "@bitwarden/vault";
|
||||
|
||||
import { HeaderModule } from "../layouts/header/header.module";
|
||||
import { SharedModule } from "../shared";
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link AppearanceComponent} and {@link SessionTimeoutComponent} instead.
|
||||
*
|
||||
* TODO Cleanup once feature flag enabled: https://bitwarden.atlassian.net/browse/PM-27297
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
selector: "app-preferences",
|
||||
templateUrl: "preferences.component.html",
|
||||
imports: [
|
||||
SharedModule,
|
||||
HeaderModule,
|
||||
PermitCipherDetailsPopoverComponent,
|
||||
SessionTimeoutInputLegacyComponent,
|
||||
],
|
||||
})
|
||||
export class PreferencesComponent implements OnInit, OnDestroy {
|
||||
// For use in template
|
||||
protected readonly VaultTimeoutAction = VaultTimeoutAction;
|
||||
|
||||
protected availableVaultTimeoutActions$: Observable<VaultTimeoutAction[]>;
|
||||
|
||||
vaultTimeoutPolicyCallout: Observable<{
|
||||
timeout: { hours: number; minutes: number };
|
||||
action: VaultTimeoutAction;
|
||||
}>;
|
||||
vaultTimeoutOptions: VaultTimeoutOption[];
|
||||
localeOptions: any[];
|
||||
themeOptions: any[];
|
||||
|
||||
private startingLocale: string;
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
form = this.formBuilder.group({
|
||||
vaultTimeout: [null as VaultTimeout | null],
|
||||
vaultTimeoutAction: [VaultTimeoutAction.Lock],
|
||||
enableFavicons: true,
|
||||
theme: [ThemeTypes.Light as Theme],
|
||||
locale: [null as string | null],
|
||||
});
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private policyService: PolicyService,
|
||||
private i18nService: I18nService,
|
||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private themeStateService: ThemeStateService,
|
||||
private domainSettingsService: DomainSettingsService,
|
||||
private dialogService: DialogService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
this.vaultTimeoutOptions = [
|
||||
{ name: i18nService.t("oneMinute"), value: 1 },
|
||||
{ name: i18nService.t("fiveMinutes"), value: 5 },
|
||||
{ name: i18nService.t("fifteenMinutes"), value: 15 },
|
||||
{ name: i18nService.t("thirtyMinutes"), value: 30 },
|
||||
{ name: i18nService.t("oneHour"), value: 60 },
|
||||
{ name: i18nService.t("fourHours"), value: 240 },
|
||||
{ name: i18nService.t("onRefresh"), value: VaultTimeoutStringType.OnRestart },
|
||||
];
|
||||
if (this.platformUtilsService.isDev()) {
|
||||
this.vaultTimeoutOptions.push({
|
||||
name: i18nService.t("never"),
|
||||
value: VaultTimeoutStringType.Never,
|
||||
});
|
||||
}
|
||||
|
||||
const localeOptions: any[] = [];
|
||||
i18nService.supportedTranslationLocales.forEach((locale) => {
|
||||
let name = locale;
|
||||
if (i18nService.localeNames.has(locale)) {
|
||||
name += " - " + i18nService.localeNames.get(locale);
|
||||
}
|
||||
localeOptions.push({ name: name, value: locale });
|
||||
});
|
||||
localeOptions.sort(Utils.getSortFunction(i18nService, "name"));
|
||||
localeOptions.splice(0, 0, { name: i18nService.t("default"), value: null });
|
||||
this.localeOptions = localeOptions;
|
||||
this.themeOptions = [
|
||||
{ name: i18nService.t("themeLight"), value: ThemeTypes.Light },
|
||||
{ name: i18nService.t("themeDark"), value: ThemeTypes.Dark },
|
||||
{ name: i18nService.t("themeSystem"), value: ThemeTypes.System },
|
||||
];
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.availableVaultTimeoutActions$ =
|
||||
this.vaultTimeoutSettingsService.availableVaultTimeoutActions$();
|
||||
|
||||
this.vaultTimeoutPolicyCallout = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.MaximumVaultTimeout, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
filter((policy) => policy != null),
|
||||
map((policy) => {
|
||||
let timeout;
|
||||
if (policy.data?.minutes) {
|
||||
timeout = {
|
||||
hours: Math.floor(policy.data?.minutes / 60),
|
||||
minutes: policy.data?.minutes % 60,
|
||||
};
|
||||
}
|
||||
return { timeout: timeout, action: policy.data?.action };
|
||||
}),
|
||||
tap((policy) => {
|
||||
if (policy.action) {
|
||||
this.form.controls.vaultTimeoutAction.disable({ emitEvent: false });
|
||||
} else {
|
||||
this.form.controls.vaultTimeoutAction.enable({ emitEvent: false });
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
this.form.controls.vaultTimeoutAction.valueChanges
|
||||
.pipe(
|
||||
concatMap(async (action) => {
|
||||
if (action === VaultTimeoutAction.LogOut) {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "vaultTimeoutLogOutConfirmationTitle" },
|
||||
content: { key: "vaultTimeoutLogOutConfirmation" },
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
if (!confirmed) {
|
||||
this.form.controls.vaultTimeoutAction.patchValue(VaultTimeoutAction.Lock, {
|
||||
emitEvent: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
const activeAcct = await firstValueFrom(this.accountService.activeAccount$);
|
||||
|
||||
const initialFormValues = {
|
||||
vaultTimeout: await firstValueFrom(
|
||||
this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(activeAcct.id),
|
||||
),
|
||||
vaultTimeoutAction: await firstValueFrom(
|
||||
this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(activeAcct.id),
|
||||
),
|
||||
enableFavicons: await firstValueFrom(this.domainSettingsService.showFavicons$),
|
||||
theme: await firstValueFrom(this.themeStateService.selectedTheme$),
|
||||
locale: (await firstValueFrom(this.i18nService.userSetLocale$)) ?? null,
|
||||
};
|
||||
this.startingLocale = initialFormValues.locale;
|
||||
this.form.setValue(initialFormValues, { emitEvent: false });
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
if (!this.form.controls.vaultTimeout.valid) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
null,
|
||||
this.i18nService.t("vaultTimeoutRangeError"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// must get raw value b/c the vault timeout action is disabled when a policy is applied
|
||||
// which removes the timeout action property and value from the normal form.value.
|
||||
const values = this.form.getRawValue();
|
||||
|
||||
const activeAcct = await firstValueFrom(this.accountService.activeAccount$);
|
||||
|
||||
await this.vaultTimeoutSettingsService.setVaultTimeoutOptions(
|
||||
activeAcct.id,
|
||||
values.vaultTimeout,
|
||||
values.vaultTimeoutAction,
|
||||
);
|
||||
|
||||
// Save other preferences (theme, locale, favicons)
|
||||
await this.domainSettingsService.setShowFavicons(values.enableFavicons);
|
||||
await this.themeStateService.setSelectedTheme(values.theme);
|
||||
await this.i18nService.setLocale(values.locale);
|
||||
if (values.locale !== this.startingLocale) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
null,
|
||||
this.i18nService.t("preferencesUpdated"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,3 @@ export { ConfirmKeyConnectorDomainComponent } from "./key-connector/confirm-key-
|
||||
export { SessionTimeoutSettingsComponent } from "./session-timeout/components/session-timeout-settings.component";
|
||||
export { SessionTimeoutSettingsComponentService } from "./session-timeout/services/session-timeout-settings-component.service";
|
||||
export { SessionTimeoutInputComponent } from "./session-timeout/components/session-timeout-input.component";
|
||||
export { SessionTimeoutInputLegacyComponent } from "./session-timeout/components/session-timeout-input-legacy.component";
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<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 filteredVaultTimeoutOptions"
|
||||
[value]="o.value"
|
||||
[label]="o.name"
|
||||
></bit-option>
|
||||
</bit-select>
|
||||
</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" 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" 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>
|
||||
<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>
|
||||
@@ -1,296 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, Input, OnChanges, OnDestroy, OnInit } from "@angular/core";
|
||||
import {
|
||||
AbstractControl,
|
||||
ControlValueAccessor,
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ReactiveFormsModule,
|
||||
ValidationErrors,
|
||||
Validator,
|
||||
} from "@angular/forms";
|
||||
import { filter, map, Observable, Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import {
|
||||
VaultTimeout,
|
||||
VaultTimeoutAction,
|
||||
VaultTimeoutOption,
|
||||
VaultTimeoutSettingsService,
|
||||
} from "@bitwarden/common/key-management/vault-timeout";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { FormFieldModule, SelectModule } from "@bitwarden/components";
|
||||
|
||||
type VaultTimeoutForm = FormGroup<{
|
||||
vaultTimeout: FormControl<VaultTimeout | null>;
|
||||
custom: FormGroup<{
|
||||
hours: FormControl<number | null>;
|
||||
minutes: FormControl<number | null>;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
type VaultTimeoutFormValue = VaultTimeoutForm["value"];
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link SessionTimeoutInputComponent} instead.
|
||||
*
|
||||
* TODO Cleanup once feature flag enabled: https://bitwarden.atlassian.net/browse/PM-27297
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
selector: "bit-session-timeout-input-legacy",
|
||||
templateUrl: "session-timeout-input-legacy.component.html",
|
||||
imports: [CommonModule, JslibModule, ReactiveFormsModule, FormFieldModule, SelectModule],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
multi: true,
|
||||
useExisting: SessionTimeoutInputLegacyComponent,
|
||||
},
|
||||
{
|
||||
provide: NG_VALIDATORS,
|
||||
multi: true,
|
||||
useExisting: SessionTimeoutInputLegacyComponent,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class SessionTimeoutInputLegacyComponent
|
||||
implements ControlValueAccessor, Validator, OnInit, OnDestroy, OnChanges
|
||||
{
|
||||
static CUSTOM_VALUE = -100;
|
||||
static MIN_CUSTOM_MINUTES = 0;
|
||||
form: VaultTimeoutForm = this.formBuilder.group({
|
||||
vaultTimeout: [null],
|
||||
custom: this.formBuilder.group({
|
||||
hours: [null],
|
||||
minutes: [null],
|
||||
}),
|
||||
});
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() vaultTimeoutOptions: VaultTimeoutOption[];
|
||||
|
||||
vaultTimeoutPolicy: Policy;
|
||||
vaultTimeoutPolicyHours: number;
|
||||
vaultTimeoutPolicyMinutes: number;
|
||||
|
||||
protected readonly VaultTimeoutAction = VaultTimeoutAction;
|
||||
|
||||
protected canLockVault$: Observable<boolean>;
|
||||
private onChange: (vaultTimeout: VaultTimeout) => void;
|
||||
private validatorChange: () => void;
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private policyService: PolicyService,
|
||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||
private i18nService: I18nService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
get showCustom() {
|
||||
return this.form.get("vaultTimeout").value === SessionTimeoutInputLegacyComponent.CUSTOM_VALUE;
|
||||
}
|
||||
|
||||
get exceedsMinimumTimeout(): boolean {
|
||||
return (
|
||||
!this.showCustom ||
|
||||
this.customTimeInMinutes() > SessionTimeoutInputLegacyComponent.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;
|
||||
});
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.MaximumVaultTimeout, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
filter((policy) => policy != null),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((policy) => {
|
||||
this.vaultTimeoutPolicy = policy;
|
||||
this.applyVaultTimeoutPolicy();
|
||||
});
|
||||
this.form.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((value: VaultTimeoutFormValue) => {
|
||||
if (this.onChange) {
|
||||
this.onChange(this.getVaultTimeout(value));
|
||||
}
|
||||
});
|
||||
|
||||
// Assign the current value to the custom fields
|
||||
// so that if the user goes from a numeric value to custom
|
||||
// we can initialize the custom fields with the current value
|
||||
// ex: user picks 5 min, goes to custom, we want to show 0 hr, 5 min in the custom fields
|
||||
this.form.controls.vaultTimeout.valueChanges
|
||||
.pipe(
|
||||
filter((value) => value !== SessionTimeoutInputLegacyComponent.CUSTOM_VALUE),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((value) => {
|
||||
const current = typeof value === "string" ? 0 : Math.max(value, 0);
|
||||
|
||||
// This cannot emit an event b/c it would cause form.valueChanges to fire again
|
||||
// and we are already handling that above so just silently update
|
||||
// custom fields when vaultTimeout changes to a non-custom value
|
||||
this.form.patchValue(
|
||||
{
|
||||
custom: {
|
||||
hours: Math.floor(current / 60),
|
||||
minutes: current % 60,
|
||||
},
|
||||
},
|
||||
{ emitEvent: false },
|
||||
);
|
||||
});
|
||||
|
||||
this.canLockVault$ = this.vaultTimeoutSettingsService
|
||||
.availableVaultTimeoutActions$()
|
||||
.pipe(map((actions) => actions.includes(VaultTimeoutAction.Lock)));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
if (
|
||||
!this.vaultTimeoutOptions.find(
|
||||
(p) => p.value === SessionTimeoutInputLegacyComponent.CUSTOM_VALUE,
|
||||
)
|
||||
) {
|
||||
this.vaultTimeoutOptions.push({
|
||||
name: this.i18nService.t("custom"),
|
||||
value: SessionTimeoutInputLegacyComponent.CUSTOM_VALUE,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getVaultTimeout(value: VaultTimeoutFormValue) {
|
||||
if (value.vaultTimeout !== SessionTimeoutInputLegacyComponent.CUSTOM_VALUE) {
|
||||
return value.vaultTimeout;
|
||||
}
|
||||
|
||||
return value.custom.hours * 60 + value.custom.minutes;
|
||||
}
|
||||
|
||||
writeValue(value: number): void {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.vaultTimeoutOptions.every((p) => p.value !== value)) {
|
||||
this.form.setValue({
|
||||
vaultTimeout: SessionTimeoutInputLegacyComponent.CUSTOM_VALUE,
|
||||
custom: {
|
||||
hours: Math.floor(value / 60),
|
||||
minutes: value % 60,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.form.patchValue({
|
||||
vaultTimeout: value,
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(onChange: any): void {
|
||||
this.onChange = onChange;
|
||||
}
|
||||
|
||||
registerOnTouched(onTouched: any): void {
|
||||
// Empty
|
||||
}
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
// Empty
|
||||
}
|
||||
|
||||
validate(control: AbstractControl): ValidationErrors {
|
||||
if (this.vaultTimeoutPolicy && this.vaultTimeoutPolicy?.data?.minutes < control.value) {
|
||||
return { policyError: true };
|
||||
}
|
||||
|
||||
if (!this.exceedsMinimumTimeout) {
|
||||
return { minTimeoutError: true };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
registerOnValidatorChange(fn: () => void): void {
|
||||
this.validatorChange = fn;
|
||||
}
|
||||
|
||||
private customTimeInMinutes() {
|
||||
return this.form.value.custom.hours * 60 + this.form.value.custom.minutes;
|
||||
}
|
||||
|
||||
private applyVaultTimeoutPolicy() {
|
||||
this.vaultTimeoutPolicyHours = Math.floor(this.vaultTimeoutPolicy.data.minutes / 60);
|
||||
this.vaultTimeoutPolicyMinutes = this.vaultTimeoutPolicy.data.minutes % 60;
|
||||
|
||||
this.vaultTimeoutOptions = this.vaultTimeoutOptions.filter((vaultTimeoutOption) => {
|
||||
// Always include the custom option
|
||||
if (vaultTimeoutOption.value === SessionTimeoutInputLegacyComponent.CUSTOM_VALUE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof vaultTimeoutOption.value === "number") {
|
||||
// Include numeric values that are less than or equal to the policy minutes
|
||||
return vaultTimeoutOption.value <= this.vaultTimeoutPolicy.data.minutes;
|
||||
}
|
||||
|
||||
// Exclude all string cases when there's a numeric policy defined
|
||||
return false;
|
||||
});
|
||||
|
||||
// Only call validator change if it's been set
|
||||
if (this.validatorChange) {
|
||||
this.validatorChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user