@quiltt/react-native 3.6.6 → 3.6.8

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/CHANGELOG.md CHANGED
@@ -1,14 +1,24 @@
1
1
  # @quiltt/react-native
2
2
 
3
- ## 3.6.6
3
+ ## 3.6.8
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - [#251](https://github.com/quiltt/quiltt-js/pull/251) [`07a3eb1`](https://github.com/quiltt/quiltt-js/commit/07a3eb1b2b719ae1073287079d6a0e61e432cc96) Thanks [@zubairaziz](https://github.com/zubairaziz)! - Update @quiltt/react-native OAuthURL handling
7
+ - [#258](https://github.com/quiltt/quiltt-js/pull/258) [`dc97e95`](https://github.com/quiltt/quiltt-js/commit/dc97e95dfa73bc1ccf09add6af70e4f95a458fab) Thanks [@rubendinho](https://github.com/rubendinho)! - Add URLs to WebView allowList
8
8
 
9
- - Updated dependencies [[`07a3eb1`](https://github.com/quiltt/quiltt-js/commit/07a3eb1b2b719ae1073287079d6a0e61e432cc96)]:
10
- - @quiltt/react@3.6.6
11
- - @quiltt/core@3.6.6
9
+ - Updated dependencies [[`dc97e95`](https://github.com/quiltt/quiltt-js/commit/dc97e95dfa73bc1ccf09add6af70e4f95a458fab)]:
10
+ - @quiltt/core@3.6.8
11
+ - @quiltt/react@3.6.8
12
+
13
+ ## 3.6.7
14
+
15
+ ### Patch Changes
16
+
17
+ - [#256](https://github.com/quiltt/quiltt-js/pull/256) [`824e21e`](https://github.com/quiltt/quiltt-js/commit/824e21e14b4731e5ebb0d8bd3ba141ca7d9418e2) Thanks [@zubairaziz](https://github.com/zubairaziz)! - Add Google recaptcha to allowed URLs
18
+
19
+ - Updated dependencies [[`824e21e`](https://github.com/quiltt/quiltt-js/commit/824e21e14b4731e5ebb0d8bd3ba141ca7d9418e2)]:
20
+ - @quiltt/react@3.6.7
21
+ - @quiltt/core@3.6.7
12
22
 
13
23
  ## 3.6.5
14
24
 
package/dist/index.cjs CHANGED
@@ -10,13 +10,126 @@ var reactNativeWebview = require('react-native-webview');
10
10
  var reactNative = require('react-native');
11
11
  var util = require('@honeybadger-io/core/build/src/util');
12
12
 
13
+ // Generated by genversion.
14
+ const version = '3.6.8';
15
+
16
+ const AndroidSafeAreaView = ({ testId, children })=>/*#__PURE__*/ jsxRuntime.jsx(reactNative.SafeAreaView, {
17
+ testID: testId,
18
+ style: styles$1.AndroidSafeArea,
19
+ children: children
20
+ });
21
+ const styles$1 = reactNative.StyleSheet.create({
22
+ AndroidSafeArea: {
23
+ flex: 1,
24
+ backgroundColor: 'white',
25
+ paddingTop: reactNative.Platform.OS === 'android' ? reactNative.StatusBar.currentHeight : 0
26
+ }
27
+ });
28
+
29
+ const ErrorScreen = ({ testId, error, cta })=>/*#__PURE__*/ jsxRuntime.jsx(AndroidSafeAreaView, {
30
+ testId: testId,
31
+ children: /*#__PURE__*/ jsxRuntime.jsxs(reactNative.View, {
32
+ style: [
33
+ styles.container,
34
+ styles.padding
35
+ ],
36
+ children: [
37
+ /*#__PURE__*/ jsxRuntime.jsxs(reactNative.View, {
38
+ style: {
39
+ flex: 1,
40
+ justifyContent: 'center'
41
+ },
42
+ children: [
43
+ /*#__PURE__*/ jsxRuntime.jsx(reactNative.View, {
44
+ style: {
45
+ flexDirection: 'row',
46
+ justifyContent: 'space-between',
47
+ alignItems: 'center',
48
+ marginVertical: 10
49
+ },
50
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
51
+ style: [
52
+ styles.title
53
+ ],
54
+ children: "Cannot connect to the internet."
55
+ })
56
+ }),
57
+ /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
58
+ style: [
59
+ styles.subtitle
60
+ ],
61
+ children: error
62
+ })
63
+ ]
64
+ }),
65
+ /*#__PURE__*/ jsxRuntime.jsx(reactNative.Pressable, {
66
+ style: [
67
+ styles.pressable
68
+ ],
69
+ onPress: cta,
70
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
71
+ style: [
72
+ styles.pressableText
73
+ ],
74
+ children: "Exit"
75
+ })
76
+ })
77
+ ]
78
+ })
79
+ });
80
+ const styles = reactNative.StyleSheet.create({
81
+ container: {
82
+ flex: 1,
83
+ flexDirection: 'column',
84
+ justifyContent: 'flex-start',
85
+ alignItems: 'stretch',
86
+ backgroundColor: '#F3F4F6'
87
+ },
88
+ title: {
89
+ color: '#1F2937',
90
+ fontSize: 30,
91
+ fontWeight: 'bold'
92
+ },
93
+ subtitle: {
94
+ color: 'rgba(107, 114, 128, 1)'
95
+ },
96
+ padding: {
97
+ paddingHorizontal: 16,
98
+ paddingVertical: 24
99
+ },
100
+ pressable: {
101
+ marginTop: 20,
102
+ backgroundColor: '#1F2937',
103
+ padding: 10,
104
+ paddingHorizontal: 25,
105
+ borderRadius: 5
106
+ },
107
+ pressableText: {
108
+ color: '#fff',
109
+ textAlign: 'center'
110
+ }
111
+ });
112
+
113
+ const LoadingScreen = ({ testId })=>/*#__PURE__*/ jsxRuntime.jsx(AndroidSafeAreaView, {
114
+ testId: testId,
115
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.View, {
116
+ style: {
117
+ flex: 1,
118
+ justifyContent: 'center',
119
+ alignItems: 'center'
120
+ },
121
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.ActivityIndicator, {
122
+ testID: "activity-indicator",
123
+ size: "large",
124
+ color: "#5928A3"
125
+ })
126
+ })
127
+ });
128
+
13
129
  const ErrorReporterConfig = {
14
130
  honeybadger_api_key: 'undefined'
15
131
  };
16
132
 
17
- // Generated by genversion.
18
- const version = '3.6.6';
19
-
20
133
  // Quick hack to send error to Honeybadger to debug why the connector is not routable
21
134
  const notifier = {
22
135
  name: 'Quiltt React Native SDK Reporter',
@@ -101,7 +214,7 @@ const getErrorMessage = (responseStatus, error)=>{
101
214
  return responseStatus ? `The URL is not routable. Response status: ${responseStatus}` : 'An error occurred while checking the connector URL';
102
215
  };
103
216
 
104
- const errorReporter$1 = new ErrorReporter(`${reactNative.Platform.OS} ${reactNative.Platform.Version}`);
217
+ const errorReporter = new ErrorReporter(`${reactNative.Platform.OS} ${reactNative.Platform.Version}`);
105
218
  const PREFLIGHT_RETRY_COUNT = 3;
106
219
  const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
107
220
  let responseStatus;
@@ -136,149 +249,21 @@ const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
136
249
  connectorUrl,
137
250
  responseStatus
138
251
  };
139
- if (responseStatus !== 404) await errorReporter$1.send(errorToSend, context);
252
+ if (responseStatus !== 404) await errorReporter.send(errorToSend, context);
140
253
  return {
141
254
  checked: true,
142
255
  error: errorMessage
143
256
  };
144
257
  };
