@onairos/react-native 3.1.15 → 3.1.17

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 (191) hide show
  1. package/README.md +404 -0
  2. package/lib/commonjs/assets/images/Checkbox.svg +3 -3
  3. package/lib/commonjs/assets/images/EnochE.svg +19 -19
  4. package/lib/commonjs/assets/images/Personalityprofile.svg +3 -3
  5. package/lib/commonjs/assets/images/Personalitytraits.svg +3 -3
  6. package/lib/commonjs/assets/images/Userpreferences.svg +3 -3
  7. package/lib/commonjs/assets/images/arrow.svg +20 -20
  8. package/lib/commonjs/assets/images/basicproficon.svg +43 -43
  9. package/lib/commonjs/assets/images/basicprofile.svg +3 -3
  10. package/lib/commonjs/assets/images/checkmark.svg +4 -4
  11. package/lib/commonjs/assets/images/contentanalysis.svg +3 -3
  12. package/lib/commonjs/assets/images/contenticon.svg +23 -23
  13. package/lib/commonjs/assets/images/personalityicon.svg +18 -18
  14. package/lib/commonjs/assets/images/x-close.svg +3 -3
  15. package/lib/commonjs/components/OnairosSignInButton.js +32 -74
  16. package/lib/commonjs/components/OnairosSignInButton.js.map +1 -1
  17. package/lib/commonjs/components/UniversalOnboarding.js +4 -4
  18. package/lib/commonjs/config/api.js +2 -2
  19. package/lib/commonjs/hooks/useConnections.js +6 -6
  20. package/lib/commonjs/hooks/useUserConnections.js +10 -10
  21. package/lib/commonjs/index.js +5 -12
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/commonjs/services/apiClient.js +35 -35
  24. package/lib/commonjs/services/apiKeyService.js +99 -99
  25. package/lib/commonjs/services/authService.js +82 -82
  26. package/lib/commonjs/services/biometricPinService.js +10 -10
  27. package/lib/commonjs/services/connectedAccountsService.js +32 -32
  28. package/lib/commonjs/services/googleAuthService.js +15 -15
  29. package/lib/commonjs/services/imageCompressionService.js +15 -15
  30. package/lib/commonjs/services/jwtStorageService.js +59 -59
  31. package/lib/commonjs/services/mobileTrainingService.js +14 -14
  32. package/lib/commonjs/services/pinEncryptionService.js +10 -10
  33. package/lib/commonjs/services/pinStorageUtils.js +15 -15
  34. package/lib/commonjs/services/platformAuthService.js +47 -47
  35. package/lib/commonjs/services/storageService.js +31 -31
  36. package/lib/commonjs/services/trainingApiHelpers.js +33 -33
  37. package/lib/commonjs/services/userConnectionsService.js +24 -24
  38. package/lib/commonjs/utils/Portal.js +4 -4
  39. package/lib/commonjs/utils/api.js +24 -24
  40. package/lib/commonjs/utils/auth.js +18 -18
  41. package/lib/commonjs/utils/crypto.js +13 -13
  42. package/lib/commonjs/utils/encryption.js +12 -12
  43. package/lib/commonjs/utils/eventUtils.js +52 -52
  44. package/lib/commonjs/utils/programmaticFlow.js +16 -16
  45. package/lib/commonjs/utils/retryHelper.js +27 -27
  46. package/lib/module/assets/images/Checkbox.svg +3 -3
  47. package/lib/module/assets/images/EnochE.svg +19 -19
  48. package/lib/module/assets/images/Personalityprofile.svg +3 -3
  49. package/lib/module/assets/images/Personalitytraits.svg +3 -3
  50. package/lib/module/assets/images/Userpreferences.svg +3 -3
  51. package/lib/module/assets/images/arrow.svg +20 -20
  52. package/lib/module/assets/images/basicproficon.svg +43 -43
  53. package/lib/module/assets/images/basicprofile.svg +3 -3
  54. package/lib/module/assets/images/checkmark.svg +4 -4
  55. package/lib/module/assets/images/contentanalysis.svg +3 -3
  56. package/lib/module/assets/images/contenticon.svg +23 -23
  57. package/lib/module/assets/images/personalityicon.svg +18 -18
  58. package/lib/module/assets/images/x-close.svg +3 -3
  59. package/lib/module/components/OnairosSignInButton.js +32 -74
  60. package/lib/module/components/OnairosSignInButton.js.map +1 -1
  61. package/lib/module/components/UniversalOnboarding.js +4 -4
  62. package/lib/module/config/api.js +2 -2
  63. package/lib/module/hooks/useConnections.js +6 -6
  64. package/lib/module/hooks/useUserConnections.js +10 -10
  65. package/lib/module/index.js +5 -6
  66. package/lib/module/index.js.map +1 -1
  67. package/lib/module/services/apiClient.js +35 -35
  68. package/lib/module/services/apiKeyService.js +99 -99
  69. package/lib/module/services/authService.js +82 -82
  70. package/lib/module/services/biometricPinService.js +10 -10
  71. package/lib/module/services/connectedAccountsService.js +32 -32
  72. package/lib/module/services/googleAuthService.js +15 -15
  73. package/lib/module/services/imageCompressionService.js +15 -15
  74. package/lib/module/services/jwtStorageService.js +59 -59
  75. package/lib/module/services/mobileTrainingService.js +14 -14
  76. package/lib/module/services/pinEncryptionService.js +10 -10
  77. package/lib/module/services/pinStorageUtils.js +15 -15
  78. package/lib/module/services/platformAuthService.js +47 -47
  79. package/lib/module/services/storageService.js +31 -31
  80. package/lib/module/services/trainingApiHelpers.js +33 -33
  81. package/lib/module/services/userConnectionsService.js +24 -24
  82. package/lib/module/utils/Portal.js +4 -4
  83. package/lib/module/utils/api.js +24 -24
  84. package/lib/module/utils/auth.js +18 -18
  85. package/lib/module/utils/crypto.js +13 -13
  86. package/lib/module/utils/encryption.js +12 -12
  87. package/lib/module/utils/eventUtils.js +52 -52
  88. package/lib/module/utils/programmaticFlow.js +16 -16
  89. package/lib/module/utils/retryHelper.js +27 -27
  90. package/lib/typescript/components/OnairosSignInButton.d.ts.map +1 -1
  91. package/lib/typescript/index.d.ts +0 -1
  92. package/lib/typescript/index.d.ts.map +1 -1
  93. package/package.json +163 -163
  94. package/src/api/index.ts +151 -151
  95. package/src/assets/images/Checkbox.svg +3 -3
  96. package/src/assets/images/EnochE.svg +19 -19
  97. package/src/assets/images/Personalityprofile.svg +3 -3
  98. package/src/assets/images/Personalitytraits.svg +3 -3
  99. package/src/assets/images/Userpreferences.svg +3 -3
  100. package/src/assets/images/arrow.svg +20 -20
  101. package/src/assets/images/basicproficon.svg +43 -43
  102. package/src/assets/images/basicprofile.svg +3 -3
  103. package/src/assets/images/checkmark.svg +4 -4
  104. package/src/assets/images/contentanalysis.svg +3 -3
  105. package/src/assets/images/contenticon.svg +23 -23
  106. package/src/assets/images/personalityicon.svg +18 -18
  107. package/src/assets/images/x-close.svg +3 -3
  108. package/src/components/BodyText.tsx +33 -33
  109. package/src/components/BrandMark.tsx +62 -62
  110. package/src/components/CodeInput.tsx +32 -32
  111. package/src/components/DataRequestScreen.tsx +355 -355
  112. package/src/components/EmailInput.tsx +31 -31
  113. package/src/components/EmailVerificationModal.tsx +363 -363
  114. package/src/components/ExistingUserDataConfirmation.tsx +506 -506
  115. package/src/components/GoogleButton.tsx +55 -55
  116. package/src/components/HeadingGroup.tsx +49 -49
  117. package/src/components/ModalHeader.tsx +125 -125
  118. package/src/components/ModalSheet.tsx +57 -57
  119. package/src/components/Onairos.tsx +422 -422
  120. package/src/components/OnairosButton.tsx +339 -339
  121. package/src/components/OnairosSignInButton.tsx +130 -166
  122. package/src/components/Overlay.tsx +506 -506
  123. package/src/components/PersonaImage.tsx +79 -79
  124. package/src/components/PersonaLoadingScreen.tsx +201 -201
  125. package/src/components/PersonalizationConsentScreen.tsx +410 -410
  126. package/src/components/PinCreationScreen.tsx +492 -492
  127. package/src/components/PinInput.tsx +555 -555
  128. package/src/components/PlatformConnectorsStep.tsx +891 -891
  129. package/src/components/PlatformList.tsx +144 -144
  130. package/src/components/PlatformToggle.tsx +226 -226
  131. package/src/components/PrimaryButton.tsx +213 -213
  132. package/src/components/SignInMatchAnimation.tsx +225 -225
  133. package/src/components/SignInStep.tsx +217 -217
  134. package/src/components/TrainingModal.tsx +1047 -1047
  135. package/src/components/UniversalOnboarding.tsx +2887 -2887
  136. package/src/components/VerificationStep.tsx +198 -198
  137. package/src/components/WelcomeScreen.tsx +473 -473
  138. package/src/components/icons/Basicproficon.tsx +30 -30
  139. package/src/components/icons/Basicprofile.tsx +17 -17
  140. package/src/components/icons/Checkbox.tsx +17 -17
  141. package/src/components/icons/Checkmark.tsx +24 -24
  142. package/src/components/icons/Contentanalysis.tsx +17 -17
  143. package/src/components/icons/Contenticon.tsx +30 -30
  144. package/src/components/icons/EnochE.tsx +39 -39
  145. package/src/components/icons/Personalityicon.tsx +22 -22
  146. package/src/components/icons/Personalityprofile.tsx +17 -17
  147. package/src/components/icons/Personalitytraits.tsx +17 -17
  148. package/src/components/icons/Userpreferences.tsx +17 -17
  149. package/src/components/icons/index.ts +12 -12
  150. package/src/components/onboarding/OAuthWebView.tsx +232 -232
  151. package/src/config/api.ts +25 -25
  152. package/src/context/AuthContext.tsx +393 -393
  153. package/src/hooks/useConnectedAccounts.ts +138 -138
  154. package/src/hooks/useConnections.ts +161 -161
  155. package/src/hooks/useCredentials.ts +174 -174
  156. package/src/hooks/useUserConnections.ts +165 -165
  157. package/src/index.js +14 -14
  158. package/src/index.ts +94 -95
  159. package/src/services/apiClient.ts +336 -336
  160. package/src/services/apiKeyService.ts +919 -919
  161. package/src/services/authService.ts +1008 -1008
  162. package/src/services/biometricPinService.ts +192 -192
  163. package/src/services/connectedAccountsService.ts +289 -289
  164. package/src/services/googleAuthService.ts +279 -279
  165. package/src/services/imageCompressionService.ts +302 -302
  166. package/src/services/jwtStorageService.ts +256 -256
  167. package/src/services/mobileTrainingService.ts +203 -203
  168. package/src/services/pinEncryptionService.ts +75 -75
  169. package/src/services/pinStorageUtils.ts +96 -96
  170. package/src/services/platformAuthService.ts +1346 -1346
  171. package/src/services/storageService.ts +451 -451
  172. package/src/services/trainingApiHelpers.ts +66 -66
  173. package/src/services/userConnectionsService.ts +556 -556
  174. package/src/services/youtubeMigrationService.ts +453 -453
  175. package/src/theme/index.ts +239 -239
  176. package/src/types/ambient.d.ts +28 -28
  177. package/src/types/index.ts +265 -265
  178. package/src/types/node-fix.d.ts +18 -18
  179. package/src/types/node-override.d.ts +23 -23
  180. package/src/types/opacity.d.ts +15 -15
  181. package/src/types/types.d.ts +17 -17
  182. package/src/utils/Portal.tsx +82 -82
  183. package/src/utils/api.js +111 -111
  184. package/src/utils/auth.js +103 -103
  185. package/src/utils/crypto.js +59 -59
  186. package/src/utils/encryption.ts +68 -68
  187. package/src/utils/eventUtils.ts +302 -302
  188. package/src/utils/haptics.ts +58 -58
  189. package/src/utils/imagePreloader.ts +2 -2
  190. package/src/utils/programmaticFlow.ts +112 -112
  191. package/src/utils/retryHelper.ts +274 -274
