@0xpass/webauthn-signer
Advanced tools
Comparing version 0.0.2 to 0.0.3
/// <reference lib="dom" /> | ||
import { RegistrationPublicKeyCredential } from "./webauthn"; | ||
import { CredentialCreationOptionsJSON, CredentialRequestOptionsJSON } from "@github/webauthn-json"; | ||
import { AllowCredential, CredentialCreator, CredentialSigner } from "@0xpass/models"; | ||
export type WebAuthnSignerConfig = { | ||
@@ -9,3 +12,3 @@ rpId: string; | ||
}; | ||
export declare class WebauthnSigner { | ||
export declare class WebauthnSigner implements CredentialSigner<PublicKeyCredential, CredentialRequestOptionsJSON>, CredentialCreator<RegistrationPublicKeyCredential, CredentialCreationOptionsJSON> { | ||
rpId: string; | ||
@@ -17,8 +20,10 @@ rpName: string; | ||
constructor(config: WebAuthnSignerConfig); | ||
register(username: string, userId: string): Promise<import("./webauthn").RegistrationPublicKeyCredential>; | ||
sign(payload: string): Promise<{ | ||
signHeaderName: string; | ||
signHeaderValue: string; | ||
getHeaderName(): string; | ||
sign(options: CredentialRequestOptionsJSON): Promise<PublicKeyCredential>; | ||
create(options: CredentialCreationOptionsJSON): Promise<RegistrationPublicKeyCredential>; | ||
getAllowCredentials(): Promise<{ | ||
key: AllowCredential[]; | ||
webauthn: AllowCredential[]; | ||
}>; | ||
} | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,3 +0,2 @@ | ||
import { createResponseToJSON, getResponseToJSON } from '@github/webauthn-json/extended'; | ||
import { Buffer } from 'buffer'; | ||
import { createResponseToJSON, getResponseToJSON, getRequestFromJSON, createRequestFromJSON } from '@github/webauthn-json/extended'; | ||
@@ -18,3 +17,3 @@ async function create(options) { | ||
const signHeaderName = "X-WebAuthn-Signature"; | ||
const defaultTimeout = 5 * 60 * 1000; // five minutes | ||
const DEFAULT_TIMEOUT = 5 * 60 * 1000; // five minutes | ||
const defaultUserVerification = "preferred"; | ||
@@ -25,68 +24,74 @@ class WebauthnSigner { | ||
this.rpName = config.rpName; | ||
this.timeout = config.timeout || defaultTimeout; | ||
this.timeout = config.timeout || DEFAULT_TIMEOUT; | ||
this.userVerification = config.userVerification || defaultUserVerification; | ||
this.allowCredentials = config.allowCredentials || []; | ||
} | ||
async register(username, userId) { | ||
const userHandle = bufferToUint8Array(userId); | ||
const registrationOptions = { | ||
publicKey: { | ||
rp: { | ||
name: this.rpName, | ||
id: this.rpId, | ||
}, | ||
user: { | ||
id: userHandle, | ||
name: username, | ||
displayName: username, | ||
}, | ||
pubKeyCredParams: [ | ||
{ | ||
type: "public-key", | ||
alg: -7, | ||
}, | ||
], | ||
challenge: await getChallengeFromPayload(username), | ||
}, | ||
}; | ||
const credential = await create(registrationOptions); | ||
return credential; | ||
getHeaderName() { | ||
return signHeaderName; | ||
} | ||
async sign(payload) { | ||
const challenge = await getChallengeFromPayload(payload); | ||
const signingOptions = { | ||
publicKey: { | ||
rpId: this.rpId, | ||
challenge: challenge, | ||
allowCredentials: this.allowCredentials, | ||
timeout: this.timeout, | ||
userVerification: this.userVerification, | ||
}, | ||
}; | ||
const clientGetResult = await get(signingOptions); | ||
const assertion = clientGetResult.toJSON(); | ||
const sign = { | ||
authenticatorData: assertion.response.authenticatorData, | ||
clientDataJson: assertion.response.clientDataJSON, | ||
credentialId: assertion.id, | ||
signature: assertion.response.signature, | ||
}; | ||
async sign(options) { | ||
if (!hasWebAuthnSupport()) { | ||
throw new Error("WebAuthn is not supported by this browser."); | ||
} | ||
try { | ||
const requestOptions = getRequestFromJSON(options); | ||
return await get(requestOptions); | ||
} | ||
catch (error) { | ||
console.error("Error parsing options or singing with WebAuthn credential:", error); | ||
throw error; | ||
} | ||
} | ||
async create(options) { | ||
if (!hasWebAuthnSupport()) { | ||
throw new Error("WebAuthn is not supported by this browser."); | ||
} | ||
try { | ||
const creationOptions = createRequestFromJSON(options); | ||
return await create(creationOptions); | ||
} | ||
catch (error) { | ||
console.error("Error parsing options or creating WebAuthn credential:", error); | ||
throw error; | ||
} | ||
} | ||
// async sign(payload: CredentialCreationOptionsJSON) { | ||
// const challenge = await getChallengeFromPayload(payload); | ||
// const signingOptions: CredentialRequestOptions = { | ||
// publicKey: { | ||
// rpId: this.rpId, | ||
// challenge: challenge, | ||
// allowCredentials: this.allowCredentials, | ||
// timeout: this.timeout, | ||
// userVerification: this.userVerification, | ||
// }, | ||
// }; | ||
// const clientGetResult = await webauthnCredentialGet(signingOptions); | ||
// const assertion = clientGetResult.toJSON(); | ||
// const sign = { | ||
// authenticatorData: assertion.response.authenticatorData, | ||
// clientDataJson: assertion.response.clientDataJSON, | ||
// credentialId: assertion.id, | ||
// signature: assertion.response.signature, | ||
// }; | ||
// return { | ||
// signHeaderName: signHeaderName, | ||
// signHeaderValue: JSON.stringify(sign), | ||
// }; | ||
// } | ||
async getAllowCredentials() { | ||
return { | ||
signHeaderName: signHeaderName, | ||
signHeaderValue: JSON.stringify(sign), | ||
key: [], | ||
webauthn: [], | ||
}; | ||
} | ||
} | ||
function bufferToUint8Array(buffer) { | ||
return new TextEncoder().encode(buffer); | ||
// `hasWebAuthnSupport` checks for barebones webauthn support. | ||
// For additional details and granular settings, see: | ||
// https://web.dev/articles/passkey-form-autofill#feature-detection, https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential | ||
function hasWebAuthnSupport() { | ||
return !!window.PublicKeyCredential; | ||
} | ||
async function getChallengeFromPayload(payload) { | ||
const messageBuffer = new TextEncoder().encode(payload); | ||
const hashBuffer = await crypto.subtle.digest("SHA-256", messageBuffer); | ||
const hexString = Buffer.from(hashBuffer).toString("hex"); | ||
const hexBuffer = Buffer.from(hexString, "utf8"); | ||
return new Uint8Array(hexBuffer); | ||
} | ||
export { WebauthnSigner }; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@0xpass/webauthn-signer", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"main": "dist/index.js", | ||
@@ -15,3 +15,4 @@ "types": "dist/index.d.ts", | ||
"@github/webauthn-json": "^2.1.1", | ||
"buffer": "^6.0.3" | ||
"buffer": "^6.0.3", | ||
"@0xpass/models": "0.0.2" | ||
}, | ||
@@ -37,2 +38,3 @@ "devDependencies": { | ||
"compile": "rollup --config rollup.config.js", | ||
"dev": "rollup --config rollup.config.js --watch", | ||
"test": "vitest", | ||
@@ -39,0 +41,0 @@ "test:run": "vitest run" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
9335
133
3
+ Added@0xpass/models@0.0.2
+ Added@0xpass/models@0.0.2(transitive)