@tryfinch/react-connect 4.1.0 → 5.0.1
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/README.md +87 -5
- package/dist/core.d.ts +11 -0
- package/dist/index-with-react.d.ts +2 -0
- package/dist/index.d.ts +12 -46
- package/dist/index.es.js +161 -98
- package/dist/index.js +150 -128
- package/dist/react.d.ts +6 -0
- package/dist/react.es.js +182 -0
- package/dist/types.d.ts +57 -0
- package/dist/umd.d.ts +2 -0
- package/dist/utils.d.ts +11 -0
- package/package.json +45 -27
- package/.eslintignore +0 -5
- package/.eslintrc.js +0 -62
- package/.github/pull_request_template.md +0 -66
- package/.github/workflows/pr.yml +0 -92
- package/.github/workflows/release.yml +0 -80
- package/.nvmrc +0 -1
- package/.prettierrc.js +0 -5
- package/CHANGELOG.md +0 -11
- package/LICENSE +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/index.es.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/example/README.md +0 -2026
- package/example/package-lock.json +0 -31464
- package/example/package.json +0 -35
- package/example/public/index.html +0 -20
- package/example/public/manifest.json +0 -8
- package/example/src/App.css +0 -49
- package/example/src/App.tsx +0 -80
- package/example/src/Result.tsx +0 -26
- package/example/src/index.css +0 -11
- package/example/src/index.js +0 -7
- package/example/src/react-app-env.d.ts +0 -1
- package/example/tsconfig.json +0 -26
- package/jest.config.js +0 -7
- package/rollup.config.js +0 -22
- package/src/index.test.ts +0 -111
- package/src/index.ts +0 -253
- package/tsconfig.json +0 -15
package/dist/index.js
CHANGED
|
@@ -1,154 +1,176 @@
|
|
|
1
|
-
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.FinchConnect = factory());
|
|
5
|
+
})(this, (function () { 'use strict';
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const constructAuthUrl = ({ sessionId, state, apiConfig, }) => {
|
|
19
|
-
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
20
|
-
const authUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
21
|
-
authUrl.searchParams.append('session', sessionId);
|
|
22
|
-
if (state)
|
|
23
|
-
authUrl.searchParams.append('state', state);
|
|
24
|
-
appendBaseParams(authUrl);
|
|
25
|
-
return authUrl.href;
|
|
26
|
-
};
|
|
27
|
-
const constructPreviewUrl = ({ clientId, products, apiConfig, }) => {
|
|
28
|
-
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
29
|
-
const previewUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
30
|
-
previewUrl.searchParams.append('preview', 'true');
|
|
31
|
-
previewUrl.searchParams.append('client_id', clientId);
|
|
32
|
-
previewUrl.searchParams.append('products', (products !== null && products !== void 0 ? products : []).join(' '));
|
|
33
|
-
// This will be replaced by a universally allowed redirect URI in the backend
|
|
34
|
-
// We won't ever redirect to anything in preview mode, so we just need a value to pass validation
|
|
35
|
-
previewUrl.searchParams.append('redirect_uri', 'https://www.tryfinch.com');
|
|
36
|
-
appendBaseParams(previewUrl);
|
|
37
|
-
return previewUrl.href;
|
|
38
|
-
};
|
|
39
|
-
let isUseFinchConnectInitialized = false;
|
|
40
|
-
const useFinchConnect = (initializeArgs) => {
|
|
41
|
-
const isHookMounted = react.useRef(false);
|
|
42
|
-
react.useEffect(() => {
|
|
43
|
-
if (!isHookMounted.current) {
|
|
44
|
-
if (isUseFinchConnectInitialized) {
|
|
45
|
-
console.error('One useFinchConnect hook has already been registered. Please ensure to only call useFinchConnect once to avoid your event callbacks getting called more than once. You can pass in override options to the open function if you so require.');
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
isUseFinchConnectInitialized = true;
|
|
49
|
-
}
|
|
50
|
-
isHookMounted.current = true;
|
|
51
|
-
}
|
|
52
|
-
}, []);
|
|
53
|
-
const createAndAttachIFrame = ({ src, zIndexOverride, }) => {
|
|
54
|
-
if (!document.getElementById(FINCH_CONNECT_IFRAME_ID)) {
|
|
55
|
-
const iframe = document.createElement('iframe');
|
|
56
|
-
iframe.src = src;
|
|
57
|
-
iframe.frameBorder = '0';
|
|
58
|
-
iframe.id = FINCH_CONNECT_IFRAME_ID;
|
|
59
|
-
iframe.style.position = 'fixed';
|
|
60
|
-
iframe.style.zIndex = (zIndexOverride === null || zIndexOverride === void 0 ? void 0 : zIndexOverride.toString()) || '999';
|
|
61
|
-
iframe.style.height = '100%';
|
|
62
|
-
iframe.style.width = '100%';
|
|
63
|
-
iframe.style.top = '0';
|
|
64
|
-
iframe.style.backgroundColor = 'none transparent';
|
|
65
|
-
iframe.style.border = 'none';
|
|
66
|
-
iframe.allow = 'clipboard-write; clipboard-read';
|
|
67
|
-
document.body.prepend(iframe);
|
|
68
|
-
document.body.style.overflow = 'hidden';
|
|
69
|
-
}
|
|
7
|
+
const appendBaseParams = (url) => {
|
|
8
|
+
url.searchParams.append('app_type', 'spa');
|
|
9
|
+
url.searchParams.append('sdk_host_url', window.location.origin);
|
|
10
|
+
url.searchParams.append('mode', 'employer');
|
|
11
|
+
url.searchParams.append('sdk_version', 'unified-5.0.1');
|
|
12
|
+
};
|
|
13
|
+
const constructAuthUrl = ({ sessionId, state, apiConfig, }) => {
|
|
14
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
15
|
+
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
16
|
+
const authUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
17
|
+
authUrl.searchParams.append('session', sessionId);
|
|
18
|
+
if (state)
|
|
19
|
+
authUrl.searchParams.append('state', state);
|
|
20
|
+
appendBaseParams(authUrl);
|
|
21
|
+
return authUrl.href;
|
|
70
22
|
};
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
23
|
+
const constructPreviewUrl = ({ clientId, products, apiConfig, }) => {
|
|
24
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
25
|
+
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
26
|
+
const previewUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
27
|
+
previewUrl.searchParams.append('preview', 'true');
|
|
28
|
+
previewUrl.searchParams.append('client_id', clientId);
|
|
29
|
+
previewUrl.searchParams.append('products', products.join(' '));
|
|
30
|
+
previewUrl.searchParams.append('redirect_uri', 'https://www.tryfinch.com');
|
|
31
|
+
appendBaseParams(previewUrl);
|
|
32
|
+
return previewUrl.href;
|
|
81
33
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
34
|
+
|
|
35
|
+
const POST_MESSAGE_NAME = 'finch-auth-message-v2';
|
|
36
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
37
|
+
const FINCH_CONNECT_IFRAME_ID = 'finch-connect-iframe';
|
|
38
|
+
const createAndAttachIFrame = ({ src, zIndex = 999, }) => {
|
|
39
|
+
const existingIframe = document.getElementById(FINCH_CONNECT_IFRAME_ID);
|
|
40
|
+
if (existingIframe) {
|
|
41
|
+
existingIframe.remove();
|
|
42
|
+
}
|
|
43
|
+
const iframe = document.createElement('iframe');
|
|
44
|
+
iframe.src = src;
|
|
45
|
+
iframe.frameBorder = '0';
|
|
46
|
+
iframe.id = FINCH_CONNECT_IFRAME_ID;
|
|
47
|
+
iframe.style.position = 'fixed';
|
|
48
|
+
iframe.style.zIndex = zIndex.toString();
|
|
49
|
+
iframe.style.height = '100%';
|
|
50
|
+
iframe.style.width = '100%';
|
|
51
|
+
iframe.style.top = '0';
|
|
52
|
+
iframe.style.backgroundColor = 'none transparent';
|
|
53
|
+
iframe.style.border = 'none';
|
|
54
|
+
iframe.allow = 'clipboard-write; clipboard-read';
|
|
55
|
+
document.body.prepend(iframe);
|
|
56
|
+
document.body.style.overflow = 'hidden';
|
|
57
|
+
return iframe;
|
|
91
58
|
};
|
|
92
|
-
const
|
|
93
|
-
var _a;
|
|
59
|
+
const removeIFrame = () => {
|
|
94
60
|
const frameToRemove = document.getElementById(FINCH_CONNECT_IFRAME_ID);
|
|
95
61
|
if (frameToRemove) {
|
|
96
|
-
|
|
62
|
+
frameToRemove.remove();
|
|
97
63
|
document.body.style.overflow = 'inherit';
|
|
98
64
|
}
|
|
99
65
|
};
|
|
100
|
-
|
|
101
|
-
|
|
66
|
+
const createMessageHandler = (callbacks, closeFn) => {
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
return (event) => {
|
|
102
69
|
var _a, _b, _c, _d;
|
|
103
|
-
const
|
|
104
|
-
if (!
|
|
70
|
+
const typedEvent = event;
|
|
71
|
+
if (!typedEvent.data)
|
|
105
72
|
return;
|
|
106
|
-
if (
|
|
73
|
+
if (typedEvent.data.name !== POST_MESSAGE_NAME)
|
|
107
74
|
return;
|
|
108
|
-
|
|
75
|
+
const CONNECT_URL = ((_a = callbacks.apiConfig) === null || _a === void 0 ? void 0 : _a.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
76
|
+
if (!typedEvent.origin.startsWith(CONNECT_URL))
|
|
109
77
|
return;
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
switch (
|
|
78
|
+
if (typedEvent.data.kind !== 'error')
|
|
79
|
+
closeFn();
|
|
80
|
+
switch (typedEvent.data.kind) {
|
|
113
81
|
case 'closed':
|
|
114
|
-
|
|
82
|
+
callbacks.onClose();
|
|
115
83
|
break;
|
|
116
84
|
case 'error':
|
|
117
|
-
if ((_b =
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
errorMessage: (_c =
|
|
121
|
-
errorType: (_d =
|
|
85
|
+
if ((_b = typedEvent.data.error) === null || _b === void 0 ? void 0 : _b.shouldClose)
|
|
86
|
+
closeFn();
|
|
87
|
+
callbacks.onError({
|
|
88
|
+
errorMessage: ((_c = typedEvent.data.error) === null || _c === void 0 ? void 0 : _c.message) || 'Unknown error',
|
|
89
|
+
errorType: (_d = typedEvent.data.error) === null || _d === void 0 ? void 0 : _d.type,
|
|
122
90
|
});
|
|
123
91
|
break;
|
|
124
92
|
case 'success':
|
|
125
|
-
|
|
126
|
-
code:
|
|
127
|
-
state:
|
|
128
|
-
idpRedirectUri:
|
|
93
|
+
callbacks.onSuccess({
|
|
94
|
+
code: typedEvent.data.code,
|
|
95
|
+
state: typedEvent.data.state,
|
|
96
|
+
idpRedirectUri: typedEvent.data.idpRedirectUri,
|
|
129
97
|
});
|
|
130
98
|
break;
|
|
131
|
-
default:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
errorMessage: `Report to developers@tryfinch.com: unable to handle window.postMessage for: ${JSON.stringify(event.data)}`,
|
|
99
|
+
default:
|
|
100
|
+
callbacks.onError({
|
|
101
|
+
errorMessage: `Report to developers@tryfinch.com: unable to handle window.postMessage for: ${JSON.stringify(typedEvent.data)}`,
|
|
135
102
|
});
|
|
136
|
-
}
|
|
137
103
|
}
|
|
138
|
-
}
|
|
139
|
-
window.addEventListener('message', handleFinchAuth);
|
|
140
|
-
return () => {
|
|
141
|
-
window.removeEventListener('message', handleFinchAuth);
|
|
142
|
-
isUseFinchConnectInitialized = false;
|
|
143
104
|
};
|
|
144
|
-
}, [initializeArgs.onClose, initializeArgs.onError, initializeArgs.onSuccess]);
|
|
145
|
-
return {
|
|
146
|
-
open,
|
|
147
|
-
openPreview,
|
|
148
105
|
};
|
|
149
|
-
|
|
106
|
+
const createFinchConnectCore = (callbacks) => {
|
|
107
|
+
const close = () => {
|
|
108
|
+
removeIFrame();
|
|
109
|
+
};
|
|
110
|
+
const messageHandler = createMessageHandler(callbacks, close);
|
|
111
|
+
const open = (args) => {
|
|
112
|
+
const url = constructAuthUrl({
|
|
113
|
+
sessionId: args.sessionId,
|
|
114
|
+
state: args.state,
|
|
115
|
+
apiConfig: callbacks.apiConfig,
|
|
116
|
+
});
|
|
117
|
+
createAndAttachIFrame({
|
|
118
|
+
src: url,
|
|
119
|
+
zIndex: args.zIndex,
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
const openPreview = (args) => {
|
|
123
|
+
const url = constructPreviewUrl({
|
|
124
|
+
clientId: args.clientId,
|
|
125
|
+
products: args.products,
|
|
126
|
+
apiConfig: callbacks.apiConfig,
|
|
127
|
+
});
|
|
128
|
+
createAndAttachIFrame({
|
|
129
|
+
src: url,
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
const destroy = () => {
|
|
133
|
+
close();
|
|
134
|
+
window.removeEventListener('message', messageHandler);
|
|
135
|
+
};
|
|
136
|
+
window.addEventListener('message', messageHandler);
|
|
137
|
+
return {
|
|
138
|
+
open,
|
|
139
|
+
openPreview,
|
|
140
|
+
close,
|
|
141
|
+
destroy,
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
let isInitialized = false;
|
|
146
|
+
class FinchConnect {
|
|
147
|
+
constructor(args) {
|
|
148
|
+
this.open = (args) => {
|
|
149
|
+
this.core.open(args);
|
|
150
|
+
};
|
|
151
|
+
this.openPreview = (args) => {
|
|
152
|
+
this.core.openPreview(args);
|
|
153
|
+
};
|
|
154
|
+
this.close = () => {
|
|
155
|
+
this.core.close();
|
|
156
|
+
};
|
|
157
|
+
this.destroy = () => {
|
|
158
|
+
this.core.destroy();
|
|
159
|
+
isInitialized = false;
|
|
160
|
+
};
|
|
161
|
+
if (isInitialized) {
|
|
162
|
+
console.error('FinchConnect.initialize has already been called. Please ensure to only call FinchConnect.initialize once to avoid your event callbacks being triggered multiple times.');
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
isInitialized = true;
|
|
166
|
+
}
|
|
167
|
+
this.core = createFinchConnectCore(args);
|
|
168
|
+
}
|
|
169
|
+
static initialize(args) {
|
|
170
|
+
return new FinchConnect(args);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return FinchConnect;
|
|
150
175
|
|
|
151
|
-
|
|
152
|
-
exports.constructPreviewUrl = constructPreviewUrl;
|
|
153
|
-
exports.useFinchConnect = useFinchConnect;
|
|
154
|
-
//# sourceMappingURL=index.js.map
|
|
176
|
+
}));
|
package/dist/react.d.ts
ADDED
package/dist/react.es.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const appendBaseParams = (url) => {
|
|
4
|
+
url.searchParams.append('app_type', 'spa');
|
|
5
|
+
url.searchParams.append('sdk_host_url', window.location.origin);
|
|
6
|
+
url.searchParams.append('mode', 'employer');
|
|
7
|
+
url.searchParams.append('sdk_version', 'unified-5.0.1');
|
|
8
|
+
};
|
|
9
|
+
const constructAuthUrl = ({ sessionId, state, apiConfig, }) => {
|
|
10
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
11
|
+
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
12
|
+
const authUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
13
|
+
authUrl.searchParams.append('session', sessionId);
|
|
14
|
+
if (state)
|
|
15
|
+
authUrl.searchParams.append('state', state);
|
|
16
|
+
appendBaseParams(authUrl);
|
|
17
|
+
return authUrl.href;
|
|
18
|
+
};
|
|
19
|
+
const constructPreviewUrl = ({ clientId, products, apiConfig, }) => {
|
|
20
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
21
|
+
const CONNECT_URL = (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
22
|
+
const previewUrl = new URL(`${CONNECT_URL}/authorize`);
|
|
23
|
+
previewUrl.searchParams.append('preview', 'true');
|
|
24
|
+
previewUrl.searchParams.append('client_id', clientId);
|
|
25
|
+
previewUrl.searchParams.append('products', products.join(' '));
|
|
26
|
+
previewUrl.searchParams.append('redirect_uri', 'https://www.tryfinch.com');
|
|
27
|
+
appendBaseParams(previewUrl);
|
|
28
|
+
return previewUrl.href;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const POST_MESSAGE_NAME = 'finch-auth-message-v2';
|
|
32
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
33
|
+
const FINCH_CONNECT_IFRAME_ID = 'finch-connect-iframe';
|
|
34
|
+
const createAndAttachIFrame = ({ src, zIndex = 999, }) => {
|
|
35
|
+
const existingIframe = document.getElementById(FINCH_CONNECT_IFRAME_ID);
|
|
36
|
+
if (existingIframe) {
|
|
37
|
+
existingIframe.remove();
|
|
38
|
+
}
|
|
39
|
+
const iframe = document.createElement('iframe');
|
|
40
|
+
iframe.src = src;
|
|
41
|
+
iframe.frameBorder = '0';
|
|
42
|
+
iframe.id = FINCH_CONNECT_IFRAME_ID;
|
|
43
|
+
iframe.style.position = 'fixed';
|
|
44
|
+
iframe.style.zIndex = zIndex.toString();
|
|
45
|
+
iframe.style.height = '100%';
|
|
46
|
+
iframe.style.width = '100%';
|
|
47
|
+
iframe.style.top = '0';
|
|
48
|
+
iframe.style.backgroundColor = 'none transparent';
|
|
49
|
+
iframe.style.border = 'none';
|
|
50
|
+
iframe.allow = 'clipboard-write; clipboard-read';
|
|
51
|
+
document.body.prepend(iframe);
|
|
52
|
+
document.body.style.overflow = 'hidden';
|
|
53
|
+
return iframe;
|
|
54
|
+
};
|
|
55
|
+
const removeIFrame = () => {
|
|
56
|
+
const frameToRemove = document.getElementById(FINCH_CONNECT_IFRAME_ID);
|
|
57
|
+
if (frameToRemove) {
|
|
58
|
+
frameToRemove.remove();
|
|
59
|
+
document.body.style.overflow = 'inherit';
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const createMessageHandler = (callbacks, closeFn) => {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
64
|
+
return (event) => {
|
|
65
|
+
var _a, _b, _c, _d;
|
|
66
|
+
const typedEvent = event;
|
|
67
|
+
if (!typedEvent.data)
|
|
68
|
+
return;
|
|
69
|
+
if (typedEvent.data.name !== POST_MESSAGE_NAME)
|
|
70
|
+
return;
|
|
71
|
+
const CONNECT_URL = ((_a = callbacks.apiConfig) === null || _a === void 0 ? void 0 : _a.connectUrl) || BASE_FINCH_CONNECT_URI;
|
|
72
|
+
if (!typedEvent.origin.startsWith(CONNECT_URL))
|
|
73
|
+
return;
|
|
74
|
+
if (typedEvent.data.kind !== 'error')
|
|
75
|
+
closeFn();
|
|
76
|
+
switch (typedEvent.data.kind) {
|
|
77
|
+
case 'closed':
|
|
78
|
+
callbacks.onClose();
|
|
79
|
+
break;
|
|
80
|
+
case 'error':
|
|
81
|
+
if ((_b = typedEvent.data.error) === null || _b === void 0 ? void 0 : _b.shouldClose)
|
|
82
|
+
closeFn();
|
|
83
|
+
callbacks.onError({
|
|
84
|
+
errorMessage: ((_c = typedEvent.data.error) === null || _c === void 0 ? void 0 : _c.message) || 'Unknown error',
|
|
85
|
+
errorType: (_d = typedEvent.data.error) === null || _d === void 0 ? void 0 : _d.type,
|
|
86
|
+
});
|
|
87
|
+
break;
|
|
88
|
+
case 'success':
|
|
89
|
+
callbacks.onSuccess({
|
|
90
|
+
code: typedEvent.data.code,
|
|
91
|
+
state: typedEvent.data.state,
|
|
92
|
+
idpRedirectUri: typedEvent.data.idpRedirectUri,
|
|
93
|
+
});
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
callbacks.onError({
|
|
97
|
+
errorMessage: `Report to developers@tryfinch.com: unable to handle window.postMessage for: ${JSON.stringify(typedEvent.data)}`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
const createFinchConnectCore = (callbacks) => {
|
|
103
|
+
const close = () => {
|
|
104
|
+
removeIFrame();
|
|
105
|
+
};
|
|
106
|
+
const messageHandler = createMessageHandler(callbacks, close);
|
|
107
|
+
const open = (args) => {
|
|
108
|
+
const url = constructAuthUrl({
|
|
109
|
+
sessionId: args.sessionId,
|
|
110
|
+
state: args.state,
|
|
111
|
+
apiConfig: callbacks.apiConfig,
|
|
112
|
+
});
|
|
113
|
+
createAndAttachIFrame({
|
|
114
|
+
src: url,
|
|
115
|
+
zIndex: args.zIndex,
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
const openPreview = (args) => {
|
|
119
|
+
const url = constructPreviewUrl({
|
|
120
|
+
clientId: args.clientId,
|
|
121
|
+
products: args.products,
|
|
122
|
+
apiConfig: callbacks.apiConfig,
|
|
123
|
+
});
|
|
124
|
+
createAndAttachIFrame({
|
|
125
|
+
src: url,
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const destroy = () => {
|
|
129
|
+
close();
|
|
130
|
+
window.removeEventListener('message', messageHandler);
|
|
131
|
+
};
|
|
132
|
+
window.addEventListener('message', messageHandler);
|
|
133
|
+
return {
|
|
134
|
+
open,
|
|
135
|
+
openPreview,
|
|
136
|
+
close,
|
|
137
|
+
destroy,
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
let isUseFinchConnectInitialized = false;
|
|
142
|
+
const useFinchConnect = (initializeArgs) => {
|
|
143
|
+
const isHookMounted = useRef(false);
|
|
144
|
+
const coreRef = useRef(null);
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (!isHookMounted.current) {
|
|
147
|
+
if (isUseFinchConnectInitialized) {
|
|
148
|
+
console.error('One useFinchConnect hook has already been registered. Please ensure to only call useFinchConnect once to avoid your event callbacks getting called more than once. You can pass in override options to the open function if you so require.');
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
isUseFinchConnectInitialized = true;
|
|
152
|
+
}
|
|
153
|
+
isHookMounted.current = true;
|
|
154
|
+
coreRef.current = createFinchConnectCore(initializeArgs);
|
|
155
|
+
}
|
|
156
|
+
}, []);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
return () => {
|
|
159
|
+
if (coreRef.current) {
|
|
160
|
+
coreRef.current.destroy();
|
|
161
|
+
}
|
|
162
|
+
isUseFinchConnectInitialized = false;
|
|
163
|
+
isHookMounted.current = false;
|
|
164
|
+
};
|
|
165
|
+
}, []);
|
|
166
|
+
const open = (launchArgs) => {
|
|
167
|
+
if (coreRef.current) {
|
|
168
|
+
coreRef.current.open(launchArgs);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const openPreview = (launchArgs) => {
|
|
172
|
+
if (coreRef.current) {
|
|
173
|
+
coreRef.current.openPreview(launchArgs);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
open,
|
|
178
|
+
openPreview,
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export { useFinchConnect };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type SuccessEvent = {
|
|
2
|
+
code: string;
|
|
3
|
+
state?: string;
|
|
4
|
+
idpRedirectUri?: string;
|
|
5
|
+
};
|
|
6
|
+
export type ErrorType = 'validation_error' | 'employer_connection_error';
|
|
7
|
+
export type ErrorEvent = {
|
|
8
|
+
errorMessage: string;
|
|
9
|
+
errorType?: ErrorType;
|
|
10
|
+
};
|
|
11
|
+
export type ApiConfig = {
|
|
12
|
+
connectUrl: string;
|
|
13
|
+
};
|
|
14
|
+
export type ConnectInitializeArgs = {
|
|
15
|
+
onSuccess: (e: SuccessEvent) => void;
|
|
16
|
+
onError: (e: ErrorEvent) => void;
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
apiConfig?: ApiConfig;
|
|
19
|
+
};
|
|
20
|
+
export type ConnectLaunchArgs = {
|
|
21
|
+
sessionId: string;
|
|
22
|
+
state?: string;
|
|
23
|
+
zIndex?: number;
|
|
24
|
+
};
|
|
25
|
+
export type ConnectPreviewLaunchArgs = {
|
|
26
|
+
clientId: string;
|
|
27
|
+
products: string[];
|
|
28
|
+
};
|
|
29
|
+
export type OpenFn = (args: ConnectLaunchArgs) => void;
|
|
30
|
+
export type OpenPreviewFn = (args: ConnectPreviewLaunchArgs) => void;
|
|
31
|
+
export type FinchConnectInterface = {
|
|
32
|
+
open: OpenFn;
|
|
33
|
+
openPreview: OpenPreviewFn;
|
|
34
|
+
close: () => void;
|
|
35
|
+
destroy: () => void;
|
|
36
|
+
};
|
|
37
|
+
export type FinchConnectAuthMessage = {
|
|
38
|
+
name: 'finch-auth-message-v2';
|
|
39
|
+
} & ({
|
|
40
|
+
kind: 'closed';
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'success';
|
|
43
|
+
code: string;
|
|
44
|
+
state?: string;
|
|
45
|
+
idpRedirectUri?: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'error';
|
|
48
|
+
error: {
|
|
49
|
+
shouldClose: boolean;
|
|
50
|
+
message: string;
|
|
51
|
+
type?: ErrorType;
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
export interface FinchConnectPostMessage {
|
|
55
|
+
data: FinchConnectAuthMessage;
|
|
56
|
+
origin: string;
|
|
57
|
+
}
|
package/dist/umd.d.ts
ADDED
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ApiConfig } from './types';
|
|
2
|
+
export declare const constructAuthUrl: ({ sessionId, state, apiConfig, }: {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
state?: string;
|
|
5
|
+
apiConfig?: ApiConfig;
|
|
6
|
+
}) => string;
|
|
7
|
+
export declare const constructPreviewUrl: ({ clientId, products, apiConfig, }: {
|
|
8
|
+
clientId: string;
|
|
9
|
+
products: string[];
|
|
10
|
+
apiConfig?: ApiConfig;
|
|
11
|
+
}) => string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryfinch/react-connect",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
|
+
"description": "The SDK for Finch's authorization flow, Finch Connect",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"finch",
|
|
7
7
|
"sdk",
|
|
@@ -10,48 +10,66 @@
|
|
|
10
10
|
"oauth"
|
|
11
11
|
],
|
|
12
12
|
"homepage": "https://tryfinch.com/",
|
|
13
|
-
"author": "",
|
|
13
|
+
"author": "Finch",
|
|
14
14
|
"license": "MIT",
|
|
15
|
-
"repository": "Finch-API/
|
|
15
|
+
"repository": "Finch-API/finch-connect-sdk",
|
|
16
16
|
"main": "dist/index.js",
|
|
17
|
-
"types": "dist/index.d.ts",
|
|
18
17
|
"module": "dist/index.es.js",
|
|
19
|
-
"
|
|
18
|
+
"types": "dist/index-with-react.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"require": "./dist/index.js",
|
|
22
|
+
"import": "./dist/index.es.js",
|
|
23
|
+
"types": "./dist/index-with-react.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./react": {
|
|
26
|
+
"import": "./dist/react.es.js",
|
|
27
|
+
"types": "./dist/react.d.ts"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
20
33
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
22
|
-
"npm": ">=5"
|
|
34
|
+
"node": ">=14"
|
|
23
35
|
},
|
|
24
36
|
"scripts": {
|
|
25
37
|
"build": "rollup -c",
|
|
26
|
-
"
|
|
27
|
-
"start": "rollup -c -w",
|
|
38
|
+
"dev": "rollup -c -w",
|
|
28
39
|
"test": "jest",
|
|
29
40
|
"test:watch": "jest --watch",
|
|
41
|
+
"lint": "eslint --ext .js,.jsx,.ts,.tsx src",
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
30
43
|
"prepare": "npm run build",
|
|
31
|
-
"
|
|
44
|
+
"clean": "rm -rf dist"
|
|
32
45
|
},
|
|
33
46
|
"peerDependencies": {
|
|
34
47
|
"react": ">=16.9.0"
|
|
35
48
|
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"react": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
36
54
|
"devDependencies": {
|
|
37
|
-
"@rollup/plugin-replace": "^
|
|
55
|
+
"@rollup/plugin-replace": "^5.0.0",
|
|
38
56
|
"@rollup/plugin-typescript": "^11.1.0",
|
|
39
57
|
"@types/jest": "^30.0.0",
|
|
40
|
-
"@types/react": "^
|
|
41
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
42
|
-
"@typescript-eslint/parser": "^
|
|
43
|
-
"eslint": "^
|
|
44
|
-
"eslint-config-airbnb": "^
|
|
45
|
-
"eslint-config-prettier": "^
|
|
46
|
-
"eslint-plugin-prettier": "^
|
|
47
|
-
"jest": "^30.0.
|
|
48
|
-
"jest-environment-jsdom": "^30.0.
|
|
49
|
-
"
|
|
58
|
+
"@types/react": "^18.0.0",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
60
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
61
|
+
"eslint": "^8.0.0",
|
|
62
|
+
"eslint-config-airbnb": "^19.0.4",
|
|
63
|
+
"eslint-config-prettier": "^9.0.0",
|
|
64
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
65
|
+
"jest": "^30.0.0",
|
|
66
|
+
"jest-environment-jsdom": "^30.0.0",
|
|
67
|
+
"prettier": "^3.0.0",
|
|
50
68
|
"react": "^16.9.0",
|
|
51
|
-
"rollup": "^
|
|
52
|
-
"rollup-plugin-peer-deps-external": "^2.2.
|
|
53
|
-
"ts-jest": "^29.
|
|
54
|
-
"tslib": "^2.
|
|
55
|
-
"typescript": "^
|
|
69
|
+
"rollup": "^4.0.0",
|
|
70
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
71
|
+
"ts-jest": "^29.0.0",
|
|
72
|
+
"tslib": "^2.6.0",
|
|
73
|
+
"typescript": "^5.0.0"
|
|
56
74
|
}
|
|
57
75
|
}
|