@@ -1,257 +1,257 @@
1
- import AsyncStorage from '@react-native-async-storage/async-storage';
2
- import { Buffer } from 'buffer';
3
-
4
- /**
5
- * JWT Token Storage Service - CORRECTED APPROACH
6
- * Manages 3 DISTINCT JWT token types for different route families
7
- *
8
- * TOKEN TYPES:
9
- * 1. Enoch JWT (enoch_token) - For /enoch/*, /api/auth/*, /mobile-training/enoch
10
- * 2. Onairos JWT (onairos_jwt_token) - For /youtube/*, /gmail/*, social connections
11
- * 3. Auth Token (auth_token) - For context-specific auth flows
12
- */
13
-
14
- export enum TokenType {
15
- ENOCH = 'enoch_token',
16
- ONAIROS = 'onairos_jwt_token',
17
- AUTH = 'auth_token'
18
- }
19
-
20
- /**
21
- * Route-based token mapping
22
- * Determines which token type to use for which routes
23
- */
24
- export const getTokenTypeForRoute = (route: string): TokenType => {
25
- const cleanRoute = route.toLowerCase();
26
-
27
- // Enoch routes - use Enoch JWT
28
- if (cleanRoute.includes('/enoch/') ||
29
- cleanRoute.includes('/api/auth/') ||
30
- cleanRoute.includes('/mobile-training/enoch')) {
31
- return TokenType.ENOCH;
32
- }
33
-
34
- // Onairos routes - use Onairos JWT
35
- if (cleanRoute.includes('/youtube/') ||
36
- cleanRoute.includes('/gmail/') ||
37
- cleanRoute.includes('/connectedaccounts') ||
38
- cleanRoute.includes('/social/')) {
39
- return TokenType.ONAIROS;
40
- }
41
-
42
- // Default to auth token for other routes
43
- return TokenType.AUTH;
44
- };
45
-
46
- /**
47
- * Store JWT token of specific type
48
- * @param tokenType - Type of token to store
49
- * @param token - JWT token to store
50
- * @returns Promise<boolean> - Success status
51
- */
52
- export const storeJWT = async (tokenType: TokenType, token: string): Promise<boolean> => {
53
- try {
54
- if (!token || token.trim() === '') {
55
- console.warn(`⚠️ [JWT Storage] Attempted to store empty/null ${tokenType} token`);
56
- return false;
57
- }
58
-
59
- // Validate JWT format (should have 3 parts separated by dots)
60
- const parts = token.split('.');
61
- if (parts.length !== 3) {
62
- console.warn(`⚠️ [JWT Storage] Invalid JWT format for ${tokenType} - token should have 3 parts`);
63
- return false;
64
- }
65
-
66
- await AsyncStorage.setItem(tokenType, token);
67
- console.log(`✅ [JWT Storage] ${tokenType} token stored successfully`);
68
- return true;
69
- } catch (error) {
70
- console.error(`❌ [JWT Storage] Failed to store ${tokenType} token:`, error);
71
- return false;
72
- }
73
- };
74
-
75
- /**
76
- * Retrieve JWT token of specific type
77
- * @param tokenType - Type of token to retrieve
78
- * @returns Promise<string | null> - JWT token or null if not found
79
- */
80
- export const getJWT = async (tokenType: TokenType): Promise<string | null> => {
81
- try {
82
- const token = await AsyncStorage.getItem(tokenType);
83
-
84
- if (!token) {
85
- console.log(`📭 [JWT Storage] No ${tokenType} token found in storage`);
86
- return null;
87
- }
88
-
89
- // Validate JWT format
90
- if (!isValidJWTFormat(token)) {
91
- console.warn(`⚠️ [JWT Storage] Invalid JWT format found for ${tokenType}, removing`);
92
- await clearJWT(tokenType);
93
- return null;
94
- }
95
-
96
- console.log(`🔐 [JWT Storage] ${tokenType} token retrieved successfully`);
97
- return token;
98
- } catch (error) {
99
- console.error(`❌ [JWT Storage] Failed to retrieve ${tokenType} token:`, error);
100
- return null;
101
- }
102
- };
103
-
104
- /**
105
- * Get JWT token for specific route
106
- * @param route - API route to get token for
107
- * @returns Promise<string | null> - Appropriate JWT token or null
108
- */
109
- export const getJWTForRoute = async (route: string): Promise<string | null> => {
110
- const tokenType = getTokenTypeForRoute(route);
111
- const token = await getJWT(tokenType);
112
-
113
- if (token) {
114
- console.log(`🎯 [JWT Storage] Using ${tokenType} token for route: ${route}`);
115
- } else {
116
- console.warn(`⚠️ [JWT Storage] No ${tokenType} token available for route: ${route}`);
117
- }
118
-
119
- return token;
120
- };
121
-
122
- /**
123
- * Clear JWT token of specific type
124
- * @param tokenType - Type of token to clear
125
- * @returns Promise<boolean> - Success status
126
- */
127
- export const clearJWT = async (tokenType: TokenType): Promise<boolean> => {
128
- try {
129
- await AsyncStorage.removeItem(tokenType);
130
- console.log(`✅ [JWT Storage] ${tokenType} token cleared successfully`);
131
- return true;
132
- } catch (error) {
133
- console.error(`❌ [JWT Storage] Failed to clear ${tokenType} token:`, error);
134
- return false;
135
- }
136
- };
137
-
138
- /**
139
- * Clear all JWT tokens
140
- * @returns Promise<boolean> - Success status
141
- */
142
- export const clearAllJWT = async (): Promise<boolean> => {
143
- try {
144
- await Promise.all([
145
- clearJWT(TokenType.ENOCH),
146
- clearJWT(TokenType.ONAIROS),
147
- clearJWT(TokenType.AUTH)
148
- ]);
149
- console.log('✅ [JWT Storage] All JWT tokens cleared successfully');
150
- return true;
151
- } catch (error) {
152
- console.error('❌ [JWT Storage] Failed to clear all JWT tokens:', error);
153
- return false;
154
- }
155
- };
156
-
157
- /**
158
- * Replace JWT token after verification - route-aware
159
- * @param tokenType - Type of token being replaced
160
- * @param newToken - New JWT token from verification response
161
- * @returns Promise<boolean> - Success status
162
- */
163
- export const replaceJWTAfterVerification = async (tokenType: TokenType, newToken: string): Promise<boolean> => {
164
- try {
165
- console.log(`🔄 [JWT Storage] Replacing ${tokenType} token after verification`);
166
-
167
- if (!newToken || !isValidJWTFormat(newToken)) {
168
- console.error(`❌ [JWT Storage] Invalid ${tokenType} token provided for replacement`);
169
- return false;
170
- }
171
-
172
- // Clear old token first, then store new one
173
- await clearJWT(tokenType);
174
- const stored = await storeJWT(tokenType, newToken);
175
-
176
- if (stored) {
177
- console.log(`✅ [JWT Storage] ${tokenType} token successfully replaced after verification`);
178
- }
179
-
180
- return stored;
181
- } catch (error) {
182
- console.error(`❌ [JWT Storage] Failed to replace ${tokenType} token after verification:`, error);
183
- return false;
184
- }
185
- };
186
-
187
- /**
188
- * Store Enoch JWT token (from email verification)
189
- * @param token - Enoch JWT token
190
- * @returns Promise<boolean> - Success status
191
- */
192
- export const storeEnochJWT = async (token: string): Promise<boolean> => {
193
- return await storeJWT(TokenType.ENOCH, token);
194
- };
195
-
196
- /**
197
- * Store Onairos JWT token (from sign-in/registration)
198
- * @param token - Onairos JWT token
199
- * @returns Promise<boolean> - Success status
200
- */
201
- export const storeOnairosJWT = async (token: string): Promise<boolean> => {
202
- return await storeJWT(TokenType.ONAIROS, token);
203
- };
204
-
205
- /**
206
- * Store Auth token (for context-specific flows)
207
- * @param token - Auth token
208
- * @returns Promise<boolean> - Success status
209
- */
210
- export const storeAuthToken = async (token: string): Promise<boolean> => {
211
- return await storeJWT(TokenType.AUTH, token);
212
- };
213
-
214
- /**
215
- * Validate JWT format
216
- * @param token - Token to validate
217
- * @returns boolean - True if valid JWT format
218
- */
219
- const isValidJWTFormat = (token: string): boolean => {
220
- if (!token || token.length < 20) return false;
221
-
222
- // Check if it's an email address (invalid JWT)
223
- if (token.includes('@') && token.includes('.') && !token.includes('Bearer') && token.length < 100) {
224
- return false;
225
- }
226
-
227
- // Check if it has JWT structure (3 parts separated by dots)
228
- const tokenParts = token.split('.');
229
- if (tokenParts.length !== 3) return false;
230
-
231
- // Additional validation - JWT should be longer than 50 characters typically
232
- if (token.length < 50) return false;
233
-
234
- return true;
235
- };
236
-
237
- /**
238
- * Check if JWT token of specific type exists and is valid
239
- * @param tokenType - Type of token to check
240
- * @returns Promise<boolean> - True if valid token exists
241
- */
242
- export const hasValidJWT = async (tokenType: TokenType): Promise<boolean> => {
243
- const token = await getJWT(tokenType);
244
- return token !== null;
245
- };
246
-
247
- /**
248
- * Get all available tokens (for debugging)
249
- * @returns Promise<Record<TokenType, string | null>> - All tokens
250
- */
251
- export const getAllTokens = async (): Promise<Record<TokenType, string | null>> => {
252
- return {
253
- [TokenType.ENOCH]: await getJWT(TokenType.ENOCH),
254
- [TokenType.ONAIROS]: await getJWT(TokenType.ONAIROS),
255
- [TokenType.AUTH]: await getJWT(TokenType.AUTH)
256
- };
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+ import { Buffer } from 'buffer';
3
+
4
+ /**
5
+ * JWT Token Storage Service - CORRECTED APPROACH
6
+ * Manages 3 DISTINCT JWT token types for different route families
7
+ *
8
+ * TOKEN TYPES:
9
+ * 1. Enoch JWT (enoch_token) - For /enoch/*, /api/auth/*, /mobile-training/enoch
10
+ * 2. Onairos JWT (onairos_jwt_token) - For /youtube/*, /gmail/*, social connections
11
+ * 3. Auth Token (auth_token) - For context-specific auth flows
12
+ */
13
+
14
+ export enum TokenType {
15
+ ENOCH = 'enoch_token',
16
+ ONAIROS = 'onairos_jwt_token',
17
+ AUTH = 'auth_token'
18
+ }
19
+
20
+ /**
21
+ * Route-based token mapping
22
+ * Determines which token type to use for which routes
23
+ */
24
+ export const getTokenTypeForRoute = (route: string): TokenType => {
25
+ const cleanRoute = route.toLowerCase();
26
+
27
+ // Enoch routes - use Enoch JWT
28
+ if (cleanRoute.includes('/enoch/') ||
29
+ cleanRoute.includes('/api/auth/') ||
30
+ cleanRoute.includes('/mobile-training/enoch')) {
31
+ return TokenType.ENOCH;
32
+ }
33
+
34
+ // Onairos routes - use Onairos JWT
35
+ if (cleanRoute.includes('/youtube/') ||
36
+ cleanRoute.includes('/gmail/') ||
37
+ cleanRoute.includes('/connectedaccounts') ||
38
+ cleanRoute.includes('/social/')) {
39
+ return TokenType.ONAIROS;
40
+ }
41
+
42
+ // Default to auth token for other routes
43
+ return TokenType.AUTH;
44
+ };
45
+
46
+ /**
47
+ * Store JWT token of specific type
48
+ * @param tokenType - Type of token to store
49
+ * @param token - JWT token to store
50
+ * @returns Promise<boolean> - Success status
51
+ */
52
+ export const storeJWT = async (tokenType: TokenType, token: string): Promise<boolean> => {
53
+ try {
54
+ if (!token || token.trim() === '') {
55
+ console.warn(`⚠️ [JWT Storage] Attempted to store empty/null ${tokenType} token`);
56
+ return false;
57
+ }
58
+
59
+ // Validate JWT format (should have 3 parts separated by dots)
60
+ const parts = token.split('.');
61
+ if (parts.length !== 3) {
62
+ console.warn(`⚠️ [JWT Storage] Invalid JWT format for ${tokenType} - token should have 3 parts`);
63
+ return false;
64
+ }
65
+
66
+ await AsyncStorage.setItem(tokenType, token);
67
+ console.log(`✅ [JWT Storage] ${tokenType} token stored successfully`);
68
+ return true;
69
+ } catch (error) {
70
+ console.error(`❌ [JWT Storage] Failed to store ${tokenType} token:`, error);
71
+ return false;
72
+ }
73
+ };
74
+
75
+ /**
76
+ * Retrieve JWT token of specific type
77
+ * @param tokenType - Type of token to retrieve
78
+ * @returns Promise<string | null> - JWT token or null if not found
79
+ */
80
+ export const getJWT = async (tokenType: TokenType): Promise<string | null> => {
81
+ try {
82
+ const token = await AsyncStorage.getItem(tokenType);
83
+
84
+ if (!token) {
85
+ console.log(`📭 [JWT Storage] No ${tokenType} token found in storage`);
86
+ return null;
87
+ }
88
+
89
+ // Validate JWT format
90
+ if (!isValidJWTFormat(token)) {
91
+ console.warn(`⚠️ [JWT Storage] Invalid JWT format found for ${tokenType}, removing`);
92
+ await clearJWT(tokenType);
93
+ return null;
94
+ }
95
+
96
+ console.log(`🔐 [JWT Storage] ${tokenType} token retrieved successfully`);
97
+ return token;
98
+ } catch (error) {
99
+ console.error(`❌ [JWT Storage] Failed to retrieve ${tokenType} token:`, error);
100
+ return null;
101
+ }
102
+ };
103
+
104
+ /**
105
+ * Get JWT token for specific route
106
+ * @param route - API route to get token for
107
+ * @returns Promise<string | null> - Appropriate JWT token or null
108
+ */
109
+ export const getJWTForRoute = async (route: string): Promise<string | null> => {
110
+ const tokenType = getTokenTypeForRoute(route);
111
+ const token = await getJWT(tokenType);
112
+
113
+ if (token) {
114
+ console.log(`🎯 [JWT Storage] Using ${tokenType} token for route: ${route}`);
115
+ } else {
116
+ console.warn(`⚠️ [JWT Storage] No ${tokenType} token available for route: ${route}`);
117
+ }
118
+
119
+ return token;
120
+ };
121
+
122
+ /**
123
+ * Clear JWT token of specific type
124
+ * @param tokenType - Type of token to clear
125
+ * @returns Promise<boolean> - Success status
126
+ */
127
+ export const clearJWT = async (tokenType: TokenType): Promise<boolean> => {
128
+ try {
129
+ await AsyncStorage.removeItem(tokenType);
130
+ console.log(`✅ [JWT Storage] ${tokenType} token cleared successfully`);
131
+ return true;
132
+ } catch (error) {
133
+ console.error(`❌ [JWT Storage] Failed to clear ${tokenType} token:`, error);
134
+ return false;
135
+ }
136
+ };
137
+
138
+ /**
139
+ * Clear all JWT tokens
140
+ * @returns Promise<boolean> - Success status
141
+ */
142
+ export const clearAllJWT = async (): Promise<boolean> => {
143
+ try {
144
+ await Promise.all([
145
+ clearJWT(TokenType.ENOCH),
146
+ clearJWT(TokenType.ONAIROS),
147
+ clearJWT(TokenType.AUTH)
148
+ ]);
149
+ console.log('✅ [JWT Storage] All JWT tokens cleared successfully');
150
+ return true;
151
+ } catch (error) {
152
+ console.error('❌ [JWT Storage] Failed to clear all JWT tokens:', error);
153
+ return false;
154
+ }
155
+ };
156
+
157
+ /**
158
+ * Replace JWT token after verification - route-aware
159
+ * @param tokenType - Type of token being replaced
160
+ * @param newToken - New JWT token from verification response
161
+ * @returns Promise<boolean> - Success status
162
+ */
163
+ export const replaceJWTAfterVerification = async (tokenType: TokenType, newToken: string): Promise<boolean> => {
164
+ try {
165
+ console.log(`🔄 [JWT Storage] Replacing ${tokenType} token after verification`);
166
+
167
+ if (!newToken || !isValidJWTFormat(newToken)) {
168
+ console.error(`❌ [JWT Storage] Invalid ${tokenType} token provided for replacement`);
169
+ return false;
170
+ }
171
+
172
+ // Clear old token first, then store new one
173
+ await clearJWT(tokenType);
174
+ const stored = await storeJWT(tokenType, newToken);
175
+
176
+ if (stored) {
177
+ console.log(`✅ [JWT Storage] ${tokenType} token successfully replaced after verification`);
178
+ }
179
+
180
+ return stored;
181
+ } catch (error) {
182
+ console.error(`❌ [JWT Storage] Failed to replace ${tokenType} token after verification:`, error);
183
+ return false;
184
+ }
185
+ };
186
+
187
+ /**
188
+ * Store Enoch JWT token (from email verification)
189
+ * @param token - Enoch JWT token
190
+ * @returns Promise<boolean> - Success status
191
+ */
192
+ export const storeEnochJWT = async (token: string): Promise<boolean> => {
193
+ return await storeJWT(TokenType.ENOCH, token);
194
+ };
195
+
196
+ /**
197
+ * Store Onairos JWT token (from sign-in/registration)
198
+ * @param token - Onairos JWT token
199
+ * @returns Promise<boolean> - Success status
200
+ */
201
+ export const storeOnairosJWT = async (token: string): Promise<boolean> => {
202
+ return await storeJWT(TokenType.ONAIROS, token);
203
+ };
204
+
205
+ /**
206
+ * Store Auth token (for context-specific flows)
207
+ * @param token - Auth token
208
+ * @returns Promise<boolean> - Success status
209
+ */
210
+ export const storeAuthToken = async (token: string): Promise<boolean> => {
211
+ return await storeJWT(TokenType.AUTH, token);
212
+ };
213
+
214
+ /**
215
+ * Validate JWT format
216
+ * @param token - Token to validate
217
+ * @returns boolean - True if valid JWT format
218
+ */
219
+ const isValidJWTFormat = (token: string): boolean => {
220
+ if (!token || token.length < 20) return false;
221
+
222
+ // Check if it's an email address (invalid JWT)
223
+ if (token.includes('@') && token.includes('.') && !token.includes('Bearer') && token.length < 100) {
224
+ return false;
225
+ }
226
+
227
+ // Check if it has JWT structure (3 parts separated by dots)
228
+ const tokenParts = token.split('.');
229
+ if (tokenParts.length !== 3) return false;
230
+
231
+ // Additional validation - JWT should be longer than 50 characters typically
232
+ if (token.length < 50) return false;
233
+
234
+ return true;
235
+ };
236
+
237
+ /**
238
+ * Check if JWT token of specific type exists and is valid
239
+ * @param tokenType - Type of token to check
240
+ * @returns Promise<boolean> - True if valid token exists
241
+ */
242
+ export const hasValidJWT = async (tokenType: TokenType): Promise<boolean> => {
243
+ const token = await getJWT(tokenType);
244
+ return token !== null;
245
+ };
246
+
247
+ /**
248
+ * Get all available tokens (for debugging)
249
+ * @returns Promise<Record<TokenType, string | null>> - All tokens
250
+ */
251
+ export const getAllTokens = async (): Promise<Record<TokenType, string | null>> => {
252
+ return {
253
+ [TokenType.ENOCH]: await getJWT(TokenType.ENOCH),
254
+ [TokenType.ONAIROS]: await getJWT(TokenType.ONAIROS),
255
+ [TokenType.AUTH]: await getJWT(TokenType.AUTH)
256
+ };
257
257
  };