@quiltt/react-native 3.6.5 → 3.6.6

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,5 +1,15 @@
1
1
  # @quiltt/react-native
2
2
 
3
+ ## 3.6.6
4
+
5
+ ### Patch Changes
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
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
12
+
3
13
  ## 3.6.5
4
14
 
5
15
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -10,126 +10,13 @@ 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.5';
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
-
129
13
  const ErrorReporterConfig = {
130
14
  honeybadger_api_key: 'undefined'
131
15
  };
132
16
 
17
+ // Generated by genversion.
18
+ const version = '3.6.6';
19
+
133
20
  // Quick hack to send error to Honeybadger to debug why the connector is not routable
134
21
  const notifier = {
135
22
  name: 'Quiltt React Native SDK Reporter',
@@ -214,7 +101,7 @@ const getErrorMessage = (responseStatus, error)=>{
214
101
  return responseStatus ? `The URL is not routable. Response status: ${responseStatus}` : 'An error occurred while checking the connector URL';
215
102
  };
216
103
 
217
- const errorReporter = new ErrorReporter(`${reactNative.Platform.OS} ${reactNative.Platform.Version}`);
104
+ const errorReporter$1 = new ErrorReporter(`${reactNative.Platform.OS} ${reactNative.Platform.Version}`);
218
105
  const PREFLIGHT_RETRY_COUNT = 3;
219
106
  const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
220
107
  let responseStatus;
@@ -249,21 +136,149 @@ const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
249
136
  connectorUrl,
250
137
  responseStatus
251
138
  };
252
- if (responseStatus !== 404) await errorReporter.send(errorToSend, context);
139
+ if (responseStatus !== 404) await errorReporter$1.send(errorToSend, context);
253
140
  return {
254
141
  checked: true,
255
142
  error: errorMessage
256
143
  };
257
144
  };
258
145
 
