{
  "version": 3,
  "sources": ["../../src/index.ts", "../../src/types.ts", "../../src/crypto.ts"],
  "sourcesContent": ["import { Extension } from '@magic-sdk/commons';\nimport {\n  OAuthErrorData,\n  OAuthPayloadMethods,\n  OAuthRedirectError,\n  OAuthRedirectResult,\n  OAuthRedirectConfiguration,\n} from './types';\nimport { createCryptoChallenge } from './crypto';\n\nexport class OAuthExtension extends Extension.Internal<'oauth'> {\n  name = 'oauth' as const;\n  config = {};\n  compat = {\n    'magic-sdk': '>=2.4.6',\n    '@magic-sdk/react-native': false,\n    '@magic-sdk/react-native-bare': false,\n    '@magic-sdk/react-native-expo': false,\n  };\n\n  public loginWithRedirect(configuration: OAuthRedirectConfiguration) {\n    return this.utils.createPromiEvent<void>(async resolve => {\n      const { provider, query } = await createURI.call(this, configuration);\n\n      // @ts-ignore - this.sdk.endpoint is marked protected but we need to access it.\n      window.location.href = new URL(`/v1/oauth2/${provider}/start?${query}`, this.sdk.endpoint).href;\n\n      resolve();\n    });\n  }\n\n  public getRedirectResult(lifespan?: number) {\n    const queryString = window.location.search;\n\n    // Remove the query from the redirect callback as a precaution to prevent\n    // malicious parties from parsing it before we have a chance to use it.\n    const urlWithoutQuery = window.location.origin + window.location.pathname;\n    window.history.replaceState(null, '', urlWithoutQuery);\n\n    return getResult.call(this, queryString, lifespan);\n  }\n}\n\nconst OAUTH_REDIRECT_METADATA_KEY = 'oauth_redirect_metadata';\n\nasync function createURI(this: OAuthExtension, configuration: OAuthRedirectConfiguration) {\n  // Bust any old, in-progress OAuth flows.\n  await this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n  // Unpack configuration, generate crypto values, and persist to storage.\n  const { provider, redirectURI, scope, loginHint } = configuration;\n  const { verifier, challenge, state } = await createCryptoChallenge();\n\n  /* Stringify for RN Async storage */\n  const storedData = JSON.stringify({\n    verifier,\n    state,\n  });\n\n  await this.utils.storage.setItem(OAUTH_REDIRECT_METADATA_KEY, storedData);\n\n  // Formulate the initial redirect query to Magic's OAuth hub.\n  // Required fields:\n  //   - `magic_api_key`\n  //   - `magic_challenge`\n  //   - `state`\n  //   - `redirect_uri`\n  //   - `platform`\n\n  const query = [\n    `magic_api_key=${encodeURIComponent(this.sdk.apiKey)}`,\n    `magic_challenge=${encodeURIComponent(challenge)}`,\n    `state=${encodeURIComponent(state)}`,\n    `platform=${encodeURIComponent('web')}`,\n    scope && `scope=${encodeURIComponent(scope.join(' '))}`,\n    redirectURI && `redirect_uri=${encodeURIComponent(redirectURI)}`,\n    loginHint && `login_hint=${encodeURIComponent(loginHint)}`,\n  ].reduce((prev, next) => (next ? `${prev}&${next}` : prev));\n\n  return {\n    query,\n    provider,\n    redirectURI,\n  };\n}\n\nfunction getResult(this: OAuthExtension, queryString: string, lifespan?: number) {\n  return this.utils.createPromiEvent<OAuthRedirectResult>(async (resolve, reject) => {\n    const json: string = (await this.utils.storage.getItem(OAUTH_REDIRECT_METADATA_KEY)) as string;\n\n    const { verifier, state } = JSON.parse(json);\n\n    // Remove the save OAuth state from storage, it stays in memory now...\n    this.utils.storage.removeItem(OAUTH_REDIRECT_METADATA_KEY);\n\n    const parseRedirectResult = this.utils.createJsonRpcRequestPayload(OAuthPayloadMethods.ParseRedirectResult, [\n      queryString,\n      verifier,\n      state,\n      lifespan,\n    ]);\n\n    // Parse the result, which may contain an OAuth-formatted error.\n    const resultOrError = await this.request<OAuthRedirectResult | OAuthRedirectError>(parseRedirectResult);\n    const maybeResult = resultOrError as OAuthRedirectResult;\n    const maybeError = resultOrError as OAuthRedirectError;\n\n    if (maybeError.error) {\n      reject(\n        this.createError<OAuthErrorData>(maybeError.error, maybeError.error_description ?? 'An error occurred.', {\n          errorURI: maybeError.error_uri,\n          provider: maybeError.provider,\n        }),\n      );\n    }\n\n    resolve(maybeResult);\n  });\n}\n\nexport * from './types';\n", "import { MagicUserMetadata } from '@magic-sdk/types';\n\nexport enum OAuthPayloadMethods {\n  ParseRedirectResult = 'magic_oauth_parse_redirect_result',\n}\n\nexport type OAuthProvider =\n  | 'google'\n  | 'facebook'\n  | 'apple'\n  | 'github'\n  | 'bitbucket'\n  | 'gitlab'\n  | 'linkedin'\n  | 'twitter'\n  | 'discord'\n  | 'twitch'\n  | 'microsoft';\n\nexport interface OAuthErrorData {\n  provider: OAuthProvider;\n  errorURI?: string;\n}\n\nexport interface OpenIDConnectProfile {\n  name?: string;\n  familyName?: string;\n  givenName?: string;\n  middleName?: string;\n  nickname?: string;\n  preferredUsername?: string;\n  profile?: string;\n  picture?: string;\n  website?: string;\n  gender?: string;\n  birthdate?: string;\n  zoneinfo?: string;\n  locale?: string;\n  updatedAt?: number;\n}\n\nexport interface OpenIDConnectEmail {\n  email?: string;\n  emailVerified?: boolean;\n}\n\nexport interface OpenIDConnectPhone {\n  phoneNumber?: string;\n  phoneNumberVerified?: boolean;\n}\n\nexport interface OpenIDConnectAddress {\n  address?: {\n    formatted?: string;\n    streetAddress?: string;\n    locality?: string;\n    region?: string;\n    postalCode?: string;\n    country?: string;\n  };\n}\n\nexport type OpenIDConnectUserInfo = OpenIDConnectProfile &\n  OpenIDConnectEmail &\n  OpenIDConnectPhone &\n  OpenIDConnectAddress & { sub?: string; sources?: Record<string, any> } & Record<string, any>;\n\nexport interface OAuthRedirectResult {\n  oauth: {\n    provider: OAuthProvider;\n    scope: string[];\n    accessToken: string;\n    userHandle: string;\n    userInfo: OpenIDConnectUserInfo;\n  };\n\n  magic: {\n    idToken: string;\n    userMetadata: MagicUserMetadata;\n  };\n}\n\nexport interface OAuthRedirectError {\n  provider: OAuthProvider;\n  error: string;\n  error_description?: string;\n  error_uri?: string;\n}\n\nexport interface OAuthRedirectConfiguration {\n  provider: OAuthProvider;\n  redirectURI: string;\n  scope?: string[];\n  loginHint?: string;\n}\n\nexport enum OAuthErrorCode {\n  InvalidRequest = 'invalid_request',\n  InvalidClient = 'invalid_client',\n  InvalidScope = 'invalid_scope',\n  InvalidGrant = 'invalid_grant',\n  UnauthorizedClient = 'unauthorized_client',\n  UnsupportedResponseType = 'unsupported_response_type',\n  UnsupportedGrantType = 'unsupported_grant_type',\n  UnsupportedTokenType = 'unsupported_token_type',\n  AccessDenied = 'access_denied',\n  ServerError = 'server_error',\n  TemporarilyUnavailable = 'temporarily_unavailable',\n}\n", "import Crypto from 'crypto-js';\n\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\nconst HAS_CRYPTO = typeof window !== 'undefined' && !!(window.crypto as any);\nconst HAS_SUBTLE_CRYPTO = HAS_CRYPTO && !!(window.crypto.subtle as any);\n\n/**\n * Stringifies `bytes` using the OAuth 2.0 `code_verifier` character set.\n */\nfunction bytesToVerifierString(bytes: Uint8Array) {\n  return Array.from(bytes)\n    .map((value: number) => CHARSET[value % CHARSET.length])\n    .join('');\n}\n\n/**\n * Stringifies argument (as CryptoJS `WordArray` or EcmaScript `ArrayBuffer`)\n * and encodes to URL-safe Base64.\n */\nfunction base64URLEncodeFromByteArray(arg: Crypto.lib.WordArray | ArrayBuffer): string {\n  const makeURLSafe = (base64: string) => {\n    return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n  };\n\n  if (arg instanceof ArrayBuffer) {\n    const bytes = new Uint8Array(arg);\n    const utf8Binary = Array.from(bytes)\n      .map(value => String.fromCharCode(value))\n      .join('');\n\n    const base64 = btoa(utf8Binary);\n    return makeURLSafe(base64);\n  }\n\n  return makeURLSafe(Crypto.enc.Base64.stringify(arg));\n}\n\n/**\n * Produces a SHA-256 hash of the given `message`. This function first attempts\n * to use the browser's built-in `SubtleCrypto` API, falling back to\n * CryptoJS if required.\n */\nasync function sha256(message: string) {\n  if (HAS_SUBTLE_CRYPTO) {\n    const bytes = new TextEncoder().encode(message);\n    return crypto.subtle.digest('SHA-256', bytes).then(base64URLEncodeFromByteArray);\n  }\n\n  return base64URLEncodeFromByteArray(Crypto.SHA256(message));\n}\n\n/**\n * Creates a cryptographically random string using the browser's built-in\n * `Crypto` API, falling back to `Math.random` if required.\n */\nfunction createRandomString(size: number) {\n  const bytes = new Uint8Array(size);\n\n  if (HAS_CRYPTO) {\n    window.crypto.getRandomValues(bytes);\n  } else {\n    for (let i = 0; i < size; i += 1) bytes[i] = Math.floor(Math.random() * Math.floor(255));\n  }\n\n  return bytesToVerifierString(bytes);\n}\n\n/**\n * Creates OAuth 2.0-compatible `code_verifier`, `code_challenge`, and `state`\n * parameters.\n */\nexport async function createCryptoChallenge() {\n  const state = createRandomString(128);\n  const verifier = createRandomString(128);\n  const challenge = await sha256(verifier);\n  return { verifier, challenge, state };\n}\n"],
  "mappings": "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",
  "names": ["Extension", "OAuthPayloadMethods", "OAuthErrorCode", "Crypto", "CHARSET", "HAS_CRYPTO", "HAS_SUBTLE_CRYPTO", "bytesToVerifierString", "bytes", "value", "base64URLEncodeFromByteArray", "arg", "makeURLSafe", "base64", "utf8Binary", "sha256", "message", "createRandomString", "size", "i", "createCryptoChallenge", "state", "verifier", "challenge", "OAuthExtension", "Extension", "configuration", "resolve", "provider", "query", "createURI", "lifespan", "queryString", "urlWithoutQuery", "getResult", "OAUTH_REDIRECT_METADATA_KEY", "redirectURI", "scope", "loginHint", "verifier", "challenge", "state", "createCryptoChallenge", "storedData", "prev", "next", "reject", "json", "parseRedirectResult", "resultOrError", "maybeResult", "maybeError"]
}
