@onairos/react-native 3.1.16 → 3.1.18

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 (207) 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/ModalSheet.js +8 -2
  16. package/lib/commonjs/components/ModalSheet.js.map +1 -1
  17. package/lib/commonjs/components/OnairosButton.js +290 -0
  18. package/lib/commonjs/components/OnairosButton.js.map +1 -0
  19. package/lib/commonjs/components/OnairosSignInButton.js +32 -8
  20. package/lib/commonjs/components/OnairosSignInButton.js.map +1 -1
  21. package/lib/commonjs/components/UniversalOnboarding.js +4 -4
  22. package/lib/commonjs/components/WelcomeScreen.js +29 -13
  23. package/lib/commonjs/components/WelcomeScreen.js.map +1 -1
  24. package/lib/commonjs/config/api.js +2 -2
  25. package/lib/commonjs/hooks/useConnections.js +6 -6
  26. package/lib/commonjs/hooks/useUserConnections.js +10 -10
  27. package/lib/commonjs/index.js +13 -6
  28. package/lib/commonjs/index.js.map +1 -1
  29. package/lib/commonjs/services/apiClient.js +35 -35
  30. package/lib/commonjs/services/apiKeyService.js +99 -99
  31. package/lib/commonjs/services/authService.js +82 -82
  32. package/lib/commonjs/services/biometricPinService.js +10 -10
  33. package/lib/commonjs/services/connectedAccountsService.js +32 -32
  34. package/lib/commonjs/services/googleAuthService.js +15 -15
  35. package/lib/commonjs/services/imageCompressionService.js +15 -15
  36. package/lib/commonjs/services/jwtStorageService.js +59 -59
  37. package/lib/commonjs/services/mobileTrainingService.js +14 -14
  38. package/lib/commonjs/services/pinEncryptionService.js +10 -10
  39. package/lib/commonjs/services/pinStorageUtils.js +15 -15
  40. package/lib/commonjs/services/platformAuthService.js +47 -47
  41. package/lib/commonjs/services/storageService.js +31 -31
  42. package/lib/commonjs/services/trainingApiHelpers.js +33 -33
  43. package/lib/commonjs/services/userConnectionsService.js +24 -24
  44. package/lib/commonjs/utils/Portal.js +4 -4
  45. package/lib/commonjs/utils/api.js +24 -24
  46. package/lib/commonjs/utils/auth.js +18 -18
  47. package/lib/commonjs/utils/crypto.js +13 -13
  48. package/lib/commonjs/utils/encryption.js +12 -12
  49. package/lib/commonjs/utils/eventUtils.js +52 -52
  50. package/lib/commonjs/utils/programmaticFlow.js +16 -16
  51. package/lib/commonjs/utils/retryHelper.js +27 -27
  52. package/lib/module/assets/images/Checkbox.svg +3 -3
  53. package/lib/module/assets/images/EnochE.svg +19 -19
  54. package/lib/module/assets/images/Personalityprofile.svg +3 -3
  55. package/lib/module/assets/images/Personalitytraits.svg +3 -3
  56. package/lib/module/assets/images/Userpreferences.svg +3 -3
  57. package/lib/module/assets/images/arrow.svg +20 -20
  58. package/lib/module/assets/images/basicproficon.svg +43 -43
  59. package/lib/module/assets/images/basicprofile.svg +3 -3
  60. package/lib/module/assets/images/checkmark.svg +4 -4
  61. package/lib/module/assets/images/contentanalysis.svg +3 -3
  62. package/lib/module/assets/images/contenticon.svg +23 -23
  63. package/lib/module/assets/images/personalityicon.svg +18 -18
  64. package/lib/module/assets/images/x-close.svg +3 -3
  65. package/lib/module/components/ModalSheet.js +7 -2
  66. package/lib/module/components/ModalSheet.js.map +1 -1
  67. package/lib/module/components/OnairosButton.js +282 -0
  68. package/lib/module/components/OnairosButton.js.map +1 -0
  69. package/lib/module/components/OnairosSignInButton.js +32 -8
  70. package/lib/module/components/OnairosSignInButton.js.map +1 -1
  71. package/lib/module/components/UniversalOnboarding.js +4 -4
  72. package/lib/module/components/WelcomeScreen.js +25 -10
  73. package/lib/module/components/WelcomeScreen.js.map +1 -1
  74. package/lib/module/config/api.js +2 -2
  75. package/lib/module/hooks/useConnections.js +6 -6
  76. package/lib/module/hooks/useUserConnections.js +10 -10
  77. package/lib/module/index.js +11 -11
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/services/apiClient.js +35 -35
  80. package/lib/module/services/apiKeyService.js +99 -99
  81. package/lib/module/services/authService.js +82 -82
  82. package/lib/module/services/biometricPinService.js +10 -10
  83. package/lib/module/services/connectedAccountsService.js +32 -32
  84. package/lib/module/services/googleAuthService.js +15 -15
  85. package/lib/module/services/imageCompressionService.js +15 -15
  86. package/lib/module/services/jwtStorageService.js +59 -59
  87. package/lib/module/services/mobileTrainingService.js +14 -14
  88. package/lib/module/services/pinEncryptionService.js +10 -10
  89. package/lib/module/services/pinStorageUtils.js +15 -15
  90. package/lib/module/services/platformAuthService.js +47 -47
  91. package/lib/module/services/storageService.js +31 -31
  92. package/lib/module/services/trainingApiHelpers.js +33 -33
  93. package/lib/module/services/userConnectionsService.js +24 -24
  94. package/lib/module/utils/Portal.js +4 -4
  95. package/lib/module/utils/api.js +24 -24
  96. package/lib/module/utils/auth.js +18 -18
  97. package/lib/module/utils/crypto.js +13 -13
  98. package/lib/module/utils/encryption.js +12 -12
  99. package/lib/module/utils/eventUtils.js +52 -52
  100. package/lib/module/utils/programmaticFlow.js +16 -16
  101. package/lib/module/utils/retryHelper.js +27 -27
  102. package/lib/typescript/components/ModalSheet.d.ts.map +1 -1
  103. package/lib/typescript/components/OnairosButton.d.ts +37 -0
  104. package/lib/typescript/components/OnairosButton.d.ts.map +1 -0
  105. package/lib/typescript/components/OnairosSignInButton.d.ts.map +1 -1
  106. package/lib/typescript/components/WelcomeScreen.d.ts.map +1 -1
  107. package/lib/typescript/index.d.ts +3 -1
  108. package/lib/typescript/index.d.ts.map +1 -1
  109. package/package.json +145 -163
  110. package/src/api/index.ts +151 -151
  111. package/src/assets/images/Checkbox.svg +3 -3
  112. package/src/assets/images/EnochE.svg +19 -19
  113. package/src/assets/images/Personalityprofile.svg +3 -3
  114. package/src/assets/images/Personalitytraits.svg +3 -3
  115. package/src/assets/images/Userpreferences.svg +3 -3
  116. package/src/assets/images/arrow.svg +20 -20
  117. package/src/assets/images/basicproficon.svg +43 -43
  118. package/src/assets/images/basicprofile.svg +3 -3
  119. package/src/assets/images/checkmark.svg +4 -4
  120. package/src/assets/images/contentanalysis.svg +3 -3
  121. package/src/assets/images/contenticon.svg +23 -23
  122. package/src/assets/images/personalityicon.svg +18 -18
  123. package/src/assets/images/x-close.svg +3 -3
  124. package/src/components/BodyText.tsx +33 -33
  125. package/src/components/BrandMark.tsx +62 -62
  126. package/src/components/CodeInput.tsx +32 -32
  127. package/src/components/DataRequestScreen.tsx +355 -355
  128. package/src/components/EmailInput.tsx +31 -31
  129. package/src/components/EmailVerificationModal.tsx +363 -363
  130. package/src/components/ExistingUserDataConfirmation.tsx +506 -506
  131. package/src/components/GoogleButton.tsx +55 -55
  132. package/src/components/HeadingGroup.tsx +49 -49
  133. package/src/components/ModalHeader.tsx +125 -125
  134. package/src/components/ModalSheet.tsx +59 -57
  135. package/src/components/Onairos.tsx +422 -422
  136. package/src/components/OnairosButton.tsx +339 -0
  137. package/src/components/OnairosSignInButton.tsx +31 -9
  138. package/src/components/Overlay.tsx +506 -506
  139. package/src/components/PersonaImage.tsx +79 -79
  140. package/src/components/PersonaLoadingScreen.tsx +201 -201
  141. package/src/components/PersonalizationConsentScreen.tsx +410 -410
  142. package/src/components/PinCreationScreen.tsx +492 -492
  143. package/src/components/PinInput.tsx +555 -555
  144. package/src/components/PlatformConnectorsStep.tsx +891 -891
  145. package/src/components/PlatformList.tsx +144 -144
  146. package/src/components/PlatformToggle.tsx +226 -226
  147. package/src/components/PrimaryButton.tsx +213 -213
  148. package/src/components/SignInMatchAnimation.tsx +225 -225
  149. package/src/components/SignInStep.tsx +217 -217
  150. package/src/components/TrainingModal.tsx +1047 -1047
  151. package/src/components/UniversalOnboarding.tsx +2887 -2887
  152. package/src/components/VerificationStep.tsx +198 -198
  153. package/src/components/WelcomeScreen.tsx +490 -473
  154. package/src/components/icons/Basicproficon.tsx +30 -30
  155. package/src/components/icons/Basicprofile.tsx +17 -17
  156. package/src/components/icons/Checkbox.tsx +17 -17
  157. package/src/components/icons/Checkmark.tsx +24 -24
  158. package/src/components/icons/Contentanalysis.tsx +17 -17
  159. package/src/components/icons/Contenticon.tsx +30 -30
  160. package/src/components/icons/EnochE.tsx +39 -39
  161. package/src/components/icons/Personalityicon.tsx +22 -22
  162. package/src/components/icons/Personalityprofile.tsx +17 -17
  163. package/src/components/icons/Personalitytraits.tsx +17 -17
  164. package/src/components/icons/Userpreferences.tsx +17 -17
  165. package/src/components/icons/index.ts +12 -12
  166. package/src/components/onboarding/OAuthWebView.tsx +232 -232
  167. package/src/config/api.ts +25 -25
  168. package/src/context/AuthContext.tsx +393 -393
  169. package/src/hooks/useConnectedAccounts.ts +138 -138
  170. package/src/hooks/useConnections.ts +161 -161
  171. package/src/hooks/useCredentials.ts +174 -174
  172. package/src/hooks/useUserConnections.ts +165 -165
  173. package/src/index.js +14 -0
  174. package/src/index.ts +99 -96
  175. package/src/services/apiClient.ts +336 -336
  176. package/src/services/apiKeyService.ts +919 -919
  177. package/src/services/authService.ts +1008 -1008
  178. package/src/services/biometricPinService.ts +192 -192
  179. package/src/services/connectedAccountsService.ts +289 -289
  180. package/src/services/googleAuthService.ts +279 -279
  181. package/src/services/imageCompressionService.ts +302 -302
  182. package/src/services/jwtStorageService.ts +256 -256
  183. package/src/services/mobileTrainingService.ts +203 -203
  184. package/src/services/pinEncryptionService.ts +75 -75
  185. package/src/services/pinStorageUtils.ts +96 -96
  186. package/src/services/platformAuthService.ts +1346 -1346
  187. package/src/services/storageService.ts +451 -451
  188. package/src/services/trainingApiHelpers.ts +66 -66
  189. package/src/services/userConnectionsService.ts +556 -556
  190. package/src/services/youtubeMigrationService.ts +453 -453
  191. package/src/theme/index.ts +239 -239
  192. package/src/types/ambient.d.ts +28 -28
  193. package/src/types/index.ts +265 -265
  194. package/src/types/node-fix.d.ts +18 -18
  195. package/src/types/node-override.d.ts +23 -23
  196. package/src/types/opacity.d.ts +15 -15
  197. package/src/types/types.d.ts +17 -17
  198. package/src/utils/Portal.tsx +82 -82
  199. package/src/utils/api.js +111 -111
  200. package/src/utils/auth.js +103 -103
  201. package/src/utils/crypto.js +59 -59
  202. package/src/utils/encryption.ts +68 -68
  203. package/src/utils/eventUtils.ts +302 -302
  204. package/src/utils/haptics.ts +58 -58
  205. package/src/utils/imagePreloader.ts +2 -2
  206. package/src/utils/programmaticFlow.ts +112 -112
  207. 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
  };