Skip to content

Commit

Permalink
refactor(providers): convert GitHub provider to TypeScript (#4908)
Browse files Browse the repository at this point in the history
* 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
mshd and balazsorban44 committed Jul 13, 2022
1 parent cdf467e commit 3666e43
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 46 deletions.
2 changes: 1 addition & 1 deletion docs/docs/providers/github.md
Expand Up @@ -19,7 +19,7 @@ https://github.com/settings/apps

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion docs/versioned_docs/version-v3/providers/github.md
Expand Up @@ -15,7 +15,7 @@ https://github.com/settings/apps

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

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

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

Expand Down
44 changes: 0 additions & 44 deletions packages/next-auth/src/providers/github.js

This file was deleted.

109 changes: 109 additions & 0 deletions packages/next-auth/src/providers/github.ts
@@ -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,
}
}

1 comment on commit 3666e43

@vercel
Copy link

@vercel vercel bot commented on 3666e43 Jul 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.