Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <info@balazsorban.com> * add eslint disable next line Co-authored-by: Balázs Orbán <info@balazsorban.com>
- Loading branch information
1 parent
cdf467e
commit 3666e43
Showing
4 changed files
with
111 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import type { OAuthConfig, OAuthUserConfig } from "." | ||
|
||
/** | ||
* Source https://docs.github.com/en/rest/users/users#get-the-authenticated-user | ||
*/ | ||
export interface GithubProfile extends Record<string, any> { | ||
login: string | ||
id: number | ||
node_id: string | ||
avatar_url: string | ||
gravatar_id: string | null | ||
url: string | ||
html_url: string | ||
followers_url: string | ||
following_url: string | ||
gists_url: string | ||
starred_url: string | ||
subscriptions_url: string | ||
organizations_url: string | ||
repos_url: string | ||
events_url: string | ||
received_events_url: string | ||
type: string | ||
site_admin: boolean | ||
name: string | null | ||
company: string | null | ||
blog: string | null | ||
location: string | null | ||
email: string | null | ||
hireable: boolean | null | ||
bio: string | null | ||
twitter_username?: string | null | ||
public_repos: number | ||
public_gists: number | ||
followers: number | ||
following: number | ||
created_at: string | ||
updated_at: string | ||
private_gists?: number | ||
total_private_repos?: number | ||
owned_private_repos?: number | ||
disk_usage?: number | ||
suspended_at?: string | null | ||
collaborators?: number | ||
two_factor_authentication: boolean | ||
plan?: { | ||
collaborators: number | ||
name: string | ||
space: number | ||
private_repos: number | ||
} | ||
} | ||
|
||
export interface GithubEmail extends Record<string, any> { | ||
email: string | ||
primary: boolean | ||
verified: boolean | ||
visibility: string | null | ||
} | ||
|
||
export default function Github<P extends GithubProfile>( | ||
options: OAuthUserConfig<P> | ||
): OAuthConfig<P> { | ||
return { | ||
id: "github", | ||
name: "GitHub", | ||
type: "oauth", | ||
authorization: { | ||
url: "https://github.com/login/oauth/authorize", | ||
params: { scope: "read:user+user:email" }, | ||
}, | ||
token: "https://github.com/login/oauth/access_token", | ||
userinfo: { | ||
url: "https://api.github.com/user", | ||
async request({ client, tokens }) { | ||
// Get base profile | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const profile = await client.userinfo(tokens.access_token!) | ||
|
||
// If user has email hidden, get their primary email from the GitHub API | ||
if (!profile.email) { | ||
const emails: GithubEmail[] = await ( | ||
await fetch("https://api.github.com/user/emails", { | ||
headers: { Authorization: `token ${tokens.access_token}` }, | ||
}) | ||
).json() | ||
|
||
if (emails?.length > 0) { | ||
// Get primary email | ||
profile.email = emails.find((email) => email.primary)?.email | ||
// And if for some reason it doesn't exist, just use the first | ||
if (!profile.email) profile.email = emails[0].email | ||
} | ||
} | ||
|
||
return profile | ||
}, | ||
}, | ||
profile(profile) { | ||
return { | ||
id: profile.id.toString(), | ||
name: profile.name ?? profile.login, | ||
email: profile.email, | ||
image: profile.avatar_url, | ||
} | ||
}, | ||
options, | ||
} | ||
} |
3666e43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
next-auth – ./
next-auth-git-main-nextauthjs.vercel.app
next-auth-phi-two.vercel.app
www.next-auth.js.org
next-auth-nextauthjs.vercel.app
next-auth.js.org