Skip to content

Commit 844c9b1

Browse files
blekmuscaidenwilsonbalazsorban44
authored
feat(providers): add Trakt provider (#3771)
* added trakt provider * fixed incorrect auth url * Update src/providers/trakt.ts Co-authored-by: Balázs Orbán <[email protected]> * Update src/providers/trakt.ts Co-authored-by: Balázs Orbán <[email protected]> * Update trakt.ts Co-authored-by: caidenwilson <[email protected]> Co-authored-by: Balázs Orbán <[email protected]>
1 parent c9e16fb commit 844c9b1

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

app/.env.local.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ TWITTER_SECRET=
3333
LINE_ID=
3434
LINE_SECRET=
3535

36+
TRAKT_ID=
37+
TRAKT_SECRET=
38+
3639
# Example configuration for a Gmail account (will need SMTP enabled)
3740
EMAIL_SERVER=smtps://[email protected]:[email protected]:465
3841

app/pages/api/auth/[...nextauth].ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import AzureB2C from "next-auth/providers/azure-ad-b2c"
2828
import OsuProvider from "next-auth/providers/osu"
2929
import AppleProvider from "next-auth/providers/apple"
3030
import PatreonProvider from "next-auth/providers/patreon"
31+
import TraktProvider from "next-auth/providers/trakt"
3132

3233
// import { PrismaAdapter } from "@next-auth/prisma-adapter"
3334
// import { PrismaClient } from "@prisma/client"
@@ -190,6 +191,10 @@ export const authOptions: NextAuthOptions = {
190191
clientId: process.env.PATREON_ID,
191192
clientSecret: process.env.PATREON_SECRET,
192193
}),
194+
TraktProvider({
195+
clientId: process.env.TRAKT_ID,
196+
clientSecret: process.env.TRAKT_SECRET,
197+
}),
193198
],
194199
debug: true,
195200
theme: {

src/providers/trakt.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import type { OAuthConfig, OAuthUserConfig } from "."
2+
3+
export interface TraktUser {
4+
username: string
5+
private: boolean
6+
name: string
7+
vip: boolean
8+
vip_ep: boolean
9+
ids: { slug: string }
10+
joined_at: string
11+
location: string | null
12+
about: string | null
13+
gender: string | null
14+
age: number | null
15+
images: { avatar: { full: string } }
16+
}
17+
18+
export default function Trakt<
19+
P extends Record<string, any> = TraktUser
20+
>(options: OAuthUserConfig<P>): OAuthConfig<P> {
21+
return {
22+
id: "trakt",
23+
name: "Trakt",
24+
type: "oauth",
25+
authorization: {
26+
url: "https://trakt.tv/oauth/authorize",
27+
params: { scope: "" }, // when default, trakt returns auth error
28+
},
29+
token: "https://api.trakt.tv/oauth/token",
30+
31+
userinfo: {
32+
async request(context) {
33+
const res = await fetch("https://api.trakt.tv/users/me?extended=full", {
34+
headers: {
35+
Authorization: `Bearer ${context.tokens.access_token}`,
36+
"trakt-api-version": "2",
37+
"trakt-api-key": context.provider.clientId as string,
38+
},
39+
})
40+
41+
if (res.ok) return await res.json()
42+
43+
throw new Error("Expected 200 OK from the userinfo endpoint")
44+
},
45+
},
46+
profile(profile) {
47+
return {
48+
id: profile.ids.slug,
49+
name: profile.name,
50+
email: null, // trakt does not provide user emails
51+
image: profile.images.avatar.full, // trakt does not allow hotlinking
52+
}
53+
},
54+
options,
55+
}
56+
}

0 commit comments

Comments
 (0)