mirror of
https://github.com/bitwarden/desktop.git
synced 2024-11-27 12:26:38 +01:00
Vault Timeout Policy (#1052)
This commit is contained in:
parent
da4af743f3
commit
aa19e678f7
@ -7,14 +7,7 @@
|
||||
{{'security' | i18n}}
|
||||
</div>
|
||||
<div class="box-content box-content-padded">
|
||||
<div class="form-group">
|
||||
<label for="vaultTimeouts">{{'vaultTimeout' | i18n}}</label>
|
||||
<select id="vaultTimeouts" name="VaultTimeouts" [(ngModel)]="vaultTimeout"
|
||||
(change)="saveVaultTimeoutOptions()">
|
||||
<option *ngFor="let o of vaultTimeouts" [ngValue]="o.value">{{o.name}}</option>
|
||||
</select>
|
||||
<small class="help-block">{{'vaultTimeoutDesc' | i18n}}</small>
|
||||
</div>
|
||||
<app-vault-timeout-input [vaultTimeouts]="vaultTimeouts" [formControl]="vaultTimeout" ngDefaultControl></app-vault-timeout-input>
|
||||
<div class="form-group">
|
||||
<label>{{'vaultTimeoutAction' | i18n}}</label>
|
||||
<div class="radio radio-mt-2">
|
||||
|
@ -2,8 +2,8 @@ import {
|
||||
Component,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
|
||||
import Swal from 'sweetalert2/src/sweetalert2.js';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
|
||||
import { DeviceType } from 'jslib-common/enums/deviceType';
|
||||
|
||||
@ -13,7 +13,6 @@ import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { StorageService } from 'jslib-common/abstractions/storage.service';
|
||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
|
||||
|
||||
import { ConstantsService } from 'jslib-common/services/constants.service';
|
||||
@ -32,7 +31,6 @@ import { SetPinComponent } from '../components/set-pin.component';
|
||||
templateUrl: 'settings.component.html',
|
||||
})
|
||||
export class SettingsComponent implements OnInit {
|
||||
vaultTimeout: number = null;
|
||||
vaultTimeoutAction: string;
|
||||
pin: boolean = null;
|
||||
disableFavicons: boolean = false;
|
||||
@ -70,11 +68,12 @@ export class SettingsComponent implements OnInit {
|
||||
startToTrayText: string;
|
||||
startToTrayDescText: string;
|
||||
|
||||
vaultTimeout: FormControl = new FormControl(null);
|
||||
|
||||
constructor(private i18nService: I18nService, private platformUtilsService: PlatformUtilsService,
|
||||
private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService,
|
||||
private stateService: StateService, private messagingService: MessagingService,
|
||||
private userService: UserService, private cryptoService: CryptoService,
|
||||
private modalService: ModalService) {
|
||||
private cryptoService: CryptoService, private modalService: ModalService) {
|
||||
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
|
||||
|
||||
// Workaround to avoid ghosting trays https://github.com/electron/electron/issues/17622
|
||||
@ -117,6 +116,10 @@ export class SettingsComponent implements OnInit {
|
||||
{ name: i18nService.t('never'), value: null },
|
||||
]);
|
||||
|
||||
this.vaultTimeout.valueChanges.pipe(debounceTime(500)).subscribe(() => {
|
||||
this.saveVaultTimeoutOptions();
|
||||
});
|
||||
|
||||
const localeOptions: any[] = [];
|
||||
i18nService.supportedTranslationLocales.forEach(locale => {
|
||||
let name = locale;
|
||||
@ -149,7 +152,7 @@ export class SettingsComponent implements OnInit {
|
||||
|
||||
async ngOnInit() {
|
||||
this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop;
|
||||
this.vaultTimeout = await this.storageService.get<number>(ConstantsService.vaultTimeoutKey);
|
||||
this.vaultTimeout.setValue(await this.vaultTimeoutService.getVaultTimeout());
|
||||
this.vaultTimeoutAction = await this.storageService.get<string>(ConstantsService.vaultTimeoutActionKey);
|
||||
const pinSet = await this.vaultTimeoutService.isPinLockSet();
|
||||
this.pin = pinSet[0] || pinSet[1];
|
||||
@ -187,8 +190,18 @@ export class SettingsComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout != null ? this.vaultTimeout : null,
|
||||
this.vaultTimeoutAction);
|
||||
|
||||
// Avoid saving 0 since it's useless as a timeout value.
|
||||
if (this.vaultTimeout.value === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.vaultTimeout.valid) {
|
||||
this.platformUtilsService.showToast('error', null, this.i18nService.t('vaultTimeoutTooLarge'));
|
||||
return;
|
||||
}
|
||||
|
||||
await this.vaultTimeoutService.setVaultTimeoutOptions(this.vaultTimeout.value, this.vaultTimeoutAction);
|
||||
}
|
||||
|
||||
async updatePin() {
|
||||
|
24
src/app/accounts/vault-timeout-input.component.html
Normal file
24
src/app/accounts/vault-timeout-input.component.html
Normal file
@ -0,0 +1,24 @@
|
||||
<app-callout type="info" *ngIf="vaultTimeoutPolicy">
|
||||
{{'vaultTimeoutPolicyInEffect' | i18n : vaultTimeoutPolicyHours : vaultTimeoutPolicyMinutes}}
|
||||
</app-callout>
|
||||
|
||||
<div [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<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>
|
||||
<small class="form-text text-muted">{{'vaultTimeoutDesc' | i18n}}</small>
|
||||
</div>
|
||||
<div class="form-group row" *ngIf="showCustom" formGroupName="custom">
|
||||
<div class="col">
|
||||
<label for="hours">{{'hours' | i18n}}</label>
|
||||
<input id="hours" class="form-control" type="number" min="0" name="hours" formControlName="hours">
|
||||
</div>
|
||||
<div class="col">
|
||||
<label for="minutes">{{'minutes' | i18n}}</label>
|
||||
<input id="minutes" class="form-control" type="number" min="0" max="59" name="minutes" formControlName="minutes">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"></div> <!-- Styling fix -->
|
||||
</div>
|
28
src/app/accounts/vault-timeout-input.component.ts
Normal file
28
src/app/accounts/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 {
|
||||
}
|
@ -28,6 +28,7 @@ import { SsoComponent } from './accounts/sso.component';
|
||||
import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
|
||||
import { TwoFactorComponent } from './accounts/two-factor.component';
|
||||
import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
|
||||
import { VaultTimeoutInputComponent } from './accounts/vault-timeout-input.component';
|
||||
|
||||
import { CalloutComponent } from 'jslib-angular/components/callout.component';
|
||||
import { IconComponent } from 'jslib-angular/components/icon.component';
|
||||
@ -224,6 +225,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
ViewComponent,
|
||||
PasswordRepromptComponent,
|
||||
SetPinComponent,
|
||||
VaultTimeoutInputComponent,
|
||||
],
|
||||
providers: [DatePipe],
|
||||
bootstrap: [AppComponent],
|
||||
|
@ -120,7 +120,7 @@ const sendService = new SendService(cryptoService, userService, apiService, file
|
||||
const policyService = new PolicyService(userService, storageService);
|
||||
const vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService,
|
||||
cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService,
|
||||
null, async () => messagingService.send('logout', { expired: false }));
|
||||
policyService, null, async () => messagingService.send('logout', { expired: false }));
|
||||
const syncService = new SyncService(userService, apiService, settingsService,
|
||||
folderService, cipherService, cryptoService, collectionService, storageService, messagingService, policyService,
|
||||
sendService, async (expired: boolean) => messagingService.send('logout', { expired: expired }));
|
||||
|
@ -1703,6 +1703,28 @@
|
||||
"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."
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vaultTimeoutTooLarge": {
|
||||
"message": "Your vault timeout exceeds the restrictions set by your organization."
|
||||
},
|
||||
"resetPasswordPolicyAutoEnroll": {
|
||||
"message": "Automatic Enrollment"
|
||||
},
|
||||
|
10
src/scss/grid.scss
Normal file
10
src/scss/grid.scss
Normal file
@ -0,0 +1,10 @@
|
||||
.row {
|
||||
display: flex;
|
||||
margin: 0 -15px;
|
||||
}
|
||||
|
||||
.col {
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
padding: 0 15px;
|
||||
}
|
@ -253,6 +253,11 @@ form, .form {
|
||||
border-color: themed('inputBorderColor');
|
||||
}
|
||||
}
|
||||
|
||||
input[type=text], input[type=number] {
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
|
@ -1,6 +1,7 @@
|
||||
@import "../css/webfonts.css";
|
||||
@import "variables.scss";
|
||||
@import "base.scss";
|
||||
@import "grid.scss";
|
||||
@import "pages.scss";
|
||||
@import "vault.scss";
|
||||
@import "list.scss";
|
||||
|
Loading…
Reference in New Issue
Block a user