{"version":3,"sources":["../../../src/oauth2/provider/github.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { OAuth2Token, Provider } from '../types';\nimport { createAuthorizationUri, exchangeAuthorizationCode } from './common';\n\nexport function createGithubProvider(): Provider {\n  return {\n    authorizationUri: 'https://github.com/login/oauth/authorize',\n    tokenUri: 'https://github.com/login/oauth/access_token',\n    userInfoUri: 'https://api.github.com/user',\n    userNameAttribute: 'id',\n    defaultScope: ['user:email'],\n    createAuthorizationUri({ pkce: _, ...params }) {\n      return createAuthorizationUri({\n        ...params,\n        scope: params.scope ?? this.defaultScope,\n        authorizationUri: this.authorizationUri,\n      });\n    },\n    async exchangeAuthorizationCode({ pkce: _, ...params }) {\n      const response = await exchangeAuthorizationCode({ ...params, tokenUri: this.tokenUri });\n      if (!response.ok) {\n        const { error, error_description } = (await response.json()) as GithubErrorResponse;\n        throw new OAuth2Error(response.status, error, error_description);\n      }\n      return (await response.json()) as GithubToken;\n    },\n    async getUserInfo({ access_token }) {\n      invariant(access_token, 'access_token is required');\n      invariant(this.userInfoUri, 'userInfoUri is required');\n      const headers = { Accept: 'application/json', Authorization: `Bearer ${access_token}` };\n      const response = await fetch(this.userInfoUri, { headers });\n      if (!response.ok) {\n        throw new OAuth2Error(response.status, 'invalid_request', 'Failed to fetch user info');\n      }\n      const data = (await response.json()) as GithubUserInfo;\n      const emailResponse = await fetch('https://api.github.com/user/emails', { headers });\n      if (!emailResponse.ok) {\n        throw new OAuth2Error(\n          emailResponse.status,\n          'invalid_request',\n          'Failed to fetch user email'\n        );\n      }\n      const emails = (await emailResponse.json()) as GithubEmail[];\n      data.email = emails.find((email) => email.primary)?.email || data.email;\n      const email_verified = emails.find((email) => email.email === data.email)?.verified || false;\n      return {\n        data,\n        claims: {\n          sub: data.id,\n          name: data.name || data.login,\n          email_verified,\n          email: data.email,\n          picture: data.avatar_url,\n          profile: data.html_url,\n          website: data.html_url,\n          updated_at: data.updated_at ? Date.parse(data.updated_at) : undefined,\n        },\n      };\n    },\n  };\n}\n\nexport const github = createGithubProvider();\n\nexport interface GithubUserInfo {\n  login: string;\n  id: string;\n  node_id: string;\n  avatar_url: string;\n  gravatar_id: string;\n  url: string;\n  html_url: string;\n  followers_url: string;\n  following_url: string;\n  gists_url: string;\n  starred_url: string;\n  subscriptions_url: string;\n  organizations_url: string;\n  repos_url: string;\n  events_url: string;\n  received_events_url: string;\n  type: string;\n  site_admin: boolean;\n  name: string;\n  company: string;\n  blog: string;\n  location: string;\n  email: string;\n  hireable: boolean;\n  bio: string;\n  twitter_username: string;\n  public_repos: string;\n  public_gists: string;\n  followers: string;\n  following: string;\n  created_at: string;\n  updated_at: string;\n  private_gists: string;\n  total_private_repos: string;\n  owned_private_repos: string;\n  disk_usage: string;\n  collaborators: string;\n  two_factor_authentication: boolean;\n  plan: {\n    name: string;\n    space: string;\n    private_repos: string;\n    collaborators: string;\n  };\n}\n\ninterface GithubEmail {\n  email: string;\n  primary: boolean;\n  verified: boolean;\n  visibility: 'public' | 'private';\n}\n\nexport interface GithubToken extends OAuth2Token {\n  access_token: string;\n  token_type: string;\n  scope: string;\n  expires_in: number;\n  refresh_token: string;\n}\n\ninterface GithubErrorResponse {\n  error: string;\n  error_description: string;\n  error_uri: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAC1B,mBAA4B;AAE5B,oBAAkE;AAE3D,SAAS,uBAAiC;AAC/C,SAAO;AAAA,IACL,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,cAAc,CAAC,YAAY;AAAA,IAC3B,uBAAuB,EAAE,MAAM,GAAG,GAAG,OAAO,GAAG;AAC7C,iBAAO,sCAAuB;AAAA,QAC5B,GAAG;AAAA,QACH,OAAO,OAAO,SAAS,KAAK;AAAA,QAC5B,kBAAkB,KAAK;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,IACA,MAAM,0BAA0B,EAAE,MAAM,GAAG,GAAG,OAAO,GAAG;AACtD,YAAM,WAAW,UAAM,yCAA0B,EAAE,GAAG,QAAQ,UAAU,KAAK,SAAS,CAAC;AACvF,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,kBAAkB,IAAK,MAAM,SAAS,KAAK;AAC1D,cAAM,IAAI,yBAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,EAAE,aAAa,GAAG;AAClC,kCAAU,cAAc,0BAA0B;AAClD,kCAAU,KAAK,aAAa,yBAAyB;AACrD,YAAM,UAAU,EAAE,QAAQ,oBAAoB,eAAe,UAAU,YAAY,GAAG;AACtF,YAAM,WAAW,MAAM,MAAM,KAAK,aAAa,EAAE,QAAQ,CAAC;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,yBAAY,SAAS,QAAQ,mBAAmB,2BAA2B;AAAA,MACvF;AACA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,gBAAgB,MAAM,MAAM,sCAAsC,EAAE,QAAQ,CAAC;AACnF,UAAI,CAAC,cAAc,IAAI;AACrB,cAAM,IAAI;AAAA,UACR,cAAc;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAU,MAAM,cAAc,KAAK;AACzC,WAAK,QAAQ,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,GAAG,SAAS,KAAK;AAClE,YAAM,iBAAiB,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,KAAK,KAAK,GAAG,YAAY;AACvF,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,UACN,KAAK,KAAK;AAAA,UACV,MAAM,KAAK,QAAQ,KAAK;AAAA,UACxB;AAAA,UACA,OAAO,KAAK;AAAA,UACZ,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,UACd,SAAS,KAAK;AAAA,UACd,YAAY,KAAK,aAAa,KAAK,MAAM,KAAK,UAAU,IAAI;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,SAAS,qBAAqB;","names":[]}