145
258
 
146
- const errorReporter = new ErrorReporter(`${reactNative.Platform.OS} ${reactNative.Platform.Version}`);
147
- const handleOAuthUrl = async (oauthUrl, context)=>{
148
- const parsedUrl = new reactNativeUrlPolyfill.URL(oauthUrl.href);
149
- try {
150
- // Check if the URL protocol is HTTPS
151
- if (parsedUrl.protocol !== 'https:') {
152
- console.warn(`handleOAuthUrl - Skipping non-HTTPS URL - ${parsedUrl.href}`);
153
- return;
154
- }
155
- // Open the URL using Linking module
156
- await reactNative.Linking.openURL(parsedUrl.href);
157
- } catch (error) {
158
- console.error('handleOAuthUrl - Error opening URL:', error);
159
- // Report error to HoneyBadger
160
- const errorContext = {
161
- ...context,
162
- oauthUrl: parsedUrl.href,
163
- passedUrl: oauthUrl.toString()
164
- };
165
- await errorReporter.send(error, errorContext);
259
+ const handleOAuthUrl = (oauthUrl)=>{
260
+ if (oauthUrl.protocol !== 'https:') {
261
+ console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`);
262
+ return;
166
263
  }
264
+ reactNative.Linking.openURL(oauthUrl.href);
167
265
  };
168
266
 
169
- const AndroidSafeAreaView = ({ testId, children })=>/*#__PURE__*/ jsxRuntime.jsx(reactNative.SafeAreaView, {
170
- testID: testId,
171
- style: styles$1.AndroidSafeArea,
172
- children: children
173
- });
174
- const styles$1 = reactNative.StyleSheet.create({
175
- AndroidSafeArea: {
176
- flex: 1,
177
- backgroundColor: 'white',
178
- paddingTop: reactNative.Platform.OS === 'android' ? reactNative.StatusBar.currentHeight : 0
179
- }
180
- });
181
-
182
- const ErrorScreen = ({ testId, error, cta })=>/*#__PURE__*/ jsxRuntime.jsx(AndroidSafeAreaView, {
183
- testId: testId,
184
- children: /*#__PURE__*/ jsxRuntime.jsxs(reactNative.View, {
185
- style: [
186
- styles.container,
187
- styles.padding
188
- ],
189
- children: [
190
- /*#__PURE__*/ jsxRuntime.jsxs(reactNative.View, {
191
- style: {
192
- flex: 1,
193
- justifyContent: 'center'
194
- },
195
- children: [
196
- /*#__PURE__*/ jsxRuntime.jsx(reactNative.View, {
197
- style: {
198
- flexDirection: 'row',
199
- justifyContent: 'space-between',
200
- alignItems: 'center',
201
- marginVertical: 10
202
- },
203
- children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
204
- style: [
205
- styles.title
206
- ],
207
- children: "Cannot connect to the internet."
208
- })
209
- }),
210
- /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
211
- style: [
212
- styles.subtitle
213
- ],
214
- children: error
215
- })
216
- ]
217
- }),
218
- /*#__PURE__*/ jsxRuntime.jsx(reactNative.Pressable, {
219
- style: [
220
- styles.pressable
221
- ],
222
- onPress: cta,
223
- children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.Text, {
224
- style: [
225
- styles.pressableText
226
- ],
227
- children: "Exit"
228
- })
229
- })
230
- ]
231
- })
232
- });
233
- const styles = reactNative.StyleSheet.create({
234
- container: {
235
- flex: 1,
236
- flexDirection: 'column',
237
- justifyContent: 'flex-start',
238
- alignItems: 'stretch',
239
- backgroundColor: '#F3F4F6'
240
- },
241
- title: {
242
- color: '#1F2937',
243
- fontSize: 30,
244
- fontWeight: 'bold'
245
- },
246
- subtitle: {
247
- color: 'rgba(107, 114, 128, 1)'
248
- },
249
- padding: {
250
- paddingHorizontal: 16,
251
- paddingVertical: 24
252
- },
253
- pressable: {
254
- marginTop: 20,
255
- backgroundColor: '#1F2937',
256
- padding: 10,
257
- paddingHorizontal: 25,
258
- borderRadius: 5
259
- },
260
- pressableText: {
261
- color: '#fff',
262
- textAlign: 'center'
263
- }
264
- });
265
-
266
- const LoadingScreen = ({ testId })=>/*#__PURE__*/ jsxRuntime.jsx(AndroidSafeAreaView, {
267
- testId: testId,
268
- children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.View, {
269
- style: {
270
- flex: 1,
271
- justifyContent: 'center',
272
- alignItems: 'center'
273
- },
274
- children: /*#__PURE__*/ jsxRuntime.jsx(reactNative.ActivityIndicator, {
275
- testID: "activity-indicator",
276
- size: "large",
277
- color: "#5928A3"
278
- })
279
- })
280
- });
281
-
282
267
  const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError })=>{
283
268
  const webViewRef = react$1.useRef(null);
284
269
  const { session } = react.useQuilttSession();
@@ -335,13 +320,20 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
335
320
  session?.token
336
321
  ]);
337
322
  // allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview
338
- // For other urls, we assume those are bank urls, which needs to be handle in external browser.
323
+ // For other urls, we assume those are bank urls, which need to be handled in external browser.
339
324
  // TODO: Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.
340
325
  const allowedListUrl = react$1.useMemo(()=>[
326
+ 'quiltt.io',
341
327
  'quiltt.app',
342
328
  'quiltt.dev',
343
329
  'moneydesktop.com',
344
- 'cdn.plaid.com'
330
+ 'plaid.com',
331
+ 'https://cdn.plaid.com/link',
332
+ 'https://www.google.com/recaptcha',
333
+ 'https://challenges.cloudflare.com',
334
+ 'https://api.stripe.com',
335
+ 'https://cdn.jsdelivr.net',
336
+ 'https://auth0.com'
345
337
  ], []);
346
338
  const isQuilttEvent = react$1.useCallback((url)=>url.protocol === 'quilttconnector:', []);
347
339
  const shouldRender = react$1.useCallback((url)=>{
@@ -354,10 +346,10 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
354
346
  allowedListUrl,
355
347
  isQuilttEvent
356
348
  ]);
357
- const clearLocalStorage = react$1.useCallback(()=>{
349
+ const clearLocalStorage = ()=>{
358
350
  const script = 'localStorage.clear();';
359
351
  webViewRef.current?.injectJavaScript(script);
360
- }, []);
352
+ };
361
353
  const handleQuilttEvent = react$1.useCallback((url)=>{
362
354
  url.searchParams.delete('source');
363
355
  url.searchParams.append('connectorId', connectorId);
@@ -390,12 +382,7 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
390
382
  case 'Authenticate':
391
383
  break;
392
384
  case 'OauthRequested':
393
- handleOAuthUrl(new reactNativeUrlPolyfill.URL(url.searchParams.get('oauthUrl')), {
394
- connectorId,
395
- connectionId,
396
- institution,
397
- oauthRedirectUrl
398
- });
385
+ handleOAuthUrl(new reactNativeUrlPolyfill.URL(url.searchParams.get('oauthUrl')));
399
386
  break;
400
387
  default:
401
388
  console.log('unhandled event', url);
@@ -405,15 +392,11 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
405
392
  connectorId,
406
393
  initInjectedJavaScript,
407
394
  onEvent,
408
- onLoad,
409
- clearLocalStorage,
410
395
  onExit,
411
396
  onExitAbort,
412
397
  onExitError,
413
398
  onExitSuccess,
414
- connectionId,
415
- institution,
416
- oauthRedirectUrl
399
+ onLoad
417
400
  ]);
418
401
  const requestHandler = react$1.useCallback((request)=>{
419
402
  const url = new reactNativeUrlPolyfill.URL(request.url);
@@ -424,20 +407,11 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
424
407
  if (shouldRender(url)) return true;
425
408
  // Plaid set oauth url by doing window.location.href = url
426
409
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
427
- handleOAuthUrl(url, {
428
- connectorId,
429
- connectionId,
430
- institution,
431
- oauthRedirectUrl
432
- });
410
+ handleOAuthUrl(url);
433
411
  return false;
434
412
  }, [
435
- connectionId,
436
- connectorId,
437
413
  handleQuilttEvent,
438
- institution,
439
414
  isQuilttEvent,
440
- oauthRedirectUrl,
441
415
  shouldRender
442
416
  ]);
443
417
  if (!preFlightCheck.checked) return /*#__PURE__*/ jsxRuntime.jsx(LoadingScreen, {
package/dist/index.js CHANGED
@@ -6,16 +6,129 @@ import { jsx, jsxs } from 'react/jsx-runtime';
6
6
  import { useRef, useMemo, useState, useEffect, useCallback } from 'react';
7
7
  import { URL } from 'react-native-url-polyfill';
8
8
  import { WebView } from 'react-native-webview';
9
- import { Platform, Linking, StyleSheet, StatusBar, SafeAreaView, View, Text, Pressable, ActivityIndicator } from 'react-native';
9
+ import { StyleSheet, Platform, StatusBar, SafeAreaView, View, Text, Pressable, ActivityIndicator, Linking } from 'react-native';
10
10
  import { generateStackTrace, makeBacktrace, getCauses } from '@honeybadger-io/core/build/src/util';
11
11
 
12
+ // Generated by genversion.
13
+ const version = '3.6.8';
14
+
15
+ const AndroidSafeAreaView = ({ testId, children })=>/*#__PURE__*/ jsx(SafeAreaView, {
16
+ testID: testId,
17
+ style: styles$1.AndroidSafeArea,
18
+ children: children
19
+ });
20
+ const styles$1 = StyleSheet.create({
21
+ AndroidSafeArea: {
22
+ flex: 1,
23
+ backgroundColor: 'white',
24
+ paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0
25
+ }
26
+ });
27
+
28
+ const ErrorScreen = ({ testId, error, cta })=>/*#__PURE__*/ jsx(AndroidSafeAreaView, {
29
+ testId: testId,
30
+ children: /*#__PURE__*/ jsxs(View, {
31
+ style: [
32
+ styles.container,
33
+ styles.padding
34
+ ],
35
+ children: [
36
+ /*#__PURE__*/ jsxs(View, {
37
+ style: {
38
+ flex: 1,
39
+ justifyContent: 'center'
40
+ },
41
+ children: [
42
+ /*#__PURE__*/ jsx(View, {
43
+ style: {
44
+ flexDirection: 'row',
45
+ justifyContent: 'space-between',
46
+ alignItems: 'center',
47
+ marginVertical: 10
48
+ },
49
+ children: /*#__PURE__*/ jsx(Text, {
50
+ style: [
51
+ styles.title
52
+ ],
53
+ children: "Cannot connect to the internet."
54
+ })
55
+ }),
56
+ /*#__PURE__*/ jsx(Text, {
57
+ style: [
58
+ styles.subtitle
59
+ ],
60
+ children: error
61
+ })
62
+ ]
63
+ }),
64
+ /*#__PURE__*/ jsx(Pressable, {
65
+ style: [
66
+ styles.pressable
67
+ ],
68
+ onPress: cta,
69
+ children: /*#__PURE__*/ jsx(Text, {
70
+ style: [
71
+ styles.pressableText
72
+ ],
73
+ children: "Exit"
74
+ })
75
+ })
76
+ ]
77
+ })
78
+ });
79
+ const styles = StyleSheet.create({
80
+ container: {
81
+ flex: 1,
82
+ flexDirection: 'column',
83
+ justifyContent: 'flex-start',
84
+ alignItems: 'stretch',
85
+ backgroundColor: '#F3F4F6'
86
+ },
87
+ title: {
88
+ color: '#1F2937',
89
+ fontSize: 30,
90
+ fontWeight: 'bold'
91
+ },
92
+ subtitle: {
93
+ color: 'rgba(107, 114, 128, 1)'
94
+ },
95
+ padding: {
96
+ paddingHorizontal: 16,
97
+ paddingVertical: 24
98
+ },
99
+ pressable: {
100
+ marginTop: 20,
101
+ backgroundColor: '#1F2937',
102
+ padding: 10,
103
+ paddingHorizontal: 25,
104
+ borderRadius: 5
105
+ },
106
+ pressableText: {
107
+ color: '#fff',
108
+ textAlign: 'center'
109
+ }
110
+ });
111
+
112
+ const LoadingScreen = ({ testId })=>/*#__PURE__*/ jsx(AndroidSafeAreaView, {
113
+ testId: testId,
114
+ children: /*#__PURE__*/ jsx(View, {
115
+ style: {
116
+ flex: 1,
117
+ justifyContent: 'center',
118
+ alignItems: 'center'
119
+ },
120
+ children: /*#__PURE__*/ jsx(ActivityIndicator, {
121
+ testID: "activity-indicator",
122
+ size: "large",
123
+ color: "#5928A3"
124
+ })
125
+ })
126
+ });
127
+
12
128
  const ErrorReporterConfig = {
13
129
  honeybadger_api_key: 'undefined'
14
130
  };
15
131
 
16
- // Generated by genversion.
17
- const version = '3.6.6';
18
-
19
132
  // Quick hack to send error to Honeybadger to debug why the connector is not routable
20
133
  const notifier = {
21
134
  name: 'Quiltt React Native SDK Reporter',
@@ -100,7 +213,7 @@ const getErrorMessage = (responseStatus, error)=>{
100
213
  return responseStatus ? `The URL is not routable. Response status: ${responseStatus}` : 'An error occurred while checking the connector URL';
101
214
  };
102
215
 
103
- const errorReporter$1 = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
216
+ const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
104
217
  const PREFLIGHT_RETRY_COUNT = 3;
105
218
  const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
106
219
  let responseStatus;
@@ -135,149 +248,21 @@ const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
135
248
  connectorUrl,
136
249
  responseStatus
137
250
  };
138
- if (responseStatus !== 404) await errorReporter$1.send(errorToSend, context);
251
+ if (responseStatus !== 404) await errorReporter.send(errorToSend, context);
139
252
  return {
140
253
  checked: true,
141
254
  error: errorMessage
142
255
  };
143
256
  };
144
257
 
145
- const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
146
- const handleOAuthUrl = async (oauthUrl, context)=>{
147
- const parsedUrl = new URL(oauthUrl.href);
148
- try {
149
- // Check if the URL protocol is HTTPS
150
- if (parsedUrl.protocol !== 'https:') {
151
- console.warn(`handleOAuthUrl - Skipping non-HTTPS URL - ${parsedUrl.href}`);
152
- return;
153
- }
154
- // Open the URL using Linking module
155
- await Linking.openURL(parsedUrl.href);
156
- } catch (error) {
157
- console.error('handleOAuthUrl - Error opening URL:', error);
158
- // Report error to HoneyBadger
159
- const errorContext = {
160
- ...context,
161
- oauthUrl: parsedUrl.href,
162
- passedUrl: oauthUrl.toString()
163
- };
164
- await errorReporter.send(error, errorContext);
258
+ const handleOAuthUrl = (oauthUrl)=>{
259
+ if (oauthUrl.protocol !== 'https:') {
260
+ console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`);
261
+ return;
165
262
  }
263
+ Linking.openURL(oauthUrl.href);
166
264
  };
167
265
 
168
- const AndroidSafeAreaView = ({ testId, children })=>/*#__PURE__*/ jsx(SafeAreaView, {
169
- testID: testId,
170
- style: styles$1.AndroidSafeArea,
171
- children: children
172
- });
173
- const styles$1 = StyleSheet.create({
174
- AndroidSafeArea: {
175
- flex: 1,
176
- backgroundColor: 'white',
177
- paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0
178
- }
179
- });
180
-
181
- const ErrorScreen = ({ testId, error, cta })=>/*#__PURE__*/ jsx(AndroidSafeAreaView, {
182
- testId: testId,
183
- children: /*#__PURE__*/ jsxs(View, {
184
- style: [
185
- styles.container,
186
- styles.padding
187
- ],
188
- children: [
189
- /*#__PURE__*/ jsxs(View, {
190
- style: {
191
- flex: 1,
192
- justifyContent: 'center'
193
- },
194
- children: [
195
- /*#__PURE__*/ jsx(View, {
196
- style: {
197
- flexDirection: 'row',
198
- justifyContent: 'space-between',
199
- alignItems: 'center',
200
- marginVertical: 10
201
- },
202
- children: /*#__PURE__*/ jsx(Text, {
203
- style: [
204
- styles.title
205
- ],
206
- children: "Cannot connect to the internet."
207
- })
208
- }),
209
- /*#__PURE__*/ jsx(Text, {
210
- style: [
211
- styles.subtitle
212
- ],
213
- children: error
214
- })
215
- ]
216
- }),
217
- /*#__PURE__*/ jsx(Pressable, {
218
- style: [
219
- styles.pressable
220
- ],
221
- onPress: cta,
222
- children: /*#__PURE__*/ jsx(Text, {
223
- style: [
224
- styles.pressableText
225
- ],
226
- children: "Exit"
227
- })
228
- })
229
- ]
230
- })
231
- });
232
- const styles = StyleSheet.create({
233
- container: {
234
- flex: 1,
235
- flexDirection: 'column',
236
- justifyContent: 'flex-start',
237
- alignItems: 'stretch',
238
- backgroundColor: '#F3F4F6'
239
- },
240
- title: {
241
- color: '#1F2937',
242
- fontSize: 30,
243
- fontWeight: 'bold'
244
- },
245
- subtitle: {
246
- color: 'rgba(107, 114, 128, 1)'
247
- },
248
- padding: {
249
- paddingHorizontal: 16,
250
- paddingVertical: 24
251
- },
252
- pressable: {
253
- marginTop: 20,
254
- backgroundColor: '#1F2937',
255
- padding: 10,
256
- paddingHorizontal: 25,
257
- borderRadius: 5
258
- },
259
- pressableText: {
260
- color: '#fff',
261
- textAlign: 'center'
262
- }
263
- });
264
-
265
- const LoadingScreen = ({ testId })=>/*#__PURE__*/ jsx(AndroidSafeAreaView, {
266
- testId: testId,
267
- children: /*#__PURE__*/ jsx(View, {
268
- style: {
269
- flex: 1,
270
- justifyContent: 'center',
271
- alignItems: 'center'
272
- },
273
- children: /*#__PURE__*/ jsx(ActivityIndicator, {
274
- testID: "activity-indicator",
275
- size: "large",
276
- color: "#5928A3"
277
- })
278
- })
279
- });
280
-
281
266
  const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError })=>{
282
267
  const webViewRef = useRef(null);
283
268
  const { session } = useQuilttSession();
@@ -334,13 +319,20 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
334
319
  session?.token
335
320
  ]);
