Skip to content

feat: preserve afterLoginHref / redir in emailStart and emailVerify - #13

Merged
treeder merged 1 commit into
mainfrom
feat/email-redirect
Sep 22, 2026
Merged

treeder merged 1 commit into
mainfrom
feat/email-redirect

Conversation

@treeder

@treeder treeder commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Preserves afterLoginHref / redir / redirect in email verification flow so users are redirected back to the referring page after signing in.

@treeder
treeder merged commit efe2a59 into main Sep 22, 2026
3 of 4 checks passed
@treeder
treeder deleted the feat/email-redirect branch September 22, 2026 05:18

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review Summary

This PR adds support for custom post-verification redirect URLs in emailStart and emailVerify, allowing redirects via afterLoginHref, redir, or redirect parameters. It also adds a comprehensive unit test verifying that afterLoginHref is preserved across the email verification flow.

🔍 General Feedback

  • The inclusion of Test 8 in test/test_passkeys_multi.js provides good test coverage for the new redirect parameter flow across emailStart and emailVerify.
  • Be mindful of Open Redirect risks when reading arbitrary redirect targets from query parameters or unvalidated user input.
📊 Token Usage & Cost Efficiency
Metric Value
Input Tokens (uncached) 3,686
Input Tokens (cached) 27,574 (⚡ 88.2% cached)
Output Tokens 361
Total Session Tokens 31,621
Cost (uncached input) $0.0028
Cost (cached input) $0.0021
Cost (output) $0.0014
Estimated Total Cost $0.0062

Gemini 3.8 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.8 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.

Comment thread src/passkeys.js
Comment on lines +121 to +129
let url =
searchParams.get('redir') ||
searchParams.get('redirect') ||
searchParams.get('afterLoginHref') ||
rr.afterLoginHref ||
rr.redir ||
rr.redirect ||
this.opts.afterEmailVerifyURL ||
`${hostURL(c)}/signin`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Accepting unvalidated target URLs directly from request parameters (searchParams.get('redir'), searchParams.get('redirect'), or searchParams.get('afterLoginHref')) can introduce an Open Redirect vulnerability. If an attacker constructs an email verification link targeting an external malicious site (e.g., https://malicious.example.com or //malicious.example.com), victims completing email verification could be redirected to an untrusted destination. Consider validating that the target redirect URL is a relative path or matches expected origin/host boundaries before setting the Location header.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant