lock with master pass on restart option on PIN lock
This commit is contained in:
parent
a2064939d2
commit
f28d7a1af6
2
jslib
2
jslib
|
@ -1 +1 @@
|
||||||
Subproject commit f67fac3eebc21b8935a54a28b7a21152c8513322
|
Subproject commit 43872f82ccd7453926c75240ecde196151e89ce9
|
|
@ -1191,5 +1191,8 @@
|
||||||
},
|
},
|
||||||
"yourVaultIsLockedPinCode": {
|
"yourVaultIsLockedPinCode": {
|
||||||
"message": "Your vault is locked. Verify your PIN code to continue."
|
"message": "Your vault is locked. Verify your PIN code to continue."
|
||||||
|
},
|
||||||
|
"lockWithMasterPassOnRestart": {
|
||||||
|
"message": "Lock with master password on browser restart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ export default class IdleBackground {
|
||||||
if (newState === 'locked') {
|
if (newState === 'locked') {
|
||||||
const lockOption = await this.storageService.get<number>(ConstantsService.lockOptionKey);
|
const lockOption = await this.storageService.get<number>(ConstantsService.lockOptionKey);
|
||||||
if (lockOption === -2) {
|
if (lockOption === -2) {
|
||||||
this.lockService.lock();
|
this.lockService.lock(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -160,7 +160,7 @@ export default class MainBackground {
|
||||||
this.auditService = new AuditService(cryptoFunctionService, this.apiService);
|
this.auditService = new AuditService(cryptoFunctionService, this.apiService);
|
||||||
this.exportService = new ExportService(this.folderService, this.cipherService, this.apiService);
|
this.exportService = new ExportService(this.folderService, this.cipherService, this.apiService);
|
||||||
this.notificationsService = new NotificationsService(this.userService, this.syncService, this.appIdService,
|
this.notificationsService = new NotificationsService(this.userService, this.syncService, this.appIdService,
|
||||||
this.apiService, this.cryptoService, () => this.logout(true));
|
this.apiService, this.lockService, () => this.logout(true));
|
||||||
this.environmentService = new EnvironmentService(this.apiService, this.storageService,
|
this.environmentService = new EnvironmentService(this.apiService, this.storageService,
|
||||||
this.notificationsService);
|
this.notificationsService);
|
||||||
this.analytics = new Analytics(window, () => BrowserApi.gaFilter(), this.platformUtilsService,
|
this.analytics = new Analytics(window, () => BrowserApi.gaFilter(), this.platformUtilsService,
|
||||||
|
@ -223,12 +223,12 @@ export default class MainBackground {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isAuthenticated = await this.userService.isAuthenticated();
|
const isAuthenticated = await this.userService.isAuthenticated();
|
||||||
const hasKey = await this.cryptoService.hasKey();
|
const locked = await this.lockService.isLocked();
|
||||||
|
|
||||||
let suffix = '';
|
let suffix = '';
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
suffix = '_gray';
|
suffix = '_gray';
|
||||||
} else if (!hasKey) {
|
} else if (locked) {
|
||||||
suffix = '_locked';
|
suffix = '_locked';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +273,10 @@ export default class MainBackground {
|
||||||
this.folderService.clear(userId),
|
this.folderService.clear(userId),
|
||||||
this.collectionService.clear(userId),
|
this.collectionService.clear(userId),
|
||||||
this.passwordGenerationService.clear(),
|
this.passwordGenerationService.clear(),
|
||||||
|
this.lockService.clear(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
this.lockService.pinLocked = false;
|
||||||
this.searchService.clearIndex();
|
this.searchService.clearIndex();
|
||||||
this.messagingService.send('doneLoggingOut', { expired: expired });
|
this.messagingService.send('doneLoggingOut', { expired: expired });
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ $fa-font-path: "~font-awesome/fonts";
|
||||||
.swal-content {
|
.swal-content {
|
||||||
margin: 15px 0 0 0;
|
margin: 15px 0 0 0;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
font-size: $font-size-base;
|
||||||
|
|
||||||
.swal-text {
|
.swal-text {
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
@ -132,6 +133,17 @@ $fa-font-path: "~font-awesome/fonts";
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.checkbox {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
text-align: left;
|
||||||
|
align-items: top;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin: 3px 5px 0 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.swal-custom-icon {
|
i.swal-custom-icon {
|
||||||
|
|
|
@ -6,12 +6,12 @@ import {
|
||||||
Router,
|
Router,
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
|
|
||||||
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
import { LockService } from 'jslib/abstractions/lock.service';
|
||||||
import { UserService } from 'jslib/abstractions/user.service';
|
import { UserService } from 'jslib/abstractions/user.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LaunchGuardService implements CanActivate {
|
export class LaunchGuardService implements CanActivate {
|
||||||
constructor(private cryptoService: CryptoService, private userService: UserService, private router: Router) { }
|
constructor(private lockService: LockService, private userService: UserService, private router: Router) { }
|
||||||
|
|
||||||
async canActivate() {
|
async canActivate() {
|
||||||
if (BrowserApi.getBackgroundPage() == null) {
|
if (BrowserApi.getBackgroundPage() == null) {
|
||||||
|
@ -28,8 +28,8 @@ export class LaunchGuardService implements CanActivate {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasKey = await this.cryptoService.hasKey();
|
const locked = await this.lockService.isLocked();
|
||||||
if (!hasKey) {
|
if (locked) {
|
||||||
this.router.navigate(['lock']);
|
this.router.navigate(['lock']);
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate(['tabs/current']);
|
this.router.navigate(['tabs/current']);
|
||||||
|
|
|
@ -89,7 +89,8 @@ export class SettingsComponent implements OnInit {
|
||||||
}
|
}
|
||||||
this.previousLockOption = this.lockOption;
|
this.previousLockOption = this.lockOption;
|
||||||
|
|
||||||
this.pin = await this.lockService.isPinLockSet();
|
const pinSet = await this.lockService.isPinLockSet();
|
||||||
|
this.pin = pinSet[0] || pinSet[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveLockOption(newValue: number) {
|
async saveLockOption(newValue: number) {
|
||||||
|
@ -116,31 +117,55 @@ export class SettingsComponent implements OnInit {
|
||||||
|
|
||||||
async updatePin() {
|
async updatePin() {
|
||||||
if (this.pin) {
|
if (this.pin) {
|
||||||
const pin = await swal({
|
const div = document.createElement('div');
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.className = 'checkbox';
|
||||||
|
const checkboxText = document.createElement('span');
|
||||||
|
const restartText = document.createTextNode(this.i18nService.t('lockWithMasterPassOnRestart'));
|
||||||
|
checkboxText.appendChild(restartText);
|
||||||
|
label.innerHTML = '<input type="checkbox" id="master-pass-restart" checked>';
|
||||||
|
label.appendChild(checkboxText);
|
||||||
|
div.innerHTML = '<input type="text" class="swal-content__input" id="pin-val">';
|
||||||
|
(div.querySelector('#pin-val') as HTMLInputElement).placeholder = this.i18nService.t('pin');
|
||||||
|
div.appendChild(label);
|
||||||
|
|
||||||
|
const submitted = await swal({
|
||||||
text: this.i18nService.t('setYourPinCode'),
|
text: this.i18nService.t('setYourPinCode'),
|
||||||
content: { element: 'input' },
|
content: { element: div },
|
||||||
buttons: [this.i18nService.t('cancel'), this.i18nService.t('submit')],
|
buttons: [this.i18nService.t('cancel'), this.i18nService.t('submit')],
|
||||||
});
|
});
|
||||||
|
let pin: string = null;
|
||||||
|
let masterPassOnRestart: boolean = null;
|
||||||
|
if (submitted) {
|
||||||
|
pin = (document.getElementById('pin-val') as HTMLInputElement).value;
|
||||||
|
masterPassOnRestart = (document.getElementById('master-pass-restart') as HTMLInputElement).checked;
|
||||||
|
}
|
||||||
if (pin != null && pin.trim() !== '') {
|
if (pin != null && pin.trim() !== '') {
|
||||||
const kdf = await this.userService.getKdf();
|
if (masterPassOnRestart) {
|
||||||
const kdfIterations = await this.userService.getKdfIterations();
|
const encPin = await this.cryptoService.encrypt(pin);
|
||||||
const email = await this.userService.getEmail();
|
await this.storageService.save(ConstantsService.protectedPin, encPin.encryptedString);
|
||||||
const pinKey = await this.cryptoService.makePinKey(pin, email, kdf, kdfIterations);
|
} else {
|
||||||
const key = await this.cryptoService.getKey();
|
const kdf = await this.userService.getKdf();
|
||||||
const pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);
|
const kdfIterations = await this.userService.getKdfIterations();
|
||||||
await this.storageService.save(ConstantsService.pinProtectedKey, pinProtectedKey.encryptedString);
|
const email = await this.userService.getEmail();
|
||||||
|
const pinKey = await this.cryptoService.makePinKey(pin, email, kdf, kdfIterations);
|
||||||
|
const key = await this.cryptoService.getKey();
|
||||||
|
const pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);
|
||||||
|
await this.storageService.save(ConstantsService.pinProtectedKey, pinProtectedKey.encryptedString);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.pin = false;
|
this.pin = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.pin) {
|
if (!this.pin) {
|
||||||
await this.storageService.remove(ConstantsService.pinProtectedKey);
|
await this.storageService.remove(ConstantsService.pinProtectedKey);
|
||||||
|
await this.storageService.remove(ConstantsService.protectedPin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async lock() {
|
async lock() {
|
||||||
this.analytics.eventTrack.next({ action: 'Lock Now' });
|
this.analytics.eventTrack.next({ action: 'Lock Now' });
|
||||||
await this.lockService.lock();
|
await this.lockService.lock(true);
|
||||||
this.router.navigate(['lock']);
|
this.router.navigate(['lock']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue