@biconomy/passkey
Version:
Passkey validator plug in for Biconomy SDK
112 lines • 4.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toWebAuthnKey = exports.encodeWebAuthnPubKey = exports.WebAuthnMode = void 0;
const browser_1 = require("@simplewebauthn/browser");
const viem_1 = require("viem");
const constants_js_1 = require("./constants.js");
const utils_js_1 = require("./utils.js");
var WebAuthnMode;
(function (WebAuthnMode) {
WebAuthnMode["Register"] = "register";
WebAuthnMode["Login"] = "login";
})(WebAuthnMode || (exports.WebAuthnMode = WebAuthnMode = {}));
const encodeWebAuthnPubKey = (pubKey) => {
return (0, viem_1.concatHex)([
(0, viem_1.toHex)(pubKey.pubX, { size: 32 }),
(0, viem_1.toHex)(pubKey.pubY, { size: 32 }),
(0, viem_1.pad)(pubKey.authenticatorIdHash, { size: 32 })
]);
};
exports.encodeWebAuthnPubKey = encodeWebAuthnPubKey;
const toWebAuthnKey = async ({ passkeyName, rpID, webAuthnKey, mode = WebAuthnMode.Register, credentials = "include", passkeyServerHeaders = {} }) => {
if (webAuthnKey) {
return webAuthnKey;
}
let pubKey;
let authenticatorId;
if (mode === WebAuthnMode.Login) {
const loginOptionsResponse = await fetch(`${constants_js_1.DEFAULT_PASSKEY_SERVER_URL}/login/options`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...passkeyServerHeaders
},
body: JSON.stringify({ rpID }),
credentials
});
const loginOptions = await loginOptionsResponse.json();
const loginCred = await (0, browser_1.startAuthentication)(loginOptions);
authenticatorId = loginCred.id;
const loginVerifyResponse = await fetch(`${constants_js_1.DEFAULT_PASSKEY_SERVER_URL}/login/verify`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...passkeyServerHeaders
},
body: JSON.stringify({ cred: loginCred, rpID }),
credentials
});
const loginVerifyResult = await loginVerifyResponse.json();
if (!loginVerifyResult.verification.verified) {
throw new Error("Login not verified");
}
pubKey = loginVerifyResult.pubkey;
}
else {
const registerOptionsResponse = await fetch(`${constants_js_1.DEFAULT_PASSKEY_SERVER_URL}/register/options`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...passkeyServerHeaders
},
body: JSON.stringify({ username: passkeyName, rpID }),
credentials
});
const registerOptions = await registerOptionsResponse.json();
const registerCred = await (0, browser_1.startRegistration)(registerOptions.options);
authenticatorId = registerCred.id;
const registerVerifyResponse = await fetch(`${constants_js_1.DEFAULT_PASSKEY_SERVER_URL}/register/verify`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...passkeyServerHeaders
},
body: JSON.stringify({
userId: registerOptions.userId,
username: passkeyName,
cred: registerCred,
rpID
}),
credentials
});
const registerVerifyResult = await registerVerifyResponse.json();
if (!registerVerifyResult.verified) {
throw new Error("Registration not verified");
}
pubKey = registerCred.response.publicKey;
}
if (!pubKey) {
throw new Error("No public key returned from registration credential");
}
if (!authenticatorId) {
throw new Error("No authenticator id returned from registration credential");
}
const authenticatorIdHash = (0, viem_1.keccak256)((0, utils_js_1.uint8ArrayToHexString)((0, utils_js_1.b64ToBytes)(authenticatorId)));
const spkiDer = Buffer.from(pubKey, "base64");
const key = await crypto.subtle.importKey("spki", spkiDer, {
name: "ECDSA",
namedCurve: "P-256"
}, true, ["verify"]);
const rawKey = await crypto.subtle.exportKey("raw", key);
const rawKeyBuffer = Buffer.from(rawKey);
const pubKeyX = rawKeyBuffer.subarray(1, 33).toString("hex");
const pubKeyY = rawKeyBuffer.subarray(33).toString("hex");
return {
pubX: BigInt(`0x${pubKeyX}`),
pubY: BigInt(`0x${pubKeyY}`),
authenticatorId,
authenticatorIdHash
};
};
exports.toWebAuthnKey = toWebAuthnKey;
//# sourceMappingURL=toWebAuthnKey.js.map