336
321
  // allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview
337
- // For other urls, we assume those are bank urls, which needs to be handle in external browser.
322
+ // For other urls, we assume those are bank urls, which need to be handled in external browser.
338
323
  // TODO: Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.
339
324
  const allowedListUrl = useMemo(()=>[
325
+ 'quiltt.io',
340
326
  'quiltt.app',
341
327
  'quiltt.dev',
342
328
  'moneydesktop.com',
343
- 'cdn.plaid.com'
329
+ 'plaid.com',
330
+ 'https://cdn.plaid.com/link',
331
+ 'https://www.google.com/recaptcha',
332
+ 'https://challenges.cloudflare.com',
333
+ 'https://api.stripe.com',
334
+ 'https://cdn.jsdelivr.net',
335
+ 'https://auth0.com'
344
336
  ], []);
345
337
  const isQuilttEvent = useCallback((url)=>url.protocol === 'quilttconnector:', []);
346
338
  const shouldRender = useCallback((url)=>{
@@ -353,10 +345,10 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
353
345
  allowedListUrl,
354
346
  isQuilttEvent
355
347
  ]);
356
- const clearLocalStorage = useCallback(()=>{
348
+ const clearLocalStorage = ()=>{
357
349
  const script = 'localStorage.clear();';
358
350
  webViewRef.current?.injectJavaScript(script);
359
- }, []);
351
+ };
360
352
  const handleQuilttEvent = useCallback((url)=>{
361
353
  url.searchParams.delete('source');
362
354
  url.searchParams.append('connectorId', connectorId);
@@ -389,12 +381,7 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
389
381
  case 'Authenticate':
390
382
  break;
391
383
  case 'OauthRequested':
392
- handleOAuthUrl(new URL(url.searchParams.get('oauthUrl')), {
393
- connectorId,
394
- connectionId,
395
- institution,
396
- oauthRedirectUrl
397
- });
384
+ handleOAuthUrl(new URL(url.searchParams.get('oauthUrl')));
398
385
  break;
399
386
  default:
400
387
  console.log('unhandled event', url);
@@ -404,15 +391,11 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
404
391
  connectorId,
405
392
  initInjectedJavaScript,
406
393
  onEvent,
407
- onLoad,
408
- clearLocalStorage,
409
394
  onExit,
410
395
  onExitAbort,
411
396
  onExitError,
412
397
  onExitSuccess,
413
- connectionId,
414
- institution,
415
- oauthRedirectUrl
398
+ onLoad
416
399
  ]);
