@onairos/react-native 3.0.71 → 3.0.72

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.
Files changed (47) hide show
  1. package/lib/commonjs/components/Onairos.js +294 -155
  2. package/lib/commonjs/components/Onairos.js.map +1 -1
  3. package/lib/commonjs/components/OnairosButton.js +1 -1
  4. package/lib/commonjs/components/OnairosButton.js.map +1 -1
  5. package/lib/commonjs/components/UniversalOnboarding.js +6 -6
  6. package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
  7. package/lib/commonjs/components/onboarding/OAuthWebView.js +188 -52
  8. package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
  9. package/lib/commonjs/index.js +66 -0
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/services/apiKeyService.js +325 -0
  12. package/lib/commonjs/services/apiKeyService.js.map +1 -0
  13. package/lib/commonjs/services/platformAuthService.js +104 -113
  14. package/lib/commonjs/services/platformAuthService.js.map +1 -1
  15. package/lib/module/components/Onairos.js +297 -158
  16. package/lib/module/components/Onairos.js.map +1 -1
  17. package/lib/module/components/OnairosButton.js +1 -1
  18. package/lib/module/components/OnairosButton.js.map +1 -1
  19. package/lib/module/components/UniversalOnboarding.js +6 -6
  20. package/lib/module/components/UniversalOnboarding.js.map +1 -1
  21. package/lib/module/components/onboarding/OAuthWebView.js +188 -52
  22. package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
  23. package/lib/module/index.js +4 -1
  24. package/lib/module/index.js.map +1 -1
  25. package/lib/module/services/apiKeyService.js +310 -0
  26. package/lib/module/services/apiKeyService.js.map +1 -0
  27. package/lib/module/services/platformAuthService.js +104 -113
  28. package/lib/module/services/platformAuthService.js.map +1 -1
  29. package/lib/typescript/components/Onairos.d.ts +6 -5
  30. package/lib/typescript/components/Onairos.d.ts.map +1 -1
  31. package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +1 -1
  32. package/lib/typescript/index.d.ts +3 -2
  33. package/lib/typescript/index.d.ts.map +1 -1
  34. package/lib/typescript/services/apiKeyService.d.ts +48 -0
  35. package/lib/typescript/services/apiKeyService.d.ts.map +1 -0
  36. package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
  37. package/lib/typescript/types.d.ts +36 -3
  38. package/lib/typescript/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/components/Onairos.tsx +336 -184
  41. package/src/components/OnairosButton.tsx +1 -1
  42. package/src/components/UniversalOnboarding.tsx +6 -6
  43. package/src/components/onboarding/OAuthWebView.tsx +236 -71
  44. package/src/index.ts +19 -0
  45. package/src/services/apiKeyService.ts +325 -0
  46. package/src/services/platformAuthService.ts +111 -130
  47. package/src/types.ts +40 -3
