1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-08 04:33:38 +00:00

Apply more fixes

This commit is contained in:
Bernd Schoolmann
2025-05-30 14:30:04 +02:00
parent ab5eb30929
commit 8a4feb4b5b
10 changed files with 88 additions and 16 deletions

View File

@@ -2180,6 +2180,9 @@
"lockScreenDesktopRunningButLoggedOut": {
"message": "User account synchronization is enabled, but the active account is logged out in the desktop app."
},
"lockScreenDesktopRunningButNotTrusted": {
"message": "The connection fingerprint verification was denied in the desktop app."
},
"unlockWithBiometrics": {
"message": "Unlock with biometrics"
},

View File

@@ -85,6 +85,7 @@ export default class RuntimeBackground {
SyncedUnlockStateCommands.GetUserKeyFromDesktop,
SyncedUnlockStateCommands.GetUserStatusFromDesktop,
SyncedUnlockStateCommands.FocusDesktopApp,
SyncedUnlockStateCommands.IsConnectionTrusted,
"getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag",
"getUserPremiumStatus",
];
@@ -225,6 +226,9 @@ export default class RuntimeBackground {
case SyncedUnlockStateCommands.FocusDesktopApp: {
return await this.main.syncedUnlockService.focusDesktopApp();
}
case SyncedUnlockStateCommands.IsConnectionTrusted: {
return await this.main.syncedUnlockService.isConnectionTrusted();
}
case "getUseTreeWalkerApiForPageDetailsCollectionFeatureFlag": {
return await this.configService.getFeatureFlag(
FeatureFlag.UseTreeWalkerApiForPageDetailsCollection,

View File

@@ -18,8 +18,14 @@ import {
import { NativeMessagingBackground } from "../../background/nativeMessaging.background";
const SYNC_INTERVAL = 1000; // 1 second
const TRUST_DENIED_TIMEOUT = 30000; // 30 seconds
const STATUS_TIMEOUT = 5000; // 5 seconds
@Injectable()
export class BackgroundSyncedUnlockService extends SyncedUnlockService {
private hasTrustDenied = false;
constructor(
private nativeMessagingBackground: () => NativeMessagingBackground,
private logService: LogService,
@@ -30,7 +36,7 @@ export class BackgroundSyncedUnlockService extends SyncedUnlockService {
private syncedUnlockStateService: SyncedUnlockStateServiceAbstraction,
) {
super();
timer(0, 1000)
timer(0, SYNC_INTERVAL)
.pipe(
concatMap(async () => {
const isConnected = await this.isConnected();
@@ -47,15 +53,12 @@ export class BackgroundSyncedUnlockService extends SyncedUnlockService {
const desktopAccountStatus = await Promise.race([
this.getUserStatusFromDesktop(activeAccount.id),
new Promise((resolve) =>
setTimeout(() => resolve(AuthenticationStatus.Locked), 5000),
setTimeout(() => resolve(AuthenticationStatus.Locked), STATUS_TIMEOUT),
),
]);
const localAccountStatus = await firstValueFrom(
this.authService.authStatusFor$(activeAccount.id),
);
this.logService.info(
`Synced unlock: ${activeAccount.id} - Desktop: ${desktopAccountStatus} - Local: ${localAccountStatus}`,
);
if (
desktopAccountStatus === AuthenticationStatus.Locked &&
localAccountStatus === AuthenticationStatus.Unlocked
@@ -66,9 +69,16 @@ export class BackgroundSyncedUnlockService extends SyncedUnlockService {
desktopAccountStatus === AuthenticationStatus.Unlocked &&
localAccountStatus === AuthenticationStatus.Locked
) {
this.logService.info("Asking for user key from desktop");
const userKey = await this.getUserKeyFromDesktop(activeAccount.id);
if (userKey) {
if (userKey != null) {
await this.keyService.setUserKey(userKey, activeAccount.id);
} else {
this.hasTrustDenied = true;
// this means the user has denied access to the key on connection fingerprint verification
// Wait 30 seconds
await new Promise((resolve) => setTimeout(resolve, TRUST_DENIED_TIMEOUT));
this.hasTrustDenied = false;
}
}
}
@@ -117,4 +127,8 @@ export class BackgroundSyncedUnlockService extends SyncedUnlockService {
command: SyncedUnlockStateCommands.FocusDesktopApp,
});
}
async isConnectionTrusted(): Promise<boolean> {
return !this.hasTrustDenied && this.isConnected();
}
}

View File

@@ -69,4 +69,15 @@ export class ForegroundSyncedUnlockService extends SyncedUnlockService {
throw response.error;
}
}
async isConnectionTrusted(): Promise<boolean> {
const response = await BrowserApi.sendMessageWithResponse<{
result: boolean;
error: string;
}>(SyncedUnlockStateCommands.IsConnectionTrusted);
if (response.result == null) {
throw response.error;
}
return response.result;
}
}

View File

@@ -276,6 +276,14 @@ export class BiometricMessageHandlerService {
case SyncedUnlockStateCommands.GetUserKeyFromDesktop: {
if (!(await this.validateFingerprint(appId))) {
this.logService.info("[Native Messaging IPC] Fingerprint validation failed.");
return await this.send(
{
command: SyncedUnlockStateCommands.GetUserKeyFromDesktop,
messageId,
response: null,
},
appId,
);
}
const userId = message.userId as UserId;