Closed Kostecki closed 1 year ago
Trying to have a look but after registering, I get the following under register:
Thank you for your interest in Untappd’s API. At this time, we are no longer accepting new applications for API access as we work to improve our review and support processes. We do not have a planned date to begin accepting new applications, so please check back soon.
If you have credentials (client id and client secret) to loan, reach out to me on Twitter (or e-mail, etc.) and I can have a closer look.
My suspicion is that although they claim to be OAuth 2 compliant, the https://untappd.com/oauth/authorize endpoint (which should semantically rather be called /token
) does not return a spec-compliant token response. https://www.rfc-editor.org/rfc/rfc6749#section-4.1.4
It puts the access_token
under an object response
for some reason, likely causing the 'access_token not present in TokenSet'
error to be thrown.
I'll go ahead and guess that you can fix it by the following:
@auth/core
:
{
id: "untappd",
name: "Untappd",
type: "oauth",
authorization: "https://untappd.com/oauth/authenticate",
token: {
url: "https://untappd.com/oauth/authorize",
async conform(response) {
if (response.ok) {
const body = await response.clone().json()
if (body?.response?.access_token) {
return new Response(JSON.stringify(body.response), response)
} else if (body?.access_token) {
console.warn("Token response conforms to the standard, workaround not needed.")
}
}
return response
},
},
userinfo: "https://api.untappd.com/v4/user/info?compact=true",
}
next-auth
:
{
id: "untappd",
name: "Untappd",
type: "oauth",
authorization: "https://untappd.com/oauth/authenticate",
token: {
url: "https://untappd.com/oauth/authorize",
async request({ client, params, checks, provider }) {
const tokens = await client.oauthCallback(provider.callbackUrl, params, checks)
if(tokens.response) {
return { tokens: tokens.response }
}
console.warn("Token response conforms to the standard, workaround not needed.")
return { tokens }
},
},
userinfo: "https://api.untappd.com/v4/user/info?compact=true",
}
Assuming you set the redirect URL to http://localhost:3000/api/auth/callback/untappd
, this should hopefully work. Please let me know.
Thanks for contacting me on Twitter. I was able to have a look, here is the final, working config! 🍻:
{
id: "untappd",
name: "Untappd",
type: "oauth",
clientId: process.env.UNTAPPD_ID,
clientSecret: process.env.UNTAPPD_SECRET,
authorization: "https://untappd.com/oauth/authenticate",
token: {
async request({ params, provider }) {
const tokenEndpoint = `https://untappd.com/oauth/authorize?${new URLSearchParams({
...params,
client_id: provider.clientId,
client_secret: provider.clientSecret,
redirect_url: provider.callbackUrl,
})}`
const response = await fetch(tokenEndpoint)
const tokens = await response.json()
return { tokens: tokens.response }
},
},
userinfo: "https://api.untappd.com/v4/user/info",
profile(profile) {
const { user } = profile.response
return {
id: user.id,
name: user.user_name,
email: user.settings.email_address,
image: user.user_avatar_hd,
}
},
},
Proof:
Unfortunately, the token endpoint deviates so much from the spec, that it might be complicated to implement this for @auth/core
, subsequently @auth/nextjs
when that takes next-auth
over, since we are trying to enforce spec-compliance. In this case, the conform
method only is able to correct the code exchange response, but Untappd even assumes the wrong request format.
It requires a GET
request to the authorization endpoint, with client_id
, client_secret
, and redirect_uri
search params, while the spec would expect a POST
request as described here: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3
Assuming next-auth
is good enough for your current use case, I will close this issue for now. Cheers 🍻!
PS.: I reached out to Untappd on Twitter and in an email to hear back if they would be open to adhering to the spec. Will let you know if they answer.
Absolutely amazing. I ended up having to do none of the work and still got all of the rewards! I fully understand your stance on atually adding them as a provider - hopefully they'll get their act together some day 🍻
Description 📓
I have been trying to add Untappd (https://untappd.com/api/docs#authentication) as a provider, but what i figured would be a easy task has gotten me a bit stumped.
Untappd does authentication in the following way:
https://untappd.com/oauth/authenticate/?client_id=CLIENTID&response_type=code&redirect_url=REDIRECT_URL
REDIRECT_URL?code=code
with thecode
parameter.https://untappd.com/oauth/authorize/?client_id=CLIENTID&client_secret=CLIENTSECRET&response_type=code&redirect_url=REDIRECT_URL&code=CODE
which then returns the access_token that you can then use to get user info (and consume the api in general)Doing this whole thing manually in Postman works fine. Calling the
authorize
-endpoint with the code returns the access_token but i'm not quite sure on how to translate that intro a provider.How to reproduce ☕️
Basic provider code like so:
All this does is get the code-paramter and then return
message: 'access_token not present in TokenSet'
Contributing 🙌🏽
Yes, I am willing to help implement this feature in a PR
I wasn't quite sure where to put this as it's sort of a feature request, but also me trying to actually complete the request 🤷♂️