mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-1975] Move FIDO2 files into vault folder (#5496)
* Moved fido2 models to vault in libs * Moved fido2 models to vault in libs * Moved fido2 services and abstractions to vault folder in libs * Moved fido2 popup to vault folder on the browser * Updated import path after moving files to the vault folder * Moved authenticator abstraction and service to the vault folder * Updated content and page script path * Added content script, page script and background messaging to vault * fixed lint issue * Updated reference paths * Added missing fallbacksupported property in test files * Added missing fallbacksupported to the newSession method
This commit is contained in:
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* REMOVE BEFORE MERGE
|
||||
*
|
||||
* This is the old version of our FIDO2 client which was built according to spec.
|
||||
* It left here for reference purposes until we no longer need it.
|
||||
*
|
||||
*/
|
||||
|
||||
// export type UserVerification = "discouraged" | "preferred" | "required";
|
||||
|
||||
// export interface CredentialRegistrationParams {
|
||||
// origin: string;
|
||||
// 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 CredentialRegistrationResult {
|
||||
// credentialId: string;
|
||||
// clientDataJSON: string;
|
||||
// attestationObject: string;
|
||||
// authData: string;
|
||||
// publicKeyAlgorithm: number;
|
||||
// transports: string[];
|
||||
// }
|
||||
|
||||
// export interface CredentialAssertParams {
|
||||
// allowedCredentialIds: string[];
|
||||
// rpId: string;
|
||||
// origin: string;
|
||||
// challenge: string;
|
||||
// userVerification?: UserVerification;
|
||||
// timeout: number;
|
||||
// }
|
||||
|
||||
// export interface CredentialAssertResult {
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class NoCredentialFoundError extends Fido2Error {
|
||||
// constructor() {
|
||||
// super("No valid credential found", true);
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class OriginMismatchError extends Fido2Error {
|
||||
// constructor() {
|
||||
// super(
|
||||
// "Authentication requests must originate from the same source that created the credential.",
|
||||
// false
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// export abstract class Fido2Service {
|
||||
// createCredential: (
|
||||
// params: CredentialRegistrationParams,
|
||||
// abortController?: AbortController
|
||||
// ) => Promise<CredentialRegistrationResult>;
|
||||
// assertCredential: (
|
||||
// params: CredentialAssertParams,
|
||||
// abortController?: AbortController
|
||||
// ) => Promise<CredentialAssertResult>;
|
||||
// }
|
||||
@@ -1,474 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* REMOVE BEFORE MERGE
|
||||
*
|
||||
* This is the old version of our FIDO2 client which was built according to spec.
|
||||
* It left here for reference purposes until we no longer need it.
|
||||
*
|
||||
*/
|
||||
|
||||
// import { CBOR } from "cbor-redux";
|
||||
|
||||
// import { Utils } from "../../misc/utils";
|
||||
// import { CipherService } from "../../vault/abstractions/cipher.service";
|
||||
// import { CipherType } from "../../vault/enums/cipher-type";
|
||||
// import { Cipher } from "../../vault/models/domain/cipher";
|
||||
// import { CipherView } from "../../vault/models/view/cipher.view";
|
||||
// import { Fido2UserInterfaceService } from "../abstractions/fido2-user-interface.service.abstraction";
|
||||
// import { Fido2Utils } from "../abstractions/fido2-utils";
|
||||
// import {
|
||||
// CredentialAssertParams,
|
||||
// CredentialAssertResult,
|
||||
// CredentialRegistrationParams,
|
||||
// CredentialRegistrationResult,
|
||||
// Fido2Service as Fido2ServiceAbstraction,
|
||||
// NoCredentialFoundError,
|
||||
// UserVerification,
|
||||
// } from "../abstractions/fido2.service.abstraction";
|
||||
// import { Fido2KeyView } from "../models/view/fido2-key.view";
|
||||
|
||||
// import { CredentialId } from "./credential-id";
|
||||
// import { joseToDer } from "./ecdsa-utils";
|
||||
|
||||
// // We support self-signing, but Google won't accept it.
|
||||
// // TODO: Look into supporting self-signed packed format.
|
||||
// const STANDARD_ATTESTATION_FORMAT: "none" | "packed" = "none";
|
||||
// const TIMEOUTS = {
|
||||
// NO_VERIFICATION: {
|
||||
// DEFAULT: 120000,
|
||||
// MIN: 30000,
|
||||
// MAX: 180000,
|
||||
// },
|
||||
// WITH_VERIFICATION: {
|
||||
// DEFAULT: 300000,
|
||||
// MIN: 30000,
|
||||
// MAX: 600000,
|
||||
// },
|
||||
// };
|
||||
|
||||
// interface BitCredential {
|
||||
// credentialId: CredentialId;
|
||||
// keyType: "ECDSA";
|
||||
// keyCurve: "P-256";
|
||||
// keyValue: CryptoKey;
|
||||
// rpId: string;
|
||||
// rpName: string;
|
||||
// userHandle: Uint8Array;
|
||||
// userName: string;
|
||||
// origin: string;
|
||||
// }
|
||||
|
||||
// const KeyUsages: KeyUsage[] = ["sign"];
|
||||
|
||||
// export class Fido2Service implements Fido2ServiceAbstraction {
|
||||
// constructor(
|
||||
// private fido2UserInterfaceService: Fido2UserInterfaceService,
|
||||
// private cipherService: CipherService
|
||||
// ) {}
|
||||
|
||||
// async createCredential(
|
||||
// params: CredentialRegistrationParams,
|
||||
// abortController = new AbortController()
|
||||
// ): Promise<CredentialRegistrationResult> {
|
||||
// // Comment: Timeouts could potentially be implemented using decorators.
|
||||
// // But since I try to use decorators a little as possible and only
|
||||
// // for the most generic solutions, I'm gonne leave this as is untill peer review.
|
||||
// const timeout = setAbortTimeout(
|
||||
// abortController,
|
||||
// params.authenticatorSelection.userVerification,
|
||||
// params.timeout
|
||||
// );
|
||||
|
||||
// const presence = await this.fido2UserInterfaceService.confirmNewCredential(
|
||||
// {
|
||||
// credentialName: params.rp.name,
|
||||
// userName: params.user.displayName,
|
||||
// },
|
||||
// abortController
|
||||
// );
|
||||
|
||||
// const attestationFormat = STANDARD_ATTESTATION_FORMAT;
|
||||
// const encoder = new TextEncoder();
|
||||
|
||||
// const clientData = encoder.encode(
|
||||
// JSON.stringify({
|
||||
// type: "webauthn.create",
|
||||
// challenge: params.challenge,
|
||||
// origin: params.origin,
|
||||
// crossOrigin: false,
|
||||
// })
|
||||
// );
|
||||
// const keyPair = await crypto.subtle.generateKey(
|
||||
// {
|
||||
// name: "ECDSA",
|
||||
// namedCurve: "P-256",
|
||||
// },
|
||||
// true,
|
||||
// KeyUsages
|
||||
// );
|
||||
|
||||
// const credentialId = await this.saveCredential({
|
||||
// keyType: "ECDSA",
|
||||
// keyCurve: "P-256",
|
||||
// keyValue: keyPair.privateKey,
|
||||
// origin: params.origin,
|
||||
// rpId: params.rp.id,
|
||||
// rpName: params.rp.name,
|
||||
// userHandle: Fido2Utils.stringToBuffer(params.user.id),
|
||||
// userName: params.user.displayName,
|
||||
// });
|
||||
|
||||
// const authData = await generateAuthData({
|
||||
// rpId: params.rp.id,
|
||||
// credentialId,
|
||||
// userPresence: presence,
|
||||
// userVerification: true, // TODO: Change to false
|
||||
// keyPair,
|
||||
// });
|
||||
|
||||
// const asn1Der_signature = await generateSignature({
|
||||
// authData,
|
||||
// clientData,
|
||||
// privateKey: keyPair.privateKey,
|
||||
// });
|
||||
|
||||
// const attestationObject = new Uint8Array(
|
||||
// CBOR.encode({
|
||||
// fmt: attestationFormat,
|
||||
// attStmt:
|
||||
// attestationFormat === "packed"
|
||||
// ? {
|
||||
// alg: -7,
|
||||
// sig: asn1Der_signature,
|
||||
// }
|
||||
// : {},
|
||||
// authData,
|
||||
// })
|
||||
// );
|
||||
|
||||
// clearTimeout(timeout);
|
||||
|
||||
// return {
|
||||
// credentialId: Fido2Utils.bufferToString(credentialId.raw),
|
||||
// clientDataJSON: Fido2Utils.bufferToString(clientData),
|
||||
// attestationObject: Fido2Utils.bufferToString(attestationObject),
|
||||
// authData: Fido2Utils.bufferToString(authData),
|
||||
// publicKeyAlgorithm: -7,
|
||||
// transports: ["nfc", "usb"],
|
||||
// };
|
||||
// }
|
||||
|
||||
// async assertCredential(
|
||||
// params: CredentialAssertParams,
|
||||
// abortController = new AbortController()
|
||||
// ): Promise<CredentialAssertResult> {
|
||||
// const timeout = setAbortTimeout(abortController, params.userVerification, params.timeout);
|
||||
// let credential: BitCredential | undefined;
|
||||
|
||||
// if (params.allowedCredentialIds && params.allowedCredentialIds.length > 0) {
|
||||
// // We're looking for regular non-resident keys
|
||||
// credential = await this.getCredential(params.allowedCredentialIds);
|
||||
|
||||
// if (credential === undefined) {
|
||||
// throw new NoCredentialFoundError();
|
||||
// }
|
||||
|
||||
// // TODO: Google doesn't work with this. Look into how we're supposed to check this
|
||||
// // if (credential.origin !== params.origin) {
|
||||
// // throw new OriginMismatchError();
|
||||
// // }
|
||||
|
||||
// await this.fido2UserInterfaceService.confirmCredential(
|
||||
// credential.credentialId.encoded,
|
||||
// abortController
|
||||
// );
|
||||
// } else {
|
||||
// // We're looking for a resident key
|
||||
// const credentials = await this.getCredentialsByRp(params.rpId);
|
||||
|
||||
// if (credentials.length === 0) {
|
||||
// throw new NoCredentialFoundError();
|
||||
// }
|
||||
|
||||
// const pickedId = await this.fido2UserInterfaceService.pickCredential(
|
||||
// credentials.map((c) => c.credentialId.encoded),
|
||||
// abortController
|
||||
// );
|
||||
// credential = credentials.find((c) => c.credentialId.encoded === pickedId);
|
||||
// }
|
||||
|
||||
// const encoder = new TextEncoder();
|
||||
// const clientData = encoder.encode(
|
||||
// JSON.stringify({
|
||||
// type: "webauthn.get",
|
||||
// challenge: params.challenge,
|
||||
// origin: params.origin,
|
||||
// })
|
||||
// );
|
||||
|
||||
// const authData = await generateAuthData({
|
||||
// credentialId: credential.credentialId,
|
||||
// rpId: params.rpId,
|
||||
// userPresence: true,
|
||||
// userVerification: true, // TODO: Change to false!
|
||||
// });
|
||||
|
||||
// const signature = await generateSignature({
|
||||
// authData,
|
||||
// clientData,
|
||||
// privateKey: credential.keyValue,
|
||||
// });
|
||||
|
||||
// clearTimeout(timeout);
|
||||
|
||||
// return {
|
||||
// credentialId: credential.credentialId.encoded,
|
||||
// clientDataJSON: Fido2Utils.bufferToString(clientData),
|
||||
// authenticatorData: Fido2Utils.bufferToString(authData),
|
||||
// signature: Fido2Utils.bufferToString(signature),
|
||||
// userHandle: Fido2Utils.bufferToString(credential.userHandle),
|
||||
// };
|
||||
// }
|
||||
|
||||
// private async getCredential(allowedCredentialIds: string[]): Promise<BitCredential | undefined> {
|
||||
// let cipher: Cipher | undefined;
|
||||
// for (const allowedCredential of allowedCredentialIds) {
|
||||
// cipher = await this.cipherService.get(allowedCredential);
|
||||
|
||||
// if (cipher?.deletedDate != undefined) {
|
||||
// cipher = undefined;
|
||||
// }
|
||||
|
||||
// if (cipher != undefined) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (cipher == undefined) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
// const cipherView = await cipher.decrypt();
|
||||
// return await mapCipherViewToBitCredential(cipherView);
|
||||
// }
|
||||
|
||||
// private async saveCredential(
|
||||
// credential: Omit<BitCredential, "credentialId">
|
||||
// ): Promise<CredentialId> {
|
||||
// const pcks8Key = await crypto.subtle.exportKey("pkcs8", credential.keyValue);
|
||||
|
||||
// const view = new CipherView();
|
||||
// view.type = CipherType.Fido2Key;
|
||||
// view.name = credential.rpName;
|
||||
|
||||
// view.fido2Key = new Fido2KeyView();
|
||||
// view.fido2Key.origin = credential.origin;
|
||||
// view.fido2Key.keyType = credential.keyType;
|
||||
// view.fido2Key.keyCurve = credential.keyCurve;
|
||||
// view.fido2Key.keyValue = Fido2Utils.bufferToString(pcks8Key);
|
||||
// view.fido2Key.rpId = credential.rpId;
|
||||
// view.fido2Key.rpName = credential.rpName;
|
||||
// view.fido2Key.userHandle = Fido2Utils.bufferToString(credential.userHandle);
|
||||
// view.fido2Key.userName = credential.userName;
|
||||
// view.fido2Key.origin = credential.origin;
|
||||
|
||||
// const cipher = await this.cipherService.encrypt(view);
|
||||
// await this.cipherService.createWithServer(cipher);
|
||||
|
||||
// // TODO: Cipher service modifies supplied object, we might wanna change that.
|
||||
// return new CredentialId(cipher.id);
|
||||
// }
|
||||
|
||||
// private async getCredentialsByRp(rpId: string): Promise<BitCredential[]> {
|
||||
// const allCipherViews = await this.cipherService.getAllDecrypted();
|
||||
// const cipherViews = allCipherViews.filter(
|
||||
// (cv) => !cv.isDeleted && cv.type === CipherType.Fido2Key && cv.fido2Key?.rpId === rpId
|
||||
// );
|
||||
|
||||
// return await Promise.all(cipherViews.map((view) => mapCipherViewToBitCredential(view)));
|
||||
// }
|
||||
// }
|
||||
|
||||
// interface AuthDataParams {
|
||||
// rpId: string;
|
||||
// credentialId: CredentialId;
|
||||
// userPresence: boolean;
|
||||
// userVerification: boolean;
|
||||
// keyPair?: CryptoKeyPair;
|
||||
// }
|
||||
|
||||
// async function mapCipherViewToBitCredential(cipherView: CipherView): Promise<BitCredential> {
|
||||
// const keyBuffer = Fido2Utils.stringToBuffer(cipherView.fido2Key.keyValue);
|
||||
// const privateKey = await crypto.subtle.importKey(
|
||||
// "pkcs8",
|
||||
// keyBuffer,
|
||||
// {
|
||||
// name: cipherView.fido2Key.keyType,
|
||||
// namedCurve: cipherView.fido2Key.keyCurve,
|
||||
// },
|
||||
// true,
|
||||
// KeyUsages
|
||||
// );
|
||||
|
||||
// return {
|
||||
// credentialId: new CredentialId(cipherView.id),
|
||||
// keyType: cipherView.fido2Key.keyType,
|
||||
// keyCurve: cipherView.fido2Key.keyCurve,
|
||||
// keyValue: privateKey,
|
||||
// rpId: cipherView.fido2Key.rpId,
|
||||
// rpName: cipherView.fido2Key.rpName,
|
||||
// userHandle: Fido2Utils.stringToBuffer(cipherView.fido2Key.userHandle),
|
||||
// userName: cipherView.fido2Key.userName,
|
||||
// origin: cipherView.fido2Key.origin,
|
||||
// };
|
||||
// }
|
||||
|
||||
// async function generateAuthData(params: AuthDataParams) {
|
||||
// const encoder = new TextEncoder();
|
||||
|
||||
// const authData: Array<number> = [];
|
||||
|
||||
// const rpIdHash = new Uint8Array(
|
||||
// await crypto.subtle.digest({ name: "SHA-256" }, encoder.encode(params.rpId))
|
||||
// );
|
||||
// authData.push(...rpIdHash);
|
||||
|
||||
// const flags = authDataFlags({
|
||||
// extensionData: false,
|
||||
// attestationData: params.keyPair !== undefined,
|
||||
// userVerification: params.userVerification,
|
||||
// userPresence: params.userPresence,
|
||||
// });
|
||||
// authData.push(flags);
|
||||
|
||||
// // add 4 bytes of counter - we use time in epoch seconds as monotonic counter
|
||||
// // TODO: Consider changing this to a cryptographically safe random number
|
||||
// const now = new Date().getTime() / 1000;
|
||||
// authData.push(
|
||||
// ((now & 0xff000000) >> 24) & 0xff,
|
||||
// ((now & 0x00ff0000) >> 16) & 0xff,
|
||||
// ((now & 0x0000ff00) >> 8) & 0xff,
|
||||
// now & 0x000000ff
|
||||
// );
|
||||
|
||||
// // attestedCredentialData
|
||||
// const attestedCredentialData: Array<number> = [];
|
||||
|
||||
// // Use 0 because we're self-signing at the moment
|
||||
// const aaguid = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
// attestedCredentialData.push(...aaguid);
|
||||
|
||||
// // credentialIdLength (2 bytes) and credential Id
|
||||
// const rawId = params.credentialId.raw;
|
||||
// const credentialIdLength = [(rawId.length - (rawId.length & 0xff)) / 256, rawId.length & 0xff];
|
||||
// attestedCredentialData.push(...credentialIdLength);
|
||||
// attestedCredentialData.push(...rawId);
|
||||
|
||||
// if (params.keyPair) {
|
||||
// const publicKeyJwk = await crypto.subtle.exportKey("jwk", params.keyPair.publicKey);
|
||||
// // COSE format of the EC256 key
|
||||
// const keyX = Utils.fromUrlB64ToArray(publicKeyJwk.x);
|
||||
// const keyY = Utils.fromUrlB64ToArray(publicKeyJwk.y);
|
||||
|
||||
// // const credPublicKeyCOSE = {
|
||||
// // "1": 2, // kty
|
||||
// // "3": -7, // alg
|
||||
// // "-1": 1, // crv
|
||||
// // "-2": keyX,
|
||||
// // "-3": keyY,
|
||||
// // };
|
||||
// // const coseBytes = new Uint8Array(cbor.encode(credPublicKeyCOSE));
|
||||
|
||||
// // Can't get `cbor-redux` to encode in CTAP2 canonical CBOR. So we do it manually:
|
||||
// const coseBytes = new Uint8Array(77);
|
||||
// coseBytes.set([0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20], 0);
|
||||
// coseBytes.set(keyX, 10);
|
||||
// coseBytes.set([0x22, 0x58, 0x20], 10 + 32);
|
||||
// coseBytes.set(keyY, 10 + 32 + 3);
|
||||
|
||||
// // credential public key - convert to array from CBOR encoded COSE key
|
||||
// attestedCredentialData.push(...coseBytes);
|
||||
|
||||
// authData.push(...attestedCredentialData);
|
||||
// }
|
||||
|
||||
// return new Uint8Array(authData);
|
||||
// }
|
||||
|
||||
// interface SignatureParams {
|
||||
// authData: Uint8Array;
|
||||
// clientData: Uint8Array;
|
||||
// privateKey: CryptoKey;
|
||||
// }
|
||||
|
||||
// async function generateSignature(params: SignatureParams) {
|
||||
// const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, params.clientData);
|
||||
// const sigBase = new Uint8Array([...params.authData, ...new Uint8Array(clientDataHash)]);
|
||||
// const p1336_signature = new Uint8Array(
|
||||
// await window.crypto.subtle.sign(
|
||||
// {
|
||||
// name: "ECDSA",
|
||||
// hash: { name: "SHA-256" },
|
||||
// },
|
||||
// params.privateKey,
|
||||
// sigBase
|
||||
// )
|
||||
// );
|
||||
|
||||
// const asn1Der_signature = joseToDer(p1336_signature, "ES256");
|
||||
|
||||
// return asn1Der_signature;
|
||||
// }
|
||||
|
||||
// interface Flags {
|
||||
// extensionData: boolean;
|
||||
// attestationData: boolean;
|
||||
// userVerification: boolean;
|
||||
// userPresence: boolean;
|
||||
// }
|
||||
|
||||
// function authDataFlags(options: Flags): number {
|
||||
// let flags = 0;
|
||||
|
||||
// if (options.extensionData) {
|
||||
// flags |= 0b1000000;
|
||||
// }
|
||||
|
||||
// if (options.attestationData) {
|
||||
// flags |= 0b01000000;
|
||||
// }
|
||||
|
||||
// if (options.userVerification) {
|
||||
// flags |= 0b00000100;
|
||||
// }
|
||||
|
||||
// if (options.userPresence) {
|
||||
// flags |= 0b00000001;
|
||||
// }
|
||||
|
||||
// return flags;
|
||||
// }
|
||||
|
||||
// function setAbortTimeout(
|
||||
// abortController: AbortController,
|
||||
// userVerification: UserVerification,
|
||||
// timeout?: number
|
||||
// ): number {
|
||||
// let clampedTimeout: number;
|
||||
|
||||
// if (userVerification === "discouraged") {
|
||||
// timeout = timeout ?? TIMEOUTS.NO_VERIFICATION.DEFAULT;
|
||||
// clampedTimeout = Math.max(
|
||||
// TIMEOUTS.NO_VERIFICATION.MIN,
|
||||
// Math.min(timeout, TIMEOUTS.NO_VERIFICATION.MAX)
|
||||
// );
|
||||
// } else {
|
||||
// timeout = timeout ?? TIMEOUTS.WITH_VERIFICATION.DEFAULT;
|
||||
// clampedTimeout = Math.max(
|
||||
// TIMEOUTS.WITH_VERIFICATION.MIN,
|
||||
// Math.min(timeout, TIMEOUTS.WITH_VERIFICATION.MAX)
|
||||
// );
|
||||
// }
|
||||
|
||||
// return window.setTimeout(() => abortController.abort(), clampedTimeout);
|
||||
// }
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Fido2KeyApi } from "../../fido2/models/api/fido2-key.api";
|
||||
import { Fido2KeyApi } from "../../vault/api/fido2-key.api";
|
||||
import { BaseResponse } from "../response/base.response";
|
||||
|
||||
import { LoginUriApi } from "./login-uri.api";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseResponse } from "../../../models/response/base.response";
|
||||
import { BaseResponse } from "../../models/response/base.response";
|
||||
|
||||
export class Fido2KeyApi extends BaseResponse {
|
||||
nonDiscoverableId: string;
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Fido2KeyData } from "../../../fido2/models/data/fido2-key.data";
|
||||
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
|
||||
import { CipherType } from "../../enums/cipher-type";
|
||||
import { CipherResponse } from "../response/cipher.response";
|
||||
|
||||
import { AttachmentData } from "./attachment.data";
|
||||
import { CardData } from "./card.data";
|
||||
import { Fido2KeyData } from "./fido2-key.data";
|
||||
import { FieldData } from "./field.data";
|
||||
import { IdentityData } from "./identity.data";
|
||||
import { LoginData } from "./login.data";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Fido2KeyApi } from "../api/fido2-key.api";
|
||||
import { Fido2KeyApi } from "../../api/fido2-key.api";
|
||||
|
||||
export class Fido2KeyData {
|
||||
nonDiscoverableId: string;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Fido2KeyData } from "../../../fido2/models/data/fido2-key.data";
|
||||
import { LoginApi } from "../../../models/api/login.api";
|
||||
|
||||
import { Fido2KeyData } from "./fido2-key.data";
|
||||
import { LoginUriData } from "./login-uri.data";
|
||||
|
||||
export class LoginData {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { Fido2Key } from "../../../fido2/models/domain/fido2-key";
|
||||
import { Decryptable } from "../../../interfaces/decryptable.interface";
|
||||
import Domain from "../../../models/domain/domain-base";
|
||||
import { EncString } from "../../../models/domain/enc-string";
|
||||
@@ -14,6 +13,7 @@ import { CipherView } from "../view/cipher.view";
|
||||
|
||||
import { Attachment } from "./attachment";
|
||||
import { Card } from "./card";
|
||||
import { Fido2Key } from "./fido2-key";
|
||||
import { Field } from "./field";
|
||||
import { Identity } from "./identity";
|
||||
import { Login } from "./login";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { Fido2Key } from "../../../fido2/models/domain/fido2-key";
|
||||
import Domain from "../../../models/domain/domain-base";
|
||||
import { EncString } from "../../../models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "../../../models/domain/symmetric-crypto-key";
|
||||
import { LoginData } from "../data/login.data";
|
||||
import { LoginView } from "../view/login.view";
|
||||
|
||||
import { Fido2Key } from "./fido2-key";
|
||||
import { LoginUri } from "./login-uri";
|
||||
|
||||
export class Login extends Domain {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Fido2KeyApi } from "../../../fido2/models/api/fido2-key.api";
|
||||
import { CardApi } from "../../../models/api/card.api";
|
||||
import { FieldApi } from "../../../models/api/field.api";
|
||||
import { IdentityApi } from "../../../models/api/identity.api";
|
||||
import { LoginUriApi } from "../../../models/api/login-uri.api";
|
||||
import { LoginApi } from "../../../models/api/login.api";
|
||||
import { SecureNoteApi } from "../../../models/api/secure-note.api";
|
||||
import { Fido2KeyApi } from "../../api/fido2-key.api";
|
||||
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
|
||||
import { CipherType } from "../../enums/cipher-type";
|
||||
import { Cipher } from "../domain/cipher";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Fido2KeyApi } from "../../../fido2/models/api/fido2-key.api";
|
||||
import { CardApi } from "../../../models/api/card.api";
|
||||
import { FieldApi } from "../../../models/api/field.api";
|
||||
import { IdentityApi } from "../../../models/api/identity.api";
|
||||
import { LoginApi } from "../../../models/api/login.api";
|
||||
import { SecureNoteApi } from "../../../models/api/secure-note.api";
|
||||
import { BaseResponse } from "../../../models/response/base.response";
|
||||
import { Fido2KeyApi } from "../../api/fido2-key.api";
|
||||
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
|
||||
|
||||
import { AttachmentResponse } from "./attachment.response";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { LinkedIdType } from "../../../enums";
|
||||
import { Fido2KeyView } from "../../../fido2/models/view/fido2-key.view";
|
||||
import { InitializerMetadata } from "../../../interfaces/initializer-metadata.interface";
|
||||
import { View } from "../../../models/view/view";
|
||||
import { InitializerKey } from "../../../services/cryptography/initializer-key";
|
||||
@@ -12,6 +11,7 @@ import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { AttachmentView } from "./attachment.view";
|
||||
import { CardView } from "./card.view";
|
||||
import { Fido2KeyView } from "./fido2-key.view";
|
||||
import { FieldView } from "./field.view";
|
||||
import { IdentityView } from "./identity.view";
|
||||
import { LoginView } from "./login.view";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { ItemView } from "../../../vault/models/view/item.view";
|
||||
import { ItemView } from "./item.view";
|
||||
|
||||
export class Fido2KeyView extends ItemView {
|
||||
nonDiscoverableId: string;
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
import { LoginLinkedId as LinkedId, UriMatchType } from "../../../enums";
|
||||
import { Fido2KeyView } from "../../../fido2/models/view/fido2-key.view";
|
||||
import { linkedFieldOption } from "../../../misc/linkedFieldOption.decorator";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
import { Login } from "../domain/login";
|
||||
|
||||
import { Fido2KeyView } from "./fido2-key.view";
|
||||
import { ItemView } from "./item.view";
|
||||
import { LoginUriView } from "./login-uri.view";
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import { SearchService } from "../../abstractions/search.service";
|
||||
import { SettingsService } from "../../abstractions/settings.service";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { FieldType, UriMatchType } from "../../enums";
|
||||
import { Fido2Key } from "../../fido2/models/domain/fido2-key";
|
||||
import { sequentialize } from "../../misc/sequentialize";
|
||||
import { Utils } from "../../misc/utils";
|
||||
import Domain from "../../models/domain/domain-base";
|
||||
@@ -22,6 +21,7 @@ import { CipherData } from "../models/data/cipher.data";
|
||||
import { Attachment } from "../models/domain/attachment";
|
||||
import { Card } from "../models/domain/card";
|
||||
import { Cipher } from "../models/domain/cipher";
|
||||
import { Fido2Key } from "../models/domain/fido2-key";
|
||||
import { Field } from "../models/domain/field";
|
||||
import { Identity } from "../models/domain/identity";
|
||||
import { Login } from "../models/domain/login";
|
||||
|
||||
@@ -3,26 +3,26 @@ import { TextEncoder } from "util";
|
||||
import { CBOR } from "cbor-redux";
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { CipherService } from "../../vault/abstractions/cipher.service";
|
||||
import { CipherType } from "../../vault/enums/cipher-type";
|
||||
import { Cipher } from "../../vault/models/domain/cipher";
|
||||
import { CipherView } from "../../vault/models/view/cipher.view";
|
||||
import { LoginView } from "../../vault/models/view/login.view";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
import { CipherService } from "../../abstractions/cipher.service";
|
||||
import {
|
||||
Fido2AutenticatorErrorCode,
|
||||
Fido2AuthenticatorGetAssertionParams,
|
||||
Fido2AuthenticatorMakeCredentialsParams,
|
||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
||||
import {
|
||||
Fido2UserInterfaceService,
|
||||
Fido2UserInterfaceSession,
|
||||
NewCredentialParams,
|
||||
} from "../abstractions/fido2-user-interface.service.abstraction";
|
||||
import { Fido2Utils } from "../abstractions/fido2-utils";
|
||||
import { Fido2KeyView } from "../models/view/fido2-key.view";
|
||||
} from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
||||
import { CipherType } from "../../enums/cipher-type";
|
||||
import { Cipher } from "../../models/domain/cipher";
|
||||
import { CipherView } from "../../models/view/cipher.view";
|
||||
import { Fido2KeyView } from "../../models/view/fido2-key.view";
|
||||
import { LoginView } from "../../models/view/login.view";
|
||||
|
||||
import { AAGUID, Fido2AuthenticatorService } from "./fido2-authenticator.service";
|
||||
import { Fido2Utils } from "./fido2-utils";
|
||||
|
||||
const RpId = "bitwarden.com";
|
||||
|
||||
@@ -573,6 +573,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
],
|
||||
requireResidentKey: params.requireResidentKey ?? false,
|
||||
requireUserVerification: params.requireUserVerification ?? false,
|
||||
fallbackSupported: params.fallbackSupported ?? false,
|
||||
extensions: params.extensions ?? {
|
||||
appid: undefined,
|
||||
appidExclude: undefined,
|
||||
@@ -908,6 +909,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
allowCredentialDescriptorList: params.allowCredentialDescriptorList ?? [],
|
||||
requireUserVerification: params.requireUserVerification ?? false,
|
||||
extensions: params.extensions ?? {},
|
||||
fallbackSupported: params.fallbackSupported ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { CBOR } from "cbor-redux";
|
||||
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { CipherService } from "../../vault/abstractions/cipher.service";
|
||||
import { CipherType } from "../../vault/enums/cipher-type";
|
||||
import { CipherView } from "../../vault/models/view/cipher.view";
|
||||
import { LogService } from "../../../abstractions/log.service";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
import { CipherService } from "../../abstractions/cipher.service";
|
||||
import {
|
||||
Fido2AlgorithmIdentifier,
|
||||
Fido2AutenticatorError,
|
||||
@@ -15,12 +13,14 @@ import {
|
||||
Fido2AuthenticatorMakeCredentialsParams,
|
||||
Fido2AuthenticatorService as Fido2AuthenticatorServiceAbstraction,
|
||||
PublicKeyCredentialDescriptor,
|
||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||
import { Fido2UserInterfaceService } from "../abstractions/fido2-user-interface.service.abstraction";
|
||||
import { Fido2Utils } from "../abstractions/fido2-utils";
|
||||
import { Fido2KeyView } from "../models/view/fido2-key.view";
|
||||
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
||||
import { Fido2UserInterfaceService } from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
||||
import { CipherType } from "../../enums/cipher-type";
|
||||
import { CipherView } from "../../models/view/cipher.view";
|
||||
import { Fido2KeyView } from "../../models/view/fido2-key.view";
|
||||
|
||||
import { joseToDer } from "./ecdsa-utils";
|
||||
import { Fido2Utils } from "./fido2-utils";
|
||||
|
||||
// AAGUID: 6e8248d5-b479-40db-a3d8-11116f7e8349
|
||||
export const AAGUID = new Uint8Array([
|
||||
@@ -1,22 +1,22 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction";
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { ConfigServiceAbstraction } from "../../../abstractions/config/config.service.abstraction";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
import {
|
||||
Fido2AutenticatorError,
|
||||
Fido2AutenticatorErrorCode,
|
||||
Fido2AuthenticatorGetAssertionResult,
|
||||
Fido2AuthenticatorMakeCredentialResult,
|
||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
||||
import {
|
||||
AssertCredentialParams,
|
||||
CreateCredentialParams,
|
||||
FallbackRequestedError,
|
||||
} from "../abstractions/fido2-client.service.abstraction";
|
||||
import { Fido2Utils } from "../abstractions/fido2-utils";
|
||||
} from "../../abstractions/fido2/fido2-client.service.abstraction";
|
||||
|
||||
import { Fido2AuthenticatorService } from "./fido2-authenticator.service";
|
||||
import { Fido2ClientService } from "./fido2-client.service";
|
||||
import { Fido2Utils } from "./fido2-utils";
|
||||
|
||||
const RpId = "bitwarden.com";
|
||||
|
||||
@@ -228,6 +228,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
id: "YmFzZTY0LWVuY29kZWQtdXNlci1pZA",
|
||||
displayName: "User Name",
|
||||
},
|
||||
fallbackSupported: params.fallbackSupported ?? false,
|
||||
timeout: params.timeout,
|
||||
};
|
||||
}
|
||||
@@ -408,13 +409,14 @@ describe("FidoAuthenticatorService", () => {
|
||||
timeout: params.timeout,
|
||||
userVerification: params.userVerification,
|
||||
sameOriginWithAncestors: true,
|
||||
fallbackSupported: params.fallbackSupported ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
function createAuthenticatorAssertResult(): Fido2AuthenticatorGetAssertionResult {
|
||||
return {
|
||||
selectedCredential: {
|
||||
id: Utils.newGuid(),
|
||||
id: randomBytes(32),
|
||||
userHandle: randomBytes(32),
|
||||
},
|
||||
authenticatorData: randomBytes(64),
|
||||
@@ -1,9 +1,9 @@
|
||||
import { parse } from "tldts";
|
||||
|
||||
import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { FeatureFlag } from "../../enums/feature-flag.enum";
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { ConfigServiceAbstraction } from "../../../abstractions/config/config.service.abstraction";
|
||||
import { LogService } from "../../../abstractions/log.service";
|
||||
import { FeatureFlag } from "../../../enums/feature-flag.enum";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
import {
|
||||
Fido2AutenticatorError,
|
||||
Fido2AutenticatorErrorCode,
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
Fido2AuthenticatorMakeCredentialsParams,
|
||||
Fido2AuthenticatorService,
|
||||
PublicKeyCredentialDescriptor,
|
||||
} from "../abstractions/fido2-authenticator.service.abstraction";
|
||||
} from "../../abstractions/fido2/fido2-authenticator.service.abstraction";
|
||||
import {
|
||||
AssertCredentialParams,
|
||||
AssertCredentialResult,
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
PublicKeyCredentialParam,
|
||||
UserRequestedFallbackAbortReason,
|
||||
UserVerification,
|
||||
} from "../abstractions/fido2-client.service.abstraction";
|
||||
import { Fido2Utils } from "../abstractions/fido2-utils";
|
||||
} from "../../abstractions/fido2/fido2-client.service.abstraction";
|
||||
|
||||
import { isValidRpId } from "./domain-utils";
|
||||
import { Fido2Utils } from "./fido2-utils";
|
||||
|
||||
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
||||
constructor(
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { Utils } from "../../../misc/utils";
|
||||
|
||||
export class Fido2Utils {
|
||||
static bufferToString(bufferSource: BufferSource): string {
|
||||
@@ -1,10 +1,13 @@
|
||||
import {
|
||||
Fido2UserInterfaceService as Fido2UserInterfaceServiceAbstraction,
|
||||
Fido2UserInterfaceSession,
|
||||
} from "../abstractions/fido2-user-interface.service.abstraction";
|
||||
} from "../../abstractions/fido2/fido2-user-interface.service.abstraction";
|
||||
|
||||
export class Fido2UserInterfaceService implements Fido2UserInterfaceServiceAbstraction {
|
||||
newSession(abortController?: AbortController): Promise<Fido2UserInterfaceSession> {
|
||||
newSession(
|
||||
fallbackSupported: boolean,
|
||||
abortController?: AbortController
|
||||
): Promise<Fido2UserInterfaceSession> {
|
||||
throw new Error("Not implemented exception");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user