agora-appbuilder-core 4.0.0-ms.3 → 4.0.0-ms.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/src/AppRoutes.tsx +3 -3
- package/template/src/auth/AuthProvider.tsx +165 -82
- package/template/src/auth/AuthRoute.tsx +15 -7
- package/template/src/auth/IDPAuth.electron.tsx +30 -0
- package/template/src/auth/IDPAuth.tsx +20 -2
- package/template/src/auth/IDPLogoutComponent.tsx +149 -0
- package/template/src/auth/config.ts +15 -8
- package/template/src/auth/openIDPURL.electron.tsx +26 -0
- package/template/src/auth/openIDPURL.native.tsx +40 -0
- package/template/src/auth/openIDPURL.tsx +18 -0
- package/template/src/auth/useIDPAuth.electron.tsx +62 -0
- package/template/src/auth/useIDPAuth.native.tsx +66 -0
- package/template/src/auth/useIDPAuth.tsx +36 -17
- package/template/src/auth/useTokenAuth.tsx +50 -33
- package/template/src/components/GraphQLProvider.tsx +32 -35
- package/template/src/components/Navigation.native.tsx +1 -15
- package/template/src/components/Precall.native.tsx +24 -2
- package/template/src/components/Precall.tsx +17 -1
- package/template/src/components/Share.tsx +21 -1
- package/template/src/components/StorageContext.tsx +18 -3
- package/template/src/pages/Create.tsx +21 -1
- package/template/src/pages/Join.tsx +21 -1
- package/template/src/pages/Login.tsx +8 -27
- package/template/src/utils/common.tsx +20 -0
package/package.json
CHANGED
|
@@ -23,16 +23,16 @@ import {Text} from 'react-native';
|
|
|
23
23
|
function AppRoutes() {
|
|
24
24
|
return (
|
|
25
25
|
<Switch>
|
|
26
|
-
<Route exact path={'/login'}>
|
|
26
|
+
{/* <Route exact path={'/login'}>
|
|
27
27
|
<Login />
|
|
28
|
-
</Route>
|
|
28
|
+
</Route> */}
|
|
29
29
|
<Route exact path={'/'}>
|
|
30
30
|
<Redirect to={'/create'} />
|
|
31
31
|
</Route>
|
|
32
32
|
{/* <Route exact path={'/authorize/:token'}>
|
|
33
33
|
<StoreToken />
|
|
34
34
|
</Route> */}
|
|
35
|
-
<Route exact path={'/authorize'}>
|
|
35
|
+
<Route exact path={'/authorize/:token?'}>
|
|
36
36
|
<IDPAuth />
|
|
37
37
|
</Route>
|
|
38
38
|
<AuthRoute exact path={'/join'}>
|
|
@@ -4,7 +4,7 @@ import React, {
|
|
|
4
4
|
useEffect,
|
|
5
5
|
Dispatch,
|
|
6
6
|
SetStateAction,
|
|
7
|
-
|
|
7
|
+
useContext,
|
|
8
8
|
} from 'react';
|
|
9
9
|
import {useHistory, useLocation} from '../components/Router';
|
|
10
10
|
import {gql, useApolloClient} from '@apollo/client';
|
|
@@ -12,12 +12,19 @@ import {useIDPAuth} from './useIDPAuth';
|
|
|
12
12
|
import Loading from '../subComponents/Loading';
|
|
13
13
|
import useTokenAuth from './useTokenAuth';
|
|
14
14
|
import Toast from '../../react-native-toast-message';
|
|
15
|
-
import {
|
|
15
|
+
import {ENABLE_AUTH, GET_UNAUTH_FLOW_API_ENDPOINT} from './config';
|
|
16
16
|
import isSDK from '../utils/isSDK';
|
|
17
17
|
import {Linking} from 'react-native';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
isAndroid,
|
|
20
|
+
isIOS,
|
|
21
|
+
isWeb,
|
|
22
|
+
isDesktop,
|
|
23
|
+
processDeepLinkURI,
|
|
24
|
+
getParamFromURL,
|
|
25
|
+
} from '../utils/common';
|
|
19
26
|
import SDKMethodEventsManager from '../utils/SdkMethodEvents';
|
|
20
|
-
import
|
|
27
|
+
import StorageContext from '../components/StorageContext';
|
|
21
28
|
|
|
22
29
|
const GET_USER = gql`
|
|
23
30
|
query getUser {
|
|
@@ -38,14 +45,17 @@ interface AuthContextInterface {
|
|
|
38
45
|
setIsAuthenticated: Dispatch<SetStateAction<boolean>>;
|
|
39
46
|
authLogin: () => void;
|
|
40
47
|
authLogout: () => void;
|
|
48
|
+
returnTo: string;
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
const AuthContext = createContext<AuthContextInterface | null>(null);
|
|
44
52
|
|
|
45
53
|
const AuthProvider = (props: AuthProviderProps) => {
|
|
54
|
+
const {setStore, store} = useContext(StorageContext);
|
|
46
55
|
const [authenticated, setIsAuthenticated] = useState(false);
|
|
47
56
|
const [authError, setAuthError] = useState<string | null>(null);
|
|
48
57
|
const [loading, setLoading] = useState(true);
|
|
58
|
+
const [returnTo, setReturnTo] = useState('');
|
|
49
59
|
// auth hooks
|
|
50
60
|
const {enableIDPAuth, idpLogout} = useIDPAuth();
|
|
51
61
|
const {enableTokenAuth, tokenLogout} = useTokenAuth();
|
|
@@ -55,26 +65,106 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
55
65
|
// client
|
|
56
66
|
const apolloClient = useApolloClient();
|
|
57
67
|
|
|
58
|
-
const enableAuth = $config.ENABLE_IDP_AUTH || $config.ENABLE_TOKEN_AUTH;
|
|
59
|
-
|
|
60
68
|
useEffect(() => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rej('SDK Login failed' + JSON.stringify(error));
|
|
69
|
+
if (!ENABLE_AUTH && !authenticated && store.token) {
|
|
70
|
+
setIsAuthenticated(true);
|
|
71
|
+
if (isAndroid() || isIOS()) {
|
|
72
|
+
if (returnTo) {
|
|
73
|
+
history.push(returnTo);
|
|
74
|
+
}
|
|
68
75
|
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
}
|
|
77
|
+
}, [store?.token]);
|
|
78
|
+
|
|
79
|
+
const deepLinkUrl = (link: string | null) => {
|
|
80
|
+
console.log('debugging Deep-linking url: ', link);
|
|
81
|
+
|
|
82
|
+
if (link !== null) {
|
|
83
|
+
//deeplinking handling with authentication enabled
|
|
84
|
+
if ($config.ENABLE_IDP_AUTH) {
|
|
85
|
+
const url = processDeepLinkURI(link);
|
|
86
|
+
console.log('debugging Deep-linking processed url', url);
|
|
87
|
+
try {
|
|
88
|
+
if (url?.indexOf('authorize') !== -1) {
|
|
89
|
+
const token = getParamFromURL(url, 'token');
|
|
90
|
+
if (token) {
|
|
91
|
+
console.log('debugging deep-linking got token');
|
|
92
|
+
enableTokenAuth(token)
|
|
93
|
+
.then(() => {
|
|
94
|
+
setIsAuthenticated(true);
|
|
95
|
+
if (returnTo) {
|
|
96
|
+
history.push(returnTo);
|
|
97
|
+
} else {
|
|
98
|
+
history.push('/');
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.catch(() => {
|
|
102
|
+
setIsAuthenticated(false);
|
|
103
|
+
console.log('debugging error on IDP token setting');
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
console.log('debugging deep-linking token is empty');
|
|
107
|
+
history.push('/');
|
|
108
|
+
}
|
|
109
|
+
} else if (url?.indexOf('authorize') === -1) {
|
|
110
|
+
console.log('debugging deep-linking setting return to');
|
|
111
|
+
setReturnTo(url);
|
|
112
|
+
} else {
|
|
113
|
+
history.push(url);
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.log('debugging deep-linking error catch');
|
|
117
|
+
history.push('/');
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
//deeplinking handling with authentication enabled
|
|
121
|
+
console.log('debugging path', processDeepLinkURI(link));
|
|
122
|
+
const url = processDeepLinkURI(link);
|
|
123
|
+
setReturnTo(url);
|
|
76
124
|
}
|
|
77
|
-
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
//handling the deeplink for native
|
|
130
|
+
if (isIOS() || isAndroid()) {
|
|
131
|
+
const deepLink = async () => {
|
|
132
|
+
const initialUrl = await Linking.getInitialURL();
|
|
133
|
+
console.log('debugging getting initialUrl', initialUrl);
|
|
134
|
+
Linking.addEventListener('url', (e) => {
|
|
135
|
+
console.log('debugging url from listener', e.url);
|
|
136
|
+
deepLinkUrl(e.url);
|
|
137
|
+
});
|
|
138
|
+
deepLinkUrl(initialUrl);
|
|
139
|
+
};
|
|
140
|
+
deepLink();
|
|
141
|
+
}
|
|
142
|
+
}, [history]);
|
|
143
|
+
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
if (isSDK()) {
|
|
146
|
+
SDKMethodEventsManager.on('login', async (res, rej, token) => {
|
|
147
|
+
try {
|
|
148
|
+
setStore((prevState) => {
|
|
149
|
+
return {...prevState, token};
|
|
150
|
+
});
|
|
151
|
+
setTimeout(async () => {
|
|
152
|
+
await enableTokenAuth(token);
|
|
153
|
+
res();
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
rej('SDK Login failed' + JSON.stringify(error));
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
SDKMethodEventsManager.on('logout', async (res, rej) => {
|
|
160
|
+
try {
|
|
161
|
+
await tokenLogout();
|
|
162
|
+
res();
|
|
163
|
+
} catch (error) {
|
|
164
|
+
rej('SDK Logout failed' + JSON.stringify(error));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
78
168
|
}, []);
|
|
79
169
|
|
|
80
170
|
useEffect(() => {
|
|
@@ -105,27 +195,35 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
105
195
|
getUserDetails()
|
|
106
196
|
.then((_) => {
|
|
107
197
|
setIsAuthenticated(true);
|
|
108
|
-
|
|
109
|
-
|
|
198
|
+
if (isSDK()) {
|
|
199
|
+
history.push(location.pathname);
|
|
200
|
+
}
|
|
110
201
|
})
|
|
111
|
-
.catch((
|
|
202
|
+
.catch(() => {
|
|
112
203
|
setIsAuthenticated(false);
|
|
113
204
|
authLogin();
|
|
114
|
-
if (!isSDK() && enableAuth) {
|
|
115
|
-
//show session expired notification
|
|
116
|
-
//only on auth enabled and non sdk
|
|
117
|
-
setAuthError('Your session has expird. Kindly login again');
|
|
118
|
-
//todo SDK handle session expire
|
|
119
|
-
}
|
|
120
205
|
});
|
|
121
206
|
}, []);
|
|
122
207
|
|
|
123
208
|
const authLogin = () => {
|
|
124
|
-
|
|
125
|
-
|
|
209
|
+
// Authenticated login flow
|
|
210
|
+
if (ENABLE_AUTH) {
|
|
211
|
+
//AUTH -> IDP -> NATIVE and WEB and DESKTOP
|
|
126
212
|
if ($config.ENABLE_IDP_AUTH && !isSDK()) {
|
|
127
|
-
|
|
128
|
-
|
|
213
|
+
//it will open external web link and post authentication it will redirect to application
|
|
214
|
+
//@ts-ignore
|
|
215
|
+
enableIDPAuth(
|
|
216
|
+
isWeb()
|
|
217
|
+
? location.pathname
|
|
218
|
+
: isDesktop()
|
|
219
|
+
? history
|
|
220
|
+
: isIOS() || isAndroid()
|
|
221
|
+
? deepLinkUrl
|
|
222
|
+
: '',
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
//AUTH -> IDP -> SDK ONLY
|
|
226
|
+
else if ($config.ENABLE_TOKEN_AUTH && isSDK()) {
|
|
129
227
|
enableTokenAuth()
|
|
130
228
|
.then((res) => {
|
|
131
229
|
setIsAuthenticated(true);
|
|
@@ -147,50 +245,37 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
147
245
|
history.push('/create');
|
|
148
246
|
});
|
|
149
247
|
}
|
|
150
|
-
}
|
|
151
|
-
|
|
248
|
+
}
|
|
249
|
+
// Unauthenticated login flow
|
|
250
|
+
else {
|
|
152
251
|
fetch(GET_UNAUTH_FLOW_API_ENDPOINT(), {
|
|
153
252
|
credentials: 'include',
|
|
154
253
|
})
|
|
155
254
|
.then((response) => response.json())
|
|
156
255
|
.then((response) => {
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
256
|
+
// unauthenticated flow all platform we will have to handle the token manually
|
|
257
|
+
// we need to store token manually
|
|
258
|
+
if (!response.token) {
|
|
259
|
+
throw new Error('Token not received');
|
|
260
|
+
} else {
|
|
261
|
+
enableTokenAuth(response.token)
|
|
262
|
+
.then(() => {
|
|
263
|
+
console.log('debugging token auth enabled');
|
|
264
|
+
//set auth enabled on useEffect
|
|
265
|
+
})
|
|
266
|
+
.catch((error) => {
|
|
267
|
+
//we don't need to show token expire/not found toast in the sdk
|
|
268
|
+
//we have event emitter to inform the customer application
|
|
269
|
+
//they have to listen for those events
|
|
270
|
+
if (!isSDK()) {
|
|
271
|
+
if (error instanceof Error) {
|
|
272
|
+
setAuthError(error.message);
|
|
273
|
+
} else {
|
|
274
|
+
setAuthError(error);
|
|
177
275
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
//web/mweb/desktop
|
|
185
|
-
else {
|
|
186
|
-
if (response && response.Code == 0) {
|
|
187
|
-
setIsAuthenticated(true);
|
|
188
|
-
history.push(location.pathname);
|
|
189
|
-
} else {
|
|
190
|
-
setIsAuthenticated(false);
|
|
191
|
-
//TODO fallback
|
|
192
|
-
history.push('/login');
|
|
193
|
-
}
|
|
276
|
+
}
|
|
277
|
+
setIsAuthenticated(false);
|
|
278
|
+
});
|
|
194
279
|
}
|
|
195
280
|
})
|
|
196
281
|
.catch((error) => {
|
|
@@ -200,28 +285,26 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
200
285
|
setAuthError(error);
|
|
201
286
|
}
|
|
202
287
|
setIsAuthenticated(false);
|
|
203
|
-
history.push('/login');
|
|
204
288
|
});
|
|
205
289
|
}
|
|
206
290
|
};
|
|
207
291
|
|
|
208
292
|
const authLogout = () => {
|
|
209
|
-
if (
|
|
293
|
+
if (ENABLE_AUTH && $config.ENABLE_IDP_AUTH && !isSDK()) {
|
|
210
294
|
idpLogout()
|
|
211
295
|
.then((res) => {
|
|
212
296
|
console.log('user successfully logged out');
|
|
297
|
+
setIsAuthenticated(false);
|
|
213
298
|
})
|
|
214
299
|
.catch(() => {
|
|
215
300
|
console.error('user logout failed');
|
|
216
301
|
setAuthError('user logout failed');
|
|
217
|
-
})
|
|
218
|
-
.finally(() => {
|
|
219
|
-
setIsAuthenticated(false);
|
|
220
|
-
history.push('/login');
|
|
221
302
|
});
|
|
222
303
|
} else {
|
|
223
|
-
if (!
|
|
304
|
+
if (!ENABLE_AUTH || isSDK()) {
|
|
224
305
|
//no need to logout because we need token to see the create screen
|
|
306
|
+
//unauth flow no logout
|
|
307
|
+
//sdk with auth flow will use sdk api for logout
|
|
225
308
|
history.push('/create');
|
|
226
309
|
} else {
|
|
227
310
|
tokenLogout()
|
|
@@ -234,7 +317,6 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
234
317
|
})
|
|
235
318
|
.finally(() => {
|
|
236
319
|
setIsAuthenticated(false);
|
|
237
|
-
history.push('/login');
|
|
238
320
|
});
|
|
239
321
|
}
|
|
240
322
|
}
|
|
@@ -247,9 +329,10 @@ const AuthProvider = (props: AuthProviderProps) => {
|
|
|
247
329
|
authenticated,
|
|
248
330
|
authLogin,
|
|
249
331
|
authLogout,
|
|
332
|
+
returnTo,
|
|
250
333
|
}}>
|
|
251
|
-
{
|
|
252
|
-
<Loading text={'Loading
|
|
334
|
+
{(!authenticated && !ENABLE_AUTH) || (ENABLE_AUTH && loading) ? (
|
|
335
|
+
<Loading text={'Loading...'} />
|
|
253
336
|
) : (
|
|
254
337
|
props.children
|
|
255
338
|
)}
|
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
import React, {useEffect, useRef} from 'react';
|
|
13
13
|
import {Route, Redirect} from '../components/Router';
|
|
14
14
|
import Toast from '../../react-native-toast-message';
|
|
15
|
-
|
|
16
15
|
import type {RouteProps} from 'react-router';
|
|
17
16
|
import {useAuth} from './AuthProvider';
|
|
18
17
|
import isSDK from '../utils/isSDK';
|
|
18
|
+
import Loading from '../subComponents/Loading';
|
|
19
|
+
import Login from '../pages/Login';
|
|
20
|
+
import {isAndroid, isIOS} from '../utils/common';
|
|
19
21
|
|
|
20
22
|
interface PrivateRouteProps extends RouteProps {
|
|
21
23
|
children: React.ReactNode;
|
|
@@ -44,14 +46,20 @@ const AuthRoute: React.FC<PrivateRouteProps> = (props) => {
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
return authenticated ? (
|
|
47
|
-
|
|
49
|
+
<>
|
|
50
|
+
<Route {...props} />
|
|
51
|
+
</>
|
|
52
|
+
) : isAndroid() || isIOS() ? (
|
|
53
|
+
//if user closes inapp browser then show login/signup button
|
|
54
|
+
<Login />
|
|
48
55
|
) : (
|
|
49
|
-
<
|
|
50
|
-
to={{
|
|
51
|
-
pathname: '/login',
|
|
52
|
-
}}
|
|
53
|
-
/>
|
|
56
|
+
<Loading text={'Loading...'} />
|
|
54
57
|
);
|
|
58
|
+
// <Redirect
|
|
59
|
+
// to={{
|
|
60
|
+
// pathname: '/login',
|
|
61
|
+
// }}
|
|
62
|
+
// />
|
|
55
63
|
// return (
|
|
56
64
|
// <Route
|
|
57
65
|
// {...props}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, {useEffect} from 'react';
|
|
2
|
+
import {useAuth} from './AuthProvider';
|
|
3
|
+
import {useHistory, useParams} from '../components/Router';
|
|
4
|
+
import Loading from '../subComponents/Loading';
|
|
5
|
+
import useTokenAuth from './useTokenAuth';
|
|
6
|
+
|
|
7
|
+
export const IDPAuth = () => {
|
|
8
|
+
const {setIsAuthenticated} = useAuth();
|
|
9
|
+
const {enableTokenAuth} = useTokenAuth();
|
|
10
|
+
const history = useHistory();
|
|
11
|
+
const {token}: {token: string} = useParams();
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
console.log('debugging electron token', token);
|
|
15
|
+
if (token) {
|
|
16
|
+
enableTokenAuth(token)
|
|
17
|
+
.then(() => {
|
|
18
|
+
setIsAuthenticated(true);
|
|
19
|
+
console.log('debugging electron login success');
|
|
20
|
+
history.push('/');
|
|
21
|
+
})
|
|
22
|
+
.catch(() => {
|
|
23
|
+
setIsAuthenticated(false);
|
|
24
|
+
console.log('debugging electron login failed');
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
return <Loading text={'Authorizing app...'} />;
|
|
30
|
+
};
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
import React, {useEffect} from 'react';
|
|
2
2
|
import {useAuth} from './AuthProvider';
|
|
3
|
-
import {useHistory} from '../components/Router';
|
|
3
|
+
import {useHistory, useParams} from '../components/Router';
|
|
4
4
|
import Loading from '../subComponents/Loading';
|
|
5
5
|
|
|
6
6
|
export const IDPAuth = () => {
|
|
7
7
|
const {setIsAuthenticated} = useAuth();
|
|
8
8
|
const history = useHistory();
|
|
9
|
+
const {token}: {token: string} = useParams();
|
|
10
|
+
//web token set in the cookies, using this route redirect user to origin url
|
|
11
|
+
//token used as path
|
|
12
|
+
|
|
13
|
+
// const getSearchParamFromURL = (url, param) => {
|
|
14
|
+
// const include = url.includes(param);
|
|
15
|
+
|
|
16
|
+
// if (!include) return null;
|
|
17
|
+
|
|
18
|
+
// const params = url.split(/([&,?,=])/);
|
|
19
|
+
// const index = params.indexOf(param);
|
|
20
|
+
// const value = params[index + 2];
|
|
21
|
+
// return value;
|
|
22
|
+
// };
|
|
9
23
|
|
|
10
24
|
useEffect(() => {
|
|
11
25
|
setIsAuthenticated(true);
|
|
12
|
-
|
|
26
|
+
if (token) {
|
|
27
|
+
history.push('/' + token);
|
|
28
|
+
} else {
|
|
29
|
+
history.push('/');
|
|
30
|
+
}
|
|
13
31
|
}, []);
|
|
14
32
|
|
|
15
33
|
return <Loading text={'Authorizing app...'} />;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import React, {SetStateAction, useContext, useState} from 'react';
|
|
2
|
+
import {StyleSheet, Text, View, ViewStyle} from 'react-native';
|
|
3
|
+
import Spacer from '../atoms/Spacer';
|
|
4
|
+
import Popup from '../atoms/Popup';
|
|
5
|
+
import PrimaryButton from '../atoms/PrimaryButton';
|
|
6
|
+
import ThemeConfig from '../theme';
|
|
7
|
+
import {isMobileUA, useIsDesktop} from '../utils/common';
|
|
8
|
+
import TertiaryButton from '../atoms/TertiaryButton';
|
|
9
|
+
import isSDK from '../utils/isSDK';
|
|
10
|
+
import {useAuth} from './AuthProvider';
|
|
11
|
+
|
|
12
|
+
interface LogoutPopupProps {
|
|
13
|
+
modalVisible: boolean;
|
|
14
|
+
setModalVisible: React.Dispatch<SetStateAction<boolean>>;
|
|
15
|
+
logout: () => void;
|
|
16
|
+
}
|
|
17
|
+
const LogoutPopup = (props: LogoutPopupProps) => {
|
|
18
|
+
const isDesktop = useIsDesktop()('popup');
|
|
19
|
+
const logoutLabelHeading = 'Logout?';
|
|
20
|
+
const logoutLabelSubHeading = 'Are you sure you wanna log out?';
|
|
21
|
+
|
|
22
|
+
const cancelBtnLabel = 'CANCEL';
|
|
23
|
+
const confirmBtnLabel = 'CONFIRM';
|
|
24
|
+
return (
|
|
25
|
+
<Popup
|
|
26
|
+
modalVisible={props.modalVisible}
|
|
27
|
+
setModalVisible={props.setModalVisible}
|
|
28
|
+
showCloseIcon={false}
|
|
29
|
+
contentContainerStyle={styles.contentContainer}>
|
|
30
|
+
<Text style={styles.heading}>{logoutLabelHeading}</Text>
|
|
31
|
+
<Spacer size={8} />
|
|
32
|
+
<Text style={styles.subHeading}>{logoutLabelSubHeading}</Text>
|
|
33
|
+
<Spacer size={32} />
|
|
34
|
+
<View style={isDesktop ? styles.btnContainer : styles.btnContainerMobile}>
|
|
35
|
+
<View style={isDesktop && {flex: 1}}>
|
|
36
|
+
<TertiaryButton
|
|
37
|
+
containerStyle={{
|
|
38
|
+
minWidth: 'auto',
|
|
39
|
+
width: isDesktop ? 90 : '100%',
|
|
40
|
+
height: 48,
|
|
41
|
+
paddingVertical: 12,
|
|
42
|
+
paddingHorizontal: 12,
|
|
43
|
+
borderRadius: ThemeConfig.BorderRadius.medium,
|
|
44
|
+
}}
|
|
45
|
+
textStyle={styles.btnText}
|
|
46
|
+
text={cancelBtnLabel}
|
|
47
|
+
onPress={() => {
|
|
48
|
+
props.setModalVisible(false);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
</View>
|
|
52
|
+
<Spacer
|
|
53
|
+
size={isDesktop ? 10 : 20}
|
|
54
|
+
horizontal={isDesktop ? true : false}
|
|
55
|
+
/>
|
|
56
|
+
<View style={isDesktop && {flex: 2}}>
|
|
57
|
+
<PrimaryButton
|
|
58
|
+
containerStyle={{
|
|
59
|
+
minWidth: 'auto',
|
|
60
|
+
width: '100%',
|
|
61
|
+
borderRadius: ThemeConfig.BorderRadius.medium,
|
|
62
|
+
height: 48,
|
|
63
|
+
backgroundColor: $config.SEMANTIC_ERROR,
|
|
64
|
+
paddingVertical: 12,
|
|
65
|
+
paddingHorizontal: 12,
|
|
66
|
+
}}
|
|
67
|
+
textStyle={styles.btnText}
|
|
68
|
+
text={confirmBtnLabel}
|
|
69
|
+
onPress={props.logout}
|
|
70
|
+
/>
|
|
71
|
+
</View>
|
|
72
|
+
</View>
|
|
73
|
+
</Popup>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const styles = StyleSheet.create({
|
|
78
|
+
btnContainer: {
|
|
79
|
+
flex: 1,
|
|
80
|
+
flexDirection: 'row',
|
|
81
|
+
justifyContent: 'center',
|
|
82
|
+
alignItems: 'center',
|
|
83
|
+
},
|
|
84
|
+
btnText: {
|
|
85
|
+
fontWeight: '600',
|
|
86
|
+
fontSize: 16,
|
|
87
|
+
lineHeight: 24,
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
btnContainerMobile: {
|
|
91
|
+
flexDirection: 'column-reverse',
|
|
92
|
+
},
|
|
93
|
+
contentContainer: {
|
|
94
|
+
padding: 24,
|
|
95
|
+
maxWidth: 342,
|
|
96
|
+
minWidth: 342,
|
|
97
|
+
},
|
|
98
|
+
heading: {
|
|
99
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
100
|
+
fontWeight: '600',
|
|
101
|
+
fontSize: 22,
|
|
102
|
+
color: $config.SEMANTIC_ERROR,
|
|
103
|
+
},
|
|
104
|
+
subHeading: {
|
|
105
|
+
fontFamily: ThemeConfig.FontFamily.sansPro,
|
|
106
|
+
fontWeight: '400',
|
|
107
|
+
fontSize: ThemeConfig.FontSize.small,
|
|
108
|
+
color: $config.FONT_COLOR,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
interface IDPLogoutComponentProps {
|
|
113
|
+
containerStyle?: ViewStyle;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const IDPLogoutComponent = (props?: IDPLogoutComponentProps) => {
|
|
117
|
+
const {authenticated, authLogout} = useAuth();
|
|
118
|
+
const [modalVisible, setModalVisible] = useState(false);
|
|
119
|
+
return authenticated && $config.ENABLE_IDP_AUTH && !isSDK() ? (
|
|
120
|
+
<View
|
|
121
|
+
style={[
|
|
122
|
+
{
|
|
123
|
+
zIndex: 999,
|
|
124
|
+
maxWidth: 80,
|
|
125
|
+
marginTop: isMobileUA() ? 16 : 32,
|
|
126
|
+
marginRight: isMobileUA() ? 16 : 32,
|
|
127
|
+
alignSelf: 'flex-end',
|
|
128
|
+
},
|
|
129
|
+
props?.containerStyle,
|
|
130
|
+
]}>
|
|
131
|
+
<LogoutPopup
|
|
132
|
+
logout={() => {
|
|
133
|
+
authLogout();
|
|
134
|
+
}}
|
|
135
|
+
modalVisible={modalVisible}
|
|
136
|
+
setModalVisible={setModalVisible}
|
|
137
|
+
/>
|
|
138
|
+
<TertiaryButton
|
|
139
|
+
text="Logout"
|
|
140
|
+
onPress={() => {
|
|
141
|
+
setModalVisible(true);
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
</View>
|
|
145
|
+
) : (
|
|
146
|
+
<></>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
export default IDPLogoutComponent;
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isWebInternal,
|
|
3
|
+
isAndroid,
|
|
4
|
+
isIOS,
|
|
5
|
+
isWeb,
|
|
6
|
+
isDesktop,
|
|
7
|
+
} from '../utils/common';
|
|
2
8
|
import isSDK from '../utils/isSDK';
|
|
3
9
|
|
|
10
|
+
export const AUTH_ENDPOINT_URL = `${$config.BACKEND_ENDPOINT}/v1/idp/login`;
|
|
11
|
+
|
|
12
|
+
export const ENABLE_AUTH = $config.ENABLE_IDP_AUTH || $config.ENABLE_TOKEN_AUTH;
|
|
13
|
+
|
|
4
14
|
export const getPlatformId = (): string => {
|
|
5
15
|
let platformID = 'turnkey_web';
|
|
6
16
|
// Turnkey
|
|
7
|
-
|
|
17
|
+
isWeb() && (platformID = 'turnkey_web');
|
|
18
|
+
isDesktop() && (platformID = 'turnkey_desktop');
|
|
8
19
|
(isAndroid() || isIOS()) && (platformID = 'turnkey_native');
|
|
9
20
|
// SDKs
|
|
10
21
|
isSDK() && isWebInternal() && (platformID = 'sdk_web');
|
|
@@ -19,24 +30,20 @@ export const getRequestHeaders = () => {
|
|
|
19
30
|
'X-Platform-ID': getPlatformId(),
|
|
20
31
|
};
|
|
21
32
|
};
|
|
22
|
-
|
|
23
33
|
export const getIDPAuthRedirectURL = () => {
|
|
24
|
-
return
|
|
34
|
+
return isWeb()
|
|
25
35
|
? `${window.location.origin}/authorize`
|
|
26
36
|
: `${$config.FRONTEND_ENDPOINT}/authorize`;
|
|
27
37
|
};
|
|
28
38
|
|
|
29
39
|
export const getUnauthLoginRedirectURL = () => {
|
|
30
|
-
// return 'https://conferencing.agora.io';
|
|
31
40
|
return isWebInternal()
|
|
32
41
|
? `${window.location.origin}/create`
|
|
33
42
|
: `${$config.FRONTEND_ENDPOINT}/create`;
|
|
34
43
|
};
|
|
35
44
|
|
|
36
45
|
export const getOriginURL = () => {
|
|
37
|
-
return
|
|
38
|
-
? `${window.location.origin}`
|
|
39
|
-
: `${$config.FRONTEND_ENDPOINT}`;
|
|
46
|
+
return isWeb() ? `${window.location.origin}` : `${$config.FRONTEND_ENDPOINT}`;
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
export const GET_UNAUTH_FLOW_API_ENDPOINT = () =>
|