Skip to content

Commit

Permalink
tweaks, refactoring, fixing some missing bits
Browse files Browse the repository at this point in the history
  • Loading branch information
getify committed Mar 13, 2024
1 parent a306697 commit bb1c6bc
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 56 deletions.
52 changes: 28 additions & 24 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,11 @@ async function register(regOptions = regDefaults()) {
try {
if (supportsWebAuthn) {
// ensure credential IDs are binary (not base64 string)
if (Array.isArray(regOptions[regOptions[credentialTypeKey]].excludeCredentials)) {
regOptions[regOptions[credentialTypeKey]].excludeCredentials = (
regOptions[regOptions[credentialTypeKey]].excludeCredentials.map(entry => ({
...entry,
id: (
typeof entry.id == "string" ?
sodium.from_base64(entry.id,sodium.base64_variants.ORIGINAL) :
entry.id
),
}))
);
}
regOptions[regOptions[credentialTypeKey]].excludeCredentials = (
normalizeCredentialsList(
regOptions[regOptions[credentialTypeKey]].excludeCredentials
)
);

let regResult = await navigator.credentials.create(regOptions);

Expand Down Expand Up @@ -238,6 +231,9 @@ function regDefaults({
relyingPartyName = "wacg",
attestation = "none",
challenge = sodium.randombytes_buf(20),
excludeCredentials = [
// { type: "public-key", id: ..., }
],
user: {
name: userName = "wacg-user",
displayName: userDisplayName = userName,
Expand Down Expand Up @@ -277,6 +273,8 @@ function regDefaults({

challenge,

excludeCredentials,

pubKeyCredParams: publicKeyCredentialParams,

...otherPubKeyOptions,
Expand All @@ -302,18 +300,11 @@ async function auth(authOptions = authDefaults()) {
try {
if (supportsWebAuthn) {
// ensure credential IDs are binary (not base64 string)
if (Array.isArray(authOptions[authOptions[credentialTypeKey]].allowCredentials)) {
authOptions[authOptions[credentialTypeKey]].allowCredentials = (
authOptions[authOptions[credentialTypeKey]].allowCredentials.map(entry => ({
...entry,
id: (
typeof entry.id == "string" ?
sodium.from_base64(entry.id,sodium.base64_variants.ORIGINAL) :
entry.id
),
}))
);
}
authOptions[authOptions[credentialTypeKey]].allowCredentials = (
normalizeCredentialsList(
authOptions[authOptions[credentialTypeKey]].allowCredentials
)
);

let authResult = await navigator.credentials.get(authOptions);
let authClientDataRaw = new Uint8Array(authResult.response.clientDataJSON);
Expand Down Expand Up @@ -663,3 +654,16 @@ function unpackPublicKeyJSON(publicKeyEntryJSON) {
),
};
}

function normalizeCredentialsList(credList) {
if (Array.isArray(credList)) {
return credList.map(entry => ({
...entry,
id: (
typeof entry.id == "string" ?
sodium.from_base64(entry.id,sodium.base64_variants.ORIGINAL) :
entry.id
),
}));
}
}
59 changes: 27 additions & 32 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,12 @@ async function registerNewCredential(name,userIDStr) {
displayName: name,
id: userID,
},
excludeCredentials: credentialsByID[userIDStr]?.map(({ credentialID }) => ({
type: "public-key",
id: credentialID,
})) ?? [],
excludeCredentials: (
(credentialsByID[userIDStr] || []).map(({ credentialID }) => ({
type: "public-key",
id: credentialID,
}))
),
});
try {
let regResult = await register(regOptions);
Expand All @@ -170,20 +172,13 @@ async function registerNewCredential(name,userIDStr) {

// keep registered credential info in memory only
// (no persistence)
if (userIDStr in credentialsByID) {
credentialsByID[userIDStr] = [
...credentialsByID[userIDStr],
{
credentialID: regResult.response.credentialID,
publicKey: regResult.response.publicKey,
}
];
} else {
credentialsByID[userIDStr] = [{
credentialsByID[userIDStr] = [
...(credentialsByID[userIDStr] || []),
{
credentialID: regResult.response.credentialID,
publicKey: regResult.response.publicKey,
}]
}
}
];

console.log("regResult:",regResult);
}
Expand All @@ -192,13 +187,12 @@ async function registerNewCredential(name,userIDStr) {
logError(err);

if (err.cause instanceof Error) {
var errorString = err.cause.toString();
if (errorString.includes("credentials already registered with the relying party")) {
showError(`
let errorString = err.cause.toString();
if (errorString.includes("credentials already registered")) {
return showError(`
A credential already exists for this User ID.
Please try a different User ID or pick a different authenticator.
`);
return
}
}

Expand Down Expand Up @@ -304,10 +298,12 @@ async function promptProvideAuth() {

cancelToken = new AbortController();
var authOptions = authDefaults({
allowCredentials: credentialsByID[userID].map(({ credentialID }) => ({
type: "public-key",
id: credentialID,
})),
allowCredentials: (
(credentialsByID[userID] || []).map(({ credentialID }) => ({
type: "public-key",
id: credentialID,
}))
),
signal: cancelToken.signal,
});
try {
Expand Down Expand Up @@ -382,16 +378,15 @@ async function promptPickAuth() {

async function onAuth(credentialID,publicKey) {
try {
let allowCredentials = [
...(
credentialID != null ?
[ { type: "public-key", id: credentialID, }, ] :
[]
),
];
let authOptions = authDefaults({
mediation: "optional",
allowCredentials,
allowCredentials: [
...(
credentialID != null ?
[ { type: "public-key", id: credentialID, }, ] :
[]
),
],
});
let authResult = await auth(authOptions);

Expand Down

0 comments on commit bb1c6bc

Please sign in to comment.