259
- const handleOAuthUrl = (oauthUrl)=>{
260
- if (oauthUrl.protocol !== 'https:') {
261
- console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`);
262
- return;
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);
263
166
  }
264
- reactNative.Linking.openURL(oauthUrl.href);
265
167
  };
266
168
 
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
+
267
282
  const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError })=>{
268
283
  const webViewRef = react$1.useRef(null);
269
284
  const { session } = react.useQuilttSession();
@@ -339,10 +354,10 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
339
354
  allowedListUrl,
340
355
  isQuilttEvent
341
356
  ]);
342
- const clearLocalStorage = ()=>{
357
+ const clearLocalStorage = react$1.useCallback(()=>{
343
358
  const script = 'localStorage.clear();';
344
359
  webViewRef.current?.injectJavaScript(script);
345
- };
360
+ }, []);
346
361
  const handleQuilttEvent = react$1.useCallback((url)=>{
347
362
  url.searchParams.delete('source');
348
363
  url.searchParams.append('connectorId', connectorId);
@@ -375,7 +390,12 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
375
390
  case 'Authenticate':
376
391
  break;
377
392
  case 'OauthRequested':
378
- handleOAuthUrl(new reactNativeUrlPolyfill.URL(url.searchParams.get('oauthUrl')));
393
+ handleOAuthUrl(new reactNativeUrlPolyfill.URL(url.searchParams.get('oauthUrl')), {
394
+ connectorId,
395
+ connectionId,
396
+ institution,
397
+ oauthRedirectUrl
398
+ });
379
399
  break;
380
400
  default:
381
401
  console.log('unhandled event', url);
@@ -385,11 +405,15 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
385
405
  connectorId,
386
406
  initInjectedJavaScript,
387
407
  onEvent,
408
+ onLoad,
409
+ clearLocalStorage,
388
410
  onExit,
389
411
  onExitAbort,
390
412
  onExitError,
391
413
  onExitSuccess,
392
- onLoad
414
+ connectionId,
415
+ institution,
416
+ oauthRedirectUrl
393
417
  ]);
394
418
  const requestHandler = react$1.useCallback((request)=>{
395
419
  const url = new reactNativeUrlPolyfill.URL(request.url);
@@ -400,11 +424,20 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
400
424
  if (shouldRender(url)) return true;
401
425
  // Plaid set oauth url by doing window.location.href = url
402
426
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
403
- handleOAuthUrl(url);
427
+ handleOAuthUrl(url, {
428
+ connectorId,
429
+ connectionId,
430
+ institution,
431
+ oauthRedirectUrl
432
+ });
404
433
  return false;
405
434
  }, [
435
+ connectionId,
436
+ connectorId,
406
437
  handleQuilttEvent,
438
+ institution,
407
439
  isQuilttEvent,
440
+ oauthRedirectUrl,
408
441
  shouldRender
409
442
  ]);
410
443
  if (!preFlightCheck.checked) return /*#__PURE__*/ jsxRuntime.jsx(LoadingScreen, {
package/dist/index.js CHANGED
@@ -6,129 +6,16 @@ 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 { StyleSheet, Platform, StatusBar, SafeAreaView, View, Text, Pressable, ActivityIndicator, Linking } from 'react-native';
9
+ import { Platform, Linking, StyleSheet, StatusBar, SafeAreaView, View, Text, Pressable, ActivityIndicator } 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.5';
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
-
128
12
  const ErrorReporterConfig = {
129
13
  honeybadger_api_key: 'undefined'
130
14
  };
131
15
 
16
+ // Generated by genversion.
17
+ const version = '3.6.6';
18
+
132
19
  // Quick hack to send error to Honeybadger to debug why the connector is not routable
133
20
  const notifier = {
134
21
  name: 'Quiltt React Native SDK Reporter',
@@ -213,7 +100,7 @@ const getErrorMessage = (responseStatus, error)=>{
213
100
  return responseStatus ? `The URL is not routable. Response status: ${responseStatus}` : 'An error occurred while checking the connector URL';
214
101
  };
215
102
 
216
- const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
103
+ const errorReporter$1 = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
217
104
  const PREFLIGHT_RETRY_COUNT = 3;
218
105
  const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
219
106
  let responseStatus;
@@ -248,21 +135,149 @@ const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
248
135
  connectorUrl,
249
136
  responseStatus
250
137
  };
251
- if (responseStatus !== 404) await errorReporter.send(errorToSend, context);
138
+ if (responseStatus !== 404) await errorReporter$1.send(errorToSend, context);
252
139
  return {
253
140
  checked: true,
254
141
  error: errorMessage
255
142
  };
256
143
  };
257
144
 
258
- const handleOAuthUrl = (oauthUrl)=>{
259
- if (oauthUrl.protocol !== 'https:') {
260
- console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`);
261
- return;
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);
262
165
  }
263
- Linking.openURL(oauthUrl.href);
264
166
  };
265
167
 
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
+
266
281
  const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError })=>{
267
282
  const webViewRef = useRef(null);
268
283
  const { session } = useQuilttSession();
@@ -338,10 +353,10 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
338
353
  allowedListUrl,
339
354
  isQuilttEvent
340
355
  ]);
341
- const clearLocalStorage = ()=>{
356
+ const clearLocalStorage = useCallback(()=>{
342
357
  const script = 'localStorage.clear();';
343
358
  webViewRef.current?.injectJavaScript(script);
344
- };
359
+ }, []);
345
360
  const handleQuilttEvent = useCallback((url)=>{
346
361
  url.searchParams.delete('source');
347
362
  url.searchParams.append('connectorId', connectorId);
@@ -374,7 +389,12 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
374
389
  case 'Authenticate':
375
390
  break;
376
391
  case 'OauthRequested':
377
- handleOAuthUrl(new URL(url.searchParams.get('oauthUrl')));
392
+ handleOAuthUrl(new URL(url.searchParams.get('oauthUrl')), {
393
+ connectorId,
394
+ connectionId,
395
+ institution,
396
+ oauthRedirectUrl
397
+ });
378
398
  break;
379
399
  default:
380
400
  console.log('unhandled event', url);
@@ -384,11 +404,15 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
384
404
  connectorId,
385
405
  initInjectedJavaScript,
386
406
  onEvent,
407
+ onLoad,
408
+ clearLocalStorage,
387
409
  onExit,
388
410
  onExitAbort,
389
411
  onExitError,
390
412
  onExitSuccess,
391
- onLoad
413
+ connectionId,
414
+ institution,
415
+ oauthRedirectUrl
392
416
  ]);
