1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-27 17:18:04 +01:00

Vault Timeout Policy (#2048)

This commit is contained in:
Oscar Hinton 2021-09-14 13:36:34 +02:00 committed by GitHub
parent 63d0b8f9d2
commit 2e6f0f4166
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 135 additions and 29 deletions

2
jslib

@ -1 +1 @@
Subproject commit 5f64d956520612a681611a27c5f4f2e5f27b640e
Subproject commit a85c45a34ed90b09f59ec27bdba754d66452915e

View File

@ -1776,5 +1776,27 @@
},
"ssoCompleteRegistration": {
"message": "In order to complete logging in with SSO, please set a master password to access and protect your vault."
},
"hours": {
"message": "Hours"
},
"minutes": {
"message": "Minutes"
},
"vaultTimeoutPolicyInEffect": {
"message": "Your organization policies are affecting your vault timeout. Maximum allowed Vault Timeout is $HOURS$ hour(s) and $MINUTES$ minute(s)",
"placeholders": {
"hours": {
"content": "$1",
"example": "5"
},
"minutes": {
"content": "$2",
"example": "5"
}
}
},
"vaultTimeoutToLarge": {
"message": "Your vault timeout exceeds the restrictions set by your organization."
}
}

View File

@ -197,7 +197,7 @@ export default class MainBackground {
this.policyService = new PolicyService(this.userService, this.storageService);
this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService,
this.collectionService, this.cryptoService, this.platformUtilsService, this.storageService,
this.messagingService, this.searchService, this.userService, this.tokenService,
this.messagingService, this.searchService, this.userService, this.tokenService, this.policyService,
async () => {
if (this.notificationsService != null) {
this.notificationsService.updateConnection(false);

View File

@ -37,6 +37,7 @@ import { OptionsComponent } from './settings/options.component';
import { PremiumComponent } from './settings/premium.component';
import { SettingsComponent } from './settings/settings.component';
import { SyncComponent } from './settings/sync.component';
import { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';
import { AddEditComponent } from './vault/add-edit.component';
import { AttachmentsComponent } from './vault/attachments.component';
@ -242,6 +243,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
UpdateTempPasswordComponent,
ViewComponent,
PasswordRepromptComponent,
VaultTimeoutInputComponent,
],
entryComponents: [],
providers: [

View File

@ -200,6 +200,13 @@
}
}
&.last:last-child:before {
border-bottom: 1px solid #000000;
@include themify($themes) {
border-bottom-color: themed('boxBorderColor');
}
}
&:after {
content: "";
display: table;

11
src/popup/scss/grid.scss Normal file
View File

@ -0,0 +1,11 @@
.row {
display: flex;
margin: 0 -15px;
width: 100%;
}
.col {
flex-basis: 0;
flex-grow: 1;
padding: 0 15px;
}

View File

@ -1,6 +1,7 @@
@import "../css/webfonts.css";
@import "variables.scss";
@import "base.scss";
@import "grid.scss";
@import "box.scss";
@import "buttons.scss";
@import "misc.scss";

View File

@ -28,13 +28,7 @@
<div class="box list">
<div class="box-header">{{'security' | i18n}}</div>
<div class="box-content single-line">
<div class="box-content-row display-block" appBoxRow>
<label for="vaultTimeout">{{'vaultTimeout' | i18n}}</label>
<select #vaultTimeoutSelect id="vaultTimeout" name="VaultTimeouts" [ngModel]="vaultTimeout"
(ngModelChange)="saveVaultTimeout($event)">
<option *ngFor="let o of vaultTimeouts" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
<app-vault-timeout-input [vaultTimeouts]="vaultTimeouts" [formControl]="vaultTimeout" ngDefaultControl></app-vault-timeout-input>
<div class="box-content-row display-block" appBoxRow>
<label for="vaultTimeoutAction">{{'vaultTimeoutAction' | i18n}}</label>
<select #vaultTimeoutActionSelect id="vaultTimeoutAction" name="VaultTimeoutActions"

View File

@ -1,12 +1,13 @@
import Swal from 'sweetalert2/src/sweetalert2.js';
import {
Component,
ElementRef,
OnInit,
ViewChild,
} from '@angular/core';
import { FormControl } from '@angular/forms';
import { Router } from '@angular/router';
import { ToasterService } from 'angular2-toaster';
import Swal from 'sweetalert2/src/sweetalert2.js';
import { BrowserApi } from '../../browser/browserApi';
@ -44,10 +45,8 @@ const RateUrls = {
templateUrl: 'settings.component.html',
})
export class SettingsComponent implements OnInit {
@ViewChild('vaultTimeoutSelect', { read: ElementRef, static: true }) vaultTimeoutSelectRef: ElementRef;
@ViewChild('vaultTimeoutActionSelect', { read: ElementRef, static: true }) vaultTimeoutActionSelectRef: ElementRef;
vaultTimeouts: any[];
vaultTimeout: number = null;
vaultTimeoutActions: any[];
vaultTimeoutAction: string;
pin: boolean = null;
@ -55,11 +54,14 @@ export class SettingsComponent implements OnInit {
biometric: boolean = false;
previousVaultTimeout: number = null;
vaultTimeout: FormControl = new FormControl(null);
constructor(private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,
private vaultTimeoutService: VaultTimeoutService, private storageService: StorageService,
public messagingService: MessagingService, private router: Router,
private environmentService: EnvironmentService, private cryptoService: CryptoService,
private userService: UserService, private popupUtilsService: PopupUtilsService) {
private userService: UserService, private popupUtilsService: PopupUtilsService,
private toasterService: ToasterService) {
}
async ngOnInit() {
@ -89,14 +91,18 @@ export class SettingsComponent implements OnInit {
{ name: this.i18nService.t('logOut'), value: 'logOut' },
];
let timeout = await this.storageService.get<number>(ConstantsService.vaultTimeoutKey);
let timeout = await this.vaultTimeoutService.getVaultTimeout();
if (timeout != null) {
if (timeout === -2 && !showOnLocked) {
timeout = -1;
}
this.vaultTimeout = timeout;
this.vaultTimeout.setValue(timeout);
}
this.previousVaultTimeout = this.vaultTimeout;
this.previousVaultTimeout = this.vaultTimeout.value;
this.vaultTimeout.valueChanges.subscribe(value => {
this.saveVaultTimeout(value);
});
const action = await this.storageService.get<string>(ConstantsService.vaultTimeoutActionKey);
this.vaultTimeoutAction = action == null ? 'lock' : action;
@ -113,18 +119,19 @@ export class SettingsComponent implements OnInit {
this.i18nService.t('neverLockWarning'), null,
this.i18nService.t('yes'), this.i18nService.t('cancel'), 'warning');
if (!confirmed) {
this.vaultTimeouts.forEach((option: any, i) => {
if (option.value === this.vaultTimeout) {
this.vaultTimeoutSelectRef.nativeElement.value = i + ': ' + this.vaultTimeout;
}
});
this.vaultTimeout.setValue(this.previousVaultTimeout);
return;
}
}
this.previousVaultTimeout = this.vaultTimeout;
this.vaultTimeout = newValue;
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout != null ? this.vaultTimeout : null,
this.vaultTimeoutAction);
if (!this.vaultTimeout.valid) {
this.toasterService.popAsync('error', null, this.i18nService.t('vaultTimeoutToLarge'));
return;
}
this.previousVaultTimeout = this.vaultTimeout.value;
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);
if (this.previousVaultTimeout == null) {
this.messagingService.send('bgReseedStorage');
}
@ -145,9 +152,14 @@ export class SettingsComponent implements OnInit {
return;
}
}
if (!this.vaultTimeout.valid) {
this.toasterService.popAsync('error', null, this.i18nService.t('vaultTimeoutToLarge'));
return;
}
this.vaultTimeoutAction = newValue;
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout != null ? this.vaultTimeout : null,
this.vaultTimeoutAction);
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);
}
async updatePin() {

View File

@ -0,0 +1,29 @@
<app-callout type="info" *ngIf="vaultTimeoutPolicy">
{{'vaultTimeoutPolicyInEffect' | i18n : vaultTimeoutPolicyHours : vaultTimeoutPolicyMinutes}}
</app-callout>
<div [formGroup]="form">
<div class="box-content-row last display-block" appBoxRow>
<label for="vaultTimeout">{{'vaultTimeout' | i18n}}</label>
<select id="vaultTimeout" name="VaultTimeout" formControlName="vaultTimeout" class="form-control">
<option *ngFor="let o of vaultTimeouts" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
<div class="box-content-row last" *ngIf="showCustom">
<div formGroupName="custom" class="row">
<div class="col">
<div class="display-block" appBoxRow>
<label for="customVaultTimeout">{{'hours' | i18n }}</label>
<input id="hours" class="form-control" type="number" min="0" name="hours" formControlName="hours">
</div>
</div>
<div class="col">
<div class="display-block" appBoxRow>
<label for="customVaultTimeout">{{'minutes' | i18n }}</label>
<input id="minutes" class="form-control" type="number" min="0" max="59" name="minutes"
formControlName="minutes">
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
import { Component } from '@angular/core';
import {
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
} from '@angular/forms';
import {
VaultTimeoutInputComponent as VaultTimeoutInputComponentBase
} from 'jslib-angular/components/settings/vault-timeout-input.component';
@Component({
selector: 'app-vault-timeout-input',
templateUrl: 'vault-timeout-input.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: VaultTimeoutInputComponent,
},
{
provide: NG_VALIDATORS,
multi: true,
useExisting: VaultTimeoutInputComponent,
},
],
})
export class VaultTimeoutInputComponent extends VaultTimeoutInputComponentBase {
}