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:
parent
63d0b8f9d2
commit
2e6f0f4166
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit 5f64d956520612a681611a27c5f4f2e5f27b640e
|
Subproject commit a85c45a34ed90b09f59ec27bdba754d66452915e
|
@ -1764,7 +1764,7 @@
|
|||||||
},
|
},
|
||||||
"updateMasterPasswordWarning": {
|
"updateMasterPasswordWarning": {
|
||||||
"message": "Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour."
|
"message": "Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour."
|
||||||
},
|
},
|
||||||
"resetPasswordPolicyAutoEnroll": {
|
"resetPasswordPolicyAutoEnroll": {
|
||||||
"message": "Automatic Enrollment"
|
"message": "Automatic Enrollment"
|
||||||
},
|
},
|
||||||
@ -1776,5 +1776,27 @@
|
|||||||
},
|
},
|
||||||
"ssoCompleteRegistration": {
|
"ssoCompleteRegistration": {
|
||||||
"message": "In order to complete logging in with SSO, please set a master password to access and protect your vault."
|
"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."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ export default class MainBackground {
|
|||||||
this.policyService = new PolicyService(this.userService, this.storageService);
|
this.policyService = new PolicyService(this.userService, this.storageService);
|
||||||
this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService,
|
this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService,
|
||||||
this.collectionService, this.cryptoService, this.platformUtilsService, this.storageService,
|
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 () => {
|
async () => {
|
||||||
if (this.notificationsService != null) {
|
if (this.notificationsService != null) {
|
||||||
this.notificationsService.updateConnection(false);
|
this.notificationsService.updateConnection(false);
|
||||||
|
@ -37,6 +37,7 @@ import { OptionsComponent } from './settings/options.component';
|
|||||||
import { PremiumComponent } from './settings/premium.component';
|
import { PremiumComponent } from './settings/premium.component';
|
||||||
import { SettingsComponent } from './settings/settings.component';
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
import { SyncComponent } from './settings/sync.component';
|
import { SyncComponent } from './settings/sync.component';
|
||||||
|
import { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';
|
||||||
|
|
||||||
import { AddEditComponent } from './vault/add-edit.component';
|
import { AddEditComponent } from './vault/add-edit.component';
|
||||||
import { AttachmentsComponent } from './vault/attachments.component';
|
import { AttachmentsComponent } from './vault/attachments.component';
|
||||||
@ -242,6 +243,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
|||||||
UpdateTempPasswordComponent,
|
UpdateTempPasswordComponent,
|
||||||
ViewComponent,
|
ViewComponent,
|
||||||
PasswordRepromptComponent,
|
PasswordRepromptComponent,
|
||||||
|
VaultTimeoutInputComponent,
|
||||||
],
|
],
|
||||||
entryComponents: [],
|
entryComponents: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -200,6 +200,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.last:last-child:before {
|
||||||
|
border-bottom: 1px solid #000000;
|
||||||
|
@include themify($themes) {
|
||||||
|
border-bottom-color: themed('boxBorderColor');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
display: table;
|
display: table;
|
||||||
|
11
src/popup/scss/grid.scss
Normal file
11
src/popup/scss/grid.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
margin: 0 -15px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
flex-basis: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
@import "../css/webfonts.css";
|
@import "../css/webfonts.css";
|
||||||
@import "variables.scss";
|
@import "variables.scss";
|
||||||
@import "base.scss";
|
@import "base.scss";
|
||||||
|
@import "grid.scss";
|
||||||
@import "box.scss";
|
@import "box.scss";
|
||||||
@import "buttons.scss";
|
@import "buttons.scss";
|
||||||
@import "misc.scss";
|
@import "misc.scss";
|
||||||
|
@ -28,13 +28,7 @@
|
|||||||
<div class="box list">
|
<div class="box list">
|
||||||
<div class="box-header">{{'security' | i18n}}</div>
|
<div class="box-header">{{'security' | i18n}}</div>
|
||||||
<div class="box-content single-line">
|
<div class="box-content single-line">
|
||||||
<div class="box-content-row display-block" appBoxRow>
|
<app-vault-timeout-input [vaultTimeouts]="vaultTimeouts" [formControl]="vaultTimeout" ngDefaultControl></app-vault-timeout-input>
|
||||||
<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>
|
|
||||||
<div class="box-content-row display-block" appBoxRow>
|
<div class="box-content-row display-block" appBoxRow>
|
||||||
<label for="vaultTimeoutAction">{{'vaultTimeoutAction' | i18n}}</label>
|
<label for="vaultTimeoutAction">{{'vaultTimeoutAction' | i18n}}</label>
|
||||||
<select #vaultTimeoutActionSelect id="vaultTimeoutAction" name="VaultTimeoutActions"
|
<select #vaultTimeoutActionSelect id="vaultTimeoutAction" name="VaultTimeoutActions"
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import Swal from 'sweetalert2/src/sweetalert2.js';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
OnInit,
|
OnInit,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
import Swal from 'sweetalert2/src/sweetalert2.js';
|
||||||
|
|
||||||
import { BrowserApi } from '../../browser/browserApi';
|
import { BrowserApi } from '../../browser/browserApi';
|
||||||
|
|
||||||
@ -44,10 +45,8 @@ const RateUrls = {
|
|||||||
templateUrl: 'settings.component.html',
|
templateUrl: 'settings.component.html',
|
||||||
})
|
})
|
||||||
export class SettingsComponent implements OnInit {
|
export class SettingsComponent implements OnInit {
|
||||||
@ViewChild('vaultTimeoutSelect', { read: ElementRef, static: true }) vaultTimeoutSelectRef: ElementRef;
|
|
||||||
@ViewChild('vaultTimeoutActionSelect', { read: ElementRef, static: true }) vaultTimeoutActionSelectRef: ElementRef;
|
@ViewChild('vaultTimeoutActionSelect', { read: ElementRef, static: true }) vaultTimeoutActionSelectRef: ElementRef;
|
||||||
vaultTimeouts: any[];
|
vaultTimeouts: any[];
|
||||||
vaultTimeout: number = null;
|
|
||||||
vaultTimeoutActions: any[];
|
vaultTimeoutActions: any[];
|
||||||
vaultTimeoutAction: string;
|
vaultTimeoutAction: string;
|
||||||
pin: boolean = null;
|
pin: boolean = null;
|
||||||
@ -55,11 +54,14 @@ export class SettingsComponent implements OnInit {
|
|||||||
biometric: boolean = false;
|
biometric: boolean = false;
|
||||||
previousVaultTimeout: number = null;
|
previousVaultTimeout: number = null;
|
||||||
|
|
||||||
|
vaultTimeout: FormControl = new FormControl(null);
|
||||||
|
|
||||||
constructor(private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,
|
constructor(private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,
|
||||||
private vaultTimeoutService: VaultTimeoutService, private storageService: StorageService,
|
private vaultTimeoutService: VaultTimeoutService, private storageService: StorageService,
|
||||||
public messagingService: MessagingService, private router: Router,
|
public messagingService: MessagingService, private router: Router,
|
||||||
private environmentService: EnvironmentService, private cryptoService: CryptoService,
|
private environmentService: EnvironmentService, private cryptoService: CryptoService,
|
||||||
private userService: UserService, private popupUtilsService: PopupUtilsService) {
|
private userService: UserService, private popupUtilsService: PopupUtilsService,
|
||||||
|
private toasterService: ToasterService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@ -89,14 +91,18 @@ export class SettingsComponent implements OnInit {
|
|||||||
{ name: this.i18nService.t('logOut'), value: 'logOut' },
|
{ 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 != null) {
|
||||||
if (timeout === -2 && !showOnLocked) {
|
if (timeout === -2 && !showOnLocked) {
|
||||||
timeout = -1;
|
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);
|
const action = await this.storageService.get<string>(ConstantsService.vaultTimeoutActionKey);
|
||||||
this.vaultTimeoutAction = action == null ? 'lock' : action;
|
this.vaultTimeoutAction = action == null ? 'lock' : action;
|
||||||
|
|
||||||
@ -113,18 +119,19 @@ export class SettingsComponent implements OnInit {
|
|||||||
this.i18nService.t('neverLockWarning'), null,
|
this.i18nService.t('neverLockWarning'), null,
|
||||||
this.i18nService.t('yes'), this.i18nService.t('cancel'), 'warning');
|
this.i18nService.t('yes'), this.i18nService.t('cancel'), 'warning');
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
this.vaultTimeouts.forEach((option: any, i) => {
|
this.vaultTimeout.setValue(this.previousVaultTimeout);
|
||||||
if (option.value === this.vaultTimeout) {
|
|
||||||
this.vaultTimeoutSelectRef.nativeElement.value = i + ': ' + this.vaultTimeout;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.previousVaultTimeout = this.vaultTimeout;
|
|
||||||
this.vaultTimeout = newValue;
|
if (!this.vaultTimeout.valid) {
|
||||||
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout != null ? this.vaultTimeout : null,
|
this.toasterService.popAsync('error', null, this.i18nService.t('vaultTimeoutToLarge'));
|
||||||
this.vaultTimeoutAction);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.previousVaultTimeout = this.vaultTimeout.value;
|
||||||
|
|
||||||
|
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);
|
||||||
if (this.previousVaultTimeout == null) {
|
if (this.previousVaultTimeout == null) {
|
||||||
this.messagingService.send('bgReseedStorage');
|
this.messagingService.send('bgReseedStorage');
|
||||||
}
|
}
|
||||||
@ -145,9 +152,14 @@ export class SettingsComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.vaultTimeout.valid) {
|
||||||
|
this.toasterService.popAsync('error', null, this.i18nService.t('vaultTimeoutToLarge'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.vaultTimeoutAction = newValue;
|
this.vaultTimeoutAction = newValue;
|
||||||
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout != null ? this.vaultTimeout : null,
|
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);
|
||||||
this.vaultTimeoutAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePin() {
|
async updatePin() {
|
||||||
|
29
src/popup/settings/vault-timeout-input.component.html
Normal file
29
src/popup/settings/vault-timeout-input.component.html
Normal 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>
|
28
src/popup/settings/vault-timeout-input.component.ts
Normal file
28
src/popup/settings/vault-timeout-input.component.ts
Normal 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 {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user