393
417
  const requestHandler = useCallback((request)=>{
394
418
  const url = new URL(request.url);
@@ -399,11 +423,20 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
399
423
  if (shouldRender(url)) return true;
400
424
  // Plaid set oauth url by doing window.location.href = url
401
425
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
402
- handleOAuthUrl(url);
426
+ handleOAuthUrl(url, {
427
+ connectorId,
428
+ connectionId,
429
+ institution,
430
+ oauthRedirectUrl
431
+ });
403
432
  return false;
404
433
  }, [
434
+ connectionId,
435
+ connectorId,
405
436
  handleQuilttEvent,
437
+ institution,
406
438
  isQuilttEvent,
439
+ oauthRedirectUrl,
407
440
  shouldRender
408
441
  ]);
409
442
  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.5",
3
+ "version": "3.6.6",
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,16 +27,15 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@honeybadger-io/core": "6.6.0",
30
- "@quiltt/core": "3.6.5",
31
- "@quiltt/react": "3.6.5"
30
+ "@quiltt/core": "3.6.6",
31
+ "@quiltt/react": "3.6.6"
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": "0.1.0",
37
- "@types/node": "20.12.7",
36
+ "@types/base-64": "1.0.2",
37
+ "@types/node": "20.12.10",
38
38
  "@types/react": "18.2.73",
39
- "@types/react-native": "0.72.5",
40
39
  "@typescript-eslint/eslint-plugin": "5.60.1",
41
40
  "@typescript-eslint/parser": "5.60.1",
42
41
  "bunchee": "4.4.8",
@@ -48,8 +47,11 @@
48
47
  "eslint-plugin-react-hooks": "4.6.0",
49
48
  "prettier": "2.8.8",
50
49
  "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",
51
53
  "rimraf": "5.0.5",
52
- "typescript": "5.4.3"
54
+ "typescript": "5.4.5"
53
55
  },
