UNPKG

4.2 kBJavaScriptView Raw
1import { Constants } from 'expo-constants';
2import qs from 'qs';
3import Linking from './Linking';
4import WebBrowser from './WebBrowser';
5const BASE_URL = `https://auth.expo.io`;
6let _authLock = false;
7async function startAsync(options) {
8 const returnUrl = options.returnUrl || getDefaultReturnUrl();
9 const authUrl = options.authUrl;
10 const startUrl = getStartUrl(authUrl, returnUrl);
11 // Prevent accidentally starting to an empty url
12 if (!authUrl) {
13 throw new Error('No authUrl provided to AuthSession.startAsync. An authUrl is required -- it points to the page where the user will be able to sign in.');
14 }
15 // Prevent multiple sessions from running at the same time, WebBrowser doesn't
16 // support it this makes the behavior predictable.
17 if (_authLock) {
18 if (__DEV__) {
19 console.warn('Attempted to call AuthSession.startAsync multiple times while already active. Only one AuthSession can be active at any given time.');
20 }
21 return { type: 'locked' };
22 }
23 // About to start session, set lock
24 _authLock = true;
25 let result;
26 try {
27 result = await _openWebBrowserAsync(startUrl, returnUrl);
28 }
29 finally {
30 // WebBrowser session complete, unset lock
31 _authLock = false;
32 }
33 // Handle failures
34 if (!result) {
35 throw new Error('Unexpected missing AuthSession result');
36 }
37 if (!result.url) {
38 if (result.type) {
39 return result;
40 }
41 else {
42 throw new Error('Unexpected AuthSession result with missing type');
43 }
44 }
45 let { params, errorCode } = parseUrl(result.url);
46 return {
47 type: errorCode ? 'error' : 'success',
48 params,
49 errorCode,
50 url: result.url,
51 };
52}
53function dismiss() {
54 WebBrowser.dismissAuthSession();
55}
56async function _openWebBrowserAsync(startUrl, returnUrl) {
57 // $FlowIssue: Flow thinks the awaited result can be a promise
58 let result = await WebBrowser.openAuthSessionAsync(startUrl, returnUrl);
59 if (result.type === 'cancel' || result.type === 'dismiss') {
60 return { type: result.type };
61 }
62 return result;
63}
64function getStartUrl(authUrl, returnUrl) {
65 let queryString = qs.stringify({
66 authUrl,
67 returnUrl,
68 });
69 return `${getRedirectUrl()}/start?${queryString}`;
70}
71function getRedirectUrl() {
72 const redirectUrl = `${BASE_URL}/${Constants.manifest.id}`;
73 if (__DEV__) {
74 _warnIfAnonymous(Constants.manifest.id, redirectUrl);
75 }
76 return redirectUrl;
77}
78function getDefaultReturnUrl() {
79 return Linking.makeUrl('expo-auth-session');
80}
81function parseUrl(url) {
82 let parts = url.split('#');
83 let hash = parts[1];
84 let partsWithoutHash = parts[0].split('?');
85 let queryString = partsWithoutHash[partsWithoutHash.length - 1];
86 // Get query string (?hello=world)
87 let parsedSearch = qs.parse(queryString);
88 // Pull errorCode off of params
89 let { errorCode } = parsedSearch;
90 delete parsedSearch.errorCode;
91 // Get hash (#abc=example)
92 let parsedHash = {};
93 if (parts[1]) {
94 parsedHash = qs.parse(hash);
95 }
96 // Merge search and hash
97 let params = {
98 ...parsedSearch,
99 ...parsedHash,
100 };
101 return {
102 errorCode,
103 params,
104 };
105}
106function _warnIfAnonymous(id, url) {
107 if (id.startsWith('@anonymous/')) {
108 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 whitelisting redirect URLs, we recommend that you do not whitelist this URL -- instead, you should sign in to Expo to acquired 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.`);
109 }
110}
111export default {
112 dismiss,
113 getRedirectUrl,
114 getStartUrl,
115 getDefaultReturnUrl,
116 get getRedirectUri() {
117 console.warn('Use AuthSession.getRedirectUrl rather than AuthSession.getRedirectUri (Url instead of Uri)');
118 return getRedirectUrl;
119 },
120 startAsync,
121};
122//# sourceMappingURL=AuthSession.js.map
\No newline at end of file