mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 09:13:33 +00:00
[PM-6296] Fix biometrics error prompt when biometrics are temporarily unavailable in browser extension (v2) (#10374)
* Create unavailable message for biometrics when in clamshell mode * Move browser biometrics * Inject nativemessagingbackground instead of using constructor * Fix linting * Fix build on browser
This commit is contained in:
@@ -20,6 +20,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
import { KeySuffixOptions, ThemeType } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
|
||||
@@ -133,6 +134,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
private userVerificationService: UserVerificationServiceAbstraction,
|
||||
private desktopSettingsService: DesktopSettingsService,
|
||||
private biometricStateService: BiometricStateService,
|
||||
private biometricsService: BiometricsService,
|
||||
private desktopAutofillSettingsService: DesktopAutofillSettingsService,
|
||||
private pinService: PinServiceAbstraction,
|
||||
private logService: LogService,
|
||||
@@ -287,7 +289,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
// Non-form values
|
||||
this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop;
|
||||
this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
|
||||
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
|
||||
this.supportsBiometric = await this.biometricsService.supportsBiometric();
|
||||
this.previousVaultTimeout = this.form.value.vaultTimeout;
|
||||
|
||||
this.refreshTimeoutSettings$
|
||||
@@ -466,13 +468,12 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
const needsSetup = await this.platformUtilsService.biometricsNeedsSetup();
|
||||
const supportsBiometricAutoSetup =
|
||||
await this.platformUtilsService.biometricsSupportsAutoSetup();
|
||||
const needsSetup = await this.biometricsService.biometricsNeedsSetup();
|
||||
const supportsBiometricAutoSetup = await this.biometricsService.biometricsSupportsAutoSetup();
|
||||
|
||||
if (needsSetup) {
|
||||
if (supportsBiometricAutoSetup) {
|
||||
await this.platformUtilsService.biometricsSetup();
|
||||
await this.biometricsService.biometricsSetup();
|
||||
} else {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "biometricsManualSetupTitle" },
|
||||
|
||||
@@ -56,6 +56,7 @@ import { StateService as StateServiceAbstraction } from "@bitwarden/common/platf
|
||||
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
|
||||
import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
|
||||
// eslint-disable-next-line no-restricted-imports -- Used for dependency injection
|
||||
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
|
||||
@@ -72,6 +73,7 @@ import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legac
|
||||
|
||||
import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service";
|
||||
import { DesktopSettingsService } from "../../platform/services/desktop-settings.service";
|
||||
import { ElectronBiometricsService } from "../../platform/services/electron-biometrics.service";
|
||||
import { ElectronCryptoService } from "../../platform/services/electron-crypto.service";
|
||||
import { ElectronLogRendererService } from "../../platform/services/electron-log.renderer.service";
|
||||
import {
|
||||
@@ -104,6 +106,11 @@ const RELOAD_CALLBACK = new SafeInjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
*/
|
||||
const safeProviders: SafeProvider[] = [
|
||||
safeProvider(InitService),
|
||||
safeProvider({
|
||||
provide: BiometricsService,
|
||||
useClass: ElectronBiometricsService,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider(NativeMessagingService),
|
||||
safeProvider(SearchBarService),
|
||||
safeProvider(DialogService),
|
||||
|
||||
@@ -28,6 +28,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
import { BiometricsService as AbstractBiometricService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
@@ -35,6 +36,8 @@ import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BiometricsService } from "src/platform/main/biometric";
|
||||
|
||||
import { LockComponent } from "./lock.component";
|
||||
|
||||
// ipc mock global
|
||||
@@ -53,6 +56,7 @@ describe("LockComponent", () => {
|
||||
let fixture: ComponentFixture<LockComponent>;
|
||||
let stateServiceMock: MockProxy<StateService>;
|
||||
let biometricStateService: MockProxy<BiometricStateService>;
|
||||
let biometricsService: MockProxy<BiometricsService>;
|
||||
let messagingServiceMock: MockProxy<MessagingService>;
|
||||
let broadcasterServiceMock: MockProxy<BroadcasterService>;
|
||||
let platformUtilsServiceMock: MockProxy<PlatformUtilsService>;
|
||||
@@ -163,6 +167,10 @@ describe("LockComponent", () => {
|
||||
provide: BiometricStateService,
|
||||
useValue: biometricStateService,
|
||||
},
|
||||
{
|
||||
provide: AbstractBiometricService,
|
||||
useValue: biometricsService,
|
||||
},
|
||||
{
|
||||
provide: AccountService,
|
||||
useValue: accountService,
|
||||
|
||||
@@ -25,6 +25,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
@@ -66,6 +67,7 @@ export class LockComponent extends BaseLockComponent implements OnInit, OnDestro
|
||||
userVerificationService: UserVerificationService,
|
||||
pinService: PinServiceAbstraction,
|
||||
biometricStateService: BiometricStateService,
|
||||
biometricsService: BiometricsService,
|
||||
accountService: AccountService,
|
||||
authService: AuthService,
|
||||
kdfConfigService: KdfConfigService,
|
||||
@@ -93,6 +95,7 @@ export class LockComponent extends BaseLockComponent implements OnInit, OnDestro
|
||||
userVerificationService,
|
||||
pinService,
|
||||
biometricStateService,
|
||||
biometricsService,
|
||||
accountService,
|
||||
authService,
|
||||
kdfConfigService,
|
||||
@@ -139,7 +142,7 @@ export class LockComponent extends BaseLockComponent implements OnInit, OnDestro
|
||||
|
||||
// start background listener until destroyed on interval
|
||||
this.timerId = setInterval(async () => {
|
||||
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
|
||||
this.supportsBiometric = await this.biometricsService.supportsBiometric();
|
||||
this.biometricReady = await this.canUseBiometric();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import { PowerMonitorMain } from "./main/power-monitor.main";
|
||||
import { TrayMain } from "./main/tray.main";
|
||||
import { UpdaterMain } from "./main/updater.main";
|
||||
import { WindowMain } from "./main/window.main";
|
||||
import { BiometricsService, BiometricsServiceAbstraction } from "./platform/main/biometric/index";
|
||||
import { BiometricsService, DesktopBiometricsService } from "./platform/main/biometric/index";
|
||||
import { ClipboardMain } from "./platform/main/clipboard.main";
|
||||
import { DesktopCredentialStorageListener } from "./platform/main/desktop-credential-storage-listener";
|
||||
import { MainCryptoFunctionService } from "./platform/main/main-crypto-function.service";
|
||||
@@ -64,7 +64,7 @@ export class Main {
|
||||
menuMain: MenuMain;
|
||||
powerMonitorMain: PowerMonitorMain;
|
||||
trayMain: TrayMain;
|
||||
biometricsService: BiometricsServiceAbstraction;
|
||||
biometricsService: DesktopBiometricsService;
|
||||
nativeMessagingMain: NativeMessagingMain;
|
||||
clipboardMain: ClipboardMain;
|
||||
desktopAutofillSettingsService: DesktopAutofillSettingsService;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { systemPreferences } from "electron";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { passwords } from "@bitwarden/desktop-napi";
|
||||
|
||||
import { OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
export default class BiometricDarwinMain implements OsBiometricService {
|
||||
constructor(private i18nservice: I18nService) {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
export default class NoopBiometricsService implements OsBiometricService {
|
||||
constructor() {}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { biometrics, passwords } from "@bitwarden/desktop-napi";
|
||||
import { WindowMain } from "../../../main/window.main";
|
||||
import { isFlatpak, isLinux, isSnapStore } from "../../../utils";
|
||||
|
||||
import { OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
const polkitPolicy = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
|
||||
@@ -6,7 +6,7 @@ import { biometrics, passwords } from "@bitwarden/desktop-napi";
|
||||
|
||||
import { WindowMain } from "../../../main/window.main";
|
||||
|
||||
import { OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
const KEY_WITNESS_SUFFIX = "_witness";
|
||||
const WITNESS_VALUE = "known key";
|
||||
|
||||
@@ -11,7 +11,7 @@ import { WindowMain } from "../../../main/window.main";
|
||||
import BiometricDarwinMain from "./biometric.darwin.main";
|
||||
import BiometricWindowsMain from "./biometric.windows.main";
|
||||
import { BiometricsService } from "./biometrics.service";
|
||||
import { OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
jest.mock("@bitwarden/desktop-napi", () => {
|
||||
return {
|
||||
|
||||
@@ -6,9 +6,9 @@ import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { WindowMain } from "../../../main/window.main";
|
||||
|
||||
import { BiometricsServiceAbstraction, OsBiometricService } from "./biometrics.service.abstraction";
|
||||
import { DesktopBiometricsService, OsBiometricService } from "./desktop.biometrics.service";
|
||||
|
||||
export class BiometricsService implements BiometricsServiceAbstraction {
|
||||
export class BiometricsService extends DesktopBiometricsService {
|
||||
private platformSpecificService: OsBiometricService;
|
||||
private clientKeyHalves = new Map<string, string>();
|
||||
|
||||
@@ -20,6 +20,7 @@ export class BiometricsService implements BiometricsServiceAbstraction {
|
||||
private platform: NodeJS.Platform,
|
||||
private biometricStateService: BiometricStateService,
|
||||
) {
|
||||
super();
|
||||
this.loadPlatformSpecificService(this.platform);
|
||||
}
|
||||
|
||||
@@ -63,19 +64,19 @@ export class BiometricsService implements BiometricsServiceAbstraction {
|
||||
this.platformSpecificService = new NoopBiometricsService();
|
||||
}
|
||||
|
||||
async osSupportsBiometric() {
|
||||
async supportsBiometric() {
|
||||
return await this.platformSpecificService.osSupportsBiometric();
|
||||
}
|
||||
|
||||
async osBiometricsNeedsSetup() {
|
||||
async biometricsNeedsSetup() {
|
||||
return await this.platformSpecificService.osBiometricsNeedsSetup();
|
||||
}
|
||||
|
||||
async osBiometricsCanAutoSetup() {
|
||||
async biometricsSupportsAutoSetup() {
|
||||
return await this.platformSpecificService.osBiometricsCanAutoSetup();
|
||||
}
|
||||
|
||||
async osBiometricsSetup() {
|
||||
async biometricsSetup() {
|
||||
await this.platformSpecificService.osBiometricsSetup();
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ export class BiometricsService implements BiometricsServiceAbstraction {
|
||||
const requireClientKeyHalf = await this.biometricStateService.getRequirePasswordOnStart(userId);
|
||||
const clientKeyHalfB64 = this.getClientKeyHalf(service, key);
|
||||
const clientKeyHalfSatisfied = !requireClientKeyHalf || !!clientKeyHalfB64;
|
||||
return clientKeyHalfSatisfied && (await this.osSupportsBiometric());
|
||||
return clientKeyHalfSatisfied && (await this.supportsBiometric());
|
||||
}
|
||||
|
||||
async authenticateBiometric(): Promise<boolean> {
|
||||
@@ -110,6 +111,10 @@ export class BiometricsService implements BiometricsServiceAbstraction {
|
||||
return result;
|
||||
}
|
||||
|
||||
async isBiometricUnlockAvailable(): Promise<boolean> {
|
||||
return await this.platformSpecificService.osSupportsBiometric();
|
||||
}
|
||||
|
||||
async getBiometricKey(service: string, storageKey: string): Promise<string | null> {
|
||||
return await this.interruptProcessReload(async () => {
|
||||
await this.enforceClientKeyHalf(service, storageKey);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
export abstract class BiometricsServiceAbstraction {
|
||||
abstract osSupportsBiometric(): Promise<boolean>;
|
||||
abstract osBiometricsNeedsSetup: () => Promise<boolean>;
|
||||
abstract osBiometricsCanAutoSetup: () => Promise<boolean>;
|
||||
abstract osBiometricsSetup: () => Promise<void>;
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
|
||||
/**
|
||||
* This service extends the base biometrics service to provide desktop specific functions,
|
||||
* specifically for the main process.
|
||||
*/
|
||||
export abstract class DesktopBiometricsService extends BiometricsService {
|
||||
abstract canAuthBiometric({
|
||||
service,
|
||||
key,
|
||||
@@ -12,7 +14,6 @@ export abstract class BiometricsServiceAbstraction {
|
||||
key: string;
|
||||
userId: string;
|
||||
}): Promise<boolean>;
|
||||
abstract authenticateBiometric(): Promise<boolean>;
|
||||
abstract getBiometricKey(service: string, key: string): Promise<string | null>;
|
||||
abstract setBiometricKey(service: string, key: string, value: string): Promise<void>;
|
||||
abstract setEncryptionKeyHalf({
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from "./biometrics.service.abstraction";
|
||||
export * from "./desktop.biometrics.service";
|
||||
export * from "./biometrics.service";
|
||||
|
||||
@@ -6,14 +6,14 @@ import { passwords } from "@bitwarden/desktop-napi";
|
||||
|
||||
import { BiometricMessage, BiometricAction } from "../../types/biometric-message";
|
||||
|
||||
import { BiometricsServiceAbstraction } from "./biometric/index";
|
||||
import { DesktopBiometricsService } from "./biometric/index";
|
||||
|
||||
const AuthRequiredSuffix = "_biometric";
|
||||
|
||||
export class DesktopCredentialStorageListener {
|
||||
constructor(
|
||||
private serviceName: string,
|
||||
private biometricService: BiometricsServiceAbstraction,
|
||||
private biometricService: DesktopBiometricsService,
|
||||
private logService: ConsoleLogService,
|
||||
) {}
|
||||
|
||||
@@ -77,16 +77,16 @@ export class DesktopCredentialStorageListener {
|
||||
});
|
||||
break;
|
||||
case BiometricAction.OsSupported:
|
||||
val = await this.biometricService.osSupportsBiometric();
|
||||
val = await this.biometricService.supportsBiometric();
|
||||
break;
|
||||
case BiometricAction.NeedsSetup:
|
||||
val = await this.biometricService.osBiometricsNeedsSetup();
|
||||
val = await this.biometricService.biometricsNeedsSetup();
|
||||
break;
|
||||
case BiometricAction.Setup:
|
||||
await this.biometricService.osBiometricsSetup();
|
||||
await this.biometricService.biometricsSetup();
|
||||
break;
|
||||
case BiometricAction.CanAutoSetup:
|
||||
val = await this.biometricService.osBiometricsCanAutoSetup();
|
||||
val = await this.biometricService.biometricsSupportsAutoSetup();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
|
||||
/**
|
||||
* This service implement the base biometrics service to provide desktop specific functions,
|
||||
* specifically for the renderer process by passing messages to the main process.
|
||||
*/
|
||||
@Injectable()
|
||||
export class ElectronBiometricsService extends BiometricsService {
|
||||
async supportsBiometric(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.osSupported();
|
||||
}
|
||||
|
||||
async isBiometricUnlockAvailable(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.osSupported();
|
||||
}
|
||||
|
||||
/** This method is used to authenticate the user presence _only_.
|
||||
* It should not be used in the process to retrieve
|
||||
* biometric keys, which has a separate authentication mechanism.
|
||||
* For biometric keys, invoke "keytar" with a biometric key suffix */
|
||||
async authenticateBiometric(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.authenticate();
|
||||
}
|
||||
|
||||
async biometricsNeedsSetup(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.biometricsNeedsSetup();
|
||||
}
|
||||
|
||||
async biometricsSupportsAutoSetup(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.biometricsCanAutoSetup();
|
||||
}
|
||||
|
||||
async biometricsSetup(): Promise<void> {
|
||||
return await ipc.platform.biometric.biometricsSetup();
|
||||
}
|
||||
}
|
||||
@@ -131,30 +131,6 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
return ipc.platform.clipboard.read();
|
||||
}
|
||||
|
||||
async supportsBiometric(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.osSupported();
|
||||
}
|
||||
|
||||
async biometricsNeedsSetup(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.biometricsNeedsSetup();
|
||||
}
|
||||
|
||||
async biometricsSupportsAutoSetup(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.biometricsCanAutoSetup();
|
||||
}
|
||||
|
||||
async biometricsSetup(): Promise<void> {
|
||||
return await ipc.platform.biometric.biometricsSetup();
|
||||
}
|
||||
|
||||
/** This method is used to authenticate the user presence _only_.
|
||||
* It should not be used in the process to retrieve
|
||||
* biometric keys, which has a separate authentication mechanism.
|
||||
* For biometric keys, invoke "keytar" with a biometric key suffix */
|
||||
async authenticateBiometric(): Promise<boolean> {
|
||||
return await ipc.platform.biometric.authenticate();
|
||||
}
|
||||
|
||||
supportsSecureStorage(): boolean {
|
||||
return ELECTRON_SUPPORTS_SECURE_STORAGE;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/c
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
|
||||
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
|
||||
import { KeySuffixOptions } from "@bitwarden/common/platform/enums";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
@@ -33,11 +33,11 @@ export class NativeMessagingService {
|
||||
constructor(
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private cryptoService: CryptoService,
|
||||
private platformUtilService: PlatformUtilsService,
|
||||
private logService: LogService,
|
||||
private messagingService: MessagingService,
|
||||
private desktopSettingService: DesktopSettingsService,
|
||||
private biometricStateService: BiometricStateService,
|
||||
private biometricsService: BiometricsService,
|
||||
private nativeMessageHandler: NativeMessageHandlerService,
|
||||
private dialogService: DialogService,
|
||||
private accountService: AccountService,
|
||||
@@ -133,7 +133,14 @@ export class NativeMessagingService {
|
||||
|
||||
switch (message.command) {
|
||||
case "biometricUnlock": {
|
||||
if (!(await this.platformUtilService.supportsBiometric())) {
|
||||
const isTemporarilyDisabled =
|
||||
(await this.biometricStateService.getBiometricUnlockEnabled(message.userId as UserId)) &&
|
||||
!(await this.biometricsService.supportsBiometric());
|
||||
if (isTemporarilyDisabled) {
|
||||
return this.send({ command: "biometricUnlock", response: "not available" }, appId);
|
||||
}
|
||||
|
||||
if (!(await this.biometricsService.supportsBiometric())) {
|
||||
return this.send({ command: "biometricUnlock", response: "not supported" }, appId);
|
||||
}
|
||||
|
||||
@@ -198,8 +205,18 @@ export class NativeMessagingService {
|
||||
|
||||
break;
|
||||
}
|
||||
case "biometricUnlockAvailable": {
|
||||
const isAvailable = await this.biometricsService.supportsBiometric();
|
||||
return this.send(
|
||||
{
|
||||
command: "biometricUnlockAvailable",
|
||||
response: isAvailable ? "available" : "not available",
|
||||
},
|
||||
appId,
|
||||
);
|
||||
}
|
||||
default:
|
||||
this.logService.error("NativeMessage, got unknown command.");
|
||||
this.logService.error("NativeMessage, got unknown command: " + message.command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user