1import Constants, { ExecutionEnvironment } from 'expo-constants'; 2import * as Linking from 'expo-linking'; 3import { Platform } from 'expo-modules-core'; 4import { dismissAuthSession } from 'expo-web-browser'; 5 6import { AuthRequest } from './AuthRequest'; 7import { 8 AuthRequestConfig, 9 AuthRequestPromptOptions, 10 CodeChallengeMethod, 11 Prompt, 12 ResponseType, 13} from './AuthRequest.types'; 14import { 15 AuthSessionOptions, 16 AuthSessionRedirectUriOptions, 17 AuthSessionResult, 18} from './AuthSession.types'; 19import { 20 DiscoveryDocument, 21 fetchDiscoveryAsync, 22 Issuer, 23 IssuerOrDiscovery, 24 ProviderMetadata, 25 resolveDiscoveryAsync, 26} from './Discovery'; 27import { generateHexStringAsync } from './PKCE'; 28import sessionUrlProvider from './SessionUrlProvider'; 29 30// @needsAudit 31/** 32 * Cancels an active `AuthSession` if there is one. No return value, but if there is an active `AuthSession` 33 * then the Promise returned by the `AuthSession.startAsync()` that initiated it resolves to `{ type: 'dismiss' }`. 34 */ 35export function dismiss() { 36 dismissAuthSession(); 37} 38 39export const getDefaultReturnUrl = sessionUrlProvider.getDefaultReturnUrl; 40 41// @needsAudit @docsMissing 42/** 43 * Get the URL that your authentication provider needs to redirect to. For example: `https://auth.expo.io/@your-username/your-app-slug`. You can pass an additional path component to be appended to the default redirect URL. 44 * > **Note** This method will throw an exception if you're using the bare workflow on native. 45 * 46 * @param path 47 * @return 48 * 49 * @example 50 * ```ts 51 * const url = AuthSession.getRedirectUrl('redirect'); 52 * 53 * // Managed: https://auth.expo.io/@your-username/your-app-slug/redirect 54 * // Web: https://localhost:19006/redirect 55 * ``` 56 * 57 * @deprecated Use `makeRedirectUri()` instead. 58 */ 59export function getRedirectUrl(path?: string): string { 60 return sessionUrlProvider.getRedirectUrl({ urlPath: path }); 61} 62 63// @needsAudit 64/** 65 * Create a redirect url for the current platform and environment. You need to manually define the redirect that will be used in 66 * a bare workflow React Native app, or an Expo standalone app, this is because it cannot be inferred automatically. 67 * - **Web:** Generates a path based on the current `window.location`. For production web apps, you should hard code the URL as well. 68 * - **Managed workflow:** Uses the `scheme` property of your `app.config.js` or `app.json`. 69 * - **Proxy:** Uses `auth.expo.io` as the base URL for the path. This only works in Expo Go and standalone environments. 70 * - **Bare workflow:** Will fallback to using the `native` option for bare workflow React Native apps. 71 * 72 * @param options Additional options for configuring the path. 73 * @return The `redirectUri` to use in an authentication request. 74 * 75 * @example 76 * ```ts 77 * const redirectUri = makeRedirectUri({ 78 * scheme: 'my-scheme', 79 * path: 'redirect' 80 * }); 81 * // Development Build: my-scheme://redirect 82 * // Expo Go: exp://127.0.0.1:8081/--/redirect 83 * // Web dev: https://localhost:19006/redirect 84 * // Web prod: https://yourwebsite.com/redirect 85 * 86 * const redirectUri2 = makeRedirectUri({ 87 * scheme: 'scheme2', 88 * preferLocalhost: true, 89 * isTripleSlashed: true, 90 * }); 91 * // Development Build: scheme2:/// 92 * // Expo Go: exp://localhost:8081 93 * // Web dev: https://localhost:19006 94 * // Web prod: https://yourwebsite.com 95 * ``` 96 */ 97export function makeRedirectUri({ 98 native, 99 scheme, 100 isTripleSlashed, 101 queryParams, 102 path, 103 preferLocalhost, 104}: AuthSessionRedirectUriOptions = {}): string { 105 if ( 106 Platform.OS !== 'web' && 107 native && 108 [ExecutionEnvironment.Standalone, ExecutionEnvironment.Bare].includes( 109 Constants.executionEnvironment 110 ) 111 ) { 112 // Should use the user-defined native scheme in standalone builds 113 return native; 114 } 115 const url = Linking.createURL(path || '', { 116 isTripleSlashed, 117 scheme, 118 queryParams, 119 }); 120 121 if (preferLocalhost) { 122 const ipAddress = url.match( 123 /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/ 124 ); 125 // Only replace if an IP address exists 126 if (ipAddress?.length) { 127 const [protocol, path] = url.split(ipAddress[0]); 128 return `${protocol}localhost${path}`; 129 } 130 } 131 132 return url; 133} 134 135// @needsAudit 136/** 137 * Build an `AuthRequest` and load it before returning. 138 * 139 * @param config A valid [`AuthRequestConfig`](#authrequestconfig) that specifies what provider to use. 140 * @param issuerOrDiscovery A loaded [`DiscoveryDocument`](#discoverydocument) or issuer URL. 141 * (Only `authorizationEndpoint` is required for requesting an authorization code). 142 * @return Returns an instance of `AuthRequest` that can be used to prompt the user for authorization. 143 */ 144export async function loadAsync( 145 config: AuthRequestConfig, 146 issuerOrDiscovery: IssuerOrDiscovery 147): Promise<AuthRequest> { 148 const request = new AuthRequest(config); 149 const discovery = await resolveDiscoveryAsync(issuerOrDiscovery); 150 await request.makeAuthUrlAsync(discovery); 151 return request; 152} 153 154export { useAutoDiscovery, useAuthRequest } from './AuthRequestHooks'; 155export { AuthError, TokenError } from './Errors'; 156 157export { 158 AuthSessionOptions, 159 AuthSessionRedirectUriOptions, 160 AuthSessionResult, 161 AuthRequest, 162 AuthRequestConfig, 163 AuthRequestPromptOptions, 164 CodeChallengeMethod, 165 DiscoveryDocument, 166 Issuer, 167 IssuerOrDiscovery, 168 Prompt, 169 ProviderMetadata, 170 ResponseType, 171 resolveDiscoveryAsync, 172 fetchDiscoveryAsync, 173 generateHexStringAsync, 174}; 175 176export { 177 // Token classes 178 TokenResponse, 179 AccessTokenRequest, 180 RefreshTokenRequest, 181 RevokeTokenRequest, 182 // Token methods 183 revokeAsync, 184 refreshAsync, 185 exchangeCodeAsync, 186 fetchUserInfoAsync, 187} from './TokenRequest'; 188 189// Token types 190export * from './TokenRequest.types'; 191 192// Provider specific types 193export { GoogleAuthRequestConfig } from './providers/Google'; 194export { FacebookAuthRequestConfig } from './providers/Facebook'; 195