UNPKG

2.17 kBJavaScriptView Raw
1// @flow
2import { Linking, NativeModules, Platform } from 'react-native';
3import invariant from 'invariant';
4
5const { ExponentWebBrowser } = NativeModules;
6
7type RedirectEvent = {
8 url: 'string',
9};
10
11async function openBrowserAsync(
12 url: string
13): Promise<{ type: 'cancel' | 'dismissed' }> {
14 return ExponentWebBrowser.openBrowserAsync(url);
15}
16
17function dismissBrowser(): void {
18 ExponentWebBrowser.dismissBrowser();
19}
20
21async function openAuthSessionAsync(
22 url: string,
23 redirectUrl: string
24): Promise<any> {
25 if (_authSessionIsNativelySupported()) {
26 return ExponentWebBrowser.openAuthSessionAsync(url, redirectUrl);
27 } else {
28 return _openAuthSessionPolyfillAsync(url, redirectUrl);
29 }
30}
31
32function dismissAuthSession(): void {
33 if (_authSessionIsNativelySupported()) {
34 ExponentWebBrowser.dismissAuthSession();
35 } else {
36 ExponentWebBrowser.dismissBrowser();
37 }
38}
39
40/* iOS <= 10 and Android polyfill for SFAuthenticationSession flow */
41
42function _authSessionIsNativelySupported() {
43 if (Platform.OS === 'android') {
44 return false;
45 }
46
47 const versionNumber = parseInt(Platform.Version, 10);
48 return versionNumber >= 11;
49}
50
51let _redirectHandler;
52async function _openAuthSessionPolyfillAsync(startUrl, returnUrl) {
53 invariant(
54 !_redirectHandler,
55 'WebBrowser.openAuthSessionAsync is in a bad state. _redirectHandler is defined when it should not be.'
56 );
57
58 let result;
59 let error;
60 try {
61 result = await Promise.race([
62 openBrowserAsync(startUrl),
63 _waitForRedirectAsync(returnUrl),
64 ]);
65 } catch (e) {
66 error = e;
67 }
68
69 dismissBrowser();
70 Linking.removeEventListener('url', _redirectHandler);
71 _redirectHandler = null;
72
73 if (error) {
74 throw error;
75 } else {
76 return result;
77 }
78}
79
80function _waitForRedirectAsync(returnUrl) {
81 return new Promise(resolve => {
82 _redirectHandler = (event: RedirectEvent) => {
83 if (event.url.startsWith(returnUrl)) {
84 resolve({ url: event.url, type: 'success' });
85 }
86 };
87
88 Linking.addEventListener('url', _redirectHandler);
89 });
90}
91
92export default {
93 openBrowserAsync,
94 openAuthSessionAsync,
95 dismissBrowser,
96 dismissAuthSession,
97};