expo-auth-session
Version:
Expo module for browser-based authentication
107 lines • 5.21 kB
JavaScript
import Constants, { ExecutionEnvironment } from 'expo-constants';
import * as Linking from 'expo-linking';
import { Platform } from 'expo-modules-core';
export class SessionUrlProvider {
static BASE_URL = `https://auth.expo.io`;
static SESSION_PATH = 'expo-auth-session';
getDefaultReturnUrl(urlPath, options) {
const queryParams = SessionUrlProvider.getHostAddressQueryParams();
let path = SessionUrlProvider.SESSION_PATH;
if (urlPath) {
path = [path, SessionUrlProvider.removeLeadingSlash(urlPath)].filter(Boolean).join('/');
}
return Linking.createURL(path, {
// The redirect URL doesn't matter for the proxy as long as it's valid, so silence warnings if needed.
scheme: options?.scheme ?? Linking.resolveScheme({ isSilent: true }),
queryParams,
isTripleSlashed: options?.isTripleSlashed,
});
}
getStartUrl(authUrl, returnUrl, projectNameForProxy) {
if (Platform.OS === 'web' && !Platform.isDOMAvailable) {
// Return nothing in SSR envs
return '';
}
const queryString = new URLSearchParams({
authUrl,
returnUrl,
});
return `${this.getRedirectUrl({ projectNameForProxy })}/start?${queryString}`;
}
getRedirectUrl(options) {
if (Platform.OS === 'web') {
if (Platform.isDOMAvailable) {
return [window.location.origin, options.urlPath].filter(Boolean).join('/');
}
else {
// Return nothing in SSR envs
return '';
}
}
const legacyExpoProjectFullName = options.projectNameForProxy || Constants.expoConfig?.originalFullName;
if (!legacyExpoProjectFullName) {
let nextSteps = '';
if (__DEV__) {
if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {
nextSteps =
' Ensure you have the latest version of expo-constants installed and recompile your native app. You can verify that originalFullName is defined by running `npx expo config --type public` and inspecting the output.';
}
else if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {
nextSteps =
' Report this as a bug with the contents of `expo config --type public`: https://github.com/expo/expo/issues';
}
}
if (Constants.manifest2) {
nextSteps =
' Prefer AuthRequest in combination with an Expo Development Client build of your application.' +
' To continue using the AuthSession proxy, specify the project full name (@owner/slug) using the projectNameForProxy option.';
}
throw new Error('Cannot use the AuthSession proxy because the project full name is not defined.' + nextSteps);
}
const redirectUrl = `${SessionUrlProvider.BASE_URL}/${legacyExpoProjectFullName}`;
if (__DEV__) {
SessionUrlProvider.warnIfAnonymous(legacyExpoProjectFullName, redirectUrl);
// TODO: Verify with the dev server that the manifest is up to date.
}
return redirectUrl;
}
static getHostAddressQueryParams() {
let hostUri = Constants.expoConfig?.hostUri;
if (!hostUri &&
(ExecutionEnvironment.StoreClient === Constants.executionEnvironment ||
Linking.resolveScheme({}))) {
if (!Constants.linkingUri) {
hostUri = '';
}
else {
// we're probably not using up-to-date xdl, so just fake it for now
// we have to remove the /--/ on the end since this will be inserted again later
hostUri = SessionUrlProvider.removeScheme(Constants.linkingUri).replace(/\/--(\/.*)?$/, '');
}
}
if (!hostUri) {
return undefined;
}
const uriParts = hostUri?.split('?');
try {
return Object.fromEntries(
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
new URLSearchParams(uriParts?.[1]));
}
catch { }
return undefined;
}
static warnIfAnonymous(id, url) {
if (id.startsWith('@anonymous/')) {
console.warn(`You are not currently signed in to Expo on your development machine. As a result, the redirect URL for AuthSession will be "${url}". If you are using an OAuth provider that requires adding redirect URLs to an allow list, we recommend that you do not add this URL -- instead, you should sign in to Expo to acquire a unique redirect URL. Additionally, if you do decide to publish this app using Expo, you will need to register an account to do it.`);
}
}
static removeScheme(url) {
return url.replace(/^[a-zA-Z0-9+.-]+:\/\//, '');
}
static removeLeadingSlash(url) {
return url.replace(/^\//, '');
}
}
export default new SessionUrlProvider();
//# sourceMappingURL=SessionUrlProvider.js.map