| 25 | process.env.NODE_ENV === 'test' |
| 26 | |
| 27 | export class GitHubProvider implements AuthProvider { |
| 28 | getAuthStrategy() { |
| 29 | return new GitHubStrategy( |
| 30 | { |
| 31 | clientID: process.env.GITHUB_CLIENT_ID, |
| 32 | clientSecret: process.env.GITHUB_CLIENT_SECRET, |
| 33 | callbackURL: '/auth/github/callback', |
| 34 | }, |
| 35 | async ({ profile }) => { |
| 36 | const email = profile.emails[0]?.value.trim().toLowerCase() |
| 37 | if (!email) { |
| 38 | throw new Error('Email not found') |
| 39 | } |
| 40 | const username = profile.displayName |
| 41 | const imageUrl = profile.photos[0].value |
| 42 | return { |
| 43 | email, |
| 44 | id: profile.id, |
| 45 | username, |
| 46 | name: profile.name.givenName, |
| 47 | imageUrl, |
| 48 | } |
| 49 | }, |
| 50 | ) |
| 51 | } |
| 52 | |
| 53 | async resolveConnectionData( |
| 54 | providerId: string, |
| 55 | { timings }: { timings?: Timings } = {}, |
| 56 | ) { |
| 57 | const result = await cachified({ |
| 58 | key: `connection-data:github:${providerId}`, |
| 59 | cache, |
| 60 | timings, |
| 61 | ttl: 1000 * 60, |
| 62 | swr: 1000 * 60 * 60 * 24 * 7, |
| 63 | async getFreshValue(context) { |
| 64 | const response = await fetch( |
| 65 | `https://api.github.com/user/${providerId}`, |
| 66 | { headers: { Authorization: `token ${process.env.GITHUB_TOKEN}` } }, |
| 67 | ) |
| 68 | const rawJson = await response.json() |
| 69 | const result = GitHubUserSchema.safeParse(rawJson) |
| 70 | if (!result.success) { |
| 71 | // if it was unsuccessful, then we should kick it out of the cache |
| 72 | // asap and try again. |
| 73 | context.metadata.ttl = 0 |
| 74 | } |
| 75 | return result |
| 76 | }, |
| 77 | checkValue: GitHubUserParseResult, |
| 78 | }) |
| 79 | return { |
| 80 | displayName: result.success ? result.data.login : 'Unknown', |
| 81 | link: result.success ? `https://github.com/${result.data.login}` : null, |
| 82 | } as const |
| 83 | } |
| 84 |
nothing calls this directly
no outgoing calls
no test coverage detected