expo-auth-session 3.4.2 → 3.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +14 -3
  2. package/README.md +4 -4
  3. package/build/AuthRequest.d.ts +23 -2
  4. package/build/AuthRequest.d.ts.map +1 -0
  5. package/build/AuthRequest.js +24 -3
  6. package/build/AuthRequest.js.map +1 -1
  7. package/build/AuthRequest.types.d.ts +23 -18
  8. package/build/AuthRequest.types.d.ts.map +1 -0
  9. package/build/AuthRequest.types.js +12 -10
  10. package/build/AuthRequest.types.js.map +1 -1
  11. package/build/AuthRequestHooks.d.ts +33 -7
  12. package/build/AuthRequestHooks.d.ts.map +1 -0
  13. package/build/AuthRequestHooks.js +36 -14
  14. package/build/AuthRequestHooks.js.map +1 -1
  15. package/build/AuthSession.d.ts +39 -11
  16. package/build/AuthSession.d.ts.map +1 -0
  17. package/build/AuthSession.js +47 -18
  18. package/build/AuthSession.js.map +1 -1
  19. package/build/AuthSession.types.d.ts +57 -10
  20. package/build/AuthSession.types.d.ts.map +1 -0
  21. package/build/AuthSession.types.js.map +1 -1
  22. package/build/Base64.d.ts +1 -0
  23. package/build/Base64.d.ts.map +1 -0
  24. package/build/Discovery.d.ts +25 -10
  25. package/build/Discovery.d.ts.map +1 -0
  26. package/build/Discovery.js +7 -0
  27. package/build/Discovery.js.map +1 -1
  28. package/build/Errors.d.ts +4 -1
  29. package/build/Errors.d.ts.map +1 -0
  30. package/build/Errors.js +4 -1
  31. package/build/Errors.js.map +1 -1
  32. package/build/Fetch.d.ts +1 -0
  33. package/build/Fetch.d.ts.map +1 -0
  34. package/build/Fetch.js +0 -2
  35. package/build/Fetch.js.map +1 -1
  36. package/build/PKCE.d.ts +1 -0
  37. package/build/PKCE.d.ts.map +1 -0
  38. package/build/QueryParams.d.ts +1 -0
  39. package/build/QueryParams.d.ts.map +1 -0
  40. package/build/SessionUrlProvider.d.ts +8 -4
  41. package/build/SessionUrlProvider.d.ts.map +1 -0
  42. package/build/SessionUrlProvider.js +18 -12
  43. package/build/SessionUrlProvider.js.map +1 -1
  44. package/build/TokenRequest.d.ts +16 -10
  45. package/build/TokenRequest.d.ts.map +1 -0
  46. package/build/TokenRequest.js +17 -12
  47. package/build/TokenRequest.js.map +1 -1
  48. package/build/TokenRequest.types.d.ts +13 -8
  49. package/build/TokenRequest.types.d.ts.map +1 -0
  50. package/build/TokenRequest.types.js +5 -3
  51. package/build/TokenRequest.types.js.map +1 -1
  52. package/build/providers/Facebook.d.ts +6 -2
  53. package/build/providers/Facebook.d.ts.map +1 -0
  54. package/build/providers/Facebook.js +6 -2
  55. package/build/providers/Facebook.js.map +1 -1
  56. package/build/providers/Google.d.ts +13 -4
  57. package/build/providers/Google.d.ts.map +1 -0
  58. package/build/providers/Google.js +9 -8
  59. package/build/providers/Google.js.map +1 -1
  60. package/build/providers/Provider.types.d.ts +1 -0
  61. package/build/providers/Provider.types.d.ts.map +1 -0
  62. package/build/providers/ProviderUtils.d.ts +1 -0
  63. package/build/providers/ProviderUtils.d.ts.map +1 -0
  64. package/package.json +6 -6
  65. package/src/AuthRequest.ts +24 -3
  66. package/src/AuthRequest.types.ts +27 -18
  67. package/src/AuthRequestHooks.ts +60 -39
  68. package/src/AuthSession.ts +56 -18
  69. package/src/AuthSession.types.ts +61 -8
  70. package/src/Discovery.ts +30 -12
  71. package/src/Errors.ts +4 -1
  72. package/src/Fetch.ts +0 -2
  73. package/src/SessionUrlProvider.ts +24 -14
  74. package/src/TokenRequest.ts +18 -13
  75. package/src/TokenRequest.types.ts +21 -8
  76. package/src/providers/Facebook.ts +7 -2
  77. package/src/providers/Google.ts +17 -12
package/CHANGELOG.md CHANGED
@@ -10,11 +10,22 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 3.4.22021-10-15
13
+ ## 3.6.12022-05-12
14
14
 
15
- ### 🐛 Bug fixes
15
+ ### 🎉 New features
16
16
 
