@onairos/react-native 3.1.16 → 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 (198) 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/OnairosButton.js +290 -0
  16. package/lib/commonjs/components/OnairosButton.js.map +1 -0
  17. package/lib/commonjs/components/OnairosSignInButton.js +30 -8
  18. package/lib/commonjs/components/OnairosSignInButton.js.map +1 -1
  19. package/lib/commonjs/components/UniversalOnboarding.js +4 -4
  20. package/lib/commonjs/config/api.js +2 -2
  21. package/lib/commonjs/hooks/useConnections.js +6 -6
  22. package/lib/commonjs/hooks/useUserConnections.js +10 -10
  23. package/lib/commonjs/index.js +9 -10
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/services/apiClient.js +35 -35
  26. package/lib/commonjs/services/apiKeyService.js +99 -99
  27. package/lib/commonjs/services/authService.js +82 -82
  28. package/lib/commonjs/services/biometricPinService.js +10 -10
  29. package/lib/commonjs/services/connectedAccountsService.js +32 -32
  30. package/lib/commonjs/services/googleAuthService.js +15 -15
  31. package/lib/commonjs/services/imageCompressionService.js +15 -15
  32. package/lib/commonjs/services/jwtStorageService.js +59 -59
  33. package/lib/commonjs/services/mobileTrainingService.js +14 -14
  34. package/lib/commonjs/services/pinEncryptionService.js +10 -10
  35. package/lib/commonjs/services/pinStorageUtils.js +15 -15
  36. package/lib/commonjs/services/platformAuthService.js +47 -47
  37. package/lib/commonjs/services/storageService.js +31 -31
  38. package/lib/commonjs/services/trainingApiHelpers.js +33 -33
  39. package/lib/commonjs/services/userConnectionsService.js +24 -24
  40. package/lib/commonjs/utils/Portal.js +4 -4
  41. package/lib/commonjs/utils/api.js +24 -24
  42. package/lib/commonjs/utils/auth.js +18 -18
  43. package/lib/commonjs/utils/crypto.js +13 -13
  44. package/lib/commonjs/utils/encryption.js +12 -12
  45. package/lib/commonjs/utils/eventUtils.js +52 -52
  46. package/lib/commonjs/utils/programmaticFlow.js +16 -16
  47. package/lib/commonjs/utils/retryHelper.js +27 -27
  48. package/lib/module/assets/images/Checkbox.svg +3 -3
  49. package/lib/module/assets/images/EnochE.svg +19 -19
  50. package/lib/module/assets/images/Personalityprofile.svg +3 -3
  51. package/lib/module/assets/images/Personalitytraits.svg +3 -3
  52. package/lib/module/assets/images/Userpreferences.svg +3 -3
  53. package/lib/module/assets/images/arrow.svg +20 -20
  54. package/lib/module/assets/images/basicproficon.svg +43 -43
  55. package/lib/module/assets/images/basicprofile.svg +3 -3
  56. package/lib/module/assets/images/checkmark.svg +4 -4
  57. package/lib/module/assets/images/contentanalysis.svg +3 -3
  58. package/lib/module/assets/images/contenticon.svg +23 -23
  59. package/lib/module/assets/images/personalityicon.svg +18 -18
  60. package/lib/module/assets/images/x-close.svg +3 -3
  61. package/lib/module/components/OnairosButton.js +282 -0
  62. package/lib/module/components/OnairosButton.js.map +1 -0
  63. package/lib/module/components/OnairosSignInButton.js +30 -8
  64. package/lib/module/components/OnairosSignInButton.js.map +1 -1
  65. package/lib/module/components/UniversalOnboarding.js +4 -4
  66. package/lib/module/config/api.js +2 -2
  67. package/lib/module/hooks/useConnections.js +6 -6
  68. package/lib/module/hooks/useUserConnections.js +10 -10
  69. package/lib/module/index.js +8 -10
  70. package/lib/module/index.js.map +1 -1
  71. package/lib/module/services/apiClient.js +35 -35
  72. package/lib/module/services/apiKeyService.js +99 -99
  73. package/lib/module/services/authService.js +82 -82
  74. package/lib/module/services/biometricPinService.js +10 -10
  75. package/lib/module/services/connectedAccountsService.js +32 -32
  76. package/lib/module/services/googleAuthService.js +15 -15
  77. package/lib/module/services/imageCompressionService.js +15 -15
  78. package/lib/module/services/jwtStorageService.js +59 -59
  79. package/lib/module/services/mobileTrainingService.js +14 -14
  80. package/lib/module/services/pinEncryptionService.js +10 -10
  81. package/lib/module/services/pinStorageUtils.js +15 -15
  82. package/lib/module/services/platformAuthService.js +47 -47
  83. package/lib/module/services/storageService.js +31 -31
  84. package/lib/module/services/trainingApiHelpers.js +33 -33
  85. package/lib/module/services/userConnectionsService.js +24 -24
  86. package/lib/module/utils/Portal.js +4 -4
  87. package/lib/module/utils/api.js +24 -24
  88. package/lib/module/utils/auth.js +18 -18
  89. package/lib/module/utils/crypto.js +13 -13
  90. package/lib/module/utils/encryption.js +12 -12
  91. package/lib/module/utils/eventUtils.js +52 -52
  92. package/lib/module/utils/programmaticFlow.js +16 -16
  93. package/lib/module/utils/retryHelper.js +27 -27
  94. package/lib/typescript/components/OnairosButton.d.ts +37 -0
  95. package/lib/typescript/components/OnairosButton.d.ts.map +1 -0
  96. package/lib/typescript/components/OnairosSignInButton.d.ts +2 -1
  97. package/lib/typescript/components/OnairosSignInButton.d.ts.map +1 -1
  98. package/lib/typescript/index.d.ts +3 -4
  99. package/lib/typescript/index.d.ts.map +1 -1
  100. package/package.json +163 -163
  101. package/src/api/index.ts +151 -151
  102. package/src/assets/images/Checkbox.svg +3 -3
  103. package/src/assets/images/EnochE.svg +19 -19
  104. package/src/assets/images/Personalityprofile.svg +3 -3
  105. package/src/assets/images/Personalitytraits.svg +3 -3
  106. package/src/assets/images/Userpreferences.svg +3 -3
  107. package/src/assets/images/arrow.svg +20 -20
  108. package/src/assets/images/basicproficon.svg +43 -43
  109. package/src/assets/images/basicprofile.svg +3 -3
  110. package/src/assets/images/checkmark.svg +4 -4
  111. package/src/assets/images/contentanalysis.svg +3 -3
  112. package/src/assets/images/contenticon.svg +23 -23
  113. package/src/assets/images/personalityicon.svg +18 -18
  114. package/src/assets/images/x-close.svg +3 -3
  115. package/src/components/BodyText.tsx +33 -33
  116. package/src/components/BrandMark.tsx +62 -62
  117. package/src/components/CodeInput.tsx +32 -32
  118. package/src/components/DataRequestScreen.tsx +355 -355
  119. package/src/components/EmailInput.tsx +31 -31
  120. package/src/components/EmailVerificationModal.tsx +363 -363
  121. package/src/components/ExistingUserDataConfirmation.tsx +506 -506
  122. package/src/components/GoogleButton.tsx +55 -55
  123. package/src/components/HeadingGroup.tsx +49 -49
  124. package/src/components/ModalHeader.tsx +125 -125
  125. package/src/components/ModalSheet.tsx +57 -57
  126. package/src/components/Onairos.tsx +422 -422
  127. package/src/components/OnairosButton.tsx +339 -0
  128. package/src/components/OnairosSignInButton.tsx +30 -10
  129. package/src/components/Overlay.tsx +506 -506
  130. package/src/components/PersonaImage.tsx +79 -79
  131. package/src/components/PersonaLoadingScreen.tsx +201 -201
  132. package/src/components/PersonalizationConsentScreen.tsx +410 -410
  133. package/src/components/PinCreationScreen.tsx +492 -492
  134. package/src/components/PinInput.tsx +555 -555
  135. package/src/components/PlatformConnectorsStep.tsx +891 -891
  136. package/src/components/PlatformList.tsx +144 -144
  137. package/src/components/PlatformToggle.tsx +226 -226
  138. package/src/components/PrimaryButton.tsx +213 -213
  139. package/src/components/SignInMatchAnimation.tsx +225 -225
  140. package/src/components/SignInStep.tsx +217 -217
  141. package/src/components/TrainingModal.tsx +1047 -1047
  142. package/src/components/UniversalOnboarding.tsx +2887 -2887
  143. package/src/components/VerificationStep.tsx +198 -198
  144. package/src/components/WelcomeScreen.tsx +473 -473
  145. package/src/components/icons/Basicproficon.tsx +30 -30
  146. package/src/components/icons/Basicprofile.tsx +17 -17
  147. package/src/components/icons/Checkbox.tsx +17 -17
  148. package/src/components/icons/Checkmark.tsx +24 -24
  149. package/src/components/icons/Contentanalysis.tsx +17 -17
  150. package/src/components/icons/Contenticon.tsx +30 -30
  151. package/src/components/icons/EnochE.tsx +39 -39
  152. package/src/components/icons/Personalityicon.tsx +22 -22
  153. package/src/components/icons/Personalityprofile.tsx +17 -17
  154. package/src/components/icons/Personalitytraits.tsx +17 -17
  155. package/src/components/icons/Userpreferences.tsx +17 -17
  156. package/src/components/icons/index.ts +12 -12
  157. package/src/components/onboarding/OAuthWebView.tsx +232 -232
  158. package/src/config/api.ts +25 -25
  159. package/src/context/AuthContext.tsx +393 -393
  160. package/src/hooks/useConnectedAccounts.ts +138 -138
  161. package/src/hooks/useConnections.ts +161 -161
  162. package/src/hooks/useCredentials.ts +174 -174
  163. package/src/hooks/useUserConnections.ts +165 -165
  164. package/src/index.js +14 -0
  165. package/src/index.ts +94 -96
  166. package/src/services/apiClient.ts +336 -336
  167. package/src/services/apiKeyService.ts +919 -919
  168. package/src/services/authService.ts +1008 -1008
  169. package/src/services/biometricPinService.ts +192 -192
  170. package/src/services/connectedAccountsService.ts +289 -289
  171. package/src/services/googleAuthService.ts +279 -279
  172. package/src/services/imageCompressionService.ts +302 -302
  173. package/src/services/jwtStorageService.ts +256 -256
  174. package/src/services/mobileTrainingService.ts +203 -203
  175. package/src/services/pinEncryptionService.ts +75 -75
  176. package/src/services/pinStorageUtils.ts +96 -96
  177. package/src/services/platformAuthService.ts +1346 -1346
  178. package/src/services/storageService.ts +451 -451
  179. package/src/services/trainingApiHelpers.ts +66 -66
  180. package/src/services/userConnectionsService.ts +556 -556
  181. package/src/services/youtubeMigrationService.ts +453 -453
  182. package/src/theme/index.ts +239 -239
  183. package/src/types/ambient.d.ts +28 -28
  184. package/src/types/index.ts +265 -265
  185. package/src/types/node-fix.d.ts +18 -18
  186. package/src/types/node-override.d.ts +23 -23
  187. package/src/types/opacity.d.ts +15 -15
  188. package/src/types/types.d.ts +17 -17
  189. package/src/utils/Portal.tsx +82 -82
  190. package/src/utils/api.js +111 -111
  191. package/src/utils/auth.js +103 -103
  192. package/src/utils/crypto.js +59 -59
  193. package/src/utils/encryption.ts +68 -68
  194. package/src/utils/eventUtils.ts +302 -302
  195. package/src/utils/haptics.ts +58 -58
  196. package/src/utils/imagePreloader.ts +2 -2
  197. package/src/utils/programmaticFlow.ts +112 -112
  198. package/src/utils/retryHelper.ts +274 -274
