mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01:00
Cleanup, localize error.
This commit is contained in:
parent
9064298309
commit
0a4d59092b
@ -1383,5 +1383,11 @@
|
|||||||
},
|
},
|
||||||
"startDesktopDesc": {
|
"startDesktopDesc": {
|
||||||
"message": "The bitwarden desktop application needs to be started before this function can be used."
|
"message": "The bitwarden desktop application needs to be started before this function can be used."
|
||||||
|
},
|
||||||
|
"errorEnableBiometricTitle": {
|
||||||
|
"message": "Unable to enable biometrics"
|
||||||
|
},
|
||||||
|
"errorEnableBiometricDesc": {
|
||||||
|
"message": "Action was canceld by the desktop applicaiton."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ export default class MainBackground {
|
|||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
if (this.nativeMessagingBackground != null) {
|
if (this.nativeMessagingBackground != null) {
|
||||||
const promise = this.nativeMessagingBackground.await();
|
const promise = this.nativeMessagingBackground.getResponse();
|
||||||
this.nativeMessagingBackground.send({command: 'biometricUnlock'})
|
this.nativeMessagingBackground.send({command: 'biometricUnlock'})
|
||||||
return promise.then((result) => result.response === 'unlocked');
|
return promise.then((result) => result.response === 'unlocked');
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ export class NativeMessagingBackground {
|
|||||||
private port: browser.runtime.Port | chrome.runtime.Port;
|
private port: browser.runtime.Port | chrome.runtime.Port;
|
||||||
|
|
||||||
private resolver: any = null;
|
private resolver: any = null;
|
||||||
private publicKey: ArrayBuffer;
|
|
||||||
private privateKey: ArrayBuffer = null;
|
private privateKey: ArrayBuffer = null;
|
||||||
private secureSetupResolve: any = null;
|
private secureSetupResolve: any = null;
|
||||||
private sharedSecret: SymmetricCryptoKey;
|
private sharedSecret: SymmetricCryptoKey;
|
||||||
@ -36,27 +35,36 @@ export class NativeMessagingBackground {
|
|||||||
|
|
||||||
this.connecting = true;
|
this.connecting = true;
|
||||||
|
|
||||||
this.port.onMessage.addListener((message: any) => {
|
this.port.onMessage.addListener(async (message: any) => {
|
||||||
if (message.command === 'connected') {
|
switch (message.command) {
|
||||||
this.connected = true;
|
case 'connected':
|
||||||
this.connecting = false;
|
this.connected = true;
|
||||||
resolve();
|
this.connecting = false;
|
||||||
} else if (message.command === 'disconnected') {
|
resolve();
|
||||||
if (this.connecting) {
|
break;
|
||||||
this.messagingService.send('showDialog', {
|
case 'disconnected':
|
||||||
text: this.i18nService.t('startDesktopDesc'),
|
if (this.connecting) {
|
||||||
title: this.i18nService.t('startDesktopTitle'),
|
this.messagingService.send('showDialog', {
|
||||||
confirmText: this.i18nService.t('ok'),
|
text: this.i18nService.t('startDesktopDesc'),
|
||||||
type: 'error',
|
title: this.i18nService.t('startDesktopTitle'),
|
||||||
});
|
confirmText: this.i18nService.t('ok'),
|
||||||
reject();
|
type: 'error',
|
||||||
}
|
});
|
||||||
this.connected = false;
|
reject();
|
||||||
this.port.disconnect();
|
}
|
||||||
return;
|
this.connected = false;
|
||||||
}
|
this.port.disconnect();
|
||||||
|
break;
|
||||||
|
case 'setupEncryption':
|
||||||
|
const encrypted = Utils.fromB64ToArray(message.sharedSecret);
|
||||||
|
const decrypted = await this.cryptoFunctionService.rsaDecrypt(encrypted.buffer, this.privateKey, EncryptionAlgorithm);
|
||||||
|
|
||||||
this.onMessage(message);
|
this.sharedSecret = new SymmetricCryptoKey(decrypted);
|
||||||
|
this.secureSetupResolve();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.onMessage(message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.port.onDisconnect.addListener(() => {
|
this.port.onDisconnect.addListener(() => {
|
||||||
@ -75,7 +83,6 @@ export class NativeMessagingBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async send(message: any) {
|
async send(message: any) {
|
||||||
// If not connected, try to connect
|
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
await this.connect();
|
await this.connect();
|
||||||
}
|
}
|
||||||
@ -90,21 +97,13 @@ export class NativeMessagingBackground {
|
|||||||
this.port.postMessage(encrypted);
|
this.port.postMessage(encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
await(): Promise<any> {
|
getResponse(): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.resolver = resolve;
|
this.resolver = resolve;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onMessage(rawMessage: any) {
|
private async onMessage(rawMessage: any) {
|
||||||
if (rawMessage.command === 'setupEncryption') {
|
|
||||||
const encrypted = Utils.fromB64ToArray(rawMessage.sharedSecret);
|
|
||||||
const decrypted = await this.cryptoFunctionService.rsaDecrypt(encrypted.buffer, this.privateKey, EncryptionAlgorithm);
|
|
||||||
|
|
||||||
this.sharedSecret = new SymmetricCryptoKey(decrypted);
|
|
||||||
this.secureSetupResolve();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecret));
|
const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecret));
|
||||||
|
|
||||||
if (Math.abs(message.timestamp - Date.now()) > MessageValidTimeout) {
|
if (Math.abs(message.timestamp - Date.now()) > MessageValidTimeout) {
|
||||||
@ -122,11 +121,15 @@ export class NativeMessagingBackground {
|
|||||||
if (message.response === 'unlocked') {
|
if (message.response === 'unlocked') {
|
||||||
await this.storageService.save(ConstantsService.biometricUnlockKey, true);
|
await this.storageService.save(ConstantsService.biometricUnlockKey, true);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
await this.cryptoService.toggleKey();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.vaultTimeoutService.biometricLocked) {
|
// Ignore unlock if already unlockeded
|
||||||
|
if (!this.vaultTimeoutService.biometricLocked) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.response === 'unlocked') {
|
||||||
this.cryptoService.setKey(new SymmetricCryptoKey(Utils.fromB64ToArray(message.keyB64).buffer));
|
this.cryptoService.setKey(new SymmetricCryptoKey(Utils.fromB64ToArray(message.keyB64).buffer));
|
||||||
this.vaultTimeoutService.biometricLocked = false;
|
this.vaultTimeoutService.biometricLocked = false;
|
||||||
this.runtimeBackground.processMessage({command: 'unlocked'}, null, null);
|
this.runtimeBackground.processMessage({command: 'unlocked'}, null, null);
|
||||||
@ -143,12 +146,11 @@ export class NativeMessagingBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async secureCommunication() {
|
private async secureCommunication() {
|
||||||
// Using crypto function service directly since we cannot encrypt the private key as
|
const [publicKey, privateKey] = await this.cryptoFunctionService.rsaGenerateKeyPair(2048);
|
||||||
// master key might not be available
|
this.privateKey = privateKey;
|
||||||
[this.publicKey, this.privateKey] = await this.cryptoFunctionService.rsaGenerateKeyPair(2048);
|
|
||||||
|
|
||||||
this.sendUnencrypted({command: 'setupEncryption', publicKey: Utils.fromBufferToB64(this.publicKey)});
|
this.sendUnencrypted({command: 'setupEncryption', publicKey: Utils.fromBufferToB64(publicKey)});
|
||||||
const fingerprint = (await this.cryptoService.getFingerprint(await this.userService.getUserId(), this.publicKey)).join(' ');
|
const fingerprint = (await this.cryptoService.getFingerprint(await this.userService.getUserId(), publicKey)).join(' ');
|
||||||
|
|
||||||
this.messagingService.send('showDialog', {
|
this.messagingService.send('showDialog', {
|
||||||
html: `${this.i18nService.t('desktopIntegrationVerificationText')}<br><br><strong>${fingerprint}</strong>`,
|
html: `${this.i18nService.t('desktopIntegrationVerificationText')}<br><br><strong>${fingerprint}</strong>`,
|
||||||
|
@ -46,7 +46,7 @@ export class LockComponent extends BaseLockComponent {
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.innerHTML = `<div class="swal2-text">${this.i18nService.t('awaitDesktop')}</div>`;
|
div.innerHTML = `<div class="swal2-text">${this.i18nService.t('awaitDesktop')}</div>`;
|
||||||
|
|
||||||
const submitted = Swal.fire({
|
Swal.fire({
|
||||||
heightAuto: false,
|
heightAuto: false,
|
||||||
buttonsStyling: false,
|
buttonsStyling: false,
|
||||||
html: div,
|
html: div,
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||||
<label for="biometric">{{'unlockWithBiometric' | i18n}}</label>
|
<label for="biometric">{{'unlockWithBiometric' | i18n}}</label>
|
||||||
<input id="biometric" type="checkbox" (change)="updateBiometric()" [ngModel]="biometric">
|
<input id="biometric" type="checkbox" (change)="updateBiometric()" [checked]="biometric">
|
||||||
</div>
|
</div>
|
||||||
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
|
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
|
||||||
(click)="lock()">
|
(click)="lock()">
|
||||||
|
@ -209,7 +209,6 @@ export class SettingsComponent implements OnInit {
|
|||||||
async updateBiometric() {
|
async updateBiometric() {
|
||||||
if (this.biometric) {
|
if (this.biometric) {
|
||||||
this.biometric = false;
|
this.biometric = false;
|
||||||
// TODO: Remove biometric stuff
|
|
||||||
await this.storageService.remove(ConstantsService.biometricUnlockKey);
|
await this.storageService.remove(ConstantsService.biometricUnlockKey);
|
||||||
this.vaultTimeoutService.biometricLocked = false;
|
this.vaultTimeoutService.biometricLocked = false;
|
||||||
} else {
|
} else {
|
||||||
@ -241,7 +240,7 @@ export class SettingsComponent implements OnInit {
|
|||||||
|
|
||||||
Swal.close();
|
Swal.close();
|
||||||
if (this.biometric === false) {
|
if (this.biometric === false) {
|
||||||
this.platformUtilsService.showToast('error', 'Unable to enable biometrics', 'Ensure the desktop application is running, and browser integration is enabled.');
|
this.platformUtilsService.showToast('error', this.i18nService.t('errorEnableBiometricTitle'), this.i18nService.t('errorEnableBiometricDesc'));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
Loading…
Reference in New Issue
Block a user