1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-21 02:33:46 +00:00

[BEEEP] Remove legacy biometrics protocol (#15004)

* Remove legacy biometrics protocol

* Remove legacy message handling on desktop
This commit is contained in:
Bernd Schoolmann
2025-06-10 05:25:12 +02:00
committed by GitHub
parent 9367e89bcb
commit a368b70ab5
5 changed files with 28 additions and 253 deletions

View File

@@ -335,38 +335,6 @@ describe("BiometricMessageHandlerService", () => {
});
});
it("should show update dialog when legacy unlock is requested with fingerprint active", async () => {
desktopSettingsService.browserIntegrationFingerprintEnabled$ = of(true);
(global as any).ipc.platform.ephemeralStore.listEphemeralValueKeys.mockResolvedValue([
"connectedApp_appId",
]);
(global as any).ipc.platform.ephemeralStore.getEphemeralValue.mockResolvedValue(
JSON.stringify({
publicKey: Utils.fromUtf8ToB64("publicKey"),
sessionSecret: Utils.fromBufferToB64(new Uint8Array(64)),
trusted: false,
}),
);
encryptService.decryptString.mockResolvedValue(
JSON.stringify({
command: "biometricUnlock",
messageId: 0,
timestamp: Date.now(),
userId: SomeUser,
}),
);
await service.handleMessage({
appId: "appId",
message: {
command: "biometricUnlock",
messageId: 0,
timestamp: Date.now(),
userId: SomeUser,
},
});
expect(dialogService.openSimpleDialog).toHaveBeenCalled();
});
it("should send verify fingerprint when fingerprinting is required on modern unlock, and dialog is accepted, and set to trusted", async () => {
desktopSettingsService.browserIntegrationFingerprintEnabled$ = of(true);
(global as any).ipc.platform.ephemeralStore.listEphemeralValueKeys.mockResolvedValue([

View File

@@ -1,5 +1,5 @@
import { Injectable, NgZone } from "@angular/core";
import { combineLatest, concatMap, firstValueFrom, map } from "rxjs";
import { combineLatest, concatMap, firstValueFrom } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
@@ -255,102 +255,6 @@ export class BiometricMessageHandlerService {
appId,
);
}
// TODO: legacy, remove after 2025.3
case BiometricsCommands.IsAvailable: {
const available =
(await this.biometricsService.getBiometricsStatus()) == BiometricsStatus.Available;
return this.send(
{
command: BiometricsCommands.IsAvailable,
response: available ? "available" : "not available",
},
appId,
);
}
// TODO: legacy, remove after 2025.3
case BiometricsCommands.Unlock: {
if (
await firstValueFrom(this.desktopSettingService.browserIntegrationFingerprintEnabled$)
) {
await this.send({ command: "biometricUnlock", response: "not available" }, appId);
await this.dialogService.openSimpleDialog({
title: this.i18nService.t("updateBrowserOrDisableFingerprintDialogTitle"),
content: this.i18nService.t("updateBrowserOrDisableFingerprintDialogMessage"),
type: "warning",
});
return;
}
const isTemporarilyDisabled =
(await this.biometricStateService.getBiometricUnlockEnabled(message.userId as UserId)) &&
!((await this.biometricsService.getBiometricsStatus()) == BiometricsStatus.Available);
if (isTemporarilyDisabled) {
return this.send({ command: "biometricUnlock", response: "not available" }, appId);
}
if (!((await this.biometricsService.getBiometricsStatus()) == BiometricsStatus.Available)) {
return this.send({ command: "biometricUnlock", response: "not supported" }, appId);
}
const userId =
(message.userId as UserId) ??
(await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))));
if (userId == null) {
return this.send({ command: "biometricUnlock", response: "not unlocked" }, appId);
}
const biometricUnlock =
message.userId == null
? await firstValueFrom(this.biometricStateService.biometricUnlockEnabled$)
: await this.biometricStateService.getBiometricUnlockEnabled(message.userId as UserId);
if (!biometricUnlock) {
await this.send({ command: "biometricUnlock", response: "not enabled" }, appId);
return this.ngZone.run(() =>
this.dialogService.openSimpleDialog({
type: "warning",
title: { key: "biometricsNotEnabledTitle" },
content: { key: "biometricsNotEnabledDesc" },
cancelButtonText: null,
acceptButtonText: { key: "cancel" },
}),
);
}
try {
const userKey = await this.biometricsService.unlockWithBiometricsForUser(userId);
if (userKey != null) {
await this.send(
{
command: "biometricUnlock",
response: "unlocked",
userKeyB64: userKey.keyB64,
},
appId,
);
const currentlyActiveAccountId = (
await firstValueFrom(this.accountService.activeAccount$)
)?.id;
const isCurrentlyActiveAccountUnlocked =
(await this.authService.getAuthStatus(userId)) == AuthenticationStatus.Unlocked;
// prevent proc reloading an active account, when it is the same as the browser
if (currentlyActiveAccountId != message.userId || !isCurrentlyActiveAccountUnlocked) {
ipc.platform.reloadProcess();
}
} else {
await this.send({ command: "biometricUnlock", response: "canceled" }, appId);
}
// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
await this.send({ command: "biometricUnlock", response: "canceled" }, appId);
}
break;
}
default:
this.logService.error("NativeMessage, got unknown command: " + message.command);
break;