17
- - Fixed an import from deprecated `@unimodules/react-native-adapter` package. ([#14585](https://github.com/expo/expo/pull/14585) by [@tsapeta](https://github.com/tsapeta))
17
+ - Add projectNameForProxy option. ([#17327](https://github.com/expo/expo/pull/17327) by [@wschurman](https://github.com/wschurman))
18
+
19
+ ## 3.6.0 — 2022-04-18
20
+
21
+ ### 💡 Others
22
+
23
+ - Export provider specific config types: `FacebookAuthRequestConfig` and `GoogleAuthRequestConfig`. ([#16223](https://github.com/expo/expo/pull/16223) by [@Simek](https://github.com/Simek))
24
+ - Add missing `language` field to the `GoogleAuthRequestConfig`. ([#16223](https://github.com/expo/expo/pull/16223) by [@Simek](https://github.com/Simek))
25
+
26
+ ## 3.5.0 — 2021-12-03
27
+
28
+ _This version does not introduce any user-facing changes._
18
29
 
19
30
  ## 3.4.1 — 2021-10-01
20
31
 
package/README.md CHANGED
@@ -4,16 +4,16 @@
4
4
 
5
5
  # API documentation
6
6
 
7
- - [Documentation for the master branch](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/sdk/auth-session.md)
8
- - [Documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/auth-session)
7
+ - [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/auth-session.md)
8
+ - [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/auth-session)
9
9
 
10
10
  # Installation in managed Expo projects
11
11
 
12
- For [managed](https://docs.expo.io/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/auth-session).
12
+ For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/auth-session).
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -3,9 +3,29 @@ import { AuthSessionResult } from './AuthSession.types';
3
3
  import { DiscoveryDocument } from './Discovery';
4
4
  declare type AuthDiscoveryDocument = Pick<DiscoveryDocument, 'authorizationEndpoint'>;
5
5
  /**
6
- * Implements an authorization request.
6
+ * 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].
7
+ * You can use this class directly for more info around the authorization.
7
8
  *
8
- * [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1)
9
+ * **Common use-cases:**
10
+ *
11
+ * - Parse a URL returned from the authorization server with `parseReturnUrlAsync()`.
12
+ * - Get the built authorization URL with `makeAuthUrlAsync()`.
13
+ * - Get a loaded JSON representation of the auth request with crypto state loaded with `getAuthRequestConfigAsync()`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * // Create a request.
18
+ * const request = new AuthRequest({ ... });
19
+ *
20
+ * // Prompt for an auth code
21
+ * const result = await request.promptAsync(discovery, { useProxy: true });
22
+ *
23
+ * // Get the URL to invoke
24
+ * const url = await request.makeAuthUrlAsync(discovery);
25
+ *
26
+ * // Get the URL to invoke
27
+ * const parsed = await request.parseReturnUrlAsync("<URL From Server>");
28
+ * ```
9
29
  */
10
30
  export declare class AuthRequest implements Omit<AuthRequestConfig, 'state'> {
11
31
  /**
@@ -46,3 +66,4 @@ export declare class AuthRequest implements Omit<AuthRequestConfig, 'state'> {
46
66
  private ensureCodeIsSetupAsync;
47
67
  }
48
68
  export {};
69
+ //# sourceMappingURL=AuthRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthRequest.d.ts","sourceRoot":"","sources":["../src/AuthRequest.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACP,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAShD,aAAK,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,WAAY,YAAW,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAClE;;OAEG;IACI,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,iBAAiB;IA2CtC;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAoB7D;;;;;OAKG;IACG,WAAW,CACf,SAAS,EAAE,qBAAqB,EAChC,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,GAAE,wBAA6B,GAC/D,OAAO,CAAC,iBAAiB,CAAC;IA2D7B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAgC9C;;;;OAIG;IACG,gBAAgB,CAAC,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;YA8C3D,sBAAsB;CAWrC"}
@@ -8,10 +8,31 @@ import * as QueryParams from './QueryParams';
8
8
  import sessionUrlProvider from './SessionUrlProvider';
9
9
  import { TokenResponse } from './TokenRequest';
10
10
  let _authLock = false;
11
+ // @needsAudit @docsMissing
11
12
  /**
12
- * Implements an authorization request.
13
+ * 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].
14
+ * You can use this class directly for more info around the authorization.
13
15
  *
14
- * [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1)
16
+ * **Common use-cases:**
17
+ *
18
+ * - Parse a URL returned from the authorization server with `parseReturnUrlAsync()`.
19
+ * - Get the built authorization URL with `makeAuthUrlAsync()`.
20
+ * - Get a loaded JSON representation of the auth request with crypto state loaded with `getAuthRequestConfigAsync()`.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * // Create a request.
25
+ * const request = new AuthRequest({ ... });
26
+ *
27
+ * // Prompt for an auth code
28
+ * const result = await request.promptAsync(discovery, { useProxy: true });
29
+ *
30
+ * // Get the URL to invoke
31
+ * const url = await request.makeAuthUrlAsync(discovery);
32
+ *
33
+ * // Get the URL to invoke
34
+ * const parsed = await request.parseReturnUrlAsync("<URL From Server>");
35
+ * ```
15
36
  */
16
37
  export class AuthRequest {
17
38
  /**
@@ -105,7 +126,7 @@ export class AuthRequest {
105
126
  let returnUrl = this.redirectUri;
106
127
  if (options.useProxy) {
107
128
  returnUrl = sessionUrlProvider.getDefaultReturnUrl(proxyOptions?.path, proxyOptions);
108
- startUrl = sessionUrlProvider.getStartUrl(url, returnUrl);
129
+ startUrl = sessionUrlProvider.getStartUrl(url, returnUrl, options.projectNameForProxy);
109
130
  }
110
131
  // Prevent multiple sessions from running at the same time, WebBrowser doesn't
111
132
  // support it this makes the behavior predictable.
@@ -1 +1 @@
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/**\n * Implements an authorization request.\n *\n * [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1)\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 returnUrl = sessionUrlProvider.getDefaultReturnUrl(proxyOptions?.path, proxyOptions);\n startUrl = sessionUrlProvider.getStartUrl(url, returnUrl);\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"]}
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, { useProxy: true });\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 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"]}
@@ -3,22 +3,20 @@ import { WebBrowserOpenOptions, WebBrowserWindowFeatures } from 'expo-web-browse
3
3
  export declare enum CodeChallengeMethod {
4
4
  /**
5
5
  * The default and recommended method for transforming the code verifier.
6
- * 1. Convert the code verifier to ASCII.
7
- * 2. Create a digest of the string using crypto method SHA256.
8
- * 3. Convert the digest to Base64 and URL encode it.
6
+ * - Convert the code verifier to ASCII.
7
+ * - Create a digest of the string using crypto method SHA256.
8
+ * - Convert the digest to Base64 and URL encode it.
9
9
  */
10
10
  S256 = "S256",
11
11
  /**
12
- * This should not be used.
13
- * When used, the code verifier will be sent to the server as-is.
12
+ * This should not be used. When used, the code verifier will be sent to the server as-is.
14
13
  */
15
14
  Plain = "plain"
16
15
  }
17
16
  /**
18
- * The client informs the authorization server of the
19
- * desired grant type by using the a response type.
17
+ * The client informs the authorization server of the desired grant type by using the response type.
20
18
  *
21
- * [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1)
19
+ * @see [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1).
22
20
  */
23
21
  export declare enum ResponseType {
24
22
  /**
@@ -35,10 +33,11 @@ export declare enum ResponseType {
35
33
  IdToken = "id_token"
36
34
  }
37
35
  /**
38
- * Should the user be prompted to login or consent again.
36
+ * Informs the server if the user should be prompted to login or consent again.
39
37
  * This can be used to present a dialog for switching accounts after the user has already been logged in.
38
+ * You should use this in favor of clearing cookies (which is mostly not possible on iOS).
40
39
  *
41
- * [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest)
40
+ * @see [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest).
42
41
  */
43
42
  export declare enum Prompt {
44
43
  /**
@@ -64,19 +63,23 @@ export declare enum Prompt {
64
63
  SelectAccount = "select_account"
65
64
  }
66
65
  /**
67
- * Options for the prompt window / web browser.
66
+ * Options passed to the `promptAsync()` method of `AuthRequest`s.
68
67
  * This can be used to configure how the web browser should look and behave.
69
68
  */
70
69
  export declare type AuthRequestPromptOptions = Omit<WebBrowserOpenOptions, 'windowFeatures'> & {
71
70
  /**
72
- * URL to open when prompting the user. This should be defined internally.
71
+ * URL to open when prompting the user. This usually should be defined internally and left `undefined` in most cases.
73
72
  */
74
73
  url?: string;
75
74
  /**
76
75
  * Should the authentication request use the Expo proxy service `auth.expo.io`.
77
- * Default: `false`.
76
+ * @default false
78
77
  */
79
78
  useProxy?: boolean;
79
+ /**
80
+ * Project name to use for the \`auth.expo.io\` proxy when `useProxy` is true.
81
+ */
82
+ projectNameForProxy?: string;
80
83
  /**
81
84
  * URL options to be used when creating the redirect URL for the auth proxy.
82
85
  */
@@ -84,7 +87,8 @@ export declare type AuthRequestPromptOptions = Omit<WebBrowserOpenOptions, 'wind
84
87
  path?: string;
85
88
  };
86
89
  /**
87
- * **Web:** features to use with `window.open()`
90
+ * Features to use with `window.open()`.
91
+ * @platform web
88
92
  */
89
93
  windowFeatures?: WebBrowserWindowFeatures;
90
94
  };
@@ -112,7 +116,7 @@ export interface AuthRequestConfig {
112
116
  clientId: string;
113
117
  /**
114
118
  * After completing an interaction with a resource owner the
115
- * server will redirect to this URI. Learn more about [linking in Expo](https://docs.expo.io/versions/latest/workflow/linking/).
119
+ * server will redirect to this URI. Learn more about [linking in Expo](https://docs.expo.dev/versions/latest/workflow/linking/).
116
120
  *
117
121
  * [Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)
118
122
  */
@@ -131,8 +135,8 @@ export interface AuthRequestConfig {
131
135
  */
132
136
  clientSecret?: string;
133
137
  /**
134
- * Method used to generate the code challenge.
135
- * Defaults to `S256`. You should never use `Plain` as it's not good enough for secure verification.
138
+ * Method used to generate the code challenge. You should never use `Plain` as it's not good enough for secure verification.
139
+ * @default CodeChallengeMethod.S256
136
140
  */
137
141
  codeChallengeMethod?: CodeChallengeMethod;
138
142
  /**
@@ -158,7 +162,8 @@ export interface AuthRequestConfig {
158
162
  extraParams?: Record<string, string>;
159
163
  /**
160
164
  * Should use [Proof Key for Code Exchange](https://oauth.net/2/pkce/).
161
- * Defaults to true.
165
+ * @default true
162
166
  */
163
167
  usePKCE?: boolean;
164
168
  }
169
+ //# sourceMappingURL=AuthRequest.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthRequest.types.d.ts","sourceRoot":"","sources":["../src/AuthRequest.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,oBAAY,mBAAmB;IAC7B;;;;;OAKG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;CAChB;AAGD;;;;GAIG;AACH,oBAAY,YAAY;IACtB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,OAAO,aAAa;CACrB;AAGD;;;;;;GAMG;AACH,oBAAY,MAAM;IAChB;;;;OAIG;IACH,IAAI,SAAS;IACb;;;OAGG;IACH,KAAK,UAAU;IACf;;;OAGG;IACH,OAAO,YAAY;IACnB;;;OAGG;IACH,aAAa,mBAAmB;CACjC;AAGD;;;GAGG;AACH,oBAAY,wBAAwB,GAAG,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,GAAG;IACrF;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE;;;OAGG;IACH,cAAc,CAAC,EAAE,wBAAwB,CAAC;CAC3C,CAAC;AAGF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -1,23 +1,23 @@
1
+ // @needsAudit
1
2
  export var CodeChallengeMethod;
2
3
  (function (CodeChallengeMethod) {
3
4
  /**
4
5
  * The default and recommended method for transforming the code verifier.
5
- * 1. Convert the code verifier to ASCII.
6
- * 2. Create a digest of the string using crypto method SHA256.
7
- * 3. Convert the digest to Base64 and URL encode it.
6
+ * - Convert the code verifier to ASCII.
7
+ * - Create a digest of the string using crypto method SHA256.
8
+ * - Convert the digest to Base64 and URL encode it.
8
9
  */
9
10
  CodeChallengeMethod["S256"] = "S256";
10
11
  /**
11
- * This should not be used.
12
- * When used, the code verifier will be sent to the server as-is.
12
+ * This should not be used. When used, the code verifier will be sent to the server as-is.
13
13
  */
14
14
  CodeChallengeMethod["Plain"] = "plain";
15
15
  })(CodeChallengeMethod || (CodeChallengeMethod = {}));
16
+ // @needsAudit
16
17
  /**
17
- * The client informs the authorization server of the
18
- * desired grant type by using the a response type.
18
+ * The client informs the authorization server of the desired grant type by using the response type.
19
19
  *
20
- * [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1)
20
+ * @see [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1).
21
21
  */
22
22
  export var ResponseType;
23
23
  (function (ResponseType) {
@@ -34,11 +34,13 @@ export var ResponseType;
34
34
  */
35
35
  ResponseType["IdToken"] = "id_token";
36
36
  })(ResponseType || (ResponseType = {}));
37
+ // @needsAudit
37
38
  /**
38
- * Should the user be prompted to login or consent again.
39
+ * Informs the server if the user should be prompted to login or consent again.
39
40
  * This can be used to present a dialog for switching accounts after the user has already been logged in.
41
+ * You should use this in favor of clearing cookies (which is mostly not possible on iOS).
40
42
  *
41
- * [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest)
43
+ * @see [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest).
42
44
  */
43
45
  export var Prompt;
44
46
  (function (Prompt) {
@@ -1 +1 @@
1
- {"version":3,"file":"AuthRequest.types.js","sourceRoot":"","sources":["../src/AuthRequest.types.ts"],"names":[],"mappings":"AAGA,MAAM,CAAN,IAAY,mBAaX;AAbD,WAAY,mBAAmB;IAC7B;;;;;OAKG;IACH,oCAAa,CAAA;IACb;;;OAGG;IACH,sCAAe,CAAA;AACjB,CAAC,EAbW,mBAAmB,KAAnB,mBAAmB,QAa9B;AAED;;;;;GAKG;AACH,MAAM,CAAN,IAAY,YAaX;AAbD,WAAY,YAAY;IACtB;;OAEG;IACH,6BAAa,CAAA;IACb;;OAEG;IACH,+BAAe,CAAA;IACf;;OAEG;IACH,oCAAoB,CAAA;AACtB,CAAC,EAbW,YAAY,KAAZ,YAAY,QAavB;AAED;;;;;GAKG;AACH,MAAM,CAAN,IAAY,MAsBX;AAtBD,WAAY,MAAM;IAChB;;;;OAIG;IACH,uBAAa,CAAA;IACb;;;OAGG;IACH,yBAAe,CAAA;IACf;;;OAGG;IACH,6BAAmB,CAAA;IACnB;;;OAGG;IACH,0CAAgC,CAAA;AAClC,CAAC,EAtBW,MAAM,KAAN,MAAM,QAsBjB","sourcesContent":["import { CreateURLOptions } from 'expo-linking';\nimport { WebBrowserOpenOptions, WebBrowserWindowFeatures } from 'expo-web-browser';\n\nexport enum CodeChallengeMethod {\n /**\n * The default and recommended method for transforming the code verifier.\n * 1. Convert the code verifier to ASCII.\n * 2. Create a digest of the string using crypto method SHA256.\n * 3. Convert the digest to Base64 and URL encode it.\n */\n S256 = 'S256',\n /**\n * This should not be used.\n * When used, the code verifier will be sent to the server as-is.\n */\n Plain = 'plain',\n}\n\n/**\n * The client informs the authorization server of the\n * desired grant type by using the a response type.\n *\n * [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1)\n */\nexport enum ResponseType {\n /**\n * For requesting an authorization code as described by [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1).\n */\n Code = 'code',\n /**\n * For requesting an access token (implicit grant) as described by [Section 4.2.1](https://tools.ietf.org/html/rfc6749#section-4.2.1).\n */\n Token = 'token',\n /**\n * A custom registered type for getting an `id_token` from Google OAuth.\n */\n IdToken = 'id_token',\n}\n\n/**\n * Should the user be prompted to login or consent again.\n * This can be used to present a dialog for switching accounts after the user has already been logged in.\n *\n * [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest)\n */\nexport enum Prompt {\n /**\n * Server must not display any auth or consent UI. Can be used to check for existing auth or consent.\n * An error is returned if a user isn't already authenticated or the client doesn't have pre-configured consent for the requested claims, or does not fulfill other conditions for processing the request.\n * The error code will typically be `login_required`, `interaction_required`, or another code defined in [Section 3.1.2.6](https://openid.net/specs/openid-connect-core-1_0.html#AuthError).\n */\n None = 'none',\n /**\n * The server should prompt the user to reauthenticate.\n * If it cannot reauthenticate the End-User, it must return an error, typically `login_required`.\n */\n Login = 'login',\n /**\n * Server should prompt the user for consent before returning information to the client.\n * If it cannot obtain consent, it must return an error, typically `consent_required`.\n */\n Consent = 'consent',\n /**\n * Server should prompt the user to select an account. Can be used to switch accounts.\n * If it can't obtain an account selection choice made by the user, it must return an error, typically `account_selection_required`.\n */\n SelectAccount = 'select_account',\n}\n\n/**\n * Options for the prompt window / web browser.\n * This can be used to configure how the web browser should look and behave.\n */\nexport type AuthRequestPromptOptions = Omit<WebBrowserOpenOptions, 'windowFeatures'> & {\n /**\n * URL to open when prompting the user. This should be defined internally.\n */\n url?: string;\n /**\n * Should the authentication request use the Expo proxy service `auth.expo.io`.\n * Default: `false`.\n */\n useProxy?: boolean;\n /**\n * URL options to be used when creating the redirect URL for the auth proxy.\n */\n proxyOptions?: Omit<CreateURLOptions, 'queryParams'> & { path?: string };\n /**\n * **Web:** features to use with `window.open()`\n */\n windowFeatures?: WebBrowserWindowFeatures;\n};\n\n/**\n * Represents an OAuth authorization request as JSON.\n */\nexport interface AuthRequestConfig {\n /**\n * Specifies what is returned from the authorization server.\n *\n * [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1)\n *\n * @default ResponseType.Code\n */\n responseType?: ResponseType | string;\n /**\n * A unique string representing the registration information provided by the client.\n * The client identifier is not a secret; it is exposed to the resource owner and shouldn't be used\n * alone for client authentication.\n *\n * The client identifier is unique to the authorization server.\n *\n * [Section 2.2](https://tools.ietf.org/html/rfc6749#section-2.2)\n */\n clientId: string;\n /**\n * After completing an interaction with a resource owner the\n * server will redirect to this URI. Learn more about [linking in Expo](https://docs.expo.io/versions/latest/workflow/linking/).\n *\n * [Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)\n */\n redirectUri: string;\n /**\n * List of strings to request access to.\n *\n * [Section 3.3](https://tools.ietf.org/html/rfc6749#section-3.3)\n */\n scopes?: string[];\n /**\n * Client secret supplied by an auth provider.\n * There is no secure way to store this on the client.\n *\n * [Section 2.3.1](https://tools.ietf.org/html/rfc6749#section-2.3.1)\n */\n clientSecret?: string;\n /**\n * Method used to generate the code challenge.\n * Defaults to `S256`. You should never use `Plain` as it's not good enough for secure verification.\n */\n codeChallengeMethod?: CodeChallengeMethod;\n /**\n * Derived from the code verifier by using the `CodeChallengeMethod`.\n *\n * [Section 4.2](https://tools.ietf.org/html/rfc7636#section-4.2)\n */\n codeChallenge?: string;\n /**\n * Informs the server if the user should be prompted to login or consent again.\n * This can be used to present a dialog for switching accounts after the user has already been logged in.\n *\n * [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest)\n */\n prompt?: Prompt;\n /**\n * Used for protection against [Cross-Site Request Forgery](https://tools.ietf.org/html/rfc6749#section-10.12).\n */\n state?: string;\n /**\n * Extra query params that'll be added to the query string.\n */\n extraParams?: Record<string, string>;\n /**\n * Should use [Proof Key for Code Exchange](https://oauth.net/2/pkce/).\n * Defaults to true.\n */\n usePKCE?: boolean;\n}\n"]}
1
+ {"version":3,"file":"AuthRequest.types.js","sourceRoot":"","sources":["../src/AuthRequest.types.ts"],"names":[],"mappings":"AAGA,cAAc;AACd,MAAM,CAAN,IAAY,mBAYX;AAZD,WAAY,mBAAmB;IAC7B;;;;;OAKG;IACH,oCAAa,CAAA;IACb;;OAEG;IACH,sCAAe,CAAA;AACjB,CAAC,EAZW,mBAAmB,KAAnB,mBAAmB,QAY9B;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAN,IAAY,YAaX;AAbD,WAAY,YAAY;IACtB;;OAEG;IACH,6BAAa,CAAA;IACb;;OAEG;IACH,+BAAe,CAAA;IACf;;OAEG;IACH,oCAAoB,CAAA;AACtB,CAAC,EAbW,YAAY,KAAZ,YAAY,QAavB;AAED,cAAc;AACd;;;;;;GAMG;AACH,MAAM,CAAN,IAAY,MAsBX;AAtBD,WAAY,MAAM;IAChB;;;;OAIG;IACH,uBAAa,CAAA;IACb;;;OAGG;IACH,yBAAe,CAAA;IACf;;;OAGG;IACH,6BAAmB,CAAA;IACnB;;;OAGG;IACH,0CAAgC,CAAA;AAClC,CAAC,EAtBW,MAAM,KAAN,MAAM,QAsBjB","sourcesContent":["import { CreateURLOptions } from 'expo-linking';\nimport { WebBrowserOpenOptions, WebBrowserWindowFeatures } from 'expo-web-browser';\n\n// @needsAudit\nexport enum CodeChallengeMethod {\n /**\n * The default and recommended method for transforming the code verifier.\n * - Convert the code verifier to ASCII.\n * - Create a digest of the string using crypto method SHA256.\n * - Convert the digest to Base64 and URL encode it.\n */\n S256 = 'S256',\n /**\n * This should not be used. When used, the code verifier will be sent to the server as-is.\n */\n Plain = 'plain',\n}\n\n// @needsAudit\n/**\n * The client informs the authorization server of the desired grant type by using the response type.\n *\n * @see [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1).\n */\nexport enum ResponseType {\n /**\n * For requesting an authorization code as described by [Section 4.1.1](https://tools.ietf.org/html/rfc6749#section-4.1.1).\n */\n Code = 'code',\n /**\n * For requesting an access token (implicit grant) as described by [Section 4.2.1](https://tools.ietf.org/html/rfc6749#section-4.2.1).\n */\n Token = 'token',\n /**\n * A custom registered type for getting an `id_token` from Google OAuth.\n */\n IdToken = 'id_token',\n}\n\n// @needsAudit\n/**\n * Informs the server if the user should be prompted to login or consent again.\n * This can be used to present a dialog for switching accounts after the user has already been logged in.\n * You should use this in favor of clearing cookies (which is mostly not possible on iOS).\n *\n * @see [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest).\n */\nexport enum Prompt {\n /**\n * Server must not display any auth or consent UI. Can be used to check for existing auth or consent.\n * An error is returned if a user isn't already authenticated or the client doesn't have pre-configured consent for the requested claims, or does not fulfill other conditions for processing the request.\n * The error code will typically be `login_required`, `interaction_required`, or another code defined in [Section 3.1.2.6](https://openid.net/specs/openid-connect-core-1_0.html#AuthError).\n */\n None = 'none',\n /**\n * The server should prompt the user to reauthenticate.\n * If it cannot reauthenticate the End-User, it must return an error, typically `login_required`.\n */\n Login = 'login',\n /**\n * Server should prompt the user for consent before returning information to the client.\n * If it cannot obtain consent, it must return an error, typically `consent_required`.\n */\n Consent = 'consent',\n /**\n * Server should prompt the user to select an account. Can be used to switch accounts.\n * If it can't obtain an account selection choice made by the user, it must return an error, typically `account_selection_required`.\n */\n SelectAccount = 'select_account',\n}\n\n// @needsAudit\n/**\n * Options passed to the `promptAsync()` method of `AuthRequest`s.\n * This can be used to configure how the web browser should look and behave.\n */\nexport type AuthRequestPromptOptions = Omit<WebBrowserOpenOptions, 'windowFeatures'> & {\n /**\n * URL to open when prompting the user. This usually should be defined internally and left `undefined` in most cases.\n */\n url?: string;\n /**\n * Should the authentication request use the Expo proxy service `auth.expo.io`.\n * @default false\n */\n useProxy?: boolean;\n /**\n * Project name to use for the \\`auth.expo.io\\` proxy when `useProxy` is true.\n */\n projectNameForProxy?: string;\n /**\n * URL options to be used when creating the redirect URL for the auth proxy.\n */\n proxyOptions?: Omit<CreateURLOptions, 'queryParams'> & { path?: string };\n /**\n * Features to use with `window.open()`.\n * @platform web\n */\n windowFeatures?: WebBrowserWindowFeatures;\n};\n\n// @needsAudit\n/**\n * Represents an OAuth authorization request as JSON.\n */\nexport interface AuthRequestConfig {\n /**\n * Specifies what is returned from the authorization server.\n *\n * [Section 3.1.1](https://tools.ietf.org/html/rfc6749#section-3.1.1)\n *\n * @default ResponseType.Code\n */\n responseType?: ResponseType | string;\n /**\n * A unique string representing the registration information provided by the client.\n * The client identifier is not a secret; it is exposed to the resource owner and shouldn't be used\n * alone for client authentication.\n *\n * The client identifier is unique to the authorization server.\n *\n * [Section 2.2](https://tools.ietf.org/html/rfc6749#section-2.2)\n */\n clientId: string;\n /**\n * After completing an interaction with a resource owner the\n * server will redirect to this URI. Learn more about [linking in Expo](https://docs.expo.dev/versions/latest/workflow/linking/).\n *\n * [Section 3.1.2](https://tools.ietf.org/html/rfc6749#section-3.1.2)\n */\n redirectUri: string;\n /**\n * List of strings to request access to.\n *\n * [Section 3.3](https://tools.ietf.org/html/rfc6749#section-3.3)\n */\n scopes?: string[];\n /**\n * Client secret supplied by an auth provider.\n * There is no secure way to store this on the client.\n *\n * [Section 2.3.1](https://tools.ietf.org/html/rfc6749#section-2.3.1)\n */\n clientSecret?: string;\n /**\n * Method used to generate the code challenge. You should never use `Plain` as it's not good enough for secure verification.\n * @default CodeChallengeMethod.S256\n */\n codeChallengeMethod?: CodeChallengeMethod;\n /**\n * Derived from the code verifier by using the `CodeChallengeMethod`.\n *\n * [Section 4.2](https://tools.ietf.org/html/rfc7636#section-4.2)\n */\n codeChallenge?: string;\n /**\n * Informs the server if the user should be prompted to login or consent again.\n * This can be used to present a dialog for switching accounts after the user has already been logged in.\n *\n * [Section 3.1.2.1](https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationRequest)\n */\n prompt?: Prompt;\n /**\n * Used for protection against [Cross-Site Request Forgery](https://tools.ietf.org/html/rfc6749#section-10.12).\n */\n state?: string;\n /**\n * Extra query params that'll be added to the query string.\n */\n extraParams?: Record<string, string>;\n /**\n * Should use [Proof Key for Code Exchange](https://oauth.net/2/pkce/).\n * @default true\n */\n usePKCE?: boolean;\n}\n"]}
@@ -3,21 +3,46 @@ import { AuthRequestConfig, AuthRequestPromptOptions } from './AuthRequest.types
3
3
  import { AuthSessionResult } from './AuthSession.types';
4
4
  import { DiscoveryDocument, IssuerOrDiscovery } from './Discovery';
5
5
  /**
6
- * Fetch the discovery document from an OpenID Connect issuer.
6
+ * Given an OpenID Connect issuer URL, this will fetch and return the [`DiscoveryDocument`](#discoverydocument)
7
+ * (a collection of URLs) from the resource provider.
7
8
  *
8
- * @param issuerOrDiscovery
9
+ * @param issuerOrDiscovery URL using the `https` scheme with no query or fragment component that the OP asserts as its Issuer Identifier.
10
+ * @return Returns `null` until the [`DiscoveryDocument`](#discoverydocument) has been fetched from the provided issuer URL.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const discovery = useAutoDiscovery('https://example.com/auth');
15
+ * ```
9
16
  */
10
17
  export declare function useAutoDiscovery(issuerOrDiscovery: IssuerOrDiscovery): DiscoveryDocument | null;
11
18
  export declare function useLoadedAuthRequest(config: AuthRequestConfig, discovery: DiscoveryDocument | null, AuthRequestInstance: typeof AuthRequest): AuthRequest | null;
12
19
  declare type PromptMethod = (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>;
13
20
  export declare function useAuthRequestResult(request: AuthRequest | null, discovery: DiscoveryDocument | null, customOptions?: AuthRequestPromptOptions): [AuthSessionResult | null, PromptMethod];
14
21
  /**
15
- * Load an authorization request.
16
- * Returns a loaded request, a response, and a prompt method.
17
- * When the prompt method completes then the response will be fulfilled.
22
+ * Load an authorization request for a code. When the prompt method completes then the response will be fulfilled.
23
+ *
24
+ * > In order to close the popup window on web, you need to invoke `WebBrowser.maybeCompleteAuthSession()`.
25
+ * > See the [Identity example](/guides/authentication.md#identityserver-4) for more info.
26
+ *
27
+ * If an Implicit grant flow was used, you can pass the `response.params` to `TokenResponse.fromQueryParams()`
28
+ * to get a `TokenResponse` instance which you can use to easily refresh the token.
29
+ *
30
+ * @param config A valid [`AuthRequestConfig`](#authrequestconfig) that specifies what provider to use.
31
+ * @param discovery A loaded [`DiscoveryDocument`](#discoverydocument) with endpoints used for authenticating.
32
+ * Only `authorizationEndpoint` is required for requesting an authorization code.
33
+ *
34
+ * @return Returns a loaded request, a response, and a prompt method in a single array in the following order:
35
+ * - `request` - An instance of [`AuthRequest`](#authrequest) that can be used to prompt the user for authorization.
36
+ * This will be `null` until the auth request has finished loading.
37
+ * - `response` - This is `null` until `promptAsync` has been invoked. Once fulfilled it will return information about the authorization.
38
+ * - `promptAsync` - When invoked, a web browser will open up and prompt the user for authentication.
39
+ * Accepts an [`AuthRequestPromptOptions`](#authrequestpromptoptions) object with options about how the prompt will execute.
40
+ * You can use this to enable the Expo proxy service `auth.expo.io`.
18
41
  *
19
- * @param config
20
- * @param discovery
42
+ * @example
43
+ * ```ts
44
+ * const [request, response, promptAsync] = useAuthRequest({ ... }, { ... });
45
+ * ```
21
46
  */
22
47
  export declare function useAuthRequest(config: AuthRequestConfig, discovery: DiscoveryDocument | null): [
23
48
  AuthRequest | null,
@@ -25,3 +50,4 @@ export declare function useAuthRequest(config: AuthRequestConfig, discovery: Dis
25
50
  (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>
26
51
  ];
27
52
  export {};
53
+ //# sourceMappingURL=AuthRequestHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthRequestHooks.d.ts","sourceRoot":"","sources":["../src/AuthRequestHooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAyB,MAAM,aAAa,CAAC;AAG1F;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,IAAI,CAiB/F;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,iBAAiB,GAAG,IAAI,EACnC,mBAAmB,EAAE,OAAO,WAAW,GACtC,WAAW,GAAG,IAAI,CAmCpB;AAED,aAAK,YAAY,GAAG,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,GAAG,IAAI,EAC3B,SAAS,EAAE,iBAAiB,GAAG,IAAI,EACnC,aAAa,GAAE,wBAA6B,GAC3C,CAAC,iBAAiB,GAAG,IAAI,EAAE,YAAY,CAAC,CAwB1C;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,iBAAiB,GAAG,IAAI,GAClC;IACD,WAAW,GAAG,IAAI;IAClB,iBAAiB,GAAG,IAAI;IACxB,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC,iBAAiB,CAAC;CACnE,CAIA"}
@@ -1,10 +1,18 @@
1
1
  import { useCallback, useMemo, useEffect, useState } from 'react';
2
2
  import { AuthRequest } from './AuthRequest';
3
3
  import { resolveDiscoveryAsync } from './Discovery';
4
+ // @needsAudit
4
5
  /**
5
- * Fetch the discovery document from an OpenID Connect issuer.
6
+ * Given an OpenID Connect issuer URL, this will fetch and return the [`DiscoveryDocument`](#discoverydocument)
7
+ * (a collection of URLs) from the resource provider.
6
8
  *
7
- * @param issuerOrDiscovery
9
+ * @param issuerOrDiscovery URL using the `https` scheme with no query or fragment component that the OP asserts as its Issuer Identifier.
10
+ * @return Returns `null` until the [`DiscoveryDocument`](#discoverydocument) has been fetched from the provided issuer URL.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const discovery = useAutoDiscovery('https://example.com/auth');
15
+ * ```
8
16
  */
9
17
  export function useAutoDiscovery(issuerOrDiscovery) {
10
18
  const [discovery, setDiscovery] = useState(null);
@@ -31,7 +39,6 @@ export function useLoadedAuthRequest(config, discovery, AuthRequestInstance) {
31
39
  const request = new AuthRequestInstance(config);
32
40
  request.makeAuthUrlAsync(discovery).then(() => {
33
41
  if (isMounted) {
34
- // @ts-ignore
35
42
  setRequest(request);
36
43
  }
37
44
  });
@@ -39,9 +46,7 @@ export function useLoadedAuthRequest(config, discovery, AuthRequestInstance) {
39
46
  return () => {
40
47
  isMounted = false;
41
48
  };
42
- },
43
- // eslint-disable-next-line react-hooks/exhaustive-deps
44
- [
49
+ }, [
45
50
  discovery?.authorizationEndpoint,
46
51
  config.clientId,
47
52
  config.redirectUri,
@@ -73,18 +78,35 @@ export function useAuthRequestResult(request, discovery, customOptions = {}) {
73
78
  const result = await request?.promptAsync(discovery, inputOptions);
74
79
  setResult(result);
75
80
  return result;
76
- },
77
- // eslint-disable-next-line react-hooks/exhaustive-deps
78
- [request?.url, discovery?.authorizationEndpoint]);
81
+ }, [request?.url, discovery?.authorizationEndpoint]);
79
82
  return [result, promptAsync];
80
83
  }
84
+ // @needsAudit
81
85
  /**
82
- * Load an authorization request.
83
- * Returns a loaded request, a response, and a prompt method.
84
- * When the prompt method completes then the response will be fulfilled.
86
+ * Load an authorization request for a code. When the prompt method completes then the response will be fulfilled.
87
+ *
88
+ * > In order to close the popup window on web, you need to invoke `WebBrowser.maybeCompleteAuthSession()`.
89
+ * > See the [Identity example](/guides/authentication.md#identityserver-4) for more info.
90
+ *
91
+ * If an Implicit grant flow was used, you can pass the `response.params` to `TokenResponse.fromQueryParams()`
92
+ * to get a `TokenResponse` instance which you can use to easily refresh the token.
93
+ *
94
+ * @param config A valid [`AuthRequestConfig`](#authrequestconfig) that specifies what provider to use.
95
+ * @param discovery A loaded [`DiscoveryDocument`](#discoverydocument) with endpoints used for authenticating.
96
+ * Only `authorizationEndpoint` is required for requesting an authorization code.
97
+ *
98
+ * @return Returns a loaded request, a response, and a prompt method in a single array in the following order:
99
+ * - `request` - An instance of [`AuthRequest`](#authrequest) that can be used to prompt the user for authorization.
100
+ * This will be `null` until the auth request has finished loading.
101
+ * - `response` - This is `null` until `promptAsync` has been invoked. Once fulfilled it will return information about the authorization.
102
+ * - `promptAsync` - When invoked, a web browser will open up and prompt the user for authentication.
103
+ * Accepts an [`AuthRequestPromptOptions`](#authrequestpromptoptions) object with options about how the prompt will execute.
104
+ * You can use this to enable the Expo proxy service `auth.expo.io`.
85
105
  *
86
- * @param config
87
- * @param discovery
106
+ * @example
107
+ * ```ts
108
+ * const [request, response, promptAsync] = useAuthRequest({ ... }, { ... });
109
+ * ```
88
110
  */
89
111
  export function useAuthRequest(config, discovery) {
90
112
  const request = useLoadedAuthRequest(config, discovery, AuthRequest);
@@ -1 +1 @@
1
- {"version":3,"file":"AuthRequestHooks.js","sourceRoot":"","sources":["../src/AuthRequestHooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useMemo, useEffect, useState } from 'react';\n\nimport { AuthRequest } from './AuthRequest';\nimport { AuthRequestConfig, AuthRequestPromptOptions } from './AuthRequest.types';\nimport { AuthSessionResult } from './AuthSession.types';\nimport { DiscoveryDocument, IssuerOrDiscovery, resolveDiscoveryAsync } from './Discovery';\n\n/**\n * Fetch the discovery document from an OpenID Connect issuer.\n *\n * @param issuerOrDiscovery\n */\nexport function useAutoDiscovery(issuerOrDiscovery: IssuerOrDiscovery): DiscoveryDocument | null {\n const [discovery, setDiscovery] = useState<DiscoveryDocument | null>(null);\n\n useEffect(() => {\n let isAllowed = true;\n resolveDiscoveryAsync(issuerOrDiscovery).then((discovery) => {\n if (isAllowed) {\n setDiscovery(discovery);\n }\n });\n\n return () => {\n isAllowed = false;\n };\n }, [issuerOrDiscovery]);\n\n return discovery;\n}\n\nexport function useLoadedAuthRequest(\n config: AuthRequestConfig,\n discovery: DiscoveryDocument | null,\n AuthRequestInstance: typeof AuthRequest\n): AuthRequest | null {\n const [request, setRequest] = useState<AuthRequest | null>(null);\n const scopeString = useMemo(() => config.scopes?.join(','), [config.scopes]);\n const extraParamsString = useMemo(\n () => JSON.stringify(config.extraParams || {}),\n [config.extraParams]\n );\n useEffect(\n () => {\n let isMounted = true;\n\n if (discovery) {\n const request = new AuthRequestInstance(config);\n request.makeAuthUrlAsync(discovery).then(() => {\n if (isMounted) {\n // @ts-ignore\n setRequest(request);\n }\n });\n }\n return () => {\n isMounted = false;\n };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n discovery?.authorizationEndpoint,\n config.clientId,\n config.redirectUri,\n config.responseType,\n config.prompt,\n config.clientSecret,\n config.codeChallenge,\n config.state,\n config.usePKCE,\n scopeString,\n extraParamsString,\n ]\n );\n return request;\n}\n\ntype PromptMethod = (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>;\n\nexport function useAuthRequestResult(\n request: AuthRequest | null,\n discovery: DiscoveryDocument | null,\n customOptions: AuthRequestPromptOptions = {}\n): [AuthSessionResult | null, PromptMethod] {\n const [result, setResult] = useState<AuthSessionResult | null>(null);\n\n const promptAsync = useCallback(\n async ({ windowFeatures = {}, ...options }: AuthRequestPromptOptions = {}) => {\n if (!discovery || !request) {\n throw new Error('Cannot prompt to authenticate until the request has finished loading.');\n }\n const inputOptions = {\n ...customOptions,\n ...options,\n windowFeatures: {\n ...(customOptions.windowFeatures ?? {}),\n ...windowFeatures,\n },\n };\n const result = await request?.promptAsync(discovery, inputOptions);\n setResult(result);\n return result;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [request?.url, discovery?.authorizationEndpoint]\n );\n\n return [result, promptAsync];\n}\n\n/**\n * Load an authorization request.\n * Returns a loaded request, a response, and a prompt method.\n * When the prompt method completes then the response will be fulfilled.\n *\n * @param config\n * @param discovery\n */\nexport function useAuthRequest(\n config: AuthRequestConfig,\n discovery: DiscoveryDocument | null\n): [\n AuthRequest | null,\n AuthSessionResult | null,\n (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>\n] {\n const request = useLoadedAuthRequest(config, discovery, AuthRequest);\n const [result, promptAsync] = useAuthRequestResult(request, discovery);\n return [request, result, promptAsync];\n}\n"]}
1
+ {"version":3,"file":"AuthRequestHooks.js","sourceRoot":"","sources":["../src/AuthRequestHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAwC,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAE1F,cAAc;AACd;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,iBAAoC;IACnE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IAE3E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,qBAAqB,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;YAC1D,IAAI,SAAS,EAAE;gBACb,YAAY,CAAC,SAAS,CAAC,CAAC;aACzB;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAExB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAyB,EACzB,SAAmC,EACnC,mBAAuC;IAEvC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7E,MAAM,iBAAiB,GAAG,OAAO,CAC/B,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,EAC9C,CAAC,MAAM,CAAC,WAAW,CAAC,CACrB,CAAC;IACF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,IAAI,SAAS,EAAE;YACb,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC5C,IAAI,SAAS,EAAE;oBACb,UAAU,CAAC,OAAO,CAAC,CAAC;iBACrB;YACH,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,SAAS,EAAE,qBAAqB;QAChC,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,WAAW;QAClB,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,MAAM;QACb,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,aAAa;QACpB,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,OAAO;QACd,WAAW;QACX,iBAAiB;KAClB,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAID,MAAM,UAAU,oBAAoB,CAClC,OAA2B,EAC3B,SAAmC,EACnC,gBAA0C,EAAE;IAE5C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IAErE,MAAM,WAAW,GAAG,WAAW,CAC7B,KAAK,EAAE,EAAE,cAAc,GAAG,EAAE,EAAE,GAAG,OAAO,KAA+B,EAAE,EAAE,EAAE;QAC3E,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;SAC1F;QACD,MAAM,YAAY,GAAG;YACnB,GAAG,aAAa;YAChB,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,GAAG,CAAC,aAAa,CAAC,cAAc,IAAI,EAAE,CAAC;gBACvC,GAAG,cAAc;aAClB;SACF,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,WAAW,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACnE,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,qBAAqB,CAAC,CACjD,CAAC;IAEF,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC/B,CAAC;AAED,cAAc;AACd;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAyB,EACzB,SAAmC;IAMnC,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACrE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,oBAAoB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACvE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC","sourcesContent":["import { useCallback, useMemo, useEffect, useState } from 'react';\n\nimport { AuthRequest } from './AuthRequest';\nimport { AuthRequestConfig, AuthRequestPromptOptions } from './AuthRequest.types';\nimport { AuthSessionResult } from './AuthSession.types';\nimport { DiscoveryDocument, IssuerOrDiscovery, resolveDiscoveryAsync } from './Discovery';\n\n// @needsAudit\n/**\n * Given an OpenID Connect issuer URL, this will fetch and return the [`DiscoveryDocument`](#discoverydocument)\n * (a collection of URLs) from the resource provider.\n *\n * @param issuerOrDiscovery URL using the `https` scheme with no query or fragment component that the OP asserts as its Issuer Identifier.\n * @return Returns `null` until the [`DiscoveryDocument`](#discoverydocument) has been fetched from the provided issuer URL.\n *\n * @example\n * ```ts\n * const discovery = useAutoDiscovery('https://example.com/auth');\n * ```\n */\nexport function useAutoDiscovery(issuerOrDiscovery: IssuerOrDiscovery): DiscoveryDocument | null {\n const [discovery, setDiscovery] = useState<DiscoveryDocument | null>(null);\n\n useEffect(() => {\n let isAllowed = true;\n resolveDiscoveryAsync(issuerOrDiscovery).then((discovery) => {\n if (isAllowed) {\n setDiscovery(discovery);\n }\n });\n\n return () => {\n isAllowed = false;\n };\n }, [issuerOrDiscovery]);\n\n return discovery;\n}\n\nexport function useLoadedAuthRequest(\n config: AuthRequestConfig,\n discovery: DiscoveryDocument | null,\n AuthRequestInstance: typeof AuthRequest\n): AuthRequest | null {\n const [request, setRequest] = useState<AuthRequest | null>(null);\n const scopeString = useMemo(() => config.scopes?.join(','), [config.scopes]);\n const extraParamsString = useMemo(\n () => JSON.stringify(config.extraParams || {}),\n [config.extraParams]\n );\n useEffect(() => {\n let isMounted = true;\n\n if (discovery) {\n const request = new AuthRequestInstance(config);\n request.makeAuthUrlAsync(discovery).then(() => {\n if (isMounted) {\n setRequest(request);\n }\n });\n }\n return () => {\n isMounted = false;\n };\n }, [\n discovery?.authorizationEndpoint,\n config.clientId,\n config.redirectUri,\n config.responseType,\n config.prompt,\n config.clientSecret,\n config.codeChallenge,\n config.state,\n config.usePKCE,\n scopeString,\n extraParamsString,\n ]);\n return request;\n}\n\ntype PromptMethod = (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>;\n\nexport function useAuthRequestResult(\n request: AuthRequest | null,\n discovery: DiscoveryDocument | null,\n customOptions: AuthRequestPromptOptions = {}\n): [AuthSessionResult | null, PromptMethod] {\n const [result, setResult] = useState<AuthSessionResult | null>(null);\n\n const promptAsync = useCallback(\n async ({ windowFeatures = {}, ...options }: AuthRequestPromptOptions = {}) => {\n if (!discovery || !request) {\n throw new Error('Cannot prompt to authenticate until the request has finished loading.');\n }\n const inputOptions = {\n ...customOptions,\n ...options,\n windowFeatures: {\n ...(customOptions.windowFeatures ?? {}),\n ...windowFeatures,\n },\n };\n const result = await request?.promptAsync(discovery, inputOptions);\n setResult(result);\n return result;\n },\n [request?.url, discovery?.authorizationEndpoint]\n );\n\n return [result, promptAsync];\n}\n\n// @needsAudit\n/**\n * Load an authorization request for a code. When the prompt method completes then the response will be fulfilled.\n *\n * > In order to close the popup window on web, you need to invoke `WebBrowser.maybeCompleteAuthSession()`.\n * > See the [Identity example](/guides/authentication.md#identityserver-4) for more info.\n *\n * If an Implicit grant flow was used, you can pass the `response.params` to `TokenResponse.fromQueryParams()`\n * to get a `TokenResponse` instance which you can use to easily refresh the token.\n *\n * @param config A valid [`AuthRequestConfig`](#authrequestconfig) that specifies what provider to use.\n * @param discovery A loaded [`DiscoveryDocument`](#discoverydocument) with endpoints used for authenticating.\n * Only `authorizationEndpoint` is required for requesting an authorization code.\n *\n * @return Returns a loaded request, a response, and a prompt method in a single array in the following order:\n * - `request` - An instance of [`AuthRequest`](#authrequest) that can be used to prompt the user for authorization.\n * This will be `null` until the auth request has finished loading.\n * - `response` - This is `null` until `promptAsync` has been invoked. Once fulfilled it will return information about the authorization.\n * - `promptAsync` - When invoked, a web browser will open up and prompt the user for authentication.\n * Accepts an [`AuthRequestPromptOptions`](#authrequestpromptoptions) object with options about how the prompt will execute.\n * You can use this to enable the Expo proxy service `auth.expo.io`.\n *\n * @example\n * ```ts\n * const [request, response, promptAsync] = useAuthRequest({ ... }, { ... });\n * ```\n */\nexport function useAuthRequest(\n config: AuthRequestConfig,\n discovery: DiscoveryDocument | null\n): [\n AuthRequest | null,\n AuthSessionResult | null,\n (options?: AuthRequestPromptOptions) => Promise<AuthSessionResult>\n] {\n const request = useLoadedAuthRequest(config, discovery, AuthRequest);\n const [result, promptAsync] = useAuthRequestResult(request, discovery);\n return [request, result, promptAsync];\n}\n"]}