Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(providers): rewrite github provider in typescript #4908

Merged
merged 5 commits into from Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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!)
Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/nextauthjs/next-auth/runs/7305230206?check_suite_focus=true#step:7:22

This throws as well. I believe it should always be string though, so maybe a // @ts-expect-error is forgivable here. If not, we can change it to throw an error in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


// If user has email hidden, get their primary email from the GitHub API
if (!profile.email) {
const emails: GithubEmail[] = await (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added to the types to the email request too.

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
}
}
Comment on lines +80 to +94
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if this is still needed. But probably somebody added it for a reason.


return profile
},
},
profile(profile) {
return {
id: profile.id.toString(),
name: profile.name ?? profile.login,
email: profile.email,
image: profile.avatar_url,
}
},
options,
}
}