@@ -1,279 +1,279 @@
1
- /**
2
- * Google Authentication Service
3
- * Handles Google Sign-In for user authentication and account creation
4
- */
5
-
6
- import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
7
- import AsyncStorage from '@react-native-async-storage/async-storage';
8
-
9
- // 🔑 Using the same client ID configuration as platform auth
10
- let WEB_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
11
- let IOS_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
12
-
13
- /**
14
- * Update Google OAuth client IDs for custom configurations
15
- */
16
- export const updateGoogleClientIds = (config: {
17
- webClientId?: string;
18
- iosClientId?: string;
19
- }) => {
20
- if (config.webClientId) {
21
- WEB_CLIENT_ID = config.webClientId;
22
- }
23
- if (config.iosClientId) {
24
- IOS_CLIENT_ID = config.iosClientId;
25
- }
26
-
27
- console.log('✅ Google client IDs updated:', {
28
- webClientId: WEB_CLIENT_ID,
29
- iosClientId: IOS_CLIENT_ID
30
- });
31
- };
32
-
33
- /**
34
- * Initialize Google Sign-In for user authentication
35
- */
36
- const initializeGoogleAuth = () => {
37
- GoogleSignin.configure({
38
- webClientId: WEB_CLIENT_ID,
39
- iosClientId: IOS_CLIENT_ID,
40
-
41
- // Basic scopes for user authentication
42
- scopes: [
43
- 'openid',
44
- 'profile',
45
- 'email'
46
- ],
47
-
48
- // Enable offline access for refresh tokens
49
- offlineAccess: true,
50
- forceCodeForRefreshToken: true,
51
-
52
- // Clear settings to avoid conflicts
53
- hostedDomain: '',
54
- accountName: '',
55
- });
56
- };
57
-
58
- /**
59
- * Sign in with Google and create/authenticate user account
60
- */
61
- export const signInWithGoogle = async () => {
62
- try {
63
- console.log('🔗 Initiating Google Sign-In for user authentication');
64
-
65
- // Initialize Google Sign-In
66
- initializeGoogleAuth();
67
-
68
- // Check if Google Play Services are available
69
- await GoogleSignin.hasPlayServices();
70
-
71
- // Sign out first to ensure fresh consent
72
- try {
73
- await GoogleSignin.signOut();
74
- console.log('🔄 Signed out to ensure fresh consent');
75
- } catch (signOutError) {
76
- console.log('ℹ️ Sign out not needed or failed:', signOutError);
77
- }
78
-
79
- // Sign in with Google
80
- const userInfo = await GoogleSignin.signIn();
81
- console.log('✅ Google Sign-In successful:', userInfo.data?.user?.email);
82
-
83
- const googleUser = userInfo.data?.user;
84
- if (!googleUser || !googleUser.email) {
85
- throw new Error('No user data received from Google');
86
- }
87
-
88
- console.log('👤 Google user data:', {
89
- email: googleUser.email,
90
- name: googleUser.name,
91
- photo: googleUser.photo,
92
- id: googleUser.id
93
- });
94
-
95
- // Get tokens for account creation
96
- const tokens = await GoogleSignin.getTokens();
97
- console.log('🔑 Got Google tokens');
98
-
99
- // Create user account on backend
100
- const accountResult = await createUserAccount({
101
- email: googleUser.email,
102
- name: googleUser.name || googleUser.email.split('@')[0],
103
- photoUrl: googleUser.photo || '',
104
- googleId: googleUser.id,
105
- accessToken: tokens.accessToken,
106
- idToken: tokens.idToken
107
- });
108
-
109
- if (accountResult.success) {
110
- console.log('✅ User account created/authenticated successfully');
111
-
112
- // Store authentication data
113
- await AsyncStorage.setItem('user_email', googleUser.email);
114
- await AsyncStorage.setItem('user_name', googleUser.name || '');
115
- await AsyncStorage.setItem('user_photo', googleUser.photo || '');
116
- await AsyncStorage.setItem('auth_method', 'google');
117
-
118
- if (accountResult.token) {
119
- await AsyncStorage.setItem('onairos_jwt_token', accountResult.token);
120
- await AsyncStorage.setItem('auth_token', accountResult.token);
121
- }
122
-
123
- return {
124
- success: true,
125
- user: {
126
- email: googleUser.email,
127
- name: googleUser.name,
128
- photo: googleUser.photo,
129
- id: googleUser.id
130
- },
131
- token: accountResult.token,
132
- existingUser: accountResult.existingUser
133
- };
134
- } else {
135
- throw new Error(accountResult.message || 'Failed to create user account');
136
- }
137
-
138
- } catch (error: any) {
139
- console.error('❌ Google Sign-In error:', error);
140
-
141
- // Handle specific Google Sign-In errors
142
- if (error.code === statusCodes.SIGN_IN_CANCELLED) {
143
- return {
144
- success: false,
145
- message: 'Google Sign-In was cancelled',
146
- cancelled: true
147
- };
148
- } else if (error.code === statusCodes.IN_PROGRESS) {
149
- return {
150
- success: false,
151
- message: 'Google Sign-In is already in progress'
152
- };
153
- } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
154
- return {
155
- success: false,
156
- message: 'Google Play Services not available'
157
- };
158
- } else {
159
- return {
160
- success: false,
161
- message: error.message || 'Google Sign-In failed'
162
- };
163
- }
164
- }
165
- };
166
-
167
- /**
168
- * Create or authenticate user account on backend
169
- */
170
- const createUserAccount = async (userData: {
171
- email: string;
172
- name: string;
173
- photoUrl: string;
174
- googleId: string;
175
- accessToken: string;
176
- idToken: string;
177
- }) => {
178
- try {
179
- console.log('🔐 Creating/authenticating user account for:', userData.email);
180
-
181
- // Step 1: Create Enoch user first
182
- console.log('🔐 Step 1: Creating Enoch user...');
183
- try {
184
- const enochRegisterResponse = await fetch('https://api2.onairos.uk/enoch/users/register', {
185
- method: 'POST',
186
- headers: {
187
- 'Content-Type': 'application/json'
188
- },
189
- body: JSON.stringify({
190
- email: userData.email,
191
- name: userData.name,
192
- photoUrl: userData.photoUrl
193
- })
194
- });
195
-
196
- console.log('📡 Enoch register response status:', enochRegisterResponse.status);
197
- const enochResponseData = await enochRegisterResponse.json();
198
- console.log('🔗 Enoch user creation response:', enochResponseData);
199
- } catch (enochError) {
200
- console.warn('⚠️ Enoch user creation failed (continuing):', enochError);
201
- }
202
-
203
- // Step 2: Create Onairos account to get JWT token
204
- console.log('🔐 Step 2: Creating Onairos account...');
205
- const onairosSignupResponse = await fetch('https://api2.onairos.uk/register/enoch', {
206
- method: 'POST',
207
- headers: {
208
- 'Content-Type': 'application/json'
209
- },
210
- body: JSON.stringify({
211
- email: userData.email,
212
- username: userData.name,
213
- name: userData.name,
214
- googleAuth: true, // Flag to indicate Google authentication
215
- googleId: userData.googleId,
216
- photoUrl: userData.photoUrl
217
- })
218
- });
219
-
220
- console.log('📡 Onairos register response status:', onairosSignupResponse.status);
221
- const onairosResponseData = await onairosSignupResponse.json();
222
- console.log('🔗 Onairos account creation response:', onairosResponseData);
223
-
224
- if (onairosSignupResponse.ok && onairosResponseData.token) {
225
- return {
226
- success: true,
227
- token: onairosResponseData.token,
228
- existingUser: onairosResponseData.existingUser || false,
229
- message: 'Account created/authenticated successfully'
230
- };
231
- } else {
232
- return {
233
- success: false,
234
- message: onairosResponseData.message || 'Failed to create account'
235
- };
236
- }
237
-
238
- } catch (error: any) {
239
- console.error('❌ Error creating user account:', error);
240
- return {
241
- success: false,
242
- message: error.message || 'Failed to create user account'
243
- };
244
- }
245
- };
246
-
247
- /**
248
- * Check if user is already signed in with Google
249
- */
250
- export const isGoogleSignedIn = async () => {
251
- try {
252
- const currentUser = await GoogleSignin.getCurrentUser();
253
- const isSignedIn = currentUser !== null;
254
- if (isSignedIn) {
255
- return {
256
- isSignedIn: true,
257
- user: currentUser?.user
258
- };
259
- }
260
- return { isSignedIn: false };
261
- } catch (error) {
262
- console.error('❌ Error checking Google sign-in status:', error);
263
- return { isSignedIn: false };
264
- }
265
- };
266
-
267
- /**
268
- * Sign out from Google
269
- */
270
- export const signOutFromGoogle = async () => {
271
- try {
272
- await GoogleSignin.signOut();
273
- console.log('✅ Google sign-out successful');
274
- return true;
275
- } catch (error) {
276
- console.error('❌ Google sign-out error:', error);
277
- return false;
278
- }
279
- };
1
+ /**
2
+ * Google Authentication Service
3
+ * Handles Google Sign-In for user authentication and account creation
4
+ */
5
+
6
+ import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
7
+ import AsyncStorage from '@react-native-async-storage/async-storage';
8
+
9
+ // 🔑 Using the same client ID configuration as platform auth
10
+ let WEB_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
11
+ let IOS_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
12
+
13
+ /**
14
+ * Update Google OAuth client IDs for custom configurations
15
+ */
16
+ export const updateGoogleClientIds = (config: {
17
+ webClientId?: string;
18
+ iosClientId?: string;
19
+ }) => {
20
+ if (config.webClientId) {
21
+ WEB_CLIENT_ID = config.webClientId;
22
+ }
23
+ if (config.iosClientId) {
24
+ IOS_CLIENT_ID = config.iosClientId;
25
+ }
26
+
27
+ console.log('✅ Google client IDs updated:', {
28
+ webClientId: WEB_CLIENT_ID,
29
+ iosClientId: IOS_CLIENT_ID
30
+ });
31
+ };
32
+
33
+ /**
34
+ * Initialize Google Sign-In for user authentication
35
+ */
36
+ const initializeGoogleAuth = () => {
37
+ GoogleSignin.configure({
38
+ webClientId: WEB_CLIENT_ID,
39
+ iosClientId: IOS_CLIENT_ID,
40
+
41
+ // Basic scopes for user authentication
42
+ scopes: [
43
+ 'openid',
44
+ 'profile',
45
+ 'email'
46
+ ],
47
+
48
+ // Enable offline access for refresh tokens
49
+ offlineAccess: true,
50
+ forceCodeForRefreshToken: true,
51
+
52
+ // Clear settings to avoid conflicts
53
+ hostedDomain: '',
54
+ accountName: '',
55
+ });
56
+ };
57
+
58
+ /**
59
+ * Sign in with Google and create/authenticate user account
60
+ */
61
+ export const signInWithGoogle = async () => {
62
+ try {
63
+ console.log('🔗 Initiating Google Sign-In for user authentication');
64
+
65
+ // Initialize Google Sign-In
66
+ initializeGoogleAuth();
67
+
68
+ // Check if Google Play Services are available
69
+ await GoogleSignin.hasPlayServices();
70
+
71
+ // Sign out first to ensure fresh consent
72
+ try {
73
+ await GoogleSignin.signOut();
74
+ console.log('🔄 Signed out to ensure fresh consent');
75
+ } catch (signOutError) {
76
+ console.log('ℹ️ Sign out not needed or failed:', signOutError);
77
+ }
78
+
79
+ // Sign in with Google
80
+ const userInfo = await GoogleSignin.signIn();
81
+ console.log('✅ Google Sign-In successful:', userInfo.data?.user?.email);
82
+
83
+ const googleUser = userInfo.data?.user;
84
+ if (!googleUser || !googleUser.email) {
85
+ throw new Error('No user data received from Google');
86
+ }
87
+
88
+ console.log('👤 Google user data:', {
89
+ email: googleUser.email,
90
+ name: googleUser.name,
91
+ photo: googleUser.photo,
92
+ id: googleUser.id
93
+ });
94
+
95
+ // Get tokens for account creation
96
+ const tokens = await GoogleSignin.getTokens();
97
+ console.log('🔑 Got Google tokens');
98
+
99
+ // Create user account on backend
100
+ const accountResult = await createUserAccount({
101
+ email: googleUser.email,
102
+ name: googleUser.name || googleUser.email.split('@')[0],
103
+ photoUrl: googleUser.photo || '',
104
+ googleId: googleUser.id,
105
+ accessToken: tokens.accessToken,
106
+ idToken: tokens.idToken
107
+ });
108
+
109
+ if (accountResult.success) {
110
+ console.log('✅ User account created/authenticated successfully');
111
+
112
+ // Store authentication data
113
+ await AsyncStorage.setItem('user_email', googleUser.email);
114
+ await AsyncStorage.setItem('user_name', googleUser.name || '');
115
+ await AsyncStorage.setItem('user_photo', googleUser.photo || '');
116
+ await AsyncStorage.setItem('auth_method', 'google');
117
+
118
+ if (accountResult.token) {
119
+ await AsyncStorage.setItem('onairos_jwt_token', accountResult.token);
120
+ await AsyncStorage.setItem('auth_token', accountResult.token);
121
+ }
122
+
123
+ return {
124
+ success: true,
125
+ user: {
126
+ email: googleUser.email,
127
+ name: googleUser.name,
128
+ photo: googleUser.photo,
129
+ id: googleUser.id
130
+ },
131
+ token: accountResult.token,
132
+ existingUser: accountResult.existingUser
133
+ };
134
+ } else {
135
+ throw new Error(accountResult.message || 'Failed to create user account');
136
+ }
137
+
138
+ } catch (error: any) {
139
+ console.error('❌ Google Sign-In error:', error);
140
+
141
+ // Handle specific Google Sign-In errors
142
+ if (error.code === statusCodes.SIGN_IN_CANCELLED) {
143
+ return {
144
+ success: false,
145
+ message: 'Google Sign-In was cancelled',
146
+ cancelled: true
147
+ };
148
+ } else if (error.code === statusCodes.IN_PROGRESS) {
149
+ return {
150
+ success: false,
151
+ message: 'Google Sign-In is already in progress'
152
+ };
153
+ } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
154
+ return {
155
+ success: false,
156
+ message: 'Google Play Services not available'
157
+ };
158
+ } else {
159
+ return {
160
+ success: false,
161
+ message: error.message || 'Google Sign-In failed'
162
+ };
163
+ }
164
+ }
165
+ };
166
+
167
+ /**
168
+ * Create or authenticate user account on backend
169
+ */
170
+ const createUserAccount = async (userData: {
171
+ email: string;
172
+ name: string;
173
+ photoUrl: string;
174
+ googleId: string;
175
+ accessToken: string;
176
+ idToken: string;
177
+ }) => {
178
+ try {
179
+ console.log('🔐 Creating/authenticating user account for:', userData.email);
180
+
181
+ // Step 1: Create Enoch user first
182
+ console.log('🔐 Step 1: Creating Enoch user...');
183
+ try {
184
+ const enochRegisterResponse = await fetch('https://api2.onairos.uk/enoch/users/register', {
185
+ method: 'POST',
186
+ headers: {
187
+ 'Content-Type': 'application/json'
188
+ },
189
+ body: JSON.stringify({
190
+ email: userData.email,
191
+ name: userData.name,
192
+ photoUrl: userData.photoUrl
193
+ })
194
+ });
195
+
196
+ console.log('📡 Enoch register response status:', enochRegisterResponse.status);
197
+ const enochResponseData = await enochRegisterResponse.json();
198
+ console.log('🔗 Enoch user creation response:', enochResponseData);
199
+ } catch (enochError) {
200
+ console.warn('⚠️ Enoch user creation failed (continuing):', enochError);
201
+ }
202
+
203
+ // Step 2: Create Onairos account to get JWT token
204
+ console.log('🔐 Step 2: Creating Onairos account...');
205
+ const onairosSignupResponse = await fetch('https://api2.onairos.uk/register/enoch', {
206
+ method: 'POST',
207
+ headers: {
208
+ 'Content-Type': 'application/json'
209
+ },
210
+ body: JSON.stringify({
211
+ email: userData.email,
212
+ username: userData.name,
213
+ name: userData.name,
214
+ googleAuth: true, // Flag to indicate Google authentication
215
+ googleId: userData.googleId,
216
+ photoUrl: userData.photoUrl
217
+ })
218
+ });
219
+
220
+ console.log('📡 Onairos register response status:', onairosSignupResponse.status);
221
+ const onairosResponseData = await onairosSignupResponse.json();
222
+ console.log('🔗 Onairos account creation response:', onairosResponseData);
223
+
224
+ if (onairosSignupResponse.ok && onairosResponseData.token) {
225
+ return {
226
+ success: true,
227
+ token: onairosResponseData.token,
228
+ existingUser: onairosResponseData.existingUser || false,
229
+ message: 'Account created/authenticated successfully'
230
+ };
231
+ } else {
232
+ return {
233
+ success: false,
234
+ message: onairosResponseData.message || 'Failed to create account'
235
+ };
236
+ }
237
+
238
+ } catch (error: any) {
239
+ console.error('❌ Error creating user account:', error);
240
+ return {
241
+ success: false,
242
+ message: error.message || 'Failed to create user account'
243
+ };
244
+ }
245
+ };
246
+
247
+ /**
248
+ * Check if user is already signed in with Google
249
+ */
250
+ export const isGoogleSignedIn = async () => {
251
+ try {
252
+ const currentUser = await GoogleSignin.getCurrentUser();
253
+ const isSignedIn = currentUser !== null;
254
+ if (isSignedIn) {
255
+ return {
256
+ isSignedIn: true,
257
+ user: currentUser?.user
258
+ };
259
+ }
260
+ return { isSignedIn: false };
261
+ } catch (error) {
262
+ console.error('❌ Error checking Google sign-in status:', error);
263
+ return { isSignedIn: false };
264
+ }
265
+ };
266
+
267
+ /**
268
+ * Sign out from Google
269
+ */
270
+ export const signOutFromGoogle = async () => {
271
+ try {
272
+ await GoogleSignin.signOut();
273
+ console.log('✅ Google sign-out successful');
274
+ return true;
275
+ } catch (error) {
276
+ console.error('❌ Google sign-out error:', error);
277
+ return false;
278
+ }
279
+ };