Loving Redwood. I’m having a little difficulty getting it running on Netlify though. I’ve got a User table that is 1-1 with Netlify Auth. It should create the User if it’s not in the User table.
The question is, do you have any idea why User isn’t being defined?
@csellis you shared this with me on the Twitters (might have been after you wrote the comment above):
Netlify Auth seems to return the email whereas Auth0 returns the jwt without the email to match the local User. I just need to figure how to get the User
If I understand correctly, this might be the problem/solution:
And, Chris, oh boy oh boy could we use help with Auth0 docs! Would really like to help take what you’ve learned and make it accessible for others – just let me know how I/we can help if and when you’re up for it.
So I went with passing the email through the token even though it’s not ideal. I guess I’m satisficing. I’m just stuck figuring out environment variables on Vercel. They do something funny with runtime versus build time. Thank you all for the help!
Your other options to get the complete user profile are to in a service like userManager.js and use Auth0’s two clients - AuthenticationClient (works on a bearer token and can access that users’ info) and ManagementClient (which is the “admin” client and can access any user).
You’ll have to create a new Machine to Machine client with authorized access to the API Client you have already setup in Auth0 for a ManagementClient to get the client_id and secrets needed.
// api/src/services/userManager/userManager.js
import { AuthenticationClient, ManagementClient } from 'auth0'
const auth0 = new AuthenticationClient({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
})
const management = new ManagementClient({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_MANAGEMENT_CLIENT_ID,
clientSecret: process.env.AUTH0_MANAGEMENT_CLIENT_SECRET,
scope: 'read:users update:users',
})
// fetches the user's profile specified by their accessToken using AuthenticationClient
export const fetchUserProfileByToken = async (token) => {
try {
const auth0User = await auth0.getProfile(token)
return {
email: auth0User.email,
emailVerified: auth0User.email_verified,
name: auth0User.name,
nickname: auth0User.nickname,
picture: auth0User.picture,
userId: auth0User.user_id,
}
} catch (error) {
console.log(error)
throw new Error('Could not fetch profile')
}
}
// fetches any user by their id using the ManagementClient
export const fetchUserProfileByUserId = async (userId) => {
try {
const auth0User = await management.users.get({ id: userId })
return {
email: auth0User.email,
emailVerified: auth0User.email_verified,
lastIp: auth0User.last_ip,
lastLogin: auth0User.last_login,
loginsCount: auth0User.logins_count,
name: auth0User.name,
nickname: auth0User.nickname,
picture: auth0User.picture,
userId: auth0User.user_id,
}
} catch (error) {
console.log(error)
throw new Error('Could not fetch user')
}
}
Note: you do not want to call these per each request – so not a good idea to use them in getCurrentUser but rather on a signup or some profile refresh.
I use them via a rule (on sign in) and a hook (signup) in Auth0 that posts to a function that then updates the profile.