mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-01 23:01:28 +01:00
[EC-598] feat: start implementing getAssertion
This commit is contained in:
parent
f9c684695b
commit
6d90489ace
@ -1,10 +1,17 @@
|
|||||||
export abstract class Fido2AuthenticatorService {
|
export abstract class Fido2AuthenticatorService {
|
||||||
/**
|
/**
|
||||||
* This method triggers the generation of a new credential in the authenticator
|
* Create and save a new credential
|
||||||
*
|
*
|
||||||
* @return {Uint8Array} Attestation object
|
* @return {Uint8Array} Attestation object
|
||||||
**/
|
**/
|
||||||
makeCredential: (params: Fido2AuthenticatorMakeCredentialsParams) => Promise<Uint8Array>;
|
makeCredential: (params: Fido2AuthenticatorMakeCredentialsParams) => Promise<Uint8Array>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an assertion using an existing credential
|
||||||
|
*/
|
||||||
|
getAssertion: (
|
||||||
|
params: Fido2AuthenticatorGetAssertionParams
|
||||||
|
) => Promise<Fido2AuthenticatorGetAssertionResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Fido2AlgorithmIdentifier {
|
export enum Fido2AlgorithmIdentifier {
|
||||||
@ -26,6 +33,12 @@ export class Fido2AutenticatorError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PublicKeyCredentialDescriptor {
|
||||||
|
id: BufferSource;
|
||||||
|
transports?: ("ble" | "internal" | "nfc" | "usb")[];
|
||||||
|
type: "public-key";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameters for {@link Fido2AuthenticatorService.makeCredential}
|
* Parameters for {@link Fido2AuthenticatorService.makeCredential}
|
||||||
*
|
*
|
||||||
@ -54,11 +67,7 @@ export interface Fido2AuthenticatorMakeCredentialsParams {
|
|||||||
type: "public-key"; // not used
|
type: "public-key"; // not used
|
||||||
}[];
|
}[];
|
||||||
/** An OPTIONAL list of PublicKeyCredentialDescriptor objects provided by the Relying Party with the intention that, if any of these are known to the authenticator, it SHOULD NOT create a new credential. excludeCredentialDescriptorList contains a list of known credentials. */
|
/** An OPTIONAL list of PublicKeyCredentialDescriptor objects provided by the Relying Party with the intention that, if any of these are known to the authenticator, it SHOULD NOT create a new credential. excludeCredentialDescriptorList contains a list of known credentials. */
|
||||||
excludeCredentialDescriptorList?: {
|
excludeCredentialDescriptorList?: PublicKeyCredentialDescriptor[];
|
||||||
id: BufferSource;
|
|
||||||
transports?: ("ble" | "internal" | "nfc" | "usb")[];
|
|
||||||
type: "public-key"; // not used
|
|
||||||
}[];
|
|
||||||
/** A map from extension identifiers to their authenticator extension inputs, created by the client based on the extensions requested by the Relying Party, if any. */
|
/** A map from extension identifiers to their authenticator extension inputs, created by the client based on the extensions requested by the Relying Party, if any. */
|
||||||
extensions?: {
|
extensions?: {
|
||||||
appid?: string;
|
appid?: string;
|
||||||
@ -72,5 +81,27 @@ export interface Fido2AuthenticatorMakeCredentialsParams {
|
|||||||
requireResidentKey: boolean;
|
requireResidentKey: boolean;
|
||||||
requireUserVerification: boolean;
|
requireUserVerification: boolean;
|
||||||
/** The constant Boolean value true. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a test of user presence optional although WebAuthn does not. */
|
/** The constant Boolean value true. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a test of user presence optional although WebAuthn does not. */
|
||||||
// requireUserPresence: true; // Always performed
|
// requireUserPresence: true; // Always required
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Fido2AuthenticatorGetAssertionParams {
|
||||||
|
/** The caller’s RP ID, as determined by the user agent and the client. */
|
||||||
|
rpId: string;
|
||||||
|
/** The hash of the serialized client data, provided by the client. */
|
||||||
|
hash: BufferSource;
|
||||||
|
allowCredentialDescriptorList: PublicKeyCredentialDescriptor[];
|
||||||
|
/** The effective user verification requirement for assertion, a Boolean value provided by the client. */
|
||||||
|
requireUserVerification: boolean;
|
||||||
|
/** The constant Boolean value true. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a test of user presence optional although WebAuthn does not. */
|
||||||
|
// requireUserPresence: boolean; // Always required
|
||||||
|
extensions: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Fido2AuthenticatorGetAssertionResult {
|
||||||
|
selectedCredential?: {
|
||||||
|
id: string;
|
||||||
|
userHandle: Uint8Array;
|
||||||
|
};
|
||||||
|
authenticatorData: Uint8Array;
|
||||||
|
signature: Uint8Array;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { Login } from "../../vault/models/domain/login";
|
|||||||
import { CipherView } from "../../vault/models/view/cipher.view";
|
import { CipherView } from "../../vault/models/view/cipher.view";
|
||||||
import {
|
import {
|
||||||
Fido2AutenticatorErrorCode,
|
Fido2AutenticatorErrorCode,
|
||||||
|
Fido2AuthenticatorGetAssertionParams,
|
||||||
Fido2AuthenticatorMakeCredentialsParams,
|
Fido2AuthenticatorMakeCredentialsParams,
|
||||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||||
import {
|
import {
|
||||||
@ -35,7 +36,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
authenticator = new Fido2AuthenticatorService(cipherService, userInterface);
|
authenticator = new Fido2AuthenticatorService(cipherService, userInterface);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("authenticatorMakeCredential", () => {
|
describe("makeCredential", () => {
|
||||||
let invalidParams!: InvalidParams;
|
let invalidParams!: InvalidParams;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -68,7 +69,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
* Deviation: User verification is checked before checking for excluded credentials
|
* Deviation: User verification is checked before checking for excluded credentials
|
||||||
* */
|
* */
|
||||||
it("should throw error if requireUserVerification is set to true", async () => {
|
it("should throw error if requireUserVerification is set to true", async () => {
|
||||||
const params = await createCredentialParams({ requireUserVerification: true });
|
const params = await createParams({ requireUserVerification: true });
|
||||||
|
|
||||||
const result = async () => await authenticator.makeCredential(params);
|
const result = async () => await authenticator.makeCredential(params);
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const excludedCipher = createCipher();
|
const excludedCipher = createCipher();
|
||||||
excludedCipherView = await excludedCipher.decrypt();
|
excludedCipherView = await excludedCipher.decrypt();
|
||||||
params = await createCredentialParams({
|
params = await createParams({
|
||||||
excludeCredentialDescriptorList: [
|
excludeCredentialDescriptorList: [
|
||||||
{ id: Fido2Utils.stringToBuffer(excludedCipher.id), type: "public-key" },
|
{ id: Fido2Utils.stringToBuffer(excludedCipher.id), type: "public-key" },
|
||||||
],
|
],
|
||||||
@ -151,7 +152,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
let params: Fido2AuthenticatorMakeCredentialsParams;
|
let params: Fido2AuthenticatorMakeCredentialsParams;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
params = await createCredentialParams({ requireResidentKey: true });
|
params = await createParams({ requireResidentKey: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,7 +238,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
existingCipher.login = new Login();
|
existingCipher.login = new Login();
|
||||||
existingCipher.fido2Key = undefined;
|
existingCipher.fido2Key = undefined;
|
||||||
existingCipherView = await existingCipher.decrypt();
|
existingCipherView = await existingCipher.decrypt();
|
||||||
params = await createCredentialParams();
|
params = await createParams();
|
||||||
cipherService.get.mockImplementation(async (id) =>
|
cipherService.get.mockImplementation(async (id) =>
|
||||||
id === existingCipher.id ? existingCipher : undefined
|
id === existingCipher.id ? existingCipher : undefined
|
||||||
);
|
);
|
||||||
@ -290,7 +291,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
/** Spec: If the user does not consent or if user verification fails, return an error code equivalent to "NotAllowedError" and terminate the operation. */
|
/** Spec: If the user does not consent or if user verification fails, return an error code equivalent to "NotAllowedError" and terminate the operation. */
|
||||||
it("should throw error if user denies creation request", async () => {
|
it("should throw error if user denies creation request", async () => {
|
||||||
userInterface.confirmNewNonDiscoverableCredential.mockResolvedValue(undefined);
|
userInterface.confirmNewNonDiscoverableCredential.mockResolvedValue(undefined);
|
||||||
const params = await createCredentialParams();
|
const params = await createParams();
|
||||||
|
|
||||||
const result = async () => await authenticator.makeCredential(params);
|
const result = async () => await authenticator.makeCredential(params);
|
||||||
|
|
||||||
@ -319,7 +320,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
let params: Fido2AuthenticatorMakeCredentialsParams;
|
let params: Fido2AuthenticatorMakeCredentialsParams;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
params = await createCredentialParams({ requireResidentKey: true });
|
params = await createParams({ requireResidentKey: true });
|
||||||
userInterface.confirmNewCredential.mockResolvedValue(true);
|
userInterface.confirmNewCredential.mockResolvedValue(true);
|
||||||
cipherService.encrypt.mockResolvedValue({} as unknown as Cipher);
|
cipherService.encrypt.mockResolvedValue({} as unknown as Cipher);
|
||||||
cipherService.createWithServer.mockImplementation(async (cipher) => {
|
cipherService.createWithServer.mockImplementation(async (cipher) => {
|
||||||
@ -328,7 +329,7 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only("should throw error if user denies creation request", async () => {
|
it("should throw error if user denies creation request", async () => {
|
||||||
const result = await authenticator.makeCredential(params);
|
const result = await authenticator.makeCredential(params);
|
||||||
|
|
||||||
const attestationObject = CBOR.decode(result.buffer);
|
const attestationObject = CBOR.decode(result.buffer);
|
||||||
@ -360,59 +361,110 @@ describe("FidoAuthenticatorService", () => {
|
|||||||
expect(credentialId).toEqual(cipherIdBytes);
|
expect(credentialId).toEqual(cipherIdBytes);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function createParams(
|
||||||
|
params: Partial<Fido2AuthenticatorMakeCredentialsParams> = {}
|
||||||
|
): Promise<Fido2AuthenticatorMakeCredentialsParams> {
|
||||||
|
return {
|
||||||
|
hash: params.hash ?? (await createClientDataHash()),
|
||||||
|
rpEntity: params.rpEntity ?? {
|
||||||
|
name: "Bitwarden",
|
||||||
|
id: RpId,
|
||||||
|
},
|
||||||
|
userEntity: params.userEntity ?? {
|
||||||
|
id: randomBytes(64),
|
||||||
|
name: "jane.doe@bitwarden.com",
|
||||||
|
displayName: "Jane Doe",
|
||||||
|
icon: " data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAOhJREFUeNpiFI+9E8DAwDAfiAUYSAMfgDiQBVmzlSYnUTqPXf/OANWzngVZ87pKKaIMCGp/BjeEhRjFMKAjx8bQFC2CIs9CpHNxAiYGCsEQM4Cfiwm3AY9f/yZogIcRN4ZahAFv/jAcu4E7xMNtecEYpAakFqsX8me9Yvj07R+G5jR3foaJqWJgOZAaZMAIzAv/kQV05NgZ5hdIMMiKQJIIyEYrDU6wrYkTXjBcefQTvwGwwCoJFGJIBdoMArN3fmToWf+O4SMW14EMeI8rJ8Jcgexn9BwJCoNEaNbEACCN+DSDsjNAgAEAri9Zii/uDMsAAAAASUVORK5CYII=",
|
||||||
|
},
|
||||||
|
credTypesAndPubKeyAlgs: params.credTypesAndPubKeyAlgs ?? [
|
||||||
|
{
|
||||||
|
alg: -7, // ES256
|
||||||
|
type: "public-key",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
excludeCredentialDescriptorList: params.excludeCredentialDescriptorList ?? [
|
||||||
|
{
|
||||||
|
id: randomBytes(16),
|
||||||
|
transports: ["internal"],
|
||||||
|
type: "public-key",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
requireResidentKey: params.requireResidentKey ?? false,
|
||||||
|
requireUserVerification: params.requireUserVerification ?? false,
|
||||||
|
extensions: params.extensions ?? {
|
||||||
|
appid: undefined,
|
||||||
|
appidExclude: undefined,
|
||||||
|
credProps: undefined,
|
||||||
|
uvm: false as boolean,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvalidParams = Awaited<ReturnType<typeof createInvalidParams>>;
|
||||||
|
async function createInvalidParams() {
|
||||||
|
return {
|
||||||
|
unsupportedAlgorithm: await createParams({
|
||||||
|
credTypesAndPubKeyAlgs: [{ alg: 9001, type: "public-key" }],
|
||||||
|
}),
|
||||||
|
invalidRk: await createParams({ requireResidentKey: "invalid-value" as any }),
|
||||||
|
invalidUv: await createParams({
|
||||||
|
requireUserVerification: "invalid-value" as any,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getAssertion", () => {
|
||||||
|
let invalidParams!: InvalidParams;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
invalidParams = await createInvalidParams();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("invalid input parameters", () => {
|
||||||
|
it("should throw error when requireUserVerification has invalid value", async () => {
|
||||||
|
const result = async () => await authenticator.getAssertion(invalidParams.invalidUv);
|
||||||
|
|
||||||
|
await expect(result).rejects.toThrowError(Fido2AutenticatorErrorCode.Unknown);
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Deviation: User verification is checked before checking for credentials */
|
||||||
|
it("should throw error if requireUserVerification is set to true", async () => {
|
||||||
|
const params = await createParams({ requireUserVerification: true });
|
||||||
|
|
||||||
|
const result = async () => await authenticator.getAssertion(params);
|
||||||
|
|
||||||
|
await expect(result).rejects.toThrowError(Fido2AutenticatorErrorCode.Constraint);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function createParams(
|
||||||
|
params: Partial<Fido2AuthenticatorGetAssertionParams> = {}
|
||||||
|
): Promise<Fido2AuthenticatorGetAssertionParams> {
|
||||||
|
return {
|
||||||
|
rpId: params.rpId ?? RpId,
|
||||||
|
hash: params.hash ?? (await createClientDataHash()),
|
||||||
|
allowCredentialDescriptorList: params.allowCredentialDescriptorList ?? [],
|
||||||
|
requireUserVerification: params.requireUserVerification ?? false,
|
||||||
|
extensions: params.extensions ?? {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvalidParams = Awaited<ReturnType<typeof createInvalidParams>>;
|
||||||
|
async function createInvalidParams() {
|
||||||
|
const emptyRpId = await createParams();
|
||||||
|
emptyRpId.rpId = undefined as any;
|
||||||
|
return {
|
||||||
|
emptyRpId,
|
||||||
|
invalidUv: await createParams({
|
||||||
|
requireUserVerification: "invalid-value" as any,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createCredentialParams(
|
|
||||||
params: Partial<Fido2AuthenticatorMakeCredentialsParams> = {}
|
|
||||||
): Promise<Fido2AuthenticatorMakeCredentialsParams> {
|
|
||||||
return {
|
|
||||||
hash: params.hash ?? (await createClientDataHash()),
|
|
||||||
rpEntity: params.rpEntity ?? {
|
|
||||||
name: "Bitwarden",
|
|
||||||
id: RpId,
|
|
||||||
},
|
|
||||||
userEntity: params.userEntity ?? {
|
|
||||||
id: randomBytes(64),
|
|
||||||
name: "jane.doe@bitwarden.com",
|
|
||||||
displayName: "Jane Doe",
|
|
||||||
icon: " data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAOhJREFUeNpiFI+9E8DAwDAfiAUYSAMfgDiQBVmzlSYnUTqPXf/OANWzngVZ87pKKaIMCGp/BjeEhRjFMKAjx8bQFC2CIs9CpHNxAiYGCsEQM4Cfiwm3AY9f/yZogIcRN4ZahAFv/jAcu4E7xMNtecEYpAakFqsX8me9Yvj07R+G5jR3foaJqWJgOZAaZMAIzAv/kQV05NgZ5hdIMMiKQJIIyEYrDU6wrYkTXjBcefQTvwGwwCoJFGJIBdoMArN3fmToWf+O4SMW14EMeI8rJ8Jcgexn9BwJCoNEaNbEACCN+DSDsjNAgAEAri9Zii/uDMsAAAAASUVORK5CYII=",
|
|
||||||
},
|
|
||||||
credTypesAndPubKeyAlgs: params.credTypesAndPubKeyAlgs ?? [
|
|
||||||
{
|
|
||||||
alg: -7, // ES256
|
|
||||||
type: "public-key",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
excludeCredentialDescriptorList: params.excludeCredentialDescriptorList ?? [
|
|
||||||
{
|
|
||||||
id: randomBytes(16),
|
|
||||||
transports: ["internal"],
|
|
||||||
type: "public-key",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
requireResidentKey: params.requireResidentKey ?? false,
|
|
||||||
requireUserVerification: params.requireUserVerification ?? false,
|
|
||||||
extensions: params.extensions ?? {
|
|
||||||
appid: undefined,
|
|
||||||
appidExclude: undefined,
|
|
||||||
credProps: undefined,
|
|
||||||
uvm: false as boolean,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidParams = Awaited<ReturnType<typeof createInvalidParams>>;
|
|
||||||
async function createInvalidParams() {
|
|
||||||
return {
|
|
||||||
unsupportedAlgorithm: await createCredentialParams({
|
|
||||||
credTypesAndPubKeyAlgs: [{ alg: 9001, type: "public-key" }],
|
|
||||||
}),
|
|
||||||
invalidRk: await createCredentialParams({ requireResidentKey: "invalid-value" as any }),
|
|
||||||
invalidUv: await createCredentialParams({ requireUserVerification: "invalid-value" as any }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCipher(data: Partial<Cipher> = {}): Cipher {
|
function createCipher(data: Partial<Cipher> = {}): Cipher {
|
||||||
const cipher = new Cipher();
|
const cipher = new Cipher();
|
||||||
cipher.id = data.id ?? Utils.newGuid();
|
cipher.id = data.id ?? Utils.newGuid();
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
Fido2AlgorithmIdentifier,
|
Fido2AlgorithmIdentifier,
|
||||||
Fido2AutenticatorError,
|
Fido2AutenticatorError,
|
||||||
Fido2AutenticatorErrorCode,
|
Fido2AutenticatorErrorCode,
|
||||||
|
Fido2AuthenticatorGetAssertionParams,
|
||||||
|
Fido2AuthenticatorGetAssertionResult,
|
||||||
Fido2AuthenticatorMakeCredentialsParams,
|
Fido2AuthenticatorMakeCredentialsParams,
|
||||||
Fido2AuthenticatorService as Fido2AuthenticatorServiceAbstraction,
|
Fido2AuthenticatorService as Fido2AuthenticatorServiceAbstraction,
|
||||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||||
@ -31,7 +33,6 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
private userInterface: Fido2UserInterfaceService
|
private userInterface: Fido2UserInterfaceService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async makeCredential(params: Fido2AuthenticatorMakeCredentialsParams): Promise<Uint8Array> {
|
async makeCredential(params: Fido2AuthenticatorMakeCredentialsParams): Promise<Uint8Array> {
|
||||||
if (params.credTypesAndPubKeyAlgs.every((p) => p.alg !== Fido2AlgorithmIdentifier.ES256)) {
|
if (params.credTypesAndPubKeyAlgs.every((p) => p.alg !== Fido2AlgorithmIdentifier.ES256)) {
|
||||||
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotSupported);
|
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotSupported);
|
||||||
@ -134,6 +135,23 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
|
|||||||
return attestationObject;
|
return attestationObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAssertion(
|
||||||
|
params: Fido2AuthenticatorGetAssertionParams
|
||||||
|
): Promise<Fido2AuthenticatorGetAssertionResult> {
|
||||||
|
if (
|
||||||
|
params.requireUserVerification != undefined &&
|
||||||
|
typeof params.requireUserVerification !== "boolean"
|
||||||
|
) {
|
||||||
|
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.requireUserVerification) {
|
||||||
|
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
private async vaultContainsId(ids: string[]): Promise<boolean> {
|
private async vaultContainsId(ids: string[]): Promise<boolean> {
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
if ((await this.cipherService.get(id)) != undefined) {
|
if ((await this.cipherService.get(id)) != undefined) {
|
||||||
|
Loading…
Reference in New Issue
Block a user