bitwarden-estensione-browser/apps/desktop/src/main/biometric/biometrics.service.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

172 lines
5.3 KiB
TypeScript
Raw Normal View History

[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
2023-04-18 15:09:47 +02:00
import { ElectronStateService } from "../../services/electron-state.service.abstraction";
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
import { WindowMain } from "../window.main";
2023-04-18 15:09:47 +02:00
import { BiometricsServiceAbstraction, OsBiometricService } from "./biometrics.service.abstraction";
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
export class BiometricsService implements BiometricsServiceAbstraction {
2023-04-18 15:09:47 +02:00
private platformSpecificService: OsBiometricService;
private clientKeyHalves = new Map<string, string>();
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
constructor(
private i18nService: I18nService,
private windowMain: WindowMain,
2023-04-18 15:09:47 +02:00
private stateService: ElectronStateService,
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
private logService: LogService,
private messagingService: MessagingService,
private platform: NodeJS.Platform
) {
this.loadPlatformSpecificService(this.platform);
}
private loadPlatformSpecificService(platform: NodeJS.Platform) {
if (platform === "win32") {
this.loadWindowsHelloService();
} else if (platform === "darwin") {
this.loadMacOSService();
}
}
private loadWindowsHelloService() {
// eslint-disable-next-line
const BiometricWindowsMain = require("./biometric.windows.main").default;
this.platformSpecificService = new BiometricWindowsMain(
this.i18nService,
this.windowMain,
this.stateService,
this.logService
);
}
private loadMacOSService() {
// eslint-disable-next-line
const BiometricDarwinMain = require("./biometric.darwin.main").default;
this.platformSpecificService = new BiometricDarwinMain(this.i18nService, this.stateService);
}
async init() {
return await this.platformSpecificService.init();
}
2023-04-18 15:09:47 +02:00
async osSupportsBiometric() {
return await this.platformSpecificService.osSupportsBiometric();
}
async canAuthBiometric({
service,
key,
userId,
}: {
service: string;
key: string;
userId: string;
}): Promise<boolean> {
const requireClientKeyHalf = await this.stateService.getBiometricRequirePasswordOnStart({
userId,
});
const clientKeyHalfB64 = this.getClientKeyHalf(service, key);
const clientKeyHalfSatisfied = !requireClientKeyHalf || !!clientKeyHalfB64;
return clientKeyHalfSatisfied && (await this.osSupportsBiometric());
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
}
async authenticateBiometric(): Promise<boolean> {
2023-04-18 15:09:47 +02:00
let result = false;
this.interruptProcessReload(
() => {
return this.platformSpecificService.authenticateBiometric();
},
(response) => {
result = response;
return !response;
}
);
return result;
}
async getBiometricKey(service: string, storageKey: string): Promise<string | null> {
return await this.interruptProcessReload(async () => {
await this.enforceClientKeyHalf(service, storageKey);
return await this.platformSpecificService.getBiometricKey(
service,
storageKey,
this.getClientKeyHalf(service, storageKey)
);
});
}
async setBiometricKey(service: string, storageKey: string, value: string): Promise<void> {
await this.enforceClientKeyHalf(service, storageKey);
return await this.platformSpecificService.setBiometricKey(
service,
storageKey,
value,
this.getClientKeyHalf(service, storageKey)
);
}
/** Registers the client-side encryption key half for the OS stored Biometric key. The other half is protected by the OS.*/
async setEncryptionKeyHalf({
service,
key,
value,
}: {
service: string;
key: string;
value: string;
}): Promise<void> {
if (value == null) {
this.clientKeyHalves.delete(this.clientKeyHalfKey(service, key));
} else {
this.clientKeyHalves.set(this.clientKeyHalfKey(service, key), value);
}
}
async deleteBiometricKey(service: string, storageKey: string): Promise<void> {
this.clientKeyHalves.delete(this.clientKeyHalfKey(service, storageKey));
return await this.platformSpecificService.deleteBiometricKey(service, storageKey);
}
private async interruptProcessReload<T>(
callback: () => Promise<T>,
restartReloadCallback: (arg: T) => boolean = () => false
): Promise<T> {
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
this.messagingService.send("cancelProcessReload");
2023-04-18 15:09:47 +02:00
let restartReload = false;
let response: T;
try {
response = await callback();
restartReload ||= restartReloadCallback(response);
} catch {
restartReload = true;
}
if (restartReload) {
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
this.messagingService.send("startProcessReload");
}
2023-04-18 15:09:47 +02:00
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
return response;
}
2023-04-18 15:09:47 +02:00
private clientKeyHalfKey(service: string, key: string): string {
return `${service}:${key}`;
}
private getClientKeyHalf(service: string, key: string): string | undefined {
return this.clientKeyHalves.get(this.clientKeyHalfKey(service, key)) ?? undefined;
}
private async enforceClientKeyHalf(service: string, storageKey: string): Promise<void> {
const requireClientKeyHalf = await this.stateService.getBiometricRequirePasswordOnStart();
const clientKeyHalfB64 = this.getClientKeyHalf(service, storageKey);
if (requireClientKeyHalf && !clientKeyHalfB64) {
throw new Error("Biometric key requirements not met. No client key half provided.");
}
}
[PM-469] [PM-1325] [PS-1165] [PS-1257] Small refactorings/improvements on the desktop app main (#4704) * Only pass necessary service to power-monitor PowerMonitorMain only requires the messagingService instead of a full reference to Main * Remove never changing constructor params Window.main has a defaultWidth and defaultHeight that never change, so they do not need to get passed in from outside hideTitleBar is always true, so there is no need to make it a param * Remove projectName from updater This is likely another relict from sharing this previously with dircetory-connector and is not needed anymore * Only pass necessary service to MenuMain MenuMain only needs service references instead of a full reference to Main * Refactor biometrics service Create BiometricsService that takes care of loading the platformspecifc services, hiding the implementation details Make it clearer which dependencies are needed by a specific biometrics-service (compile-error vs runtime-error) Add unit tests Isolate biometrics import/exports with a barrel file * Fix #3148 recordActivity was only getting called when user-activity in the main window is recognized When using biometrics to unlock, the Windows Hello/TouchID prompt would be focused and no input would be recognised. LastActive would have an old value and the vault would get locked * Improve reloading with biometrics * Mock import of desktop-native * Add mock for "@bitwarden/desktop-native-linux-x64-musl" * Revert "Add mock for "@bitwarden/desktop-native-linux-x64-musl"" This reverts commit 69771b94bf34ba9af9d23370b7d92ff8a20ec92e. * mock the exports of desktop-native * Pass process.platform inot BiometricsService
2023-03-10 21:32:26 +01:00
}