@@ -0,0 +1,325 @@
1
+ import type { OnairosConfig, ApiKeyValidationResult } from '../types';
2
+
3
+ /**
4
+ * API Key Service for Onairos React Native SDK
5
+ *
6
+ * This service handles API key validation, management, and authentication
7
+ * following standard SDK patterns for secure API key handling.
8
+ *
9
+ * How it works:
10
+ * 1. Initialize with API key and configuration
11
+ * 2. Validate API key with the Onairos backend
12
+ * 3. Cache validation results for performance
13
+ * 4. Include API key in all authenticated requests
14
+ * 5. Handle API key errors gracefully with developer-friendly messages
15
+ */
16
+
17
+ // Global configuration state
18
+ let globalConfig: OnairosConfig | null = null;
19
+ let validationCache: Map<string, { result: ApiKeyValidationResult; timestamp: number }> = new Map();
20
+ let isInitialized = false;
21
+
22
+ // Cache duration (5 minutes)
23
+ const CACHE_DURATION = 5 * 60 * 1000;
24
+
25
+ // API endpoints for different environments
26
+ const API_ENDPOINTS = {
27
+ production: 'https://api2.onairos.uk',
28
+ staging: 'https://staging-api.onairos.uk',
29
+ development: 'https://dev-api.onairos.uk',
30
+ };
31
+
32
+ /**
33
+ * Initialize the SDK with API key and configuration
34
+ * @param config API configuration including API key
35
+ */
36
+ export const initializeApiKey = async (config: OnairosConfig): Promise<void> => {
37
+ try {
38
+ console.log('🔑 Initializing Onairos SDK with API key...');
39
+
40
+ if (!config.apiKey) {
41
+ throw new Error('API key is required for SDK initialization');
42
+ }
43
+
44
+ if (config.apiKey.length < 32) {
45
+ throw new Error('Invalid API key format. API key must be at least 32 characters long.');
46
+ }
47
+
48
+ // Set global configuration
49
+ globalConfig = {
50
+ apiKey: config.apiKey,
51
+ environment: config.environment || 'production',
52
+ enableLogging: config.enableLogging !== false, // Default to true
53
+ timeout: config.timeout || 30000,
54
+ retryAttempts: config.retryAttempts || 3,
55
+ };
56
+
57
+ if (globalConfig.enableLogging) {
58
+ console.log('📝 SDK Configuration:', {
59
+ environment: globalConfig.environment,
60
+ timeout: globalConfig.timeout,
61
+ retryAttempts: globalConfig.retryAttempts,
62
+ apiKeyPrefix: config.apiKey.substring(0, 8) + '...',
63
+ enableLogging: globalConfig.enableLogging,
64
+ });
65
+ }
66
+
67
+ // Validate the API key
68
+ const validation = await validateApiKey(config.apiKey);
69
+
70
+ if (!validation.isValid) {
71
+ throw new Error(`API key validation failed: ${validation.error}`);
72
+ }
73
+
74
+ isInitialized = true;
75
+
76
+ if (globalConfig.enableLogging) {
77
+ console.log('✅ Onairos SDK initialized successfully');
78
+ if (validation.permissions) {
79
+ console.log('🔐 API Key Permissions:', validation.permissions);
80
+ }
81
+ if (validation.rateLimits) {
82
+ console.log('⏱️ Rate Limits:', validation.rateLimits);
83
+ }
84
+ }
85
+ } catch (error) {
86
+ console.error('❌ Failed to initialize Onairos SDK:', error);
87
+ isInitialized = false;
88
+ throw error;
89
+ }
90
+ };
91
+
92
+ /**
93
+ * Validate an API key with the Onairos backend
94
+ * @param apiKey The API key to validate
95
+ * @returns Validation result with permissions and rate limits
96
+ */
97
+ export const validateApiKey = async (apiKey: string): Promise<ApiKeyValidationResult> => {
98
+ try {
99
+ console.log('🔍 Validating API key...');
100
+
101
+ // Check cache first
102
+ const cached = validationCache.get(apiKey);
103
+ if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
104
+ if (globalConfig?.enableLogging) {
105
+ console.log('📋 Using cached API key validation result');
106
+ }
107
+ return cached.result;
108
+ }
109
+
110
+ const environment = globalConfig?.environment || 'production';
111
+ const baseUrl = API_ENDPOINTS[environment];
112
+ const timeout = globalConfig?.timeout || 30000;
113
+
114
+ // Create abort controller for timeout
115
+ const controller = new AbortController();
116
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
117
+
118
+ try {
119
+ const response = await fetch(`${baseUrl}/auth/validate-key`, {
120
+ method: 'POST',
121
+ headers: {
122
+ 'Content-Type': 'application/json',
123
+ 'Authorization': `Bearer ${apiKey}`,
124
+ 'User-Agent': 'OnairosReactNative/1.0',
125
+ },
126
+ body: JSON.stringify({
127
+ environment,
128
+ sdk_version: '3.0.71',
129
+ platform: 'react-native',
130
+ }),
131
+ signal: controller.signal,
132
+ });
133
+
134
+ clearTimeout(timeoutId);
135
+
136
+ const data = await response.json();
137
+
138
+ if (response.ok && data.success) {
139
+ const result: ApiKeyValidationResult = {
140
+ isValid: true,
141
+ permissions: data.permissions || [],
142
+ rateLimits: data.rateLimits || null,
143
+ };
144
+
145
+ // Cache the successful result
146
+ validationCache.set(apiKey, {
147
+ result,
148
+ timestamp: Date.now(),
149
+ });
150
+
151
+ if (globalConfig?.enableLogging) {
152
+ console.log('✅ API key validation successful');
153
+ }
154
+
155
+ return result;
156
+ } else {
157
+ const errorMessage = data.error || `HTTP ${response.status}: ${response.statusText}`;
158
+
159
+ const result: ApiKeyValidationResult = {
160
+ isValid: false,
161
+ error: errorMessage,
162
+ };
163
+
164
+ // Don't cache failed results
165
+ if (globalConfig?.enableLogging) {
166
+ console.error('❌ API key validation failed:', errorMessage);
167
+ }
168
+
169
+ return result;
170
+ }
171
+ } catch (fetchError) {
172
+ clearTimeout(timeoutId);
173
+
174
+ if (fetchError.name === 'AbortError') {
175
+ const errorMessage = 'API key validation timeout';
176
+ console.error('⏱️ API key validation timeout');
177
+ return { isValid: false, error: errorMessage };
178
+ }
179
+
180
+ const errorMessage = `Network error during API key validation: ${fetchError.message}`;
181
+ console.error('🌐 Network error during API key validation:', fetchError);
182
+ return { isValid: false, error: errorMessage };
183
+ }
184
+ } catch (error) {
185
+ const errorMessage = `API key validation error: ${error.message}`;
186
+ console.error('❌ API key validation error:', error);
187
+ return { isValid: false, error: errorMessage };
188
+ }
189
+ };
190
+
191
+ /**
192
+ * Get the current API configuration
193
+ * @returns Current API configuration or null if not initialized
194
+ */
195
+ export const getApiConfig = (): OnairosConfig | null => {
196
+ return globalConfig;
197
+ };
198
+
199
+ /**
200
+ * Get the current API key
201
+ * @returns Current API key or null if not initialized
202
+ */
203
+ export const getApiKey = (): string | null => {
204
+ return globalConfig?.apiKey || null;
205
+ };
206
+
207
+ /**
208
+ * Check if the SDK is properly initialized
209
+ * @returns True if initialized with valid API key
210
+ */
211
+ export const isApiKeyInitialized = (): boolean => {
212
+ return isInitialized && globalConfig !== null;
213
+ };
214
+
215
+ /**
216
+ * Get authenticated headers for API requests
217
+ * @returns Headers object with Authorization and other required headers
218
+ */
219
+ export const getAuthHeaders = (): Record<string, string> => {
220
+ if (!globalConfig?.apiKey) {
221
+ throw new Error('SDK not initialized. Call initializeApiKey() first.');
222
+ }
223
+
224
+ return {
225
+ 'Content-Type': 'application/json',
226
+ 'Authorization': `Bearer ${globalConfig.apiKey}`,
227
+ 'User-Agent': 'OnairosReactNative/3.0.71',
228
+ 'X-SDK-Version': '3.0.71',
229
+ 'X-SDK-Environment': globalConfig.environment || 'production',
230
+ };
231
+ };
232
+
233
+ /**
234
+ * Make an authenticated API request
235
+ * @param endpoint The API endpoint (relative to base URL)
236
+ * @param options Fetch options
237
+ * @returns Response promise
238
+ */
239
+ export const makeAuthenticatedRequest = async (
240
+ endpoint: string,
241
+ options: RequestInit = {}
242
+ ): Promise<Response> => {
243
+ if (!isApiKeyInitialized()) {
244
+ throw new Error('SDK not initialized. Call initializeApiKey() first.');
245
+ }
246
+
247
+ const config = getApiConfig()!;
248
+ const baseUrl = API_ENDPOINTS[config.environment || 'production'];
249
+ const url = `${baseUrl}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
250
+
251
+ // Merge authentication headers
252
+ const headers = {
253
+ ...getAuthHeaders(),
254
+ ...(options.headers || {}),
255
+ };
256
+
257
+ // Add timeout
258
+ const controller = new AbortController();
259
+ const timeoutId = setTimeout(() => controller.abort(), config.timeout || 30000);
260
+
261
+ try {
262
+ if (config.enableLogging) {
263
+ console.log(`🌐 Making authenticated request to: ${endpoint}`);
264
+ }
265
+
266
+ const response = await fetch(url, {
267
+ ...options,
268
+ headers,
269
+ signal: controller.signal,
270
+ });
271
+
272
+ clearTimeout(timeoutId);
273
+
274
+ if (config.enableLogging) {
275
+ console.log(`📡 Response status: ${response.status} for ${endpoint}`);
276
+ }
277
+
278
+ // Handle API key errors
279
+ if (response.status === 401) {
280
+ console.error('❌ API key authentication failed. Please check your API key.');
281
+ throw new Error('Invalid or expired API key');
282
+ }
283
+
284
+ if (response.status === 403) {
285
+ console.error('❌ API key permissions insufficient for this operation.');
286
+ throw new Error('Insufficient API key permissions');
287
+ }
288
+
289
+ if (response.status === 429) {
290
+ console.error('❌ API rate limit exceeded. Please try again later.');
291
+ throw new Error('Rate limit exceeded');
292
+ }
293
+
294
+ return response;
295
+ } catch (error) {
296
+ clearTimeout(timeoutId);
297
+
298
+ if (error.name === 'AbortError') {
299
+ console.error('⏱️ Request timeout for:', endpoint);
300
+ throw new Error('Request timeout');
301
+ }
302
+
303
+ throw error;
304
+ }
305
+ };
306
+
307
+ /**
308
+ * Clear the API key validation cache
309
+ */
310
+ export const clearValidationCache = (): void => {
311
+ validationCache.clear();
312
+ if (globalConfig?.enableLogging) {
313
+ console.log('🗑️ API key validation cache cleared');
314
+ }
315
+ };
316
+
317
+ /**
318
+ * Reset the SDK initialization state
319
+ */
320
+ export const resetApiKeyService = (): void => {
321
+ globalConfig = null;
322
+ isInitialized = false;
323
+ clearValidationCache();
324
+ console.log('🔄 API key service reset');
325
+ };