Skip to content

Commit

Permalink
Ensure WebAuthn redirect matches expected shape (#6987)
Browse files Browse the repository at this point in the history
In our framework helpers, we expect that the UI callback is either
called with a `code` search parameter, or a `verification_email_sent_at`
parameter, otherwise it treats the response as an error.
  • Loading branch information
scotttrinh authored and msullivan committed Mar 7, 2024
1 parent 4c65be2 commit efae5af
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
29 changes: 19 additions & 10 deletions edb/server/protocol/auth_ext/_static/webauthn-authenticate.js
Expand Up @@ -30,20 +30,32 @@ async function onAuthenticateSubmit(form) {
const redirectOnFailure = formData.get("redirect_on_failure");
const redirectTo = formData.get("redirect_to");

if (redirectTo === null) {
throw new Error("Missing redirect_to parameter");
const missingFields = Object.entries({
email,
challenge,
redirectTo,
}).filter(([k, v]) => !v);
if (missingFields.length > 0) {
throw new Error(
"Missing required parameters: " + missingFields.map(([k]) => k).join(", ")
);
}

try {
const maybeCode = await authenticate({
const response = await authenticate({
email,
provider,
challenge,
});

const redirectUrl = new URL(redirectTo);
if (maybeCode !== null) {
redirectUrl.searchParams.append("code", maybeCode);
if ("code" in response) {
redirectUrl.searchParams.append("code", response.code);
} else if ("verification_email_sent_at" in response) {
redirectUrl.searchParams.append(
"verification_email_sent_at",
response.verification_email_sent_at
);
}

window.location.href = redirectUrl.href;
Expand Down Expand Up @@ -72,8 +84,7 @@ const WEBAUTHN_AUTHENTICATE_URL = new URL(
* @param {string} props.email - Email address to register
* @param {string} props.provider - WebAuthn provider
* @param {string} props.challenge - PKCE challenge
* @returns {Promise<string | null>} - The PKCE code or null if the application
* requires email verification
* @returns {Promise<object>} - The server response
*/
export async function authenticate({ email, provider, challenge }) {
// Check if WebAuthn is supported
Expand All @@ -98,13 +109,11 @@ export async function authenticate({ email, provider, challenge }) {
});

// Register the credentials on the server
const registerResult = await authenticateAssertion({
return await authenticateAssertion({
email,
assertion,
challenge,
});

return registerResult.code ?? null;
}

/**
Expand Down
18 changes: 10 additions & 8 deletions edb/server/protocol/auth_ext/_static/webauthn-register.js
Expand Up @@ -45,7 +45,7 @@ export async function onRegisterSubmit(form) {
);
}

const maybeCode = await register({
const response = await register({
email,
provider,
challenge,
Expand All @@ -54,8 +54,13 @@ export async function onRegisterSubmit(form) {

const redirectUrl = new URL(redirectTo);
redirectUrl.searchParams.append("isSignUp", "true");
if (maybeCode !== null) {
redirectUrl.searchParams.append("code", maybeCode);
if ("code" in response) {
redirectUrl.searchParams.append("code", response.code);
} else if ("verification_email_sent_at" in response) {
redirectUrl.searchParams.append(
"verification_email_sent_at",
response.verification_email_sent_at
);
}

window.location.href = redirectUrl.href;
Expand Down Expand Up @@ -83,8 +88,7 @@ const WEBAUTHN_REGISTER_URL = new URL("../webauthn/register", window.location);
* @param {string} props.provider - WebAuthn provider
* @param {string} props.challenge - PKCE challenge
* @param {string} props.verifyUrl - URL to verify email after registration
* @returns {Promise<string | null>} - The PKCE code or null if the application
* requires email verification
* @returns {Promise<object>} - The server response
*/
export async function register({ email, provider, challenge, verifyUrl }) {
// Check if WebAuthn is supported
Expand All @@ -109,15 +113,13 @@ export async function register({ email, provider, challenge, verifyUrl }) {
});

// Register the credentials on the server
const registerResult = await registerCredentials({
return await registerCredentials({
email,
credentials,
provider,
challenge,
verifyUrl,
});

return registerResult.code ?? null;
}

/**
Expand Down

0 comments on commit efae5af

Please sign in to comment.