1 | import Constants from 'expo-constants';
|
2 | import qs from 'qs';
|
3 | import Linking from './Linking/Linking';
|
4 | import { openAuthSessionAsync, dismissAuthSession } from 'expo-web-browser';
|
5 | const BASE_URL = `https://auth.expo.io`;
|
6 | let _authLock = false;
|
7 | async function startAsync(options) {
|
8 | const returnUrl = options.returnUrl || getDefaultReturnUrl();
|
9 | const authUrl = options.authUrl;
|
10 | const startUrl = getStartUrl(authUrl, returnUrl);
|
11 |
|
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 |
|
16 |
|
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 |
|
24 | _authLock = true;
|
25 | let result;
|
26 | try {
|
27 | result = await _openWebBrowserAsync(startUrl, returnUrl);
|
28 | }
|
29 | finally {
|
30 |
|
31 | _authLock = false;
|
32 | }
|
33 |
|
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 | }
|
53 | function dismiss() {
|
54 | dismissAuthSession();
|
55 | }
|
56 | async function _openWebBrowserAsync(startUrl, returnUrl) {
|
57 |
|
58 | let result = await openAuthSessionAsync(startUrl, returnUrl);
|
59 | if (result.type === 'cancel' || result.type === 'dismiss') {
|
60 | return { type: result.type };
|
61 | }
|
62 | return result;
|
63 | }
|
64 | function getStartUrl(authUrl, returnUrl) {
|
65 | let queryString = qs.stringify({
|
66 | authUrl,
|
67 | returnUrl,
|
68 | });
|
69 | return `${getRedirectUrl()}/start?${queryString}`;
|
70 | }
|
71 | function getRedirectUrl() {
|
72 | const redirectUrl = `${BASE_URL}/${Constants.manifest.id}`;
|
73 | if (__DEV__) {
|
74 | _warnIfAnonymous(Constants.manifest.id, redirectUrl);
|
75 | }
|
76 | return redirectUrl;
|
77 | }
|
78 | function getDefaultReturnUrl() {
|
79 | return Linking.makeUrl('expo-auth-session');
|
80 | }
|
81 | function 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 |
|
87 | let parsedSearch = qs.parse(queryString);
|
88 |
|
89 | let { errorCode } = parsedSearch;
|
90 | delete parsedSearch.errorCode;
|
91 |
|
92 | let parsedHash = {};
|
93 | if (parts[1]) {
|
94 | parsedHash = qs.parse(hash);
|
95 | }
|
96 |
|
97 | let params = {
|
98 | ...parsedSearch,
|
99 | ...parsedHash,
|
100 | };
|
101 | return {
|
102 | errorCode,
|
103 | params,
|
104 | };
|
105 | }
|
106 | function _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 | }
|
111 | export 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 |
|
\ | No newline at end of file |