mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-01 23:01:28 +01:00
[EC-598] feat: start working on new Fido2ClientService
This commit is contained in:
parent
e7454501ea
commit
f172625f26
@ -0,0 +1,87 @@
|
|||||||
|
export type UserVerification = "discouraged" | "preferred" | "required";
|
||||||
|
|
||||||
|
export abstract class Fido2ClientService {
|
||||||
|
createCredential: (
|
||||||
|
params: CreateCredentialParams,
|
||||||
|
abortController?: AbortController
|
||||||
|
) => Promise<CreateCredentialResult>;
|
||||||
|
assertCredential: (
|
||||||
|
params: AssertCredentialParams,
|
||||||
|
abortController?: AbortController
|
||||||
|
) => Promise<AssertCredentialResult>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateCredentialParams {
|
||||||
|
origin: string;
|
||||||
|
sameOriginWithAncestors: boolean;
|
||||||
|
attestation?: "direct" | "enterprise" | "indirect" | "none";
|
||||||
|
authenticatorSelection?: {
|
||||||
|
// authenticatorAttachment?: AuthenticatorAttachment; // not used
|
||||||
|
requireResidentKey?: boolean;
|
||||||
|
residentKey?: "discouraged" | "preferred" | "required";
|
||||||
|
userVerification?: UserVerification;
|
||||||
|
};
|
||||||
|
challenge: string; // b64 encoded
|
||||||
|
excludeCredentials?: {
|
||||||
|
id: string; // b64 encoded
|
||||||
|
transports?: ("ble" | "internal" | "nfc" | "usb")[];
|
||||||
|
// type: "public-key"; // not used
|
||||||
|
}[];
|
||||||
|
extensions?: {
|
||||||
|
appid?: string;
|
||||||
|
appidExclude?: string;
|
||||||
|
credProps?: boolean;
|
||||||
|
uvm?: boolean;
|
||||||
|
};
|
||||||
|
pubKeyCredParams: {
|
||||||
|
alg: number;
|
||||||
|
// type: "public-key"; // not used
|
||||||
|
}[];
|
||||||
|
rp: {
|
||||||
|
id?: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
user: {
|
||||||
|
id: string; // b64 encoded
|
||||||
|
displayName: string;
|
||||||
|
};
|
||||||
|
timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateCredentialResult {
|
||||||
|
credentialId: string;
|
||||||
|
clientDataJSON: string;
|
||||||
|
attestationObject: string;
|
||||||
|
authData: string;
|
||||||
|
publicKeyAlgorithm: number;
|
||||||
|
transports: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssertCredentialParams {
|
||||||
|
allowedCredentialIds: string[];
|
||||||
|
rpId: string;
|
||||||
|
origin: string;
|
||||||
|
challenge: string;
|
||||||
|
userVerification?: UserVerification;
|
||||||
|
timeout: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssertCredentialResult {
|
||||||
|
credentialId: string;
|
||||||
|
clientDataJSON: string;
|
||||||
|
authenticatorData: string;
|
||||||
|
signature: string;
|
||||||
|
userHandle: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Fido2Error extends Error {
|
||||||
|
constructor(message: string, readonly fallbackRequested = false) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RequestAbortedError extends Fido2Error {
|
||||||
|
constructor(fallbackRequested = false) {
|
||||||
|
super("Fido2 request was aborted", fallbackRequested);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { CreateCredentialParams } from "../abstractions/fido2-client.service.abstraction";
|
||||||
|
|
||||||
|
import { Fido2AuthenticatorService } from "./fido2-authenticator.service";
|
||||||
|
import { Fido2ClientService } from "./fido2-client.service";
|
||||||
|
|
||||||
|
const RpId = "bitwarden.com";
|
||||||
|
|
||||||
|
describe("FidoAuthenticatorService", () => {
|
||||||
|
let authenticator!: MockProxy<Fido2AuthenticatorService>;
|
||||||
|
let client!: Fido2ClientService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
authenticator = mock<Fido2AuthenticatorService>();
|
||||||
|
client = new Fido2ClientService(authenticator);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("createCredential", () => {
|
||||||
|
describe("invalid input parameters", () => {
|
||||||
|
/** Spec: If sameOriginWithAncestors is false, return a "NotAllowedError" DOMException. */
|
||||||
|
it("throw error if sameOriginWithAncestors is false", async () => {
|
||||||
|
const params = createParams({ sameOriginWithAncestors: false });
|
||||||
|
|
||||||
|
const result = async () => await client.createCredential(params);
|
||||||
|
|
||||||
|
await expect(result).rejects.toThrowError(new DOMException(undefined, "NotAllowedError"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createParams(params: Partial<CreateCredentialParams> = {}): CreateCredentialParams {
|
||||||
|
return {
|
||||||
|
origin: params.origin ?? "bitwarden.com",
|
||||||
|
sameOriginWithAncestors: params.sameOriginWithAncestors ?? true,
|
||||||
|
attestation: params.attestation,
|
||||||
|
authenticatorSelection: params.authenticatorSelection,
|
||||||
|
challenge: params.challenge ?? "MzItYnl0ZXMtYmFzZTY0LWVuY29kZS1jaGFsbGVuZ2U",
|
||||||
|
excludeCredentials: params.excludeCredentials,
|
||||||
|
extensions: params.extensions,
|
||||||
|
pubKeyCredParams: params.pubKeyCredParams ?? [
|
||||||
|
{
|
||||||
|
alg: -7,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rp: params.rp ?? {
|
||||||
|
id: RpId,
|
||||||
|
name: "Bitwarden",
|
||||||
|
},
|
||||||
|
user: params.user ?? {
|
||||||
|
id: "YmFzZTY0LWVuY29kZWQtdXNlci1pZA",
|
||||||
|
displayName: "User Name",
|
||||||
|
},
|
||||||
|
timeout: params.timeout,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
30
libs/common/src/webauthn/services/fido2-client.service.ts
Normal file
30
libs/common/src/webauthn/services/fido2-client.service.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Fido2AuthenticatorService } from "../abstractions/fido2-authenticator.service.abstraction";
|
||||||
|
import {
|
||||||
|
AssertCredentialParams,
|
||||||
|
AssertCredentialResult,
|
||||||
|
CreateCredentialParams,
|
||||||
|
CreateCredentialResult,
|
||||||
|
Fido2ClientService as Fido2ClientServiceAbstraction,
|
||||||
|
} from "../abstractions/fido2-client.service.abstraction";
|
||||||
|
|
||||||
|
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
||||||
|
constructor(private authenticator: Fido2AuthenticatorService) {}
|
||||||
|
|
||||||
|
createCredential(
|
||||||
|
params: CreateCredentialParams,
|
||||||
|
abortController?: AbortController
|
||||||
|
): Promise<CreateCredentialResult> {
|
||||||
|
if (!params.sameOriginWithAncestors) {
|
||||||
|
throw new DOMException(undefined, "NotAllowedError");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertCredential(
|
||||||
|
params: AssertCredentialParams,
|
||||||
|
abortController?: AbortController
|
||||||
|
): Promise<AssertCredentialResult> {
|
||||||
|
throw new Error("Not implemented");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user