1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-06 02:23:44 +00:00

Revert "[PM-6296] Fix biometrics error prompt when biometrics are temporarily…" (#10373)

This reverts commit 1184c504d1.
This commit is contained in:
Bernd Schoolmann
2024-08-02 13:46:54 +02:00
committed by GitHub
parent 1184c504d1
commit cc45655b86
36 changed files with 101 additions and 265 deletions

View File

@@ -2018,12 +2018,6 @@
"biometricsNotUnlockedDesc": {
"message": "Please unlock this user in the desktop application and try again."
},
"biometricsNotAvailableTitle": {
"message": "Biometric unlock unavailable"
},
"biometricsNotAvailableDesc": {
"message": "Biometric unlock is currently unavailable. Please try again later."
},
"biometricsFailedTitle": {
"message": "Biometrics failed"
},

View File

@@ -24,7 +24,6 @@ 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";
@@ -68,7 +67,6 @@ export class LockComponent extends BaseLockComponent {
pinService: PinServiceAbstraction,
private routerService: BrowserRouterService,
biometricStateService: BiometricStateService,
biometricsService: BiometricsService,
accountService: AccountService,
kdfConfigService: KdfConfigService,
syncService: SyncService,
@@ -95,7 +93,6 @@ export class LockComponent extends BaseLockComponent {
userVerificationService,
pinService,
biometricStateService,
biometricsService,
accountService,
authService,
kdfConfigService,
@@ -132,35 +129,22 @@ export class LockComponent extends BaseLockComponent {
this.isInitialLockScreen &&
(await this.authService.getAuthStatus()) === AuthenticationStatus.Locked
) {
await this.unlockBiometric(true);
await this.unlockBiometric();
}
}, 100);
}
override async unlockBiometric(automaticPrompt: boolean = false): Promise<boolean> {
override async unlockBiometric(): Promise<boolean> {
if (!this.biometricLock) {
return;
}
this.pendingBiometric = true;
this.biometricError = null;
let success;
try {
const available = await super.isBiometricUnlockAvailable();
if (!available) {
if (!automaticPrompt) {
await this.dialogService.openSimpleDialog({
type: "warning",
title: { key: "biometricsNotAvailableTitle" },
content: { key: "biometricsNotAvailableDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
});
}
} else {
this.pendingBiometric = true;
success = await super.unlockBiometric();
}
success = await super.unlockBiometric();
} catch (e) {
const error = BiometricErrors[e?.message as BiometricErrorTypes];

View File

@@ -32,7 +32,6 @@ 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 {
VaultTimeout,
VaultTimeoutOption,
@@ -94,7 +93,6 @@ export class AccountSecurityComponent implements OnInit {
private dialogService: DialogService,
private changeDetectorRef: ChangeDetectorRef,
private biometricStateService: BiometricStateService,
private biometricsService: BiometricsService,
) {
this.accountSwitcherEnabled = enableAccountSwitching();
}
@@ -166,7 +164,7 @@ export class AccountSecurityComponent implements OnInit {
};
this.form.patchValue(initialValues, { emitEvent: false });
this.supportsBiometric = await this.biometricsService.supportsBiometric();
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
this.showChangeMasterPass = await this.userVerificationService.hasMasterPassword();
this.form.controls.vaultTimeout.valueChanges
@@ -395,7 +393,7 @@ export class AccountSecurityComponent implements OnInit {
this.form.controls.biometric.setValue(false);
}
}),
this.biometricsService
this.platformUtilsService
.authenticateBiometric()
.then((result) => {
this.form.controls.biometric.setValue(result);

View File

@@ -97,7 +97,6 @@ import {
BiometricStateService,
DefaultBiometricStateService,
} from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
// eslint-disable-next-line no-restricted-imports -- Used for dependency creation
@@ -224,7 +223,6 @@ import { ChromeMessageSender } from "../platform/messaging/chrome-message.sender
import { OffscreenDocumentService } from "../platform/offscreen-document/abstractions/offscreen-document";
import { DefaultOffscreenDocumentService } from "../platform/offscreen-document/offscreen-document.service";
import { BrowserTaskSchedulerService } from "../platform/services/abstractions/browser-task-scheduler.service";
import { BackgroundBrowserBiometricsService } from "../platform/services/background-browser-biometrics.";
import { BrowserCryptoService } from "../platform/services/browser-crypto.service";
import { BrowserEnvironmentService } from "../platform/services/browser-environment.service";
import BrowserLocalStorageService from "../platform/services/browser-local-storage.service";
@@ -339,7 +337,6 @@ export default class MainBackground {
organizationVaultExportService: OrganizationVaultExportServiceAbstraction;
vaultSettingsService: VaultSettingsServiceAbstraction;
biometricStateService: BiometricStateService;
biometricsService: BiometricsService;
stateEventRunnerService: StateEventRunnerService;
ssoLoginService: SsoLoginServiceAbstraction;
billingAccountProfileStateService: BillingAccountProfileStateService;
@@ -423,6 +420,7 @@ export default class MainBackground {
this.platformUtilsService = new BackgroundPlatformUtilsService(
this.messagingService,
(clipboardValue, clearMs) => this.clearClipboard(clipboardValue, clearMs),
async () => this.biometricUnlock(),
self,
this.offscreenDocumentService,
);
@@ -591,8 +589,6 @@ export default class MainBackground {
this.i18nService = new I18nService(BrowserApi.getUILanguage(), this.globalStateProvider);
this.biometricsService = new BackgroundBrowserBiometricsService(this.nativeMessagingBackground);
this.kdfConfigService = new KdfConfigService(this.stateProvider);
this.pinService = new PinService(
@@ -619,7 +615,6 @@ export default class MainBackground {
this.accountService,
this.stateProvider,
this.biometricStateService,
this.biometricsService,
this.kdfConfigService,
);
@@ -1468,6 +1463,17 @@ export default class MainBackground {
}
}
async biometricUnlock(): Promise<boolean> {
if (this.nativeMessagingBackground == null) {
return false;
}
const responsePromise = this.nativeMessagingBackground.getResponse();
await this.nativeMessagingBackground.send({ command: "biometricUnlock" });
const response = await responsePromise;
return response.response === "unlocked";
}
private async fullSync(override = false) {
const syncInternal = 6 * 60 * 60 * 1000; // 6 hours
const lastSync = await this.syncService.getLastSync();

View File

@@ -326,15 +326,6 @@ export class NativeMessagingBackground {
type: "danger",
});
break;
} else if (message.response === "not available") {
this.messagingService.send("showDialog", {
title: { key: "biometricsNotAvailableTitle" },
content: { key: "biometricsNotAvailableDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
type: "danger",
});
break;
} else if (message.response === "canceled") {
break;
}
@@ -401,10 +392,6 @@ export class NativeMessagingBackground {
}
break;
}
case "biometricUnlockAvailable": {
this.resolver(message);
break;
}
default:
this.logService.error("NativeMessage, got unknown command: " + message.command);
break;

View File

@@ -68,7 +68,6 @@ export default class RuntimeBackground {
) => {
const messagesWithResponse = [
"biometricUnlock",
"biometricUnlockAvailable",
"getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag",
"getInlineMenuFieldQualificationFeatureFlag",
];
@@ -180,11 +179,7 @@ export default class RuntimeBackground {
}
break;
case "biometricUnlock": {
const result = await this.main.biometricsService.authenticateBiometric();
return result;
}
case "biometricUnlockAvailable": {
const result = await this.main.biometricsService.isBiometricUnlockAvailable();
const result = await this.main.biometricUnlock();
return result;
}
case "getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag": {

View File

@@ -1,26 +0,0 @@
import { Injectable } from "@angular/core";
import { NativeMessagingBackground } from "../../background/nativeMessaging.background";
import { BrowserBiometricsService } from "./browser-biometrics.service";
@Injectable()
export class BackgroundBrowserBiometricsService extends BrowserBiometricsService {
constructor(private nativeMessagingBackground: NativeMessagingBackground) {
super();
}
async authenticateBiometric(): Promise<boolean> {
const responsePromise = this.nativeMessagingBackground.getResponse();
await this.nativeMessagingBackground.send({ command: "biometricUnlock" });
const response = await responsePromise;
return response.response === "unlocked";
}
async isBiometricUnlockAvailable(): Promise<boolean> {
const responsePromise = this.nativeMessagingBackground.getResponse();
await this.nativeMessagingBackground.send({ command: "biometricUnlockAvailable" });
const response = await responsePromise;
return response.response === "available";
}
}

View File

@@ -1,19 +0,0 @@
import { Injectable } from "@angular/core";
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
import { BrowserApi } from "../browser/browser-api";
@Injectable()
export abstract class BrowserBiometricsService extends BiometricsService {
async supportsBiometric() {
const platformInfo = await BrowserApi.getPlatformInfo();
if (platformInfo.os === "mac" || platformInfo.os === "win") {
return true;
}
return false;
}
abstract authenticateBiometric(): Promise<boolean>;
abstract isBiometricUnlockAvailable(): Promise<boolean>;
}

View File

@@ -11,7 +11,6 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
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 } from "@bitwarden/common/platform/enums";
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
import { USER_KEY } from "@bitwarden/common/platform/services/key-state/user-key.state";
@@ -32,7 +31,6 @@ export class BrowserCryptoService extends CryptoService {
accountService: AccountService,
stateProvider: StateProvider,
private biometricStateService: BiometricStateService,
private biometricsService: BiometricsService,
kdfConfigService: KdfConfigService,
) {
super(
@@ -70,7 +68,7 @@ export class BrowserCryptoService extends CryptoService {
userId?: UserId,
): Promise<UserKey> {
if (keySuffix === KeySuffixOptions.Biometric) {
const biometricsResult = await this.biometricsService.authenticateBiometric();
const biometricsResult = await this.platformUtilService.authenticateBiometric();
if (!biometricsResult) {
return null;

View File

@@ -1,24 +0,0 @@
import { BrowserApi } from "../browser/browser-api";
import { BrowserBiometricsService } from "./browser-biometrics.service";
export class ForegroundBrowserBiometricsService extends BrowserBiometricsService {
async authenticateBiometric(): Promise<boolean> {
const response = await BrowserApi.sendMessageWithResponse<{
result: boolean;
error: string;
}>("biometricUnlock");
if (!response.result) {
throw response.error;
}
return response.result;
}
async isBiometricUnlockAvailable(): Promise<boolean> {
const response = await BrowserApi.sendMessageWithResponse<{
result: boolean;
error: string;
}>("biometricUnlockAvailable");
return response.result && response.result === true;
}
}

View File

@@ -8,10 +8,11 @@ export class BackgroundPlatformUtilsService extends BrowserPlatformUtilsService
constructor(
private messagingService: MessagingService,
clipboardWriteCallback: (clipboardValue: string, clearMs: number) => void,
biometricCallback: () => Promise<boolean>,
win: Window & typeof globalThis,
offscreenDocumentService: OffscreenDocumentService,
) {
super(clipboardWriteCallback, win, offscreenDocumentService);
super(clipboardWriteCallback, biometricCallback, win, offscreenDocumentService);
}
override showToast(

View File

@@ -16,7 +16,7 @@ class TestBrowserPlatformUtilsService extends BrowserPlatformUtilsService {
win: Window & typeof globalThis,
offscreenDocumentService: OffscreenDocumentService,
) {
super(clipboardSpy, win, offscreenDocumentService);
super(clipboardSpy, null, win, offscreenDocumentService);
}
showToast(

View File

@@ -15,6 +15,7 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic
constructor(
private clipboardWriteCallback: (clipboardValue: string, clearMs: number) => void,
private biometricCallback: () => Promise<boolean>,
private globalContext: Window | ServiceWorkerGlobalScope,
private offscreenDocumentService: OffscreenDocumentService,
) {}
@@ -275,6 +276,18 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic
return await BrowserClipboardService.read(windowContext);
}
async supportsBiometric() {
const platformInfo = await BrowserApi.getPlatformInfo();
if (platformInfo.os === "mac" || platformInfo.os === "win") {
return true;
}
return false;
}
authenticateBiometric() {
return this.biometricCallback();
}
supportsSecureStorage(): boolean {
return false;
}

View File

@@ -8,10 +8,11 @@ export class ForegroundPlatformUtilsService extends BrowserPlatformUtilsService
constructor(
private toastService: ToastService,
clipboardWriteCallback: (clipboardValue: string, clearMs: number) => void,
biometricCallback: () => Promise<boolean>,
win: Window & typeof globalThis,
offscreenDocumentService: OffscreenDocumentService,
) {
super(clipboardWriteCallback, win, offscreenDocumentService);
super(clipboardWriteCallback, biometricCallback, win, offscreenDocumentService);
}
override showToast(

View File

@@ -57,7 +57,6 @@ import {
ObservableStorageService,
} from "@bitwarden/common/platform/abstractions/storage.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";
@@ -100,7 +99,6 @@ import { BrowserCryptoService } from "../../platform/services/browser-crypto.ser
import { BrowserEnvironmentService } from "../../platform/services/browser-environment.service";
import BrowserLocalStorageService from "../../platform/services/browser-local-storage.service";
import { BrowserScriptInjectorService } from "../../platform/services/browser-script-injector.service";
import { ForegroundBrowserBiometricsService } from "../../platform/services/foreground-browser-biometrics";
import I18nService from "../../platform/services/i18n.service";
import { ForegroundPlatformUtilsService } from "../../platform/services/platform-utils/foreground-platform-utils.service";
import { ForegroundTaskSchedulerService } from "../../platform/services/task-scheduler/foreground-task-scheduler.service";
@@ -205,7 +203,6 @@ const safeProviders: SafeProvider[] = [
accountService: AccountServiceAbstraction,
stateProvider: StateProvider,
biometricStateService: BiometricStateService,
biometricsService: BiometricsService,
kdfConfigService: KdfConfigService,
) => {
const cryptoService = new BrowserCryptoService(
@@ -220,7 +217,6 @@ const safeProviders: SafeProvider[] = [
accountService,
stateProvider,
biometricStateService,
biometricsService,
kdfConfigService,
);
new ContainerService(cryptoService, encryptService).attachToGlobal(self);
@@ -238,7 +234,6 @@ const safeProviders: SafeProvider[] = [
AccountServiceAbstraction,
StateProvider,
BiometricStateService,
BiometricsService,
KdfConfigService,
],
}),
@@ -263,19 +258,22 @@ const safeProviders: SafeProvider[] = [
(clipboardValue: string, clearMs: number) => {
void BrowserApi.sendMessage("clearClipboard", { clipboardValue, clearMs });
},
async () => {
const response = await BrowserApi.sendMessageWithResponse<{
result: boolean;
error: string;
}>("biometricUnlock");
if (!response.result) {
throw response.error;
}
return response.result;
},
window,
offscreenDocumentService,
);
},
deps: [ToastService, OffscreenDocumentService],
}),
safeProvider({
provide: BiometricsService,
useFactory: () => {
return new ForegroundBrowserBiometricsService();
},
deps: [],
}),
safeProvider({
provide: SyncService,
useFactory: getBgService<SyncService>("syncService"),