mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-08 00:01:28 +01:00
[EC-598] feat: increment counter during assertion
This commit is contained in:
parent
597bc0b197
commit
5bf4156fc6
@ -588,7 +588,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("assertion of non-discoverable credential", () => {
|
||||
describe("vault contains credential", () => {
|
||||
let credentialIds: string[];
|
||||
let ciphers: CipherView[];
|
||||
let params: Fido2AuthenticatorGetAssertionParams;
|
||||
@ -612,10 +612,66 @@ describe("FidoAuthenticatorService", () => {
|
||||
|
||||
/** Spec: Prompt the user to select a public key credential source selectedCredential from credentialOptions. */
|
||||
it("should request confirmation from the user", async () => {
|
||||
userInterface.pickCredential.mockResolvedValue(ciphers[0].id);
|
||||
|
||||
await authenticator.getAssertion(params);
|
||||
|
||||
expect(userInterface.pickCredential).toHaveBeenCalledWith(ciphers.map((c) => c.id));
|
||||
});
|
||||
|
||||
/** Spec: If the user does not consent, return an error code equivalent to "NotAllowedError" and terminate the operation. */
|
||||
it("should throw error", async () => {
|
||||
userInterface.pickCredential.mockResolvedValue(undefined);
|
||||
|
||||
const result = async () => await authenticator.getAssertion(params);
|
||||
|
||||
await expect(result).rejects.toThrowError(Fido2AutenticatorErrorCode.NotAllowed);
|
||||
});
|
||||
});
|
||||
|
||||
describe("assertion of non-discoverable credential", () => {
|
||||
let credentialIds: string[];
|
||||
let ciphers: CipherView[];
|
||||
let params: Fido2AuthenticatorGetAssertionParams;
|
||||
|
||||
beforeEach(async () => {
|
||||
credentialIds = [Utils.newGuid(), Utils.newGuid()];
|
||||
ciphers = await Promise.all(
|
||||
credentialIds.map((id) =>
|
||||
createCipherView(
|
||||
{ type: CipherType.Login },
|
||||
{ nonDiscoverableId: id, rpId: RpId, counter: 9000 }
|
||||
)
|
||||
)
|
||||
);
|
||||
params = await createParams({
|
||||
allowCredentialDescriptorList: credentialIds.map((credentialId) => ({
|
||||
id: Utils.guidToRawFormat(credentialId),
|
||||
type: "public-key",
|
||||
})),
|
||||
rpId: RpId,
|
||||
});
|
||||
cipherService.getAllDecrypted.mockResolvedValue(ciphers);
|
||||
userInterface.pickCredential.mockResolvedValue(ciphers[0].id);
|
||||
});
|
||||
|
||||
/** Spec: Increment the credential associated signature counter */
|
||||
it("should increment counter", async () => {
|
||||
const encrypted = Symbol();
|
||||
cipherService.encrypt.mockResolvedValue(encrypted as any);
|
||||
|
||||
await authenticator.getAssertion(params);
|
||||
|
||||
expect(cipherService.encrypt).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: ciphers[0].id,
|
||||
fido2Key: expect.objectContaining({
|
||||
counter: 9001,
|
||||
}),
|
||||
})
|
||||
);
|
||||
expect(cipherService.updateWithServer).toHaveBeenCalledWith(encrypted);
|
||||
});
|
||||
});
|
||||
|
||||
async function createParams(
|
||||
@ -651,10 +707,12 @@ function createCipherView(
|
||||
const cipher = new CipherView();
|
||||
cipher.id = data.id ?? Utils.newGuid();
|
||||
cipher.type = data.type ?? CipherType.Fido2Key;
|
||||
cipher.localData = {};
|
||||
cipher.login = data.type ?? data.type === CipherType.Login ? new LoginView() : null;
|
||||
cipher.fido2Key = new Fido2KeyView();
|
||||
cipher.fido2Key.nonDiscoverableId = fido2Key.nonDiscoverableId;
|
||||
cipher.fido2Key.rpId = fido2Key.rpId;
|
||||
cipher.fido2Key.rpId = fido2Key.rpId ?? RpId;
|
||||
cipher.fido2Key.counter = fido2Key.counter ?? 0;
|
||||
return cipher;
|
||||
}
|
||||
|
||||
|
@ -162,12 +162,19 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
||||
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotAllowed);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const selectedCredential = await this.userInterface.pickCredential(
|
||||
const selectedCredentialId = await this.userInterface.pickCredential(
|
||||
credentialOptions.map((cipher) => cipher.id)
|
||||
);
|
||||
const selectedCredential = credentialOptions.find((c) => c.id === selectedCredentialId);
|
||||
|
||||
return null;
|
||||
if (selectedCredential === undefined) {
|
||||
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotAllowed);
|
||||
}
|
||||
|
||||
++selectedCredential.fido2Key.counter;
|
||||
selectedCredential.localData.lastUsedDate = new Date().getTime();
|
||||
const encrypted = await this.cipherService.encrypt(selectedCredential);
|
||||
await this.cipherService.updateWithServer(encrypted);
|
||||
}
|
||||
|
||||
private async vaultContainsCredentials(
|
||||
|
Loading…
Reference in New Issue
Block a user