417
400
  const requestHandler = useCallback((request)=>{
418
401
  const url = new URL(request.url);
@@ -423,20 +406,11 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
423
406
  if (shouldRender(url)) return true;
424
407
  // Plaid set oauth url by doing window.location.href = url
425
408
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
426
- handleOAuthUrl(url, {
427
- connectorId,
428
- connectionId,
429
- institution,
430
- oauthRedirectUrl
431
- });
409
+ handleOAuthUrl(url);
432
410
  return false;
433
411
  }, [
434
- connectionId,
435
- connectorId,
436
412
  handleQuilttEvent,
437
- institution,
438
413
  isQuilttEvent,
439
- oauthRedirectUrl,
440
414
  shouldRender
441
415
  ]);
442
416
  if (!preFlightCheck.checked) return /*#__PURE__*/ jsx(LoadingScreen, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quiltt/react-native",
3
- "version": "3.6.6",
3
+ "version": "3.6.8",
4
4
  "description": "React Native components for Quiltt Connector",
5
5
  "homepage": "https://github.com/quiltt/quiltt-js/tree/main/packages/react-native#readme",
6
6
  "repository": {
@@ -27,15 +27,16 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@honeybadger-io/core": "6.6.0",
30
- "@quiltt/core": "3.6.6",
31
- "@quiltt/react": "3.6.6"
30
+ "@quiltt/core": "3.6.8",
31
+ "@quiltt/react": "3.6.8"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@apollo/client": "3.9.9",
35
35
  "@trivago/prettier-plugin-sort-imports": "4.1.1",
36
- "@types/base-64": "1.0.2",
37
- "@types/node": "20.12.10",
36
+ "@types/base-64": "0.1.0",
37
+ "@types/node": "20.12.7",
38
38
  "@types/react": "18.2.73",
39
+ "@types/react-native": "0.72.5",
39
40
  "@typescript-eslint/eslint-plugin": "5.60.1",
40
41
  "@typescript-eslint/parser": "5.60.1",
41
42
  "bunchee": "4.4.8",
@@ -47,11 +48,8 @@
47
48
  "eslint-plugin-react-hooks": "4.6.0",
48
49
  "prettier": "2.8.8",
49
50
  "react": "18.2.0",
50
- "react-native": "0.74.1",
51
- "react-native-url-polyfill": "2.0.0",
52
- "react-native-webview": "13.8.7",
53
51
  "rimraf": "5.0.5",
54
- "typescript": "5.4.5"
52
+ "typescript": "5.4.3"
55
53
  },
56
54
  "peerDependencies": {
57
55
  "base-64": "*",
@@ -1,22 +1,24 @@
1
- import {
2
- type ConnectorSDKCallbackMetadata,
3
- type ConnectorSDKCallbacks,
4
- ConnectorSDKEventType,
5
- useQuilttSession,
6
- } from '@quiltt/react'
7
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
+
8
3
  // React Native's URL implementation is incomplete
9
4
  // https://github.com/facebook/react-native/issues/16434
10
5
  import { URL } from 'react-native-url-polyfill'
11
6
  import { WebView } from 'react-native-webview'
12
7
  import type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'
13
8
 
14
- import { checkConnectorUrl, handleOAuthUrl } from '../utils'
15
- import type { PreFlightCheck } from '../utils'
9
+ import {
10
+ ConnectorSDKCallbackMetadata,
11
+ ConnectorSDKCallbacks,
12
+ ConnectorSDKEventType,
13
+ useQuilttSession,
14
+ } from '@quiltt/react'
15
+
16
16
  import { version } from '../version'
17
17
  import { AndroidSafeAreaView } from './AndroidSafeAreaView'
18
18
  import { ErrorScreen } from './ErrorScreen'
19
19
  import { LoadingScreen } from './LoadingScreen'
20
+ import { checkConnectorUrl, handleOAuthUrl } from '../utils'
21
+ import type { PreFlightCheck } from '../utils'
20
22
 
21
23
  type QuilttConnectorProps = {
22
24
  testId?: string
@@ -46,7 +48,7 @@ const QuilttConnector = ({
46
48
  [oauthRedirectUrl]
47
49
  )
48
50
  const connectorUrl = useMemo(() => {
49
- const url = new URL(`https://${connectorId}.quiltt.app`)
51
+ const url: URL = new URL(`https://${connectorId}.quiltt.app`)
50
52
  url.searchParams.append('mode', 'webview')
51
53
  url.searchParams.append('oauth_redirect_url', encodedOAuthRedirectUrl)
52
54
  url.searchParams.append('agent', `react-native-${version}`)
@@ -85,10 +87,22 @@ const QuilttConnector = ({
85
87
  }, [connectionId, connectorId, institution, session?.token])
86
88
 
87
89
  // allowedListUrl & shouldRender ensure we are only rendering Quiltt, MX and Plaid content in Webview
88
- // For other urls, we assume those are bank urls, which needs to be handle in external browser.
90
+ // For other urls, we assume those are bank urls, which need to be handled in external browser.
89
91
  // TODO: Convert it to a list from Quiltt Server to prevent MX/ Plaid changes.
90
92
  const allowedListUrl = useMemo(
91
- () => ['quiltt.app', 'quiltt.dev', 'moneydesktop.com', 'cdn.plaid.com'],
93
+ () => [
94
+ 'quiltt.io',
95
+ 'quiltt.app',
96
+ 'quiltt.dev',
97
+ 'moneydesktop.com',
98
+ 'plaid.com',
99
+ 'https://cdn.plaid.com/link',
100
+ 'https://www.google.com/recaptcha',
101
+ 'https://challenges.cloudflare.com',
102
+ 'https://api.stripe.com',
103
+ 'https://cdn.jsdelivr.net',
104
+ 'https://auth0.com',
105
+ ],
92
106
  []
93
107
  )
94
108
 
@@ -105,10 +119,10 @@ const QuilttConnector = ({
105
119
  [allowedListUrl, isQuilttEvent]
106
120
  )
107
121
 
108
- const clearLocalStorage = useCallback(() => {
122
+ const clearLocalStorage = () => {
109
123
  const script = 'localStorage.clear();'
110
124
  webViewRef.current?.injectJavaScript(script)
111
- }, [])
125
+ }
112
126
 
113
127
  const handleQuilttEvent = useCallback(
114
128
  (url: URL) => {
@@ -145,12 +159,7 @@ const QuilttConnector = ({
145
159
  // TODO: handle Authenticate
146
160
  break
147
161
  case 'OauthRequested':
148
- handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string), {
149
- connectorId,
150
- connectionId,
151
- institution,
152
- oauthRedirectUrl,
153
- })
162
+ handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string))
154
163
  break
155
164
  default:
156
165
  console.log('unhandled event', url)
@@ -161,15 +170,11 @@ const QuilttConnector = ({
161
170
  connectorId,
162
171
  initInjectedJavaScript,
163
172
  onEvent,
164
- onLoad,
165
- clearLocalStorage,
166
173
  onExit,
167
174
  onExitAbort,
168
175
  onExitError,
169
176
  onExitSuccess,
170
- connectionId,
171
- institution,
172
- oauthRedirectUrl,
177
+ onLoad,
173
178
  ]
174
179
  )
175
180
 
@@ -184,23 +189,10 @@ const QuilttConnector = ({
184
189
  if (shouldRender(url)) return true
185
190
  // Plaid set oauth url by doing window.location.href = url
186
191
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
187
- handleOAuthUrl(url, {
188
- connectorId,
189
- connectionId,
190
- institution,
191
- oauthRedirectUrl,
192
- })
192
+ handleOAuthUrl(url)
193
193
  return false
194
194
  },
195
- [
196
- connectionId,
197
- connectorId,
198
- handleQuilttEvent,
199
- institution,
200
- isQuilttEvent,
201
- oauthRedirectUrl,
202
- shouldRender,
203
- ]
195
+ [handleQuilttEvent, isQuilttEvent, shouldRender]
204
196
  )
205
197
 
206
198
  if (!preFlightCheck.checked) return <LoadingScreen testId="loading-screen" />
@@ -1,5 +1,5 @@
1
- import { Platform } from 'react-native'
2
1
  import { getErrorMessage, ErrorReporter } from '../error'
2
+ import { Platform } from 'react-native'
3
3
 
4
4
  const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`)
5
5
  const PREFLIGHT_RETRY_COUNT = 3
@@ -1,28 +1,9 @@
1
- import { Linking, Platform } from 'react-native'
2
- import { URL } from 'react-native-url-polyfill'
3
- import { ErrorReporter } from '../error'
1
+ import { Linking } from 'react-native'
4
2
 
5
- const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`)
6
-
7
- export const handleOAuthUrl = async (
8
- oauthUrl: URL,
9
- context?: Record<string, unknown>
10
- ): Promise<void> => {
11
- const parsedUrl = new URL(oauthUrl.href)
12
- try {
13
- // Check if the URL protocol is HTTPS
14
- if (parsedUrl.protocol !== 'https:') {
15
- console.warn(`handleOAuthUrl - Skipping non-HTTPS URL - ${parsedUrl.href}`)
16
- return
17
- }
18
-
19
- // Open the URL using Linking module
20
- await Linking.openURL(parsedUrl.href)
21
- } catch (error) {
22
- console.error('handleOAuthUrl - Error opening URL:', error)
23
-
24
- // Report error to HoneyBadger
25
- const errorContext = { ...context, oauthUrl: parsedUrl.href, passedUrl: oauthUrl.toString() }
26
- await errorReporter.send(error as Error, errorContext)
3
+ export const handleOAuthUrl = (oauthUrl: URL) => {
4
+ if (oauthUrl.protocol !== 'https:') {
5
+ console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`)
6
+ return
27
7
  }
8
+ Linking.openURL(oauthUrl.href)
28
9
  }
File without changes
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '3.6.6'
2
+ export const version = '3.6.8'