Skip to content

Commit 3666e43

Browse files
mshdbalazsorban44
andauthored
refactor(providers): convert GitHub provider to TypeScript (#4908)
* rewrite github provider in typescript * rename md js endings * Update packages/next-auth/src/providers/github.ts Co-authored-by: Balázs Orbán <[email protected]> * add eslint disable next line Co-authored-by: Balázs Orbán <[email protected]>
1 parent cdf467e commit 3666e43

File tree

4 files changed

+111
-46
lines changed

4 files changed

+111
-46
lines changed

docs/docs/providers/github.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ https://github.com/settings/apps
1919

2020
The **GitHub Provider** comes with a set of default options:
2121

22-
- [GitHub Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/github.js)
22+
- [GitHub Provider options](https://github.com/nextauthjs/next-auth/blob/main/packages/next-auth/src/providers/github.ts)
2323

2424
You can override any of the options to suit your own use case.
2525

docs/versioned_docs/version-v3/providers/github.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ https://github.com/settings/apps
1515

1616
The **Github Provider** comes with a set of default options:
1717

18-
- [Github Provider options](https://github.com/nextauthjs/next-auth/blob/main/src/providers/github.js)
18+
- [Github Provider options](https://github.com/nextauthjs/next-auth/blob/main/src/providers/github.ts)
1919

2020
You can override any of the options to suit your own use case.
2121

packages/next-auth/src/providers/github.js

Lines changed: 0 additions & 44 deletions
This file was deleted.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import type { OAuthConfig, OAuthUserConfig } from "."
2+
3+
/**
4+
* Source https://docs.github.com/en/rest/users/users#get-the-authenticated-user
5+
*/
6+
export interface GithubProfile extends Record<string, any> {
7+
login: string
8+
id: number
9+
node_id: string
10+
avatar_url: string
11+
gravatar_id: string | null
12+
url: string
13+
html_url: string
14+
followers_url: string
15+
following_url: string
16+
gists_url: string
17+
starred_url: string
18+
subscriptions_url: string
19+
organizations_url: string
20+
repos_url: string
21+
events_url: string
22+
received_events_url: string
23+
type: string
24+
site_admin: boolean
25+
name: string | null
26+
company: string | null
27+
blog: string | null
28+
location: string | null
29+
email: string | null
30+
hireable: boolean | null
31+
bio: string | null
32+
twitter_username?: string | null
33+
public_repos: number
34+
public_gists: number
35+
followers: number
36+
following: number
37+
created_at: string
38+
updated_at: string
39+
private_gists?: number
40+
total_private_repos?: number
41+
owned_private_repos?: number
42+
disk_usage?: number
43+
suspended_at?: string | null
44+
collaborators?: number
45+
two_factor_authentication: boolean
46+
plan?: {
47+
collaborators: number
48+
name: string
49+
space: number
50+
private_repos: number
51+
}
52+
}
53+
54+
export interface GithubEmail extends Record<string, any> {
55+
email: string
56+
primary: boolean
57+
verified: boolean
58+
visibility: string | null
59+
}
60+
61+
export default function Github<P extends GithubProfile>(
62+
options: OAuthUserConfig<P>
63+
): OAuthConfig<P> {
64+
return {
65+
id: "github",
66+
name: "GitHub",
67+
type: "oauth",
68+
authorization: {
69+
url: "https://github.com/login/oauth/authorize",
70+
params: { scope: "read:user+user:email" },
71+
},
72+
token: "https://github.com/login/oauth/access_token",
73+
userinfo: {
74+
url: "https://api.github.com/user",
75+
async request({ client, tokens }) {
76+
// Get base profile
77+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
78+
const profile = await client.userinfo(tokens.access_token!)
79+
80+
// If user has email hidden, get their primary email from the GitHub API
81+
if (!profile.email) {
82+
const emails: GithubEmail[] = await (
83+
await fetch("https://api.github.com/user/emails", {
84+
headers: { Authorization: `token ${tokens.access_token}` },
85+
})
86+
).json()
87+
88+
if (emails?.length > 0) {
89+
// Get primary email
90+
profile.email = emails.find((email) => email.primary)?.email
91+
// And if for some reason it doesn't exist, just use the first
92+
if (!profile.email) profile.email = emails[0].email
93+
}
94+
}
95+
96+
return profile
97+
},
98+
},
99+
profile(profile) {
100+
return {
101+
id: profile.id.toString(),
102+
name: profile.name ?? profile.login,
103+
email: profile.email,
104+
image: profile.avatar_url,
105+
}
106+
},
107+
options,
108+
}
109+
}

0 commit comments

Comments
 (0)