mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-31 22:51: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