54
56
  "peerDependencies": {
55
57
  "base-64": "*",
@@ -1,24 +1,22 @@
1
+ import {
2
+ type ConnectorSDKCallbackMetadata,
3
+ type ConnectorSDKCallbacks,
4
+ ConnectorSDKEventType,
5
+ useQuilttSession,
6
+ } from '@quiltt/react'
1
7
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
-
3
8
  // React Native's URL implementation is incomplete
4
9
  // https://github.com/facebook/react-native/issues/16434
5
10
  import { URL } from 'react-native-url-polyfill'
6
11
  import { WebView } from 'react-native-webview'
7
12
  import type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes'
8
13
 
9
- import {
10
- ConnectorSDKCallbackMetadata,
11
- ConnectorSDKCallbacks,
12
- ConnectorSDKEventType,
13
- useQuilttSession,
14
- } from '@quiltt/react'
15
-
16
- import { version } from '@/version'
14
+ import { checkConnectorUrl, handleOAuthUrl } from '../utils'
15
+ import type { PreFlightCheck } from '../utils'
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'
22
20
 
23
21
  type QuilttConnectorProps = {
24
22
  testId?: string
@@ -48,7 +46,7 @@ const QuilttConnector = ({
48
46
  [oauthRedirectUrl]
49
47
  )
50
48
  const connectorUrl = useMemo(() => {
51
- const url: URL = new URL(`https://${connectorId}.quiltt.app`)
49
+ const url = new URL(`https://${connectorId}.quiltt.app`)
52
50
  url.searchParams.append('mode', 'webview')
53
51
  url.searchParams.append('oauth_redirect_url', encodedOAuthRedirectUrl)
54
52
  url.searchParams.append('agent', `react-native-${version}`)
@@ -107,10 +105,10 @@ const QuilttConnector = ({
107
105
  [allowedListUrl, isQuilttEvent]
108
106
  )
109
107
 
110
- const clearLocalStorage = () => {
108
+ const clearLocalStorage = useCallback(() => {
111
109
  const script = 'localStorage.clear();'
112
110
  webViewRef.current?.injectJavaScript(script)
113
- }
111
+ }, [])
114
112
 
115
113
  const handleQuilttEvent = useCallback(
116
114
  (url: URL) => {
@@ -147,7 +145,12 @@ const QuilttConnector = ({
147
145
  // TODO: handle Authenticate
148
146
  break
149
147
  case 'OauthRequested':
150
- handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string))
148
+ handleOAuthUrl(new URL(url.searchParams.get('oauthUrl') as string), {
149
+ connectorId,
150
+ connectionId,
151
+ institution,
152
+ oauthRedirectUrl,
153
+ })
151
154
  break
152
155
  default:
153
156
  console.log('unhandled event', url)
@@ -158,11 +161,15 @@ const QuilttConnector = ({
158
161
  connectorId,
159
162
  initInjectedJavaScript,
160
163
  onEvent,
164
+ onLoad,
165
+ clearLocalStorage,
161
166
  onExit,
162
167
  onExitAbort,
163
168
  onExitError,
164
169
  onExitSuccess,
165
- onLoad,
170
+ connectionId,
171
+ institution,
172
+ oauthRedirectUrl,
166
173
  ]
167
174
  )
168
175
 
@@ -177,10 +184,23 @@ const QuilttConnector = ({
177
184
  if (shouldRender(url)) return true
178
185
  // Plaid set oauth url by doing window.location.href = url
179
186
  // So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
180
- handleOAuthUrl(url)
187
+ handleOAuthUrl(url, {
188
+ connectorId,
189
+ connectionId,
190
+ institution,
191
+ oauthRedirectUrl,
192
+ })
181
193
  return false
182
194
  },
183
- [handleQuilttEvent, isQuilttEvent, shouldRender]
195
+ [
196
+ connectionId,
197
+ connectorId,
198
+ handleQuilttEvent,
199
+ institution,
200
+ isQuilttEvent,
201
+ oauthRedirectUrl,
202
+ shouldRender,
203
+ ]
184
204
  )
185
205
 
186
206
  if (!preFlightCheck.checked) return <LoadingScreen testId="loading-screen" />
@@ -1,5 +1,5 @@
1
- import { getErrorMessage, ErrorReporter } from '../error'
2
1
  import { Platform } from 'react-native'
2
+ import { getErrorMessage, ErrorReporter } from '../error'
3
3
 
4
4
  const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`)
5
5
  const PREFLIGHT_RETRY_COUNT = 3
@@ -1,9 +1,28 @@
1
- import { Linking } from 'react-native'
1
+ import { Linking, Platform } from 'react-native'
2
+ import { URL } from 'react-native-url-polyfill'
3
+ import { ErrorReporter } from '../error'
2
4
 
3
- export const handleOAuthUrl = (oauthUrl: URL) => {
4
- if (oauthUrl.protocol !== 'https:') {
5
- console.log(`handleOAuthUrl - Skipping non https url - ${oauthUrl.href}`)
6
- return
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)
7
27
  }
8
- Linking.openURL(oauthUrl.href)
9
28
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '3.6.5'
2
+ export const version = '3.6.6'
File without changes