in fido.js [260:326]
authenticatorDataSummary: summarizeAuthenticatorData(authenticatorData),
signCount: authenticatorData.signCount,
authenticatorDataHex: Buffer.from(assertion.authenticatorData, 'base64').toString('hex').toUpperCase(),
extensionDataHex: authenticatorData.extensionDataHex,
clientDataJSONHex: Buffer.from(assertion.clientDataJSON, 'utf8').toString('hex').toUpperCase(),
signatureHex: Buffer.from(assertion.signature, 'base64').toString('hex').toUpperCase(),
userHandleHex: assertion.userHandle ?
Buffer.from(assertion.userHandle, 'base64').toString('hex').toUpperCase() : 'none'
}
}, { new: true });
return updatedCredential;
};
fido.getCredentials = async (uid) => {
const credentials = await storage.Credentials.find({ uid: uid }).lean();
return credentials;
};
fido.deleteCredential = async (uid, id) => {
await storage.Credentials.remove({ uid: uid, id: id });
};
/**
* Validates CollectedClientData
* @param {any} clientData JSON parsed client data object received from client
* @param {string} uid user id (used to validate challenge)
* @param {string} type Operation type: webauthn.create or webauthn.get
*/
const validateClientData = (clientData, uid, type) => {
if (clientData.type !== type)
throw new Error("collectedClientData type was expected to be " + type);
let origin;
try {
origin = url.parse(clientData.origin);
} catch (e) {
throw new Error("Invalid origin in collectedClientData");
}
if (origin.hostname !== hostname)
throw new Error("Invalid origin in collectedClientData. Expected hostname " + hostname);
if (hostname !== "localhost" && origin.protocol !== "https:")
throw new Error("Invalid origin in collectedClientData. Expected HTTPS protocol.");
try {
jwt.verify(base64url.decode(clientData.challenge), jwt_secret, {subject: uid});
} catch (err) {
throw new Error("Invalid challenge in collectedClientData");
}
};
/**
* Parses authData buffer and returns an authenticator data object
* @param {Buffer} authData
* @returns {AuthenticatorData} Parsed AuthenticatorData object
*/
function parseAuthenticatorData(authData) {
try {
const rpIdHash = authData.slice(0, 32);
const flags = authData[32];
const signCount = (authData[33] << 24) | (authData[34] << 16) | (authData[35] << 8) | (authData[36]);
/** @type {AuthenticatorData} */
const authenticatorData = {