Can't get user data mapped properly

I'm using Generic OAuth to authenticate to Asana. The authentication itself works fine. When I call the Asana endpoint for getUserInfo, it returns this structure:
{
id: undefined,
emailVerified: undefined,
email: undefined,
image: undefined,
name: undefined,
data: {
gid: '159277432863662',
name: 'Phil Seeman'
}
}
{
id: undefined,
emailVerified: undefined,
email: undefined,
image: undefined,
name: undefined,
data: {
gid: '159277432863662',
name: 'Phil Seeman'
}
}
This structure leads to a better-auth error that email can't be null. So I'm assuming that I need to populate the top-level better-auth enail field from the Asana email field that's within its data object. I've tried a number of variations of custom getUserInfo and mapProfileToUser functions but I can't get anything to work to map the data felds to their top-level equivalent fields. Can someone help me with what function(s) I need to make this happen? TIA!!
6 Replies
bekacru
bekacru5mo ago
can you send me your generic oauth config
Phil
PhilOP5mo ago
Sure:
genericOAuth({
config: [
{
providerId: "asana",
clientId: "643xxxxxxxx4856",
clientSecret: "90e98daxxxxxxxxxxxxxxx6ccab2158d",
authorizationUrl: 'https://app.asana.com/-/oauth_authorize',
tokenUrl: 'https://app.asana.com/-/oauth_token',
userInfoUrl: 'https://app.asana.com/api/1.0/users/me',
pkce: true,
// discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
// ... other config options
},
]
}),
genericOAuth({
config: [
{
providerId: "asana",
clientId: "643xxxxxxxx4856",
clientSecret: "90e98daxxxxxxxxxxxxxxx6ccab2158d",
authorizationUrl: 'https://app.asana.com/-/oauth_authorize',
tokenUrl: 'https://app.asana.com/-/oauth_token',
userInfoUrl: 'https://app.asana.com/api/1.0/users/me',
pkce: true,
// discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
// ... other config options
},
]
}),
I've had various bits of code in there for both getUserInfo and mapProfileToUser but nothing has worked.
bekacru
bekacru5mo ago
did you set /callback/asana or /oauth2/callback/asana as redirect uri in the provider? also could you show me how you implemented getUserInfo?
Phil
PhilOP5mo ago
Yes the redirect uri is set and I'm pretty sure that's working because Asana is properly returning the structure I posted above which is accurate for my currently-logged-in Asana user. Well I've tried a lot of different things for getUserInfo - here's one of the simpler ones:
const getUserInfo = async (tokens: OAuth2Tokens): Promise<User | null> => {
const userData = tokens.user; // assuming the data structure is passed in via tokens.user

if (!userData?.data) {
return null;
}

return {
id: userData.data.gid,
emailVerified: userData.data.email,
email: userData.data.email,
name: userData.data.name,
image: userData.data.photo?.image_128x128,
data: userData.data
};
};
const getUserInfo = async (tokens: OAuth2Tokens): Promise<User | null> => {
const userData = tokens.user; // assuming the data structure is passed in via tokens.user

if (!userData?.data) {
return null;
}

return {
id: userData.data.gid,
emailVerified: userData.data.email,
email: userData.data.email,
name: userData.data.name,
image: userData.data.photo?.image_128x128,
data: userData.data
};
};
bekacru
bekacru5mo ago
tokens.user isn't something that's returned. check if token.idToken is returned or fetch the user info using the access token.
Phil
PhilOP5mo ago
Ah Ok, thanks, yeah I should have looked at the actual value of tokens that gets passed into that function. When I don't include any custom getUserInfo function at all, the user data structure I posted above gets returned, so I assumed it was also coming into getUserInfo. But it's not - tokens just contains the actual OAuth token data itself. So like you said, I guess I'll need to fetch the user info inside the function using the token.

Did you find this page helpful?