mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
Added full synce service to the fido2 authenticator to ensure the full sync is completed before getting all decrypted ciphers
This commit is contained in:
@@ -535,6 +535,7 @@ export default class MainBackground {
|
|||||||
this.fido2AuthenticatorService = new Fido2AuthenticatorService(
|
this.fido2AuthenticatorService = new Fido2AuthenticatorService(
|
||||||
this.cipherService,
|
this.cipherService,
|
||||||
this.fido2UserInterfaceService,
|
this.fido2UserInterfaceService,
|
||||||
|
this.syncService,
|
||||||
this.logService
|
this.logService
|
||||||
);
|
);
|
||||||
this.fido2ClientService = new Fido2ClientService(
|
this.fido2ClientService = new Fido2ClientService(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NgZone } from "@angular/core";
|
import type { NgZone } from "@angular/core";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
import { DeviceType } from "@bitwarden/common/enums";
|
import { DeviceType } from "@bitwarden/common/enums";
|
||||||
@@ -213,7 +213,15 @@ export class BrowserApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ngzone run is added to fix the issue on Fido2Component, where the message listener is not running in the angular zone
|
/**
|
||||||
|
* Creates an observable that listens for messages. If an Angular zone is provided,
|
||||||
|
* ensures that the message processing runs within that zone, triggering change detection.
|
||||||
|
* This solution was devised to address an issue in the `Fido2Component`, where the
|
||||||
|
* original message listener operated outside the Angular zone.
|
||||||
|
*
|
||||||
|
* @param {NgZone} [zone] - An optional Angular zone to ensure UI updates and change
|
||||||
|
* detection are triggered. If omitted, operates outside the Angular zone.
|
||||||
|
*/
|
||||||
static messageListener$(zone?: NgZone) {
|
static messageListener$(zone?: NgZone) {
|
||||||
return new Observable<unknown>((subscriber) => {
|
return new Observable<unknown>((subscriber) => {
|
||||||
const handler = (message: unknown) => {
|
const handler = (message: unknown) => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
Fido2UserInterfaceSession,
|
Fido2UserInterfaceSession,
|
||||||
NewCredentialParams,
|
NewCredentialParams,
|
||||||
} from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
} from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
||||||
|
import { SyncService } from "../../abstractions/sync/sync.service.abstraction";
|
||||||
import { CipherType } from "../../enums/cipher-type";
|
import { CipherType } from "../../enums/cipher-type";
|
||||||
import { Cipher } from "../../models/domain/cipher";
|
import { Cipher } from "../../models/domain/cipher";
|
||||||
import { CipherView } from "../../models/view/cipher.view";
|
import { CipherView } from "../../models/view/cipher.view";
|
||||||
@@ -30,6 +31,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
let cipherService!: MockProxy<CipherService>;
|
let cipherService!: MockProxy<CipherService>;
|
||||||
let userInterface!: MockProxy<Fido2UserInterfaceService>;
|
let userInterface!: MockProxy<Fido2UserInterfaceService>;
|
||||||
let userInterfaceSession!: MockProxy<Fido2UserInterfaceSession>;
|
let userInterfaceSession!: MockProxy<Fido2UserInterfaceSession>;
|
||||||
|
let syncService!: MockProxy<SyncService>;
|
||||||
let authenticator!: Fido2AuthenticatorService;
|
let authenticator!: Fido2AuthenticatorService;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -37,7 +39,8 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
userInterface = mock<Fido2UserInterfaceService>();
|
userInterface = mock<Fido2UserInterfaceService>();
|
||||||
userInterfaceSession = mock<Fido2UserInterfaceSession>();
|
userInterfaceSession = mock<Fido2UserInterfaceSession>();
|
||||||
userInterface.newSession.mockResolvedValue(userInterfaceSession);
|
userInterface.newSession.mockResolvedValue(userInterfaceSession);
|
||||||
authenticator = new Fido2AuthenticatorService(cipherService, userInterface);
|
syncService = mock<SyncService>();
|
||||||
|
authenticator = new Fido2AuthenticatorService(cipherService, userInterface, syncService);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("makeCredential", () => {
|
describe("makeCredential", () => {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
PublicKeyCredentialDescriptor,
|
PublicKeyCredentialDescriptor,
|
||||||
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
||||||
import { Fido2UserInterfaceService } from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
import { Fido2UserInterfaceService } from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
||||||
|
import { SyncService } from "../../abstractions/sync/sync.service.abstraction";
|
||||||
import { CipherType } from "../../enums/cipher-type";
|
import { CipherType } from "../../enums/cipher-type";
|
||||||
import { CipherView } from "../../models/view/cipher.view";
|
import { CipherView } from "../../models/view/cipher.view";
|
||||||
import { Fido2KeyView } from "../../models/view/fido2-key.view";
|
import { Fido2KeyView } from "../../models/view/fido2-key.view";
|
||||||
@@ -37,6 +38,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
constructor(
|
constructor(
|
||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
private userInterface: Fido2UserInterfaceService,
|
private userInterface: Fido2UserInterfaceService,
|
||||||
|
private syncService: SyncService,
|
||||||
private logService?: LogService
|
private logService?: LogService
|
||||||
) {}
|
) {}
|
||||||
async makeCredential(
|
async makeCredential(
|
||||||
@@ -81,6 +83,9 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown);
|
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: uncomment this when working on the login flow ticket
|
||||||
|
// await userInterfaceSession.ensureUnlockedVault();
|
||||||
|
|
||||||
const existingCipherIds = await this.findExcludedCredentials(
|
const existingCipherIds = await this.findExcludedCredentials(
|
||||||
params.excludeCredentialDescriptorList
|
params.excludeCredentialDescriptorList
|
||||||
);
|
);
|
||||||
@@ -376,6 +381,11 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ensure full sync has completed before getting the ciphers
|
||||||
|
if ((await this.syncService.getLastSync()) == null) {
|
||||||
|
await this.syncService.fullSync(false);
|
||||||
|
}
|
||||||
|
|
||||||
const ciphers = await this.cipherService.getAllDecrypted();
|
const ciphers = await this.cipherService.getAllDecrypted();
|
||||||
return ciphers.filter(
|
return ciphers.filter(
|
||||||
(cipher) =>
|
(cipher) =>
|
||||||
@@ -391,6 +401,11 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async findCredentialsByRp(rpId: string): Promise<CipherView[]> {
|
private async findCredentialsByRp(rpId: string): Promise<CipherView[]> {
|
||||||
|
//ensure full sync has completed before getting the ciphers
|
||||||
|
if ((await this.syncService.getLastSync()) == null) {
|
||||||
|
await this.syncService.fullSync(false);
|
||||||
|
}
|
||||||
|
|
||||||
const ciphers = await this.cipherService.getAllDecrypted();
|
const ciphers = await this.cipherService.getAllDecrypted();
|
||||||
return ciphers.filter(
|
return ciphers.filter(
|
||||||
(cipher) =>
|
(cipher) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user