Skip to content

Commit

Permalink
WebAuthn credentials for alternative authenticatorType e.g. payment, #4
Browse files Browse the repository at this point in the history
…, #15, #19
  • Loading branch information
fabiancook committed Jun 25, 2023
1 parent 2f6bae5 commit 1df5f81
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/data/user-credential/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface UserCredentialData extends Expiring, Record<string, unknown> {
name?: string;
verifiedAt?: string;
authenticatorUserId?: string;
authenticatorType?: string;
authenticatorType?: "credential" | "payment" | string;
authenticatorTransports?: AuthenticatorTransportFuture[];
}

Expand Down
24 changes: 19 additions & 5 deletions src/listen/auth/webauthn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import base64 from "@hexagon/base64";
import fromArrayBuffer = base64.fromArrayBuffer;
import toArrayBuffer = base64.toArrayBuffer;
import {getOrigin} from "../config";
import {v4} from "uuid";

const INVALID_MESSAGE = "Authentication state invalid or expired";

Expand Down Expand Up @@ -165,16 +166,21 @@ export async function getWebAuthnAuthenticationOptions(body: WebAuthnAuthenticat
} = process.env;

const { email, authenticatorType, registration, authentication, redirectUrl } = body;

const existingUser = getMaybeUser();
const existingUserCredentials = existingUser ? await listUserCredentials(existingUser?.userId) : undefined;

const externalId = createUserId();
const reference = await getExternalReference("credential", externalId);
const existingUser = getMaybeUser();

if (reference && existingUser && reference.userId !== existingUser.userId) {
throw new Error("Expected user to be logged in");
}

const userId: string | undefined = existingUser?.userId || reference?.userId;
const credentials = userId ? await listUserCredentials(userId) : []
const credentials = userId ? (
existingUserCredentials ?? await listUserCredentials(userId)
) : []

const registrationPromise = createRegistration();
const authenticationPromise = createAuthentication();
Expand Down Expand Up @@ -241,7 +247,8 @@ export async function getWebAuthnAuthenticationOptions(body: WebAuthnAuthenticat
rpName: WEBAUTHN_RP_NAME || hostname,
rpID: WEBAUTHN_RP_ID || hostname,
userID: userId,
userName: email,
userName: email || userId,
userDisplayName: email || authenticatorType
});

const { stateKey: state } = await setAuthenticationState({
Expand All @@ -260,10 +267,17 @@ export async function getWebAuthnAuthenticationOptions(body: WebAuthnAuthenticat

function createUserId() {
const { hostname } = new URL(getOrigin());
console.log({ hostname });
const hash = createHash("sha256");
hash.update(WEBAUTHN_RP_ID || hostname);
hash.update(email);
if (existingUser) {
hash.update(existingUser.userId);
hash.update(authenticatorType);
} else if (email) {
hash.update(email);
} else {
hash.update(v4());
hash.update(authenticatorType);
}
return hash.digest().toString("hex");
}
}
Expand Down

0 comments on commit 1df5f81

Please sign in to comment.