mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-26057] Enforce session timeout policy (#17424)
* enforce session timeout policy * better angular validation * lint fix * missing switch break * fallback when timeout not supported with highest available timeout * failing unit tests * incorrect policy message * vault timeout type adjustments * fallback to "on browser refresh" for browser, when policy is set to "on system locked", but not available (Safari) * docs, naming improvements * fallback for current user session timeout to "on refresh", when policy is set to "on system locked", but not available. * don't display policy message when the policy does not affect available timeout options * 8 hours default when changing from non-numeric timeout to Custom. * failing unit test * missing locales, changing functions access to private, docs * removal of redundant magic number * missing await * await once for available timeout options * adjusted messaging * unit test coverage * vault timeout numeric module exports * unit test coverage
This commit is contained in:
@@ -7,16 +7,16 @@ import { mock } from "jest-mock-extended";
|
||||
import { Observable, of } from "rxjs";
|
||||
|
||||
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
|
||||
import {
|
||||
SessionTimeoutAction,
|
||||
SessionTimeoutType,
|
||||
} from "@bitwarden/common/key-management/session-timeout";
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/key-management/vault-timeout";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogRef, DialogService } from "@bitwarden/components";
|
||||
|
||||
import { SessionTimeoutConfirmationNeverComponent } from "./session-timeout-confirmation-never.component";
|
||||
import {
|
||||
SessionTimeoutAction,
|
||||
SessionTimeoutPolicyComponent,
|
||||
SessionTimeoutType,
|
||||
} from "./session-timeout.component";
|
||||
import { SessionTimeoutPolicyComponent } from "./session-timeout.component";
|
||||
|
||||
// Mock DialogRef, so we can mock "readonly closed" property.
|
||||
class MockDialogRef extends DialogRef {
|
||||
|
||||
@@ -10,26 +10,22 @@ import {
|
||||
} from "rxjs";
|
||||
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import {
|
||||
MaximumSessionTimeoutPolicyData,
|
||||
SessionTimeoutAction,
|
||||
SessionTimeoutType,
|
||||
} from "@bitwarden/common/key-management/session-timeout";
|
||||
import { VaultTimeoutAction } from "@bitwarden/common/key-management/vault-timeout";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
BasePolicyEditDefinition,
|
||||
BasePolicyEditComponent,
|
||||
BasePolicyEditDefinition,
|
||||
} from "@bitwarden/web-vault/app/admin-console/organizations/policies";
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
|
||||
import { SessionTimeoutConfirmationNeverComponent } from "./session-timeout-confirmation-never.component";
|
||||
|
||||
export type SessionTimeoutAction = null | "lock" | "logOut";
|
||||
export type SessionTimeoutType =
|
||||
| null
|
||||
| "never"
|
||||
| "onAppRestart"
|
||||
| "onSystemLock"
|
||||
| "immediately"
|
||||
| "custom";
|
||||
|
||||
export class SessionTimeoutPolicy extends BasePolicyEditDefinition {
|
||||
name = "sessionTimeoutPolicyTitle";
|
||||
description = "sessionTimeoutPolicyDescription";
|
||||
@@ -50,9 +46,6 @@ export class SessionTimeoutPolicyComponent
|
||||
extends BasePolicyEditComponent
|
||||
implements OnInit, OnDestroy
|
||||
{
|
||||
private destroy$ = new Subject<void>();
|
||||
private lastConfirmedType$ = new BehaviorSubject<SessionTimeoutType>(null);
|
||||
|
||||
actionOptions: { name: string; value: SessionTimeoutAction }[];
|
||||
typeOptions: { name: string; value: SessionTimeoutType }[];
|
||||
data = this.formBuilder.group({
|
||||
@@ -74,6 +67,9 @@ export class SessionTimeoutPolicyComponent
|
||||
action: new FormControl<SessionTimeoutAction>(null),
|
||||
});
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
private lastConfirmedType$ = new BehaviorSubject<SessionTimeoutType>(null);
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private i18nService: I18nService,
|
||||
@@ -123,12 +119,10 @@ export class SessionTimeoutPolicyComponent
|
||||
}
|
||||
|
||||
protected override loadData() {
|
||||
const minutes: number | null = this.policyResponse?.data?.minutes ?? null;
|
||||
const action: SessionTimeoutAction =
|
||||
this.policyResponse?.data?.action ?? (null satisfies SessionTimeoutAction);
|
||||
const minutes: number | null = this.policyData?.minutes ?? null;
|
||||
const action: SessionTimeoutAction = this.policyData?.action ?? null;
|
||||
// For backward compatibility, the "type" field might not exist, hence we initialize it based on the presence of "minutes"
|
||||
const type: SessionTimeoutType =
|
||||
this.policyResponse?.data?.type ?? ((minutes ? "custom" : null) satisfies SessionTimeoutType);
|
||||
const type: SessionTimeoutType = this.policyData?.type ?? (minutes ? "custom" : null);
|
||||
|
||||
this.updateFormControls(type);
|
||||
this.data.patchValue({
|
||||
@@ -165,7 +159,11 @@ export class SessionTimeoutPolicyComponent
|
||||
type,
|
||||
minutes,
|
||||
action: this.data.value.action,
|
||||
};
|
||||
} satisfies MaximumSessionTimeoutPolicyData;
|
||||
}
|
||||
|
||||
private get policyData(): MaximumSessionTimeoutPolicyData | null {
|
||||
return this.policyResponse?.data ?? null;
|
||||
}
|
||||
|
||||
private async confirmTypeChange(newType: SessionTimeoutType): Promise<boolean> {
|
||||
|
||||
Reference in New Issue
Block a user