Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Login with magic code #1818

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from
Draft

Conversation

Soxasora
Copy link
Member

@Soxasora Soxasora commented Jan 14, 2025

Description

Partially fixes #727
Introduces a 6-character bech32 magic code (token) that expires in 5 minutes and can be used to login with email on PWA, especially iOS since atm there's no way to open a PWA from a link.

On signIn, the email and the callbackUrl will be temporarily saved on sessionStorage

Upon submitting the magic code, it will build and redirect to a magic link (as we are used to) with the user inserted token and email, callbackUrl from sessionStorage

After 3 failed attempts, a custom useVerificationToken will delete email and token from the database, requiring the user to get a new one.

Screenshots

PWA
image

Web
image

email template:
image

error page:
image

Additional Context

afaik in this version of NextAuth we can't send parameters from signIn to /verify-request to /email without risking to be disruptive, thus I had to resort to sessionStorage

Also we can't send the default token AND the new custom token

Changed from 'login as [email protected]' to 'login with [email protected]' to make it independent from context (if login or setting an email); removed any reference to links

Checklist

Are your changes backwards compatible? Please answer below:
Yes, maintains the same behavior as before if on Web with the addition of the email via sessionStorage

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:
7: login, signup, link email, emails
7: token invalidation occurs on success and on 4th failed attempt

For frontend changes: Tested on mobile, light and dark mode? Please answer below:
Yes

Did you introduce any new environment variables? If so, call them out explicitly here:
No

Progress

  • explore better magic code input
  • magic code for non-PWA users
  • check if we can avoid sessionStorage
  • better token invalidation tests
  • avoid isPWA duplicate (pull-to-refresh.js; email.js)
  • expire token/session after 3 failed tries
  • use bech32 as generator
  • Auth, revise token generation
  • UX, better email
  • UX, adjust remaining email templates
  • cleanup

@Soxasora Soxasora marked this pull request as ready for review January 14, 2025 19:27
@Soxasora
Copy link
Member Author

Soxasora commented Jan 14, 2025

We could also enable magic code for non-PWA users, imho it would be handy, token is 6-digits anyway and you can still click the link

@Soxasora Soxasora marked this pull request as draft January 14, 2025 22:46
@Soxasora Soxasora changed the title fix: cannot login with email on PWA Login with magic code Jan 16, 2025
@Soxasora Soxasora marked this pull request as ready for review January 16, 2025 13:32
@ekzyis ekzyis self-requested a review January 18, 2025 15:46
Copy link
Member

@ekzyis ekzyis left a comment

Choose a reason for hiding this comment

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

Turns out I didn't submit this review two days ago 👀

I didn't test yet, only looked at the code. Left some questions.

We could also enable magic code for non-PWA users, imho it would be handy, token is 6-digits anyway and you can still click the link

I think this is the way to go. Less complexity in our code, less confusing for users and would allow to use emails on mobile to login on desktop and vice versa.


useEffect(checkPWA, [])
useEffect(() => {
typeof window !== 'undefined' && setIsPWA(checkPWA(window))
Copy link
Member

Choose a reason for hiding this comment

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

Do you need to check typeof window !== undefined? Do effects not always run on the client?

Copy link
Member Author

@Soxasora Soxasora Jan 20, 2025

Choose a reason for hiding this comment

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

That's what I thought and still believe, I had to include typeof window !== undefined because it seems that the code is being ran before client exposes window or on server while compiling. I might be saying some big bullshit here but that was the error I was getting.

pages/api/auth/[...nextauth].js Outdated Show resolved Hide resolved
Comment on lines +406 to +409
function randomizeToken () {
const words = bech32.toWords(Buffer.from(randomBytes(3)))
return bech32.encode('token', words).slice(6, 12)
}
Copy link
Member

Choose a reason for hiding this comment

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

I need to think more if 24 bits is strong enough even if the link is only valid for 5 mins. Need to do some research how other services deal with the low entropy 🤔

Using bech32 encoding to go from random bytes to guaranteed alphanumeric characters is also an interesting choice. I think I know why you decided to use bech32 but can you elaborate?

Copy link
Member Author

@Soxasora Soxasora Jan 20, 2025

Choose a reason for hiding this comment

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

This is more a product of better safe than sorry. Discussing with @huumn we agreed that bech32 encoding would produce a safer token than a standard 6-digit or even an 8-digit one.

The real reason is the resulting entropy, there are 32 possible characters per every 'digit', 32^6 = 1.073.741.824 (auto calc came in clutch lol).
24-bit or 32-bit entropy will result anyway in 32^6 after slicing!1

Edit:

go from random bytes to guaranteed alphanumeric characters

I realized I didn't address this, it's just one way to randomize the starting seed, we could choose whatever in place of that

Footnotes

  1. if I'm not mistaken

@Soxasora Soxasora marked this pull request as draft January 20, 2025 20:28
@Soxasora Soxasora marked this pull request as ready for review January 22, 2025 14:58
@Soxasora Soxasora marked this pull request as draft January 22, 2025 15:03
@Soxasora
Copy link
Member Author

explore better magic code input

Redrafting to give this full priority to 'complete' the PR as everything else is ready for review

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

Successfully merging this pull request may close these issues.

Cannot login PWA (iOS) with e-mail or Nostr
2 participants