1{"version":3,"file":"AuthRequest.js","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"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","sourcesContent":["import * as WebBrowser from 'expo-web-browser';\nimport invariant from 'invariant';\nimport { Platform } from 'react-native';\n\nimport {\n  AuthRequestConfig,\n  AuthRequestPromptOptions,\n  CodeChallengeMethod,\n  ResponseType,\n  Prompt,\n} from './AuthRequest.types';\nimport { AuthSessionResult } from './AuthSession.types';\nimport { DiscoveryDocument } from './Discovery';\nimport { AuthError } from './Errors';\nimport * as PKCE from './PKCE';\nimport * as QueryParams from './QueryParams';\nimport sessionUrlProvider from './SessionUrlProvider';\nimport { TokenResponse } from './TokenRequest';\n\nlet _authLock: boolean = false;\n\ntype AuthDiscoveryDocument = Pick<DiscoveryDocument, 'authorizationEndpoint'>;\n\n// @needsAudit @docsMissing\n/**\n * Used to manage an authorization request according to the OAuth spec: [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1).\n * You can use this class directly for more info around the authorization.\n *\n * **Common use-cases:**\n *\n * - Parse a URL returned from the authorization server with `parseReturnUrlAsync()`.\n * - Get the built authorization URL with `makeAuthUrlAsync()`.\n * - Get a loaded JSON representation of the auth request with crypto state loaded with `getAuthRequestConfigAsync()`.\n *\n * @example\n * ```ts\n * // Create a request.\n * const request = new AuthRequest({ ... });\n *\n * // Prompt for an auth code\n * const result = await request.promptAsync(discovery);\n *\n * // Get the URL to invoke\n * const url = await request.makeAuthUrlAsync(discovery);\n *\n * // Get the URL to invoke\n * const parsed = await request.parseReturnUrlAsync(\"<URL From Server>\");\n * ```\n */\nexport class AuthRequest implements Omit<AuthRequestConfig, 'state'> {\n  /**\n   * Used for protection against [Cross-Site Request Forgery](https://tools.ietf.org/html/rfc6749#section-10.12).\n   */\n  public state: string;\n  public url: string | null = null;\n  public codeVerifier?: string;\n  public codeChallenge?: string;\n\n  readonly responseType: ResponseType | string;\n  readonly clientId: string;\n  readonly extraParams: Record<string, string>;\n  readonly usePKCE?: boolean;\n  readonly codeChallengeMethod: CodeChallengeMethod;\n  readonly redirectUri: string;\n  readonly scopes?: string[];\n  readonly clientSecret?: string;\n  readonly prompt?: Prompt;\n\n  constructor(request: AuthRequestConfig) {\n    this.responseType = request.responseType ?? ResponseType.Code;\n    this.clientId = request.clientId;\n    this.redirectUri = request.redirectUri;\n    this.scopes = request.scopes;\n    this.clientSecret = request.clientSecret;\n    this.prompt = request.prompt;\n    this.state = request.state ?? PKCE.generateRandom(10);\n    this.extraParams = request.extraParams ?? {};\n    this.codeChallengeMethod = request.codeChallengeMethod ?? CodeChallengeMethod.S256;\n    // PKCE defaults to true\n    this.usePKCE = request.usePKCE ?? true;\n\n    // Some warnings in development about potential confusing application code\n    if (__DEV__) {\n      if (this.prompt && this.extraParams.prompt) {\n        console.warn(`\\`AuthRequest\\` \\`extraParams.prompt\\` will be overwritten by \\`prompt\\`.`);\n      }\n      if (this.clientSecret && this.extraParams.client_secret) {\n        console.warn(\n          `\\`AuthRequest\\` \\`extraParams.client_secret\\` will be overwritten by \\`clientSecret\\`.`\n        );\n      }\n      if (this.codeChallengeMethod && this.extraParams.code_challenge_method) {\n        console.warn(\n          `\\`AuthRequest\\` \\`extraParams.code_challenge_method\\` will be overwritten by \\`codeChallengeMethod\\`.`\n        );\n      }\n    }\n\n    invariant(\n      this.codeChallengeMethod !== CodeChallengeMethod.Plain,\n      `\\`AuthRequest\\` does not support \\`CodeChallengeMethod.Plain\\` as it's not secure.`\n    );\n    invariant(\n      this.redirectUri,\n      `\\`AuthRequest\\` requires a valid \\`redirectUri\\`. Ex: ${Platform.select({\n        web: 'https://yourwebsite.com/',\n        default: 'com.your.app:/oauthredirect',\n      })}`\n    );\n  }\n\n  /**\n   * Load and return a valid auth request based on the input config.\n   */\n  async getAuthRequestConfigAsync(): Promise<AuthRequestConfig> {\n    if (this.usePKCE) {\n      await this.ensureCodeIsSetupAsync();\n    }\n\n    return {\n      responseType: this.responseType,\n      clientId: this.clientId,\n      redirectUri: this.redirectUri,\n      scopes: this.scopes,\n      clientSecret: this.clientSecret,\n      codeChallenge: this.codeChallenge,\n      codeChallengeMethod: this.codeChallengeMethod,\n      prompt: this.prompt,\n      state: this.state,\n      extraParams: this.extraParams,\n      usePKCE: this.usePKCE,\n    };\n  }\n\n  /**\n   * Prompt a user to authorize for a code.\n   *\n   * @param discovery\n   * @param promptOptions\n   */\n  async promptAsync(\n    discovery: AuthDiscoveryDocument,\n    { url, proxyOptions, ...options }: AuthRequestPromptOptions = {}\n  ): Promise<AuthSessionResult> {\n    if (!url) {\n      if (!this.url) {\n        // Generate a new url\n        return this.promptAsync(discovery, {\n          ...options,\n          url: await this.makeAuthUrlAsync(discovery),\n        });\n      }\n      // Reuse the preloaded url\n      url = this.url;\n    }\n\n    // Prevent accidentally starting to an empty url\n    invariant(\n      url,\n      'No authUrl provided to AuthSession.startAsync. An authUrl is required -- it points to the page where the user will be able to sign in.'\n    );\n\n    let startUrl: string = url!;\n    let returnUrl: string = this.redirectUri;\n    if (options.useProxy) {\n      console.warn(\n        'The useProxy option is deprecated and will be removed in a future release, for more information check https://expo.fyi/auth-proxy-migration.'\n      );\n      returnUrl = sessionUrlProvider.getDefaultReturnUrl(proxyOptions?.path, proxyOptions);\n      startUrl = sessionUrlProvider.getStartUrl(url, returnUrl, options.projectNameForProxy);\n    }\n    // Prevent multiple sessions from running at the same time, WebBrowser doesn't\n    // support it this makes the behavior predictable.\n    if (_authLock) {\n      if (__DEV__) {\n        console.warn(\n          'Attempted to call AuthSession.startAsync multiple times while already active. Only one AuthSession can be active at any given time.'\n        );\n      }\n\n      return { type: 'locked' };\n    }\n\n    // About to start session, set lock\n    _authLock = true;\n\n    let result: WebBrowser.WebBrowserAuthSessionResult;\n    try {\n      const { useProxy, ...openOptions } = options;\n      result = await WebBrowser.openAuthSessionAsync(startUrl, returnUrl, openOptions);\n    } finally {\n      _authLock = false;\n    }\n\n    if (result.type === 'opened') {\n      // This should never happen\n      throw new Error('An unexpected error occurred');\n    }\n    if (result.type !== 'success') {\n      return { type: result.type };\n    }\n\n    return this.parseReturnUrl(result.url);\n  }\n\n  parseReturnUrl(url: string): AuthSessionResult {\n    const { params, errorCode } = QueryParams.getQueryParams(url);\n    const { state, error = errorCode } = params;\n\n    let parsedError: AuthError | null = null;\n    let authentication: TokenResponse | null = null;\n    if (state !== this.state) {\n      // This is a non-standard error\n      parsedError = new AuthError({\n        error: 'state_mismatch',\n        error_description:\n          'Cross-Site request verification failed. Cached state and returned state do not match.',\n      });\n    } else if (error) {\n      parsedError = new AuthError({ error, ...params });\n    }\n    if (params.access_token) {\n      authentication = TokenResponse.fromQueryParams(params);\n    }\n\n    return {\n      type: parsedError ? 'error' : 'success',\n      error: parsedError,\n      url,\n      params,\n      authentication,\n\n      // Return errorCode for legacy\n      errorCode,\n    };\n  }\n\n  /**\n   * Create the URL for authorization.\n   *\n   * @param discovery\n   */\n  async makeAuthUrlAsync(discovery: AuthDiscoveryDocument): Promise<string> {\n    const request = await this.getAuthRequestConfigAsync();\n    if (!request.state) throw new Error('Cannot make request URL without a valid `state` loaded');\n\n    // Create a query string\n    const params: Record<string, string> = {};\n\n    if (request.codeChallenge) {\n      params.code_challenge = request.codeChallenge;\n    }\n\n    // copy over extra params\n    for (const extra in request.extraParams) {\n      if (extra in request.extraParams) {\n        params[extra] = request.extraParams[extra];\n      }\n    }\n\n    if (request.usePKCE && request.codeChallengeMethod) {\n      params.code_challenge_method = request.codeChallengeMethod;\n    }\n\n    if (request.clientSecret) {\n      params.client_secret = request.clientSecret;\n    }\n\n    if (request.prompt) {\n      params.prompt = request.prompt;\n    }\n\n    // These overwrite any extra params\n    params.redirect_uri = request.redirectUri;\n    params.client_id = request.clientId;\n    params.response_type = request.responseType!;\n    params.state = request.state;\n\n    if (request.scopes?.length) {\n      params.scope = request.scopes.join(' ');\n    }\n\n    const query = QueryParams.buildQueryString(params);\n    // Store the URL for later\n    this.url = `${discovery.authorizationEndpoint}?${query}`;\n    return this.url;\n  }\n\n  private async ensureCodeIsSetupAsync(): Promise<void> {\n    if (this.codeVerifier) {\n      return;\n    }\n\n    // This method needs to be resolved like all other native methods.\n    const { codeVerifier, codeChallenge } = await PKCE.buildCodeAsync();\n\n    this.codeVerifier = codeVerifier;\n    this.codeChallenge = codeChallenge;\n  }\n}\n"]}