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"]}