@onairos/react-native 3.0.68 → 3.0.70
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/lib/commonjs/components/onboarding/OAuthWebView.js +156 -10
- package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/commonjs/index.js +54 -13
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/services/platformAuthService.js +189 -44
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- package/lib/module/components/onboarding/OAuthWebView.js +156 -10
- package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/module/services/platformAuthService.js +188 -43
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +1 -1
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/onboarding/OAuthWebView.tsx +137 -6
- package/src/services/platformAuthService.ts +204 -39
|
@@ -100,6 +100,17 @@ export const initiateOAuth = async (platform: string, username: string, appName?
|
|
|
100
100
|
console.log('🌐 Platform uses OAuth WebView flow');
|
|
101
101
|
console.log('🔗 Auth endpoint:', PLATFORM_AUTH_CONFIG[platform].authEndpoint);
|
|
102
102
|
|
|
103
|
+
// Pre-flight connectivity check
|
|
104
|
+
console.log('🔍 Performing pre-flight connectivity check...');
|
|
105
|
+
const connectivityResult = await testApiConnectivity();
|
|
106
|
+
|
|
107
|
+
if (!connectivityResult.success) {
|
|
108
|
+
console.error('❌ Pre-flight connectivity check failed:', connectivityResult.error);
|
|
109
|
+
throw new Error(`Cannot reach authentication server: ${connectivityResult.error}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log('✅ Pre-flight connectivity check passed');
|
|
113
|
+
|
|
103
114
|
// Handle Instagram with specific API format
|
|
104
115
|
if (platform === 'instagram') {
|
|
105
116
|
const state = 'djksbfds';
|
|
@@ -112,13 +123,31 @@ export const initiateOAuth = async (platform: string, username: string, appName?
|
|
|
112
123
|
|
|
113
124
|
console.log('📤 Sending Instagram OAuth request:', jsonData);
|
|
114
125
|
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
const controller = new AbortController();
|
|
127
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout
|
|
128
|
+
|
|
129
|
+
let response: Response;
|
|
130
|
+
try {
|
|
131
|
+
response = await fetch('https://api2.onairos.uk/instagram/authorize', {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
headers: {
|
|
134
|
+
'Content-Type': 'application/json',
|
|
135
|
+
'User-Agent': 'OnairosReactNative/1.0',
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify(jsonData),
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
});
|
|
140
|
+
} catch (fetchError) {
|
|
141
|
+
clearTimeout(timeoutId);
|
|
142
|
+
|
|
143
|
+
if (fetchError.name === 'AbortError') {
|
|
144
|
+
throw new Error(`Request timeout: Instagram OAuth server took too long to respond`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
throw new Error(`Network error: ${fetchError.message || 'Failed to connect to Instagram OAuth server'}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
clearTimeout(timeoutId);
|
|
122
151
|
|
|
123
152
|
console.log('📡 Instagram OAuth response status:', response.status);
|
|
124
153
|
console.log('📡 Instagram OAuth response headers:', response.headers);
|
|
@@ -134,7 +163,13 @@ export const initiateOAuth = async (platform: string, username: string, appName?
|
|
|
134
163
|
|
|
135
164
|
if (responseData.instagramURL) {
|
|
136
165
|
console.log('✅ Instagram OAuth URL received:', responseData.instagramURL);
|
|
137
|
-
|
|
166
|
+
|
|
167
|
+
// Validate the URL before returning
|
|
168
|
+
if (await validateOAuthUrl(responseData.instagramURL)) {
|
|
169
|
+
return responseData.instagramURL;
|
|
170
|
+
} else {
|
|
171
|
+
throw new Error('Received invalid Instagram OAuth URL');
|
|
172
|
+
}
|
|
138
173
|
}
|
|
139
174
|
|
|
140
175
|
console.error('❌ No Instagram URL found in response');
|
|
@@ -152,14 +187,32 @@ export const initiateOAuth = async (platform: string, username: string, appName?
|
|
|
152
187
|
|
|
153
188
|
console.log(`📤 Sending ${platform} OAuth request:`, jsonData);
|
|
154
189
|
|
|
155
|
-
// Make the request to get the OAuth URL
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
190
|
+
// Make the request to get the OAuth URL with enhanced error handling
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout
|
|
193
|
+
|
|
194
|
+
let response: Response;
|
|
195
|
+
try {
|
|
196
|
+
response = await fetch(PLATFORM_AUTH_CONFIG[platform].authEndpoint, {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
headers: {
|
|
199
|
+
'Content-Type': 'application/json',
|
|
200
|
+
'User-Agent': 'OnairosReactNative/1.0',
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify(jsonData),
|
|
203
|
+
signal: controller.signal,
|
|
204
|
+
});
|
|
205
|
+
} catch (fetchError) {
|
|
206
|
+
clearTimeout(timeoutId);
|
|
207
|
+
|
|
208
|
+
if (fetchError.name === 'AbortError') {
|
|
209
|
+
throw new Error(`Request timeout: ${platform} OAuth server took too long to respond`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
throw new Error(`Network error: ${fetchError.message || 'Failed to connect to OAuth server'}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
clearTimeout(timeoutId);
|
|
163
216
|
|
|
164
217
|
console.log(`📡 ${platform} OAuth response status:`, response.status);
|
|
165
218
|
console.log(`📡 ${platform} OAuth response headers:`, response.headers);
|
|
@@ -181,36 +234,108 @@ export const initiateOAuth = async (platform: string, username: string, appName?
|
|
|
181
234
|
}
|
|
182
235
|
|
|
183
236
|
// Check if the response contains the OAuth URL based on platform
|
|
237
|
+
let oauthUrl: string | null = null;
|
|
238
|
+
|
|
184
239
|
switch (platform) {
|
|
185
240
|
case 'reddit':
|
|
186
|
-
|
|
241
|
+
oauthUrl = data.redditURL;
|
|
187
242
|
break;
|
|
188
243
|
case 'pinterest':
|
|
189
|
-
|
|
244
|
+
oauthUrl = data.pinterestURL;
|
|
190
245
|
break;
|
|
191
246
|
case 'youtube':
|
|
192
|
-
|
|
247
|
+
oauthUrl = data.youtubeURL;
|
|
193
248
|
break;
|
|
194
249
|
case 'email':
|
|
195
250
|
// Gmail might return under different field names
|
|
196
|
-
|
|
197
|
-
if (data.gmailURL) return data.gmailURL;
|
|
198
|
-
if (data.authUrl) return data.authUrl;
|
|
199
|
-
if (data.url) return data.url;
|
|
251
|
+
oauthUrl = data.emailURL || data.gmailURL || data.authUrl || data.url;
|
|
200
252
|
break;
|
|
201
253
|
default:
|
|
202
|
-
|
|
254
|
+
oauthUrl = data.url;
|
|
203
255
|
break;
|
|
204
256
|
}
|
|
205
257
|
|
|
206
|
-
|
|
207
|
-
|
|
258
|
+
if (!oauthUrl) {
|
|
259
|
+
console.error(`❌ No OAuth URL found in response for ${platform}. Response:`, data);
|
|
260
|
+
throw new Error(`No OAuth URL found in response for ${platform}`);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
console.log(`✅ ${platform} OAuth URL received:`, oauthUrl);
|
|
264
|
+
|
|
265
|
+
// Validate the URL before returning
|
|
266
|
+
if (await validateOAuthUrl(oauthUrl)) {
|
|
267
|
+
return oauthUrl;
|
|
268
|
+
} else {
|
|
269
|
+
throw new Error(`Received invalid ${platform} OAuth URL`);
|
|
270
|
+
}
|
|
208
271
|
} catch (error) {
|
|
209
272
|
console.error(`Error initiating OAuth for ${platform}:`, error);
|
|
210
273
|
throw error;
|
|
211
274
|
}
|
|
212
275
|
};
|
|
213
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Validates an OAuth URL to ensure it's reachable
|
|
279
|
+
* @param url The OAuth URL to validate
|
|
280
|
+
* @returns Promise<boolean> indicating if the URL is valid and reachable
|
|
281
|
+
*/
|
|
282
|
+
const validateOAuthUrl = async (url: string): Promise<boolean> => {
|
|
283
|
+
try {
|
|
284
|
+
console.log('🔍 Validating OAuth URL:', url);
|
|
285
|
+
|
|
286
|
+
// Basic URL format validation
|
|
287
|
+
if (!url || typeof url !== 'string') {
|
|
288
|
+
console.error('❌ Invalid URL format:', url);
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Check if URL starts with https
|
|
293
|
+
if (!url.startsWith('https://')) {
|
|
294
|
+
console.error('❌ URL must use HTTPS:', url);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Try to parse the URL
|
|
299
|
+
try {
|
|
300
|
+
new URL(url);
|
|
301
|
+
} catch (parseError) {
|
|
302
|
+
console.error('❌ URL parsing failed:', parseError);
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Make a HEAD request to check if the URL is reachable
|
|
307
|
+
const controller = new AbortController();
|
|
308
|
+
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
const response = await fetch(url, {
|
|
312
|
+
method: 'HEAD',
|
|
313
|
+
signal: controller.signal,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
clearTimeout(timeoutId);
|
|
317
|
+
|
|
318
|
+
// Accept any response that's not a network error
|
|
319
|
+
// OAuth pages might return various status codes
|
|
320
|
+
console.log('✅ OAuth URL validation successful, status:', response.status);
|
|
321
|
+
return true;
|
|
322
|
+
} catch (fetchError) {
|
|
323
|
+
clearTimeout(timeoutId);
|
|
324
|
+
|
|
325
|
+
if (fetchError.name === 'AbortError') {
|
|
326
|
+
console.warn('⚠️ OAuth URL validation timeout, but proceeding anyway');
|
|
327
|
+
return true; // Allow timeout as URLs might be slow to respond
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.warn('⚠️ OAuth URL validation failed, but proceeding anyway:', fetchError.message);
|
|
331
|
+
return true; // Allow network errors as they might be temporary
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.warn('⚠️ OAuth URL validation error, but proceeding anyway:', error);
|
|
335
|
+
return true; // Allow validation errors to not block the flow
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
214
339
|
/**
|
|
215
340
|
* Initiates the native SDK authentication flow for a platform
|
|
216
341
|
* @param platform The platform to authenticate with
|
|
@@ -473,22 +598,62 @@ export const testApiConnectivity = async (): Promise<{ success: boolean; error?:
|
|
|
473
598
|
try {
|
|
474
599
|
console.log('🔍 Testing connectivity to Onairos API...');
|
|
475
600
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
});
|
|
601
|
+
// Test multiple endpoints for better reliability
|
|
602
|
+
const testEndpoints = [
|
|
603
|
+
'https://api2.onairos.uk/health',
|
|
604
|
+
'https://api2.onairos.uk', // Base URL
|
|
605
|
+
];
|
|
482
606
|
|
|
483
|
-
|
|
607
|
+
let lastError: string | null = null;
|
|
484
608
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
609
|
+
for (const endpoint of testEndpoints) {
|
|
610
|
+
try {
|
|
611
|
+
console.log(`🔍 Testing endpoint: ${endpoint}`);
|
|
612
|
+
|
|
613
|
+
const controller = new AbortController();
|
|
614
|
+
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
|
|
615
|
+
|
|
616
|
+
const response = await fetch(endpoint, {
|
|
617
|
+
method: 'GET',
|
|
618
|
+
headers: {
|
|
619
|
+
'Content-Type': 'application/json',
|
|
620
|
+
'User-Agent': 'OnairosReactNative/1.0',
|
|
621
|
+
},
|
|
622
|
+
signal: controller.signal,
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
clearTimeout(timeoutId);
|
|
626
|
+
|
|
627
|
+
console.log(`🌐 API connectivity test response for ${endpoint}:`, response.status);
|
|
628
|
+
|
|
629
|
+
if (response.ok || response.status === 404) {
|
|
630
|
+
// Accept 404 as it means the server is reachable
|
|
631
|
+
console.log('✅ API server is reachable');
|
|
632
|
+
return { success: true };
|
|
633
|
+
} else {
|
|
634
|
+
console.log(`⚠️ API server responded with status ${response.status} for ${endpoint}`);
|
|
635
|
+
lastError = `API server error: ${response.status}`;
|
|
636
|
+
// Continue to next endpoint
|
|
637
|
+
}
|
|
638
|
+
} catch (fetchError) {
|
|
639
|
+
console.log(`❌ Failed to reach ${endpoint}:`, fetchError);
|
|
640
|
+
|
|
641
|
+
if (fetchError.name === 'AbortError') {
|
|
642
|
+
lastError = 'Connection timeout - API server took too long to respond';
|
|
643
|
+
} else if (fetchError.message.includes('Network request failed')) {
|
|
644
|
+
lastError = 'Network error - check your internet connection';
|
|
645
|
+
} else if (fetchError.message.includes('not connected to the internet')) {
|
|
646
|
+
lastError = 'No internet connection';
|
|
647
|
+
} else {
|
|
648
|
+
lastError = `Network error: ${fetchError.message}`;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Continue to next endpoint
|
|
652
|
+
}
|
|
491
653
|
}
|
|
654
|
+
|
|
655
|
+
console.error('❌ All API connectivity tests failed');
|
|
656
|
+
return { success: false, error: lastError || 'Cannot reach API server' };
|
|
492
657
|
} catch (error) {
|
|
493
658
|
console.error('❌ API connectivity test failed:', error);
|
|
494
659
|
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
|