mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
PM-4877: Only allow replacing passkeys for the same userhandle (#9804)
* Initial draft * small cleanup * show vaul items without passkeys * Refactored a bit * tests run for me? * Fixed platform test * null and undefined * lint
This commit is contained in:
parent
aa8c5b1516
commit
dbc9b9c90b
@ -65,6 +65,7 @@ export type BrowserFido2Message = { sessionId: string } & (
|
||||
type: "ConfirmNewCredentialRequest";
|
||||
credentialName: string;
|
||||
userName: string;
|
||||
userHandle: string;
|
||||
userVerification: boolean;
|
||||
fallbackSupported: boolean;
|
||||
rpId: string;
|
||||
@ -242,6 +243,7 @@ export class BrowserFido2UserInterfaceSession implements Fido2UserInterfaceSessi
|
||||
async confirmNewCredential({
|
||||
credentialName,
|
||||
userName,
|
||||
userHandle,
|
||||
userVerification,
|
||||
rpId,
|
||||
}: NewCredentialParams): Promise<{ cipherId: string; userVerified: boolean }> {
|
||||
@ -250,6 +252,7 @@ export class BrowserFido2UserInterfaceSession implements Fido2UserInterfaceSessi
|
||||
sessionId: this.sessionId,
|
||||
credentialName,
|
||||
userName,
|
||||
userHandle,
|
||||
userVerification,
|
||||
fallbackSupported: this.fallbackSupported,
|
||||
rpId,
|
||||
|
@ -143,8 +143,10 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
this.ciphers = (await this.cipherService.getAllDecrypted()).filter(
|
||||
(cipher) => cipher.type === CipherType.Login && !cipher.isDeleted,
|
||||
);
|
||||
this.displayedCiphers = this.ciphers.filter((cipher) =>
|
||||
cipher.login.matchesUri(this.url, equivalentDomains),
|
||||
this.displayedCiphers = this.ciphers.filter(
|
||||
(cipher) =>
|
||||
cipher.login.matchesUri(this.url, equivalentDomains) &&
|
||||
this.hasNoOtherPasskeys(cipher, message.userHandle),
|
||||
);
|
||||
|
||||
if (this.displayedCiphers.length > 0) {
|
||||
@ -405,4 +407,18 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
...msg,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods returns true if a cipher either has no passkeys, or has a passkey matching with userHandle
|
||||
* @param userHandle
|
||||
*/
|
||||
private hasNoOtherPasskeys(cipher: CipherView, userHandle: string): boolean {
|
||||
if (cipher.login.fido2Credentials == null || cipher.login.fido2Credentials.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cipher.login.fido2Credentials.some((passkey) => {
|
||||
passkey.userHandle === userHandle;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,11 @@ export interface NewCredentialParams {
|
||||
*/
|
||||
userName: string;
|
||||
|
||||
/**
|
||||
* The userhandle (userid) of the user.
|
||||
*/
|
||||
userHandle: string;
|
||||
|
||||
/**
|
||||
* Whether or not the user must be verified before completing the operation.
|
||||
*/
|
||||
|
@ -215,6 +215,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
expect(userInterfaceSession.confirmNewCredential).toHaveBeenCalledWith({
|
||||
credentialName: params.rpEntity.name,
|
||||
userName: params.userEntity.name,
|
||||
userHandle: Fido2Utils.bufferToString(params.userEntity.id),
|
||||
userVerification,
|
||||
rpId: params.rpEntity.id,
|
||||
} as NewCredentialParams);
|
||||
|
@ -112,6 +112,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
||||
const response = await userInterfaceSession.confirmNewCredential({
|
||||
credentialName: params.rpEntity.name,
|
||||
userName: params.userEntity.name,
|
||||
userHandle: Fido2Utils.bufferToString(params.userEntity.id),
|
||||
userVerification: params.requireUserVerification,
|
||||
rpId: params.rpEntity.id,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user