onairos 2.0.1 → 2.0.3

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.
@@ -1,303 +1,305 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { rsaEncrypt } from './RSA.jsx';
3
- import EmailAuth from './components/EmailAuth.js';
4
- import UniversalOnboarding from './components/UniversalOnboarding.js';
5
- import PinSetup from './components/PinSetup.js';
6
- import DataRequest from './components/DataRequest.js';
7
- import {
8
- openDataRequestPopup,
9
- closeDataRequestPopup,
10
- sendDataToPopup,
11
- listenForPopupMessages
12
- } from './iframe/dataRequestHandler.js';
13
-
14
- export function OnairosButton({
15
- requestData,
16
- webpageName,
17
- inferenceData = null,
18
- onComplete = null,
19
- autoFetch = true,
20
- proofMode = false,
21
- textLayout = 'below',
22
- textColor = 'white',
23
- login = false,
24
- buttonType = 'pill',
25
- loginReturn = null,
26
- loginType = 'signIn',
27
- visualType = 'full',
28
- }) {
29
-
30
- const [showOverlay, setShowOverlay] = useState(false);
31
- const [currentFlow, setCurrentFlow] = useState('email'); // 'email' | 'onboarding' | 'pin' | 'dataRequest'
32
- const [userData, setUserData] = useState(null);
33
- const [isLoading, setIsLoading] = useState(false);
34
- const [error, setError] = useState(null);
35
- const [popupWindow, setPopupWindow] = useState(null);
36
- const messageCleanup = useRef(null);
37
-
38
- // Check for existing user session
39
- useEffect(() => {
40
- const checkExistingSession = () => {
41
- const savedUser = localStorage.getItem('onairosUser');
42
- if (savedUser) {
43
- try {
44
- const user = JSON.parse(savedUser);
45
- setUserData(user);
46
- // If user has completed onboarding and PIN setup, go directly to data request
47
- if (user.onboardingComplete && user.pinCreated) {
48
- setCurrentFlow('dataRequest');
49
- } else if (user.verified && !user.onboardingComplete) {
50
- setCurrentFlow('onboarding');
51
- } else if (user.onboardingComplete && !user.pinCreated) {
52
- setCurrentFlow('pin');
53
- }
54
- } catch (error) {
55
- console.error('Error parsing saved user data:', error);
56
- localStorage.removeItem('onairosUser');
57
- }
58
- }
59
- };
60
-
61
- checkExistingSession();
62
- }, []);
63
-
64
- // Cleanup popup and message listeners on unmount
65
- useEffect(() => {
66
- return () => {
67
- if (popupWindow) {
68
- closeDataRequestPopup(popupWindow);
69
- }
70
- if (messageCleanup.current) {
71
- messageCleanup.current();
72
- }
73
- };
74
- }, [popupWindow]);
75
-
76
- const openTerminal = async () => {
77
- try {
78
- console.log('🔥 openTerminal called');
79
-
80
- // If user has completed all steps, open popup directly for data request
81
- if (userData?.onboardingComplete && userData?.pinCreated) {
82
- openDataRequestDirectly();
83
- } else {
84
- // Otherwise show the overlay for onboarding flow
85
- setShowOverlay(true);
86
- }
87
- } catch (error) {
88
- console.error('Error in openTerminal:', error);
89
- }
90
- };
91
-
92
- const openDataRequestDirectly = () => {
93
- try {
94
- // Open popup for data request
95
- const popup = openDataRequestPopup({
96
- requestData,
97
- webpageName,
98
- userData,
99
- autoFetch,
100
- proofMode
101
- });
102
-
103
- if (popup) {
104
- setPopupWindow(popup);
105
-
106
- // Set up message listener for popup communication
107
- const cleanup = listenForPopupMessages(
108
- handlePopupMessage,
109
- {
110
- autoFetch,
111
- onApiResponse: handleApiResponse
112
- }
113
- );
114
- messageCleanup.current = cleanup;
115
- }
116
- } catch (error) {
117
- console.error('Error opening data request popup:', error);
118
- setError('Failed to open data request popup');
119
- }
120
- };
121
-
122
- const handlePopupMessage = (data) => {
123
- console.log('🔥 OnairosButton received popup message:', data);
124
-
125
- if (data.type === 'dataRequestComplete') {
126
- handleDataRequestComplete(data);
127
- } else if (data.type === 'popupClosed') {
128
- setPopupWindow(null);
129
- if (messageCleanup.current) {
130
- messageCleanup.current();
131
- messageCleanup.current = null;
132
- }
133
- }
134
- };
135
-
136
- const handleApiResponse = (apiResponse) => {
137
- console.log('🔥 API Response received:', apiResponse);
138
- // Additional handling for API response if needed
139
- };
140
-
141
- const handleCloseOverlay = () => {
142
- setShowOverlay(false);
143
- setError(null);
144
- };
145
-
146
- // Handle clicks on the backdrop to close modal
147
- const handleBackdropClick = (e) => {
148
- if (e.target === e.currentTarget) {
149
- handleCloseOverlay();
150
- }
151
- };
152
-
153
- const handleEmailAuthSuccess = (authData) => {
154
- console.log('Email auth successful:', authData);
155
- const newUserData = {
156
- ...authData,
157
- verified: true,
158
- onboardingComplete: false,
159
- pinCreated: false
160
- };
161
- setUserData(newUserData);
162
- localStorage.setItem('onairosUser', JSON.stringify(newUserData));
163
- setCurrentFlow('onboarding');
164
- };
165
-
166
- const handleOnboardingComplete = (onboardingData) => {
167
- console.log('Onboarding completed:', onboardingData);
168
- const updatedUserData = {
169
- ...userData,
170
- onboardingComplete: true,
171
- connectedAccounts: onboardingData.connectedAccounts || []
172
- };
173
- setUserData(updatedUserData);
174
- localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
175
- setCurrentFlow('pin');
176
- };
177
-
178
- const handlePinSetupComplete = (pinData) => {
179
- console.log('PIN setup completed:', pinData);
180
- const updatedUserData = {
181
- ...userData,
182
- ...pinData,
183
- pinCreated: true
184
- };
185
- setUserData(updatedUserData);
186
- localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
187
-
188
- // Close overlay and open popup for data request
189
- setShowOverlay(false);
190
- setTimeout(() => {
191
- openDataRequestDirectly();
192
- }, 300);
193
- };
194
-
195
- const handleDataRequestComplete = (requestResult) => {
196
- console.log('🔥 OnairosButton: Data request completed:', requestResult);
197
-
198
- // Update user data with request result
199
- const updatedUserData = {
200
- ...userData,
201
- lastDataRequest: requestResult
202
- };
203
- setUserData(updatedUserData);
204
- localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
205
-
206
- // Close popup
207
- if (popupWindow) {
208
- closeDataRequestPopup(popupWindow);
209
- setPopupWindow(null);
210
- }
211
-
212
- // Call onComplete callback if provided
213
- console.log('🔥 Calling onComplete callback with:', requestResult);
214
- if (onComplete) {
215
- try {
216
- onComplete(requestResult);
217
- console.log('🔥 onComplete callback executed successfully');
218
- } catch (error) {
219
- console.error('🔥 Error in onComplete callback:', error);
220
- }
221
- } else {
222
- console.log('🔥 No onComplete callback provided');
223
- }
224
- };
225
-
226
- const renderCurrentFlow = () => {
227
- switch (currentFlow) {
228
- case 'email':
229
- return (
230
- <EmailAuth
231
- onSuccess={handleEmailAuthSuccess}
232
- testMode={true} // Set to false in production
233
- />
234
- );
235
-
236
- case 'onboarding':
237
- return (
238
- <UniversalOnboarding
239
- onComplete={handleOnboardingComplete}
240
- appIcon="https://onairos.sirv.com/Images/OnairosBlack.png"
241
- appName={webpageName}
242
- />
243
- );
244
-
245
- case 'pin':
246
- return (
247
- <PinSetup
248
- onComplete={handlePinSetupComplete}
249
- userEmail={userData?.email}
250
- />
251
- );
252
-
253
- case 'dataRequest':
254
- return (
255
- <DataRequest
256
- onComplete={handleDataRequestComplete}
257
- userEmail={userData?.email}
258
- requestData={requestData}
259
- appName={webpageName}
260
- autoFetch={autoFetch}
261
- />
262
- );
263
-
264
- default:
265
- return (
266
- <div className="flex flex-col items-center space-y-4 p-6">
267
- <div className="animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent"></div>
268
- <p className="text-gray-600">Loading...</p>
269
- </div>
270
- );
271
- }
272
- };
273
-
274
- // Styling and button class based on visual type
275
- const buttonClass =
276
- `flex items-center justify-center font-bold rounded cursor-pointer ${
277
- buttonType === 'pill' ? 'px-4 py-2' : 'w-12 h-12'
278
- } bg-transparent OnairosConnect`;
279
-
280
- const buttonStyle = {
281
- flexDirection: textLayout === 'below' ? 'column' : 'row',
282
- backgroundColor: 'transparent',
283
- color: textColor,
284
- border: '1px solid transparent',
285
- };
286
-
287
- // Icon and text style based on the visualType
288
- const logoStyle = {
289
- width: '20px',
290
- height: '20px',
291
- marginRight: visualType === 'full' ? '12px' : '0',
292
- };
293
-
294
- const getText = () => {
295
- switch (loginType) {
296
- case 'signUp':
297
- return 'Sign Up with Onairos';
298
- case 'signOut':
299
- return 'Sign Out of Onairos';
300
- default:
1
+ import React, { useEffect, useState, useRef } from 'react';
2
+ import { rsaEncrypt } from './RSA.jsx';
3
+ import EmailAuth from './components/EmailAuth.js';
4
+ import UniversalOnboarding from './components/UniversalOnboarding.js';
5
+ import PinSetup from './components/PinSetup.js';
6
+ import DataRequest from './components/DataRequest.js';
7
+ import {
8
+ openDataRequestPopup,
9
+ closeDataRequestPopup,
10
+ sendDataToPopup,
11
+ listenForPopupMessages
12
+ } from './iframe/dataRequestHandler.js';
13
+
14
+ export function OnairosButton({
15
+ requestData,
16
+ webpageName,
17
+ inferenceData = null,
18
+ onComplete = null,
19
+ autoFetch = true,
20
+ proofMode = false,
21
+ textLayout = 'below',
22
+ textColor = 'white',
23
+ login = false,
24
+ buttonType = 'pill',
25
+ loginReturn = null,
26
+ loginType = 'signIn',
27
+ visualType = 'full',
28
+ appIcon = null, // App icon URL to display in the data request screen
29
+ }) {
30
+
31
+ const [showOverlay, setShowOverlay] = useState(false);
32
+ const [currentFlow, setCurrentFlow] = useState('email'); // 'email' | 'onboarding' | 'pin' | 'dataRequest'
33
+ const [userData, setUserData] = useState(null);
34
+ const [isLoading, setIsLoading] = useState(false);
35
+ const [error, setError] = useState(null);
36
+ const [popupWindow, setPopupWindow] = useState(null);
37
+ const messageCleanup = useRef(null);
38
+
39
+ // Check for existing user session
40
+ useEffect(() => {
41
+ const checkExistingSession = () => {
42
+ const savedUser = localStorage.getItem('onairosUser');
43
+ if (savedUser) {
44
+ try {
45
+ const user = JSON.parse(savedUser);
46
+ setUserData(user);
47
+ // If user has completed onboarding and PIN setup, go directly to data request
48
+ if (user.onboardingComplete && user.pinCreated) {
49
+ setCurrentFlow('dataRequest');
50
+ } else if (user.verified && !user.onboardingComplete) {
51
+ setCurrentFlow('onboarding');
52
+ } else if (user.onboardingComplete && !user.pinCreated) {
53
+ setCurrentFlow('pin');
54
+ }
55
+ } catch (error) {
56
+ console.error('Error parsing saved user data:', error);
57
+ localStorage.removeItem('onairosUser');
58
+ }
59
+ }
60
+ };
61
+
62
+ checkExistingSession();
63
+ }, []);
64
+
65
+ // Cleanup popup and message listeners on unmount
66
+ useEffect(() => {
67
+ return () => {
68
+ if (popupWindow) {
69
+ closeDataRequestPopup(popupWindow);
70
+ }
71
+ if (messageCleanup.current) {
72
+ messageCleanup.current();
73
+ }
74
+ };
75
+ }, [popupWindow]);
76
+
77
+ const openTerminal = async () => {
78
+ try {
79
+ console.log('🔥 openTerminal called');
80
+
81
+ // If user has completed all steps, open popup directly for data request
82
+ if (userData?.onboardingComplete && userData?.pinCreated) {
83
+ openDataRequestDirectly();
84
+ } else {
85
+ // Otherwise show the overlay for onboarding flow
86
+ setShowOverlay(true);
87
+ }
88
+ } catch (error) {
89
+ console.error('Error in openTerminal:', error);
90
+ }
91
+ };
92
+
93
+ const openDataRequestDirectly = () => {
94
+ try {
95
+ // Open popup for data request
96
+ const popup = openDataRequestPopup({
97
+ requestData,
98
+ webpageName,
99
+ userData,
100
+ autoFetch,
101
+ proofMode,
102
+ appIcon // Pass the app icon to the data request popup
103
+ });
104
+
105
+ if (popup) {
106
+ setPopupWindow(popup);
107
+
108
+ // Set up message listener for popup communication
109
+ const cleanup = listenForPopupMessages(
110
+ handlePopupMessage,
111
+ {
112
+ autoFetch,
113
+ onApiResponse: handleApiResponse
114
+ }
115
+ );
116
+ messageCleanup.current = cleanup;
117
+ }
118
+ } catch (error) {
119
+ console.error('Error opening data request popup:', error);
120
+ setError('Failed to open data request popup');
121
+ }
122
+ };
123
+
124
+ const handlePopupMessage = (data) => {
125
+ console.log('🔥 OnairosButton received popup message:', data);
126
+
127
+ if (data.type === 'dataRequestComplete') {
128
+ handleDataRequestComplete(data);
129
+ } else if (data.type === 'popupClosed') {
130
+ setPopupWindow(null);
131
+ if (messageCleanup.current) {
132
+ messageCleanup.current();
133
+ messageCleanup.current = null;
134
+ }
135
+ }
136
+ };
137
+
138
+ const handleApiResponse = (apiResponse) => {
139
+ console.log('🔥 API Response received:', apiResponse);
140
+ // Additional handling for API response if needed
141
+ };
142
+
143
+ const handleCloseOverlay = () => {
144
+ setShowOverlay(false);
145
+ setError(null);
146
+ };
147
+
148
+ // Handle clicks on the backdrop to close modal
149
+ const handleBackdropClick = (e) => {
150
+ if (e.target === e.currentTarget) {
151
+ handleCloseOverlay();
152
+ }
153
+ };
154
+
155
+ const handleEmailAuthSuccess = (authData) => {
156
+ console.log('Email auth successful:', authData);
157
+ const newUserData = {
158
+ ...authData,
159
+ verified: true,
160
+ onboardingComplete: false,
161
+ pinCreated: false
162
+ };
163
+ setUserData(newUserData);
164
+ localStorage.setItem('onairosUser', JSON.stringify(newUserData));
165
+ setCurrentFlow('onboarding');
166
+ };
167
+
168
+ const handleOnboardingComplete = (onboardingData) => {
169
+ console.log('Onboarding completed:', onboardingData);
170
+ const updatedUserData = {
171
+ ...userData,
172
+ onboardingComplete: true,
173
+ connectedAccounts: onboardingData.connectedAccounts || []
174
+ };
175
+ setUserData(updatedUserData);
176
+ localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
177
+ setCurrentFlow('pin');
178
+ };
179
+
180
+ const handlePinSetupComplete = (pinData) => {
181
+ console.log('PIN setup completed:', pinData);
182
+ const updatedUserData = {
183
+ ...userData,
184
+ ...pinData,
185
+ pinCreated: true
186
+ };
187
+ setUserData(updatedUserData);
188
+ localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
189
+
190
+ // Close overlay and open popup for data request
191
+ setShowOverlay(false);
192
+ setTimeout(() => {
193
+ openDataRequestDirectly();
194
+ }, 300);
195
+ };
196
+
197
+ const handleDataRequestComplete = (requestResult) => {
198
+ console.log('🔥 OnairosButton: Data request completed:', requestResult);
199
+
200
+ // Update user data with request result
201
+ const updatedUserData = {
202
+ ...userData,
203
+ lastDataRequest: requestResult
204
+ };
205
+ setUserData(updatedUserData);
206
+ localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
207
+
208
+ // Close popup
209
+ if (popupWindow) {
210
+ closeDataRequestPopup(popupWindow);
211
+ setPopupWindow(null);
212
+ }
213
+
214
+ // Call onComplete callback if provided
215
+ console.log('🔥 Calling onComplete callback with:', requestResult);
216
+ if (onComplete) {
217
+ try {
218
+ onComplete(requestResult);
219
+ console.log('🔥 onComplete callback executed successfully');
220
+ } catch (error) {
221
+ console.error('🔥 Error in onComplete callback:', error);
222
+ }
223
+ } else {
224
+ console.log('🔥 No onComplete callback provided');
225
+ }
226
+ };
227
+
228
+ const renderCurrentFlow = () => {
229
+ switch (currentFlow) {
230
+ case 'email':
231
+ return (
232
+ <EmailAuth
233
+ onSuccess={handleEmailAuthSuccess}
234
+ testMode={true} // Set to false in production
235
+ />
236
+ );
237
+
238
+ case 'onboarding':
239
+ return (
240
+ <UniversalOnboarding
241
+ onComplete={handleOnboardingComplete}
242
+ appIcon="https://onairos.sirv.com/Images/OnairosBlack.png"
243
+ appName={webpageName}
244
+ />
245
+ );
246
+
247
+ case 'pin':
248
+ return (
249
+ <PinSetup
250
+ onComplete={handlePinSetupComplete}
251
+ userEmail={userData?.email}
252
+ />
253
+ );
254
+
255
+ case 'dataRequest':
256
+ return (
257
+ <DataRequest
258
+ onComplete={handleDataRequestComplete}
259
+ userEmail={userData?.email}
260
+ requestData={requestData}
261
+ appName={webpageName}
262
+ autoFetch={autoFetch}
263
+ />
264
+ );
265
+
266
+ default:
267
+ return (
268
+ <div className="flex flex-col items-center space-y-4 p-6">
269
+ <div className="animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent"></div>
270
+ <p className="text-gray-600">Loading...</p>
271
+ </div>
272
+ );
273
+ }
274
+ };
275
+
276
+ // Styling and button class based on visual type
277
+ const buttonClass =
278
+ `flex items-center justify-center font-bold rounded cursor-pointer ${
279
+ buttonType === 'pill' ? 'px-4 py-2' : 'w-12 h-12'
280
+ } bg-transparent OnairosConnect`;
281
+
282
+ const buttonStyle = {
283
+ flexDirection: textLayout === 'below' ? 'column' : 'row',
284
+ backgroundColor: 'transparent',
285
+ color: textColor,
286
+ border: '1px solid transparent',
287
+ };
288
+
289
+ // Icon and text style based on the visualType
290
+ const logoStyle = {
291
+ width: '20px',
292
+ height: '20px',
293
+ marginRight: visualType === 'full' ? '12px' : '0',
294
+ };
295
+
296
+ const getText = () => {
297
+ switch (loginType) {
298
+ case 'signUp':
299
+ return 'Sign Up with Onairos';
300
+ case 'signOut':
301
+ return 'Sign Out of Onairos';
302
+ default:
301
303
  return 'Sign In with Onairos';
302
304
  }
303
305
  };
package/webpack.config.js CHANGED
@@ -16,7 +16,16 @@ const baseConfig = {
16
16
  commonjs2: 'react-dom',
17
17
  amd: 'ReactDOM',
18
18
  root: 'ReactDOM'
19
- }
19
+ },
20
+ 'ajv': 'ajv',
21
+ 'ajv/dist/runtime/validation_error': 'ajv/dist/runtime/validation_error',
22
+ 'ajv/dist/runtime/equal': 'ajv/dist/runtime/equal',
23
+ 'ajv/dist/runtime/ucs2length': 'ajv/dist/runtime/ucs2length',
24
+ 'ajv/dist/runtime/uri': 'ajv/dist/runtime/uri',
25
+ '@anthropic-ai/sdk': '@anthropic-ai/sdk',
26
+ '@google/generative-ai': '@google/generative-ai',
27
+ '@pinecone-database/pinecone': '@pinecone-database/pinecone',
28
+ 'openai': 'openai'
20
29
  },
21
30
  optimization: {
22
31
  minimize: true,