maybe
maybe copied to clipboard
DRAFT: Replace Auth
I wanted to provide a draft PR on this to make sure everyone is aligned with the path I'm going down here. Comments, feedback, recommendations all greatly appreciated. This is a big change!
but first, here's a demo showing registration, sign out, and signing back in:
https://github.com/maybe-finance/maybe/assets/1218724/85103c7a-10f2-491d-a1a6-3854f150048c
A lot going on here, here's a quick breakdown:
- Add NextAuth/AuthJS
- Implement email/password register/auth (figured its easiest for self host, can add more providers later)
- Add routes and services for finding existing user by email, creating user
- Add Register and Sign In pages, took best stab at styling using design library (if you have mocks from back in the day I'm happy to match previous styles)
- The newly added Auth models are all prefixed with "Auth" to prevent collisions with existing User and Account models
- Add authId to User model
- Update _app.tsx logic to check for session and redirect to sign in if user doesn't have session
TO-DO:
- Update JWT to match fields that were populated by Auth0
- ~~Update middleware and JWT checks~~
- ~~Create User and associate with AuthUser~~
- ~~Figure out how to kick off onboarding for new users~~
- Continue replacing Auth0 functionality with NextAuth
- ??? Probably a lot more that we'll find as we continue fixing things.
Hopefully this is some decent progress on #16
Amazing. Thanks for the first pass on this, @tmyracle!
Nice work @tmyracle !
credentials provider is discouraged, see https://authjs.dev/getting-started/providers/credentials-tutorial
@Shpigford do you specifically want user/pass logins or would you consider some oAuth options as well? considering the purpose of this app, I think a more secure method would be suitable theres an open PR for native passkey support, I have it running and can help with implementation if you want to go that way
@Shpigford do you specifically want user/pass logins or would you consider some oAuth options as well?
User/email + pass should be the entry point and then in the future we can add other providers if there's demand. No reason to google/apple/facebook/etc at this stage.
Made a little more progress I think? I can at least access some of the app. Had to rework things to place nice with Express since NextAuth expects just a Next.js environment, hence the cookie parsing in the middleware check. Now when registering it is creating the User object in the database automatically and associating it with the AuthUser object that is owned by NextAuth.
Onboarding is back, also fixed a few react warnings/bugs. Video here: https://github.com/maybe-finance/maybe/assets/1218724/b5b0db6b-ced7-48c4-95c5-13e11a553f16
Looks like Auth0 took care of sending email verification so I'll need to go in and create an email and related services to handle sending the email verification and handling updating when user clicks the link in the email. For now I just added a flag to skip adding the email verification step to onboarding.
Next going to remove all use of the Auth0 libraries, server endpoints, and anything else that might be calling Auth0.
Looks like Auth0 took care of sending email verification so I'll need to go in and create an email and related services to handle sending the email verification and handling updating when user clicks the link in the email. For now I just added a flag to skip adding the email verification step to onboarding.
@tmyracle I agree with this move. Let's keep the flag to skip email verification and then we'll address email sending and email verification in a future issue.
@Shpigford do you specifically want user/pass logins or would you consider some oAuth options as well?
User/email + pass should be the entry point and then in the future we can add other providers if there's demand. No reason to google/apple/facebook/etc at this stage.
Part of me would suggest to at least enable google and Microsoft (personal + 365) login support as a lot of home lab users use these services to secure their self-hosted stuff, myself included.
Enabling support for OpenID connect workflows would be enough to make this flexible for everyone and I think this is a must have for a self-hosted app.
@coman3 i 100% planning on supporting it, but it's just outside the scope/purpose of this issue/PR.
AuthJS is very flexible, once in place it can support any provider with a few lines in. Let the man do the ground work and later come and introduce google sign in if you want
This looks awesome! Thanks for all the work on this, y'all.
When I try to run this locally, I get the following error, which makes me think my API service isn't running somehow? Anyone seen this/have an idea how to resolve?
useUserApi.ts:55
GET http://localhost:3333/v1/users/onboarding/main net::ERR_CONNECTION_REFUSED
This looks awesome! Thanks for all the work on this, y'all.
When I try to run this locally, I get the following error, which makes me think my API service isn't running somehow? Anyone seen this/have an idea how to resolve?
useUserApi.ts:55 GET http://localhost:3333/v1/users/onboarding/main net::ERR_CONNECTION_REFUSED
Hmm yeah looks like server might not be running. See anything in the console logs? Can also hit localhost:3333/health and check if you get an ok message back to make sure it's running.
Looks like it's just refusing to connect all together (see screenshot).
When I boot it up, I get
error: uncaughtException: Must provide a clientSecret
ArgumentError: Must provide a clientSecret
So I'm thinking maybe that's it? But that would make it seem like it's still looking at Auth0 for that secret...
I was able to get this working. I just needed NX_AUTH0_MGMT_CLIENT_SECRET
and NX_AUTH0_CLIENT_SECRET
to have a value. And then NX_SESSION_SECRET
and NEXTAUTH_SECRET
needed to be filled out.
🎉
Ok did a bunch of cleanup, should be pretty close to move to ready for review. I decided to remove the admin router for now, I'll leave it up to @Shpigford if he wants to remove the admin functionality or re-write it to work without Auth0 which would involve re-working the roles framework and refactoring how roles are assigned since those are currently owned by the Auth0 pages and sign up flow.
Things out of scope for now, but should be addressed in next PR since this is already massive:
- Update all of the tests, they won't run now since there's a lot of Auth0 mocking
- Use Postmark to add email validation since this was taken care of by Auth0 previously (if we want this added back)
- Revisit admin functionality depending on whether it's a necessary feature for OSS version
Depending on decisions here we can spin up some new issues for folks to tackle some of these items.
Gonna go ahead and make this ready for review @Shpigford. The focus is getting an initial auth replacement implemented and pull out Auth0 and things that depend on it so that we can unblock development for other folks that want to contribute. This effort isn't complete, but I feel like its a good stopping point that achieves the goal stated above and can be built upon with future changes.
Future PRs will address:
- Updating tests and add additional tests for NextAuth/Auth.js for coverage
- Adding in email verification using Postmark (Auth0 handled this previously)
- Add forgot password flow with Postmark as email provider (might look at abstracting this so people can use whatever email provider they want)
- Remove remaining auth0 dependencies in package.json
- Implementing roles (if that's something that is necessary for the open source version of this)
Issues for those changes will be added once this is reviewed and merged 🚀
@tmyracle really great work! after registration, I'm getting an "Unable to load onboarding" error and this in the console:
Error in token validation JWEDecryptionFailed: decryption operation failed
at gcmDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:67:15)
at decrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:92:20)
at flattenedDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js:143:52)
at compactDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js:18:23)
at jwtDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwt/decrypt.js:8:23)
at decode (/Users/joshpigford/Development/maybe/node_modules/next-auth/jwt/index.js:66:7) {
code: 'ERR_JWE_DECRYPTION_FAILED'
}
@tmyracle really great work! after registration, I'm getting an "Unable to load onboarding" error and this in the console:
Error in token validation JWEDecryptionFailed: decryption operation failed at gcmDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:67:15) at decrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:92:20) at flattenedDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js:143:52) at compactDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js:18:23) at jwtDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwt/decrypt.js:8:23) at decode (/Users/joshpigford/Development/maybe/node_modules/next-auth/jwt/index.js:66:7) { code: 'ERR_JWE_DECRYPTION_FAILED' }
Hmm, I'm assuming you have NEXTAUTH_SECRET populated in your .env?
Hmm, I'm assuming you have NEXTAUTH_SECRET populated in your .env?
@tmyracle Doh. Totally missed needing to do that! I'm set. Works great. 🎉
@tmyracle really great work! after registration, I'm getting an "Unable to load onboarding" error and this in the console:
Error in token validation JWEDecryptionFailed: decryption operation failed at gcmDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:67:15) at decrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:92:20) at flattenedDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js:143:52) at compactDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js:18:23) at jwtDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwt/decrypt.js:8:23) at decode (/Users/joshpigford/Development/maybe/node_modules/next-auth/jwt/index.js:66:7) { code: 'ERR_JWE_DECRYPTION_FAILED' }
Hmm, I'm assuming you have NEXTAUTH_SECRET populated in your .env?
Maybe we could include a basic secret as part of the example instead of leaving it empty?
@tmyracle really great work! after registration, I'm getting an "Unable to load onboarding" error and this in the console:
Error in token validation JWEDecryptionFailed: decryption operation failed at gcmDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:67:15) at decrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/runtime/decrypt.js:92:20) at flattenedDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js:143:52) at compactDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js:18:23) at jwtDecrypt (/Users/joshpigford/Development/maybe/node_modules/jose/dist/node/cjs/jwt/decrypt.js:8:23) at decode (/Users/joshpigford/Development/maybe/node_modules/next-auth/jwt/index.js:66:7) { code: 'ERR_JWE_DECRYPTION_FAILED' }
Hmm, I'm assuming you have NEXTAUTH_SECRET populated in your .env?
Maybe we could include a basic secret as part of the example instead of leaving it empty?
Updated the README to add instructions for populating prior to install and run. I don't like leaving placeholder secrets because it's easy for people to not change them and introduce vulnerabilities.
Was able to run locally fine! :D LGTM 🎉
Alrighty, so 3 folks confirmed running it with the new auth. I'm gonna call it. YOLO, etc etc.
AMAZING job on this @tmyracle!