@onairos/react-native 3.1.12 โ†’ 3.1.13

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 (604) hide show
  1. package/lib/commonjs/api/index.js +75 -1
  2. package/lib/commonjs/api/index.js.map +1 -1
  3. package/lib/commonjs/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
  4. package/lib/commonjs/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  5. package/lib/commonjs/assets/icons/Facebookicon.png +0 -0
  6. package/lib/commonjs/assets/icons/Gmail.png +0 -0
  7. package/lib/commonjs/assets/icons/Linkedinicon.png +0 -0
  8. package/lib/commonjs/assets/icons/Redditicon.png +0 -0
  9. package/lib/commonjs/assets/icons/YouTubeicon2.png +0 -0
  10. package/lib/commonjs/assets/icons/YouTubeicon3.png +0 -0
  11. package/lib/commonjs/assets/icons/farcaster.png +0 -0
  12. package/lib/commonjs/assets/icons/instagram.png +0 -0
  13. package/lib/commonjs/assets/icons/pinterest.png +0 -0
  14. package/lib/commonjs/assets/icons/swerv_logo.png +0 -0
  15. package/lib/commonjs/assets/icons/twitter.jpg +0 -0
  16. package/lib/commonjs/assets/images/Checkbox.svg +3 -0
  17. package/lib/commonjs/assets/images/EnochE.svg +19 -0
  18. package/lib/commonjs/assets/images/Enochicon1.png +0 -0
  19. package/lib/commonjs/assets/images/Face_ID_logo.png +0 -0
  20. package/lib/commonjs/assets/images/Facebookicon.png +0 -0
  21. package/lib/commonjs/assets/images/Gmail.png +0 -0
  22. package/lib/commonjs/assets/images/Googlelogo.png +0 -0
  23. package/lib/commonjs/assets/images/Linkedinicon.png +0 -0
  24. package/lib/commonjs/assets/images/Onairoslogo.png +0 -0
  25. package/lib/commonjs/assets/images/Personalityprofile.svg +3 -0
  26. package/lib/commonjs/assets/images/Personalitytraits.svg +3 -0
  27. package/lib/commonjs/assets/images/Redditicon.png +0 -0
  28. package/lib/commonjs/assets/images/Userpreferences.svg +3 -0
  29. package/lib/commonjs/assets/images/YouTubeicon3.png +0 -0
  30. package/lib/commonjs/assets/images/arrow.svg +20 -0
  31. package/lib/commonjs/assets/images/basicproficon.svg +43 -0
  32. package/lib/commonjs/assets/images/basicprofile.svg +3 -0
  33. package/lib/commonjs/assets/images/checkmark.svg +4 -0
  34. package/lib/commonjs/assets/images/contentanalysis.svg +3 -0
  35. package/lib/commonjs/assets/images/contenticon.svg +23 -0
  36. package/lib/commonjs/assets/images/persona1.png +0 -0
  37. package/lib/commonjs/assets/images/persona2.png +0 -0
  38. package/lib/commonjs/assets/images/persona3.png +0 -0
  39. package/lib/commonjs/assets/images/persona4.png +0 -0
  40. package/lib/commonjs/assets/images/persona5.png +0 -0
  41. package/lib/commonjs/assets/images/personalityicon.svg +18 -0
  42. package/lib/commonjs/assets/images/x-close.svg +3 -0
  43. package/lib/commonjs/components/BodyText.js +27 -0
  44. package/lib/commonjs/components/BodyText.js.map +1 -0
  45. package/lib/commonjs/components/BrandMark.js +44 -0
  46. package/lib/commonjs/components/BrandMark.js.map +1 -0
  47. package/lib/commonjs/components/CodeInput.js +30 -0
  48. package/lib/commonjs/components/CodeInput.js.map +1 -0
  49. package/lib/commonjs/components/EmailInput.js +30 -0
  50. package/lib/commonjs/components/EmailInput.js.map +1 -0
  51. package/lib/commonjs/components/ExistingUserDataConfirmation.js +474 -0
  52. package/lib/commonjs/components/ExistingUserDataConfirmation.js.map +1 -0
  53. package/lib/commonjs/components/GoogleButton.js +55 -0
  54. package/lib/commonjs/components/GoogleButton.js.map +1 -0
  55. package/lib/commonjs/components/HeadingGroup.js +43 -0
  56. package/lib/commonjs/components/HeadingGroup.js.map +1 -0
  57. package/lib/commonjs/components/ModalHeader.js +99 -0
  58. package/lib/commonjs/components/ModalHeader.js.map +1 -0
  59. package/lib/commonjs/components/ModalSheet.js +41 -0
  60. package/lib/commonjs/components/ModalSheet.js.map +1 -0
  61. package/lib/commonjs/components/Onairos.js +1 -3
  62. package/lib/commonjs/components/Onairos.js.map +1 -1
  63. package/lib/commonjs/components/OnairosButton.js +171 -190
  64. package/lib/commonjs/components/OnairosButton.js.map +1 -1
  65. package/lib/commonjs/components/OnairosSignInButton.js +169 -0
  66. package/lib/commonjs/components/OnairosSignInButton.js.map +1 -0
  67. package/lib/commonjs/components/Overlay.js +5 -5
  68. package/lib/commonjs/components/Overlay.js.map +1 -1
  69. package/lib/commonjs/components/PersonaImage.js +60 -0
  70. package/lib/commonjs/components/PersonaImage.js.map +1 -0
  71. package/lib/commonjs/components/PersonaLoadingScreen.js +156 -0
  72. package/lib/commonjs/components/PersonaLoadingScreen.js.map +1 -0
  73. package/lib/commonjs/components/PersonalizationConsentScreen.js +316 -0
  74. package/lib/commonjs/components/PersonalizationConsentScreen.js.map +1 -0
  75. package/lib/commonjs/components/PinCreationScreen.js +393 -0
  76. package/lib/commonjs/components/PinCreationScreen.js.map +1 -0
  77. package/lib/commonjs/components/PinInput.js +282 -120
  78. package/lib/commonjs/components/PinInput.js.map +1 -1
  79. package/lib/commonjs/components/PlatformConnectorsStep.js +828 -0
  80. package/lib/commonjs/components/PlatformConnectorsStep.js.map +1 -0
  81. package/lib/commonjs/components/PlatformToggle.js +180 -0
  82. package/lib/commonjs/components/PlatformToggle.js.map +1 -0
  83. package/lib/commonjs/components/PrimaryButton.js +180 -0
  84. package/lib/commonjs/components/PrimaryButton.js.map +1 -0
  85. package/lib/commonjs/components/SignInMatchAnimation.js +197 -0
  86. package/lib/commonjs/components/SignInMatchAnimation.js.map +1 -0
  87. package/lib/commonjs/components/SignInStep.js +179 -0
  88. package/lib/commonjs/components/SignInStep.js.map +1 -0
  89. package/lib/commonjs/components/TrainingModal.js +808 -563
  90. package/lib/commonjs/components/TrainingModal.js.map +1 -1
  91. package/lib/commonjs/components/UniversalOnboarding.js +2304 -1283
  92. package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
  93. package/lib/commonjs/components/VerificationStep.js +154 -0
  94. package/lib/commonjs/components/VerificationStep.js.map +1 -0
  95. package/lib/commonjs/components/WelcomeScreen.js +385 -0
  96. package/lib/commonjs/components/WelcomeScreen.js.map +1 -0
  97. package/lib/commonjs/components/icons/Basicproficon.js +37 -0
  98. package/lib/commonjs/components/icons/Basicproficon.js.map +1 -0
  99. package/lib/commonjs/components/icons/Basicprofile.js +21 -0
  100. package/lib/commonjs/components/icons/Basicprofile.js.map +1 -0
  101. package/lib/commonjs/components/icons/Checkbox.js +21 -0
  102. package/lib/commonjs/components/icons/Checkbox.js.map +1 -0
  103. package/lib/commonjs/components/icons/Checkmark.js +27 -0
  104. package/lib/commonjs/components/icons/Checkmark.js.map +1 -0
  105. package/lib/commonjs/components/icons/Contentanalysis.js +21 -0
  106. package/lib/commonjs/components/icons/Contentanalysis.js.map +1 -0
  107. package/lib/commonjs/components/icons/Contenticon.js +39 -0
  108. package/lib/commonjs/components/icons/Contenticon.js.map +1 -0
  109. package/lib/commonjs/components/icons/EnochE.js +41 -0
  110. package/lib/commonjs/components/icons/EnochE.js.map +1 -0
  111. package/lib/commonjs/components/icons/Personalityicon.js +30 -0
  112. package/lib/commonjs/components/icons/Personalityicon.js.map +1 -0
  113. package/lib/commonjs/components/icons/Personalityprofile.js +21 -0
  114. package/lib/commonjs/components/icons/Personalityprofile.js.map +1 -0
  115. package/lib/commonjs/components/icons/Personalitytraits.js +21 -0
  116. package/lib/commonjs/components/icons/Personalitytraits.js.map +1 -0
  117. package/lib/commonjs/components/icons/Userpreferences.js +21 -0
  118. package/lib/commonjs/components/icons/Userpreferences.js.map +1 -0
  119. package/lib/commonjs/components/icons/index.js +84 -0
  120. package/lib/commonjs/components/icons/index.js.map +1 -0
  121. package/lib/commonjs/components/onboarding/OAuthWebView.js +134 -743
  122. package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
  123. package/lib/commonjs/config/api.js +34 -0
  124. package/lib/commonjs/config/api.js.map +1 -0
  125. package/lib/commonjs/context/AuthContext.js +345 -0
  126. package/lib/commonjs/context/AuthContext.js.map +1 -0
  127. package/lib/commonjs/hooks/useConnectedAccounts.js +111 -0
  128. package/lib/commonjs/hooks/useConnectedAccounts.js.map +1 -0
  129. package/lib/commonjs/hooks/useConnections.js +120 -125
  130. package/lib/commonjs/hooks/useConnections.js.map +1 -1
  131. package/lib/commonjs/hooks/useUserConnections.js +148 -0
  132. package/lib/commonjs/hooks/useUserConnections.js.map +1 -0
  133. package/lib/commonjs/index.js +149 -27
  134. package/lib/commonjs/index.js.map +1 -1
  135. package/lib/commonjs/services/apiClient.js +302 -0
  136. package/lib/commonjs/services/apiClient.js.map +1 -0
  137. package/lib/commonjs/services/apiKeyService.js +8 -9
  138. package/lib/commonjs/services/apiKeyService.js.map +1 -1
  139. package/lib/commonjs/services/authService.js +935 -0
  140. package/lib/commonjs/services/authService.js.map +1 -0
  141. package/lib/commonjs/services/biometricPinService.js +184 -0
  142. package/lib/commonjs/services/biometricPinService.js.map +1 -0
  143. package/lib/commonjs/services/connectedAccountsService.js +268 -0
  144. package/lib/commonjs/services/connectedAccountsService.js.map +1 -0
  145. package/lib/commonjs/services/googleAuthService.js +268 -0
  146. package/lib/commonjs/services/googleAuthService.js.map +1 -0
  147. package/lib/commonjs/services/imageCompressionService.js +260 -0
  148. package/lib/commonjs/services/imageCompressionService.js.map +1 -0
  149. package/lib/commonjs/services/jwtStorageService.js +256 -0
  150. package/lib/commonjs/services/jwtStorageService.js.map +1 -0
  151. package/lib/commonjs/services/mobileTrainingService.js +185 -0
  152. package/lib/commonjs/services/mobileTrainingService.js.map +1 -0
  153. package/lib/commonjs/services/pinEncryptionService.js +84 -0
  154. package/lib/commonjs/services/pinEncryptionService.js.map +1 -0
  155. package/lib/commonjs/services/pinStorageUtils.js +105 -0
  156. package/lib/commonjs/services/pinStorageUtils.js.map +1 -0
  157. package/lib/commonjs/services/platformAuthService.js +956 -722
  158. package/lib/commonjs/services/platformAuthService.js.map +1 -1
  159. package/lib/commonjs/services/storageService.js +404 -0
  160. package/lib/commonjs/services/storageService.js.map +1 -0
  161. package/lib/commonjs/services/trainingApiHelpers.js +73 -0
  162. package/lib/commonjs/services/trainingApiHelpers.js.map +1 -0
  163. package/lib/commonjs/services/userConnectionsService.js +486 -0
  164. package/lib/commonjs/services/userConnectionsService.js.map +1 -0
  165. package/lib/commonjs/services/youtubeMigrationService.js +415 -0
  166. package/lib/commonjs/services/youtubeMigrationService.js.map +1 -0
  167. package/lib/commonjs/theme/index.js +249 -0
  168. package/lib/commonjs/theme/index.js.map +1 -0
  169. package/lib/commonjs/utils/eventUtils.js +288 -0
  170. package/lib/commonjs/utils/eventUtils.js.map +1 -0
  171. package/lib/commonjs/utils/haptics.js +66 -0
  172. package/lib/commonjs/utils/haptics.js.map +1 -0
  173. package/lib/commonjs/utils/imagePreloader.js +6 -0
  174. package/lib/commonjs/utils/imagePreloader.js.map +1 -0
  175. package/lib/module/api/index.js +72 -0
  176. package/lib/module/api/index.js.map +1 -1
  177. package/lib/module/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
  178. package/lib/module/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  179. package/lib/module/assets/icons/Facebookicon.png +0 -0
  180. package/lib/module/assets/icons/Gmail.png +0 -0
  181. package/lib/module/assets/icons/Linkedinicon.png +0 -0
  182. package/lib/module/assets/icons/Redditicon.png +0 -0
  183. package/lib/module/assets/icons/YouTubeicon2.png +0 -0
  184. package/lib/module/assets/icons/YouTubeicon3.png +0 -0
  185. package/lib/module/assets/icons/farcaster.png +0 -0
  186. package/lib/module/assets/icons/instagram.png +0 -0
  187. package/lib/module/assets/icons/pinterest.png +0 -0
  188. package/lib/module/assets/icons/swerv_logo.png +0 -0
  189. package/lib/module/assets/icons/twitter.jpg +0 -0
  190. package/lib/module/assets/images/Checkbox.svg +3 -0
  191. package/lib/module/assets/images/EnochE.svg +19 -0
  192. package/lib/module/assets/images/Enochicon1.png +0 -0
  193. package/lib/module/assets/images/Face_ID_logo.png +0 -0
  194. package/lib/module/assets/images/Facebookicon.png +0 -0
  195. package/lib/module/assets/images/Gmail.png +0 -0
  196. package/lib/module/assets/images/Googlelogo.png +0 -0
  197. package/lib/module/assets/images/Linkedinicon.png +0 -0
  198. package/lib/module/assets/images/Onairoslogo.png +0 -0
  199. package/lib/module/assets/images/Personalityprofile.svg +3 -0
  200. package/lib/module/assets/images/Personalitytraits.svg +3 -0
  201. package/lib/module/assets/images/Redditicon.png +0 -0
  202. package/lib/module/assets/images/Userpreferences.svg +3 -0
  203. package/lib/module/assets/images/YouTubeicon3.png +0 -0
  204. package/lib/module/assets/images/arrow.svg +20 -0
  205. package/lib/module/assets/images/basicproficon.svg +43 -0
  206. package/lib/module/assets/images/basicprofile.svg +3 -0
  207. package/lib/module/assets/images/checkmark.svg +4 -0
  208. package/lib/module/assets/images/contentanalysis.svg +3 -0
  209. package/lib/module/assets/images/contenticon.svg +23 -0
  210. package/lib/module/assets/images/persona1.png +0 -0
  211. package/lib/module/assets/images/persona2.png +0 -0
  212. package/lib/module/assets/images/persona3.png +0 -0
  213. package/lib/module/assets/images/persona4.png +0 -0
  214. package/lib/module/assets/images/persona5.png +0 -0
  215. package/lib/module/assets/images/personalityicon.svg +18 -0
  216. package/lib/module/assets/images/x-close.svg +3 -0
  217. package/lib/module/components/BodyText.js +20 -0
  218. package/lib/module/components/BodyText.js.map +1 -0
  219. package/lib/module/components/BrandMark.js +37 -0
  220. package/lib/module/components/BrandMark.js.map +1 -0
  221. package/lib/module/components/CodeInput.js +23 -0
  222. package/lib/module/components/CodeInput.js.map +1 -0
  223. package/lib/module/components/EmailInput.js +23 -0
  224. package/lib/module/components/EmailInput.js.map +1 -0
  225. package/lib/module/components/ExistingUserDataConfirmation.js +465 -0
  226. package/lib/module/components/ExistingUserDataConfirmation.js.map +1 -0
  227. package/lib/module/components/GoogleButton.js +48 -0
  228. package/lib/module/components/GoogleButton.js.map +1 -0
  229. package/lib/module/components/HeadingGroup.js +36 -0
  230. package/lib/module/components/HeadingGroup.js.map +1 -0
  231. package/lib/module/components/ModalHeader.js +92 -0
  232. package/lib/module/components/ModalHeader.js.map +1 -0
  233. package/lib/module/components/ModalSheet.js +34 -0
  234. package/lib/module/components/ModalSheet.js.map +1 -0
  235. package/lib/module/components/Onairos.js +1 -3
  236. package/lib/module/components/Onairos.js.map +1 -1
  237. package/lib/module/components/OnairosButton.js +172 -192
  238. package/lib/module/components/OnairosButton.js.map +1 -1
  239. package/lib/module/components/OnairosSignInButton.js +160 -0
  240. package/lib/module/components/OnairosSignInButton.js.map +1 -0
  241. package/lib/module/components/Overlay.js +5 -5
  242. package/lib/module/components/Overlay.js.map +1 -1
  243. package/lib/module/components/PersonaImage.js +53 -0
  244. package/lib/module/components/PersonaImage.js.map +1 -0
  245. package/lib/module/components/PersonaLoadingScreen.js +148 -0
  246. package/lib/module/components/PersonaLoadingScreen.js.map +1 -0
  247. package/lib/module/components/PersonalizationConsentScreen.js +309 -0
  248. package/lib/module/components/PersonalizationConsentScreen.js.map +1 -0
  249. package/lib/module/components/PinCreationScreen.js +386 -0
  250. package/lib/module/components/PinCreationScreen.js.map +1 -0
  251. package/lib/module/components/PinInput.js +283 -120
  252. package/lib/module/components/PinInput.js.map +1 -1
  253. package/lib/module/components/PlatformConnectorsStep.js +820 -0
  254. package/lib/module/components/PlatformConnectorsStep.js.map +1 -0
  255. package/lib/module/components/PlatformToggle.js +173 -0
  256. package/lib/module/components/PlatformToggle.js.map +1 -0
  257. package/lib/module/components/PrimaryButton.js +172 -0
  258. package/lib/module/components/PrimaryButton.js.map +1 -0
  259. package/lib/module/components/SignInMatchAnimation.js +189 -0
  260. package/lib/module/components/SignInMatchAnimation.js.map +1 -0
  261. package/lib/module/components/SignInStep.js +171 -0
  262. package/lib/module/components/SignInStep.js.map +1 -0
  263. package/lib/module/components/TrainingModal.js +809 -565
  264. package/lib/module/components/TrainingModal.js.map +1 -1
  265. package/lib/module/components/UniversalOnboarding.js +2307 -1284
  266. package/lib/module/components/UniversalOnboarding.js.map +1 -1
  267. package/lib/module/components/VerificationStep.js +146 -0
  268. package/lib/module/components/VerificationStep.js.map +1 -0
  269. package/lib/module/components/WelcomeScreen.js +378 -0
  270. package/lib/module/components/WelcomeScreen.js.map +1 -0
  271. package/lib/module/components/icons/Basicproficon.js +30 -0
  272. package/lib/module/components/icons/Basicproficon.js.map +1 -0
  273. package/lib/module/components/icons/Basicprofile.js +14 -0
  274. package/lib/module/components/icons/Basicprofile.js.map +1 -0
  275. package/lib/module/components/icons/Checkbox.js +14 -0
  276. package/lib/module/components/icons/Checkbox.js.map +1 -0
  277. package/lib/module/components/icons/Checkmark.js +20 -0
  278. package/lib/module/components/icons/Checkmark.js.map +1 -0
  279. package/lib/module/components/icons/Contentanalysis.js +14 -0
  280. package/lib/module/components/icons/Contentanalysis.js.map +1 -0
  281. package/lib/module/components/icons/Contenticon.js +32 -0
  282. package/lib/module/components/icons/Contenticon.js.map +1 -0
  283. package/lib/module/components/icons/EnochE.js +34 -0
  284. package/lib/module/components/icons/EnochE.js.map +1 -0
  285. package/lib/module/components/icons/Personalityicon.js +23 -0
  286. package/lib/module/components/icons/Personalityicon.js.map +1 -0
  287. package/lib/module/components/icons/Personalityprofile.js +14 -0
  288. package/lib/module/components/icons/Personalityprofile.js.map +1 -0
  289. package/lib/module/components/icons/Personalitytraits.js +14 -0
  290. package/lib/module/components/icons/Personalitytraits.js.map +1 -0
  291. package/lib/module/components/icons/Userpreferences.js +14 -0
  292. package/lib/module/components/icons/Userpreferences.js.map +1 -0
  293. package/lib/module/components/icons/index.js +13 -0
  294. package/lib/module/components/icons/index.js.map +1 -0
  295. package/lib/module/components/onboarding/OAuthWebView.js +136 -744
  296. package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
  297. package/lib/module/config/api.js +26 -0
  298. package/lib/module/config/api.js.map +1 -0
  299. package/lib/module/context/AuthContext.js +335 -0
  300. package/lib/module/context/AuthContext.js.map +1 -0
  301. package/lib/module/hooks/useConnectedAccounts.js +106 -0
  302. package/lib/module/hooks/useConnectedAccounts.js.map +1 -0
  303. package/lib/module/hooks/useConnections.js +119 -125
  304. package/lib/module/hooks/useConnections.js.map +1 -1
  305. package/lib/module/hooks/useUserConnections.js +140 -0
  306. package/lib/module/hooks/useUserConnections.js.map +1 -0
  307. package/lib/module/index.js +51 -15
  308. package/lib/module/index.js.map +1 -1
  309. package/lib/module/services/apiClient.js +298 -0
  310. package/lib/module/services/apiClient.js.map +1 -0
  311. package/lib/module/services/apiKeyService.js +8 -9
  312. package/lib/module/services/apiKeyService.js.map +1 -1
  313. package/lib/module/services/authService.js +905 -0
  314. package/lib/module/services/authService.js.map +1 -0
  315. package/lib/module/services/biometricPinService.js +173 -0
  316. package/lib/module/services/biometricPinService.js.map +1 -0
  317. package/lib/module/services/connectedAccountsService.js +255 -0
  318. package/lib/module/services/connectedAccountsService.js.map +1 -0
  319. package/lib/module/services/googleAuthService.js +258 -0
  320. package/lib/module/services/googleAuthService.js.map +1 -0
  321. package/lib/module/services/imageCompressionService.js +250 -0
  322. package/lib/module/services/imageCompressionService.js.map +1 -0
  323. package/lib/module/services/jwtStorageService.js +239 -0
  324. package/lib/module/services/jwtStorageService.js.map +1 -0
  325. package/lib/module/services/mobileTrainingService.js +172 -0
  326. package/lib/module/services/mobileTrainingService.js.map +1 -0
  327. package/lib/module/services/pinEncryptionService.js +75 -0
  328. package/lib/module/services/pinEncryptionService.js.map +1 -0
  329. package/lib/module/services/pinStorageUtils.js +93 -0
  330. package/lib/module/services/pinStorageUtils.js.map +1 -0
  331. package/lib/module/services/platformAuthService.js +943 -704
  332. package/lib/module/services/platformAuthService.js.map +1 -1
  333. package/lib/module/services/storageService.js +383 -0
  334. package/lib/module/services/storageService.js.map +1 -0
  335. package/lib/module/services/trainingApiHelpers.js +67 -0
  336. package/lib/module/services/trainingApiHelpers.js.map +1 -0
  337. package/lib/module/services/userConnectionsService.js +476 -0
  338. package/lib/module/services/userConnectionsService.js.map +1 -0
  339. package/lib/module/services/youtubeMigrationService.js +404 -0
  340. package/lib/module/services/youtubeMigrationService.js.map +1 -0
  341. package/lib/module/theme/index.js +244 -0
  342. package/lib/module/theme/index.js.map +1 -0
  343. package/lib/module/utils/eventUtils.js +270 -0
  344. package/lib/module/utils/eventUtils.js.map +1 -0
  345. package/lib/module/utils/haptics.js +59 -0
  346. package/lib/module/utils/haptics.js.map +1 -0
  347. package/lib/module/utils/imagePreloader.js +3 -0
  348. package/lib/module/utils/imagePreloader.js.map +1 -0
  349. package/lib/typescript/api/index.d.ts +8 -0
  350. package/lib/typescript/api/index.d.ts.map +1 -1
  351. package/lib/typescript/components/BodyText.d.ts +10 -0
  352. package/lib/typescript/components/BodyText.d.ts.map +1 -0
  353. package/lib/typescript/components/BrandMark.d.ts +11 -0
  354. package/lib/typescript/components/BrandMark.d.ts.map +1 -0
  355. package/lib/typescript/components/CodeInput.d.ts +10 -0
  356. package/lib/typescript/components/CodeInput.d.ts.map +1 -0
  357. package/lib/typescript/components/EmailInput.d.ts +8 -0
  358. package/lib/typescript/components/EmailInput.d.ts.map +1 -0
  359. package/lib/typescript/components/ExistingUserDataConfirmation.d.ts +12 -0
  360. package/lib/typescript/components/ExistingUserDataConfirmation.d.ts.map +1 -0
  361. package/lib/typescript/components/GoogleButton.d.ts +11 -0
  362. package/lib/typescript/components/GoogleButton.d.ts.map +1 -0
  363. package/lib/typescript/components/HeadingGroup.d.ts +11 -0
  364. package/lib/typescript/components/HeadingGroup.d.ts.map +1 -0
  365. package/lib/typescript/components/ModalHeader.d.ts +11 -0
  366. package/lib/typescript/components/ModalHeader.d.ts.map +1 -0
  367. package/lib/typescript/components/ModalSheet.d.ts +13 -0
  368. package/lib/typescript/components/ModalSheet.d.ts.map +1 -0
  369. package/lib/typescript/components/Onairos.d.ts.map +1 -1
  370. package/lib/typescript/components/OnairosButton.d.ts +29 -4
  371. package/lib/typescript/components/OnairosButton.d.ts.map +1 -1
  372. package/lib/typescript/components/OnairosSignInButton.d.ts +14 -0
  373. package/lib/typescript/components/OnairosSignInButton.d.ts.map +1 -0
  374. package/lib/typescript/components/PersonaImage.d.ts +8 -0
  375. package/lib/typescript/components/PersonaImage.d.ts.map +1 -0
  376. package/lib/typescript/components/PersonaLoadingScreen.d.ts +10 -0
  377. package/lib/typescript/components/PersonaLoadingScreen.d.ts.map +1 -0
  378. package/lib/typescript/components/PersonalizationConsentScreen.d.ts +10 -0
  379. package/lib/typescript/components/PersonalizationConsentScreen.d.ts.map +1 -0
  380. package/lib/typescript/components/PinCreationScreen.d.ts +10 -0
  381. package/lib/typescript/components/PinCreationScreen.d.ts.map +1 -0
  382. package/lib/typescript/components/PinInput.d.ts +11 -1
  383. package/lib/typescript/components/PinInput.d.ts.map +1 -1
  384. package/lib/typescript/components/PlatformConnectorsStep.d.ts +11 -0
  385. package/lib/typescript/components/PlatformConnectorsStep.d.ts.map +1 -0
  386. package/lib/typescript/components/PlatformToggle.d.ts +20 -0
  387. package/lib/typescript/components/PlatformToggle.d.ts.map +1 -0
  388. package/lib/typescript/components/PrimaryButton.d.ts +22 -0
  389. package/lib/typescript/components/PrimaryButton.d.ts.map +1 -0
  390. package/lib/typescript/components/SignInMatchAnimation.d.ts +9 -0
  391. package/lib/typescript/components/SignInMatchAnimation.d.ts.map +1 -0
  392. package/lib/typescript/components/SignInStep.d.ts +12 -0
  393. package/lib/typescript/components/SignInStep.d.ts.map +1 -0
  394. package/lib/typescript/components/TrainingModal.d.ts +12 -1
  395. package/lib/typescript/components/TrainingModal.d.ts.map +1 -1
  396. package/lib/typescript/components/UniversalOnboarding.d.ts +14 -1
  397. package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
  398. package/lib/typescript/components/VerificationStep.d.ts +13 -0
  399. package/lib/typescript/components/VerificationStep.d.ts.map +1 -0
  400. package/lib/typescript/components/WelcomeScreen.d.ts +9 -0
  401. package/lib/typescript/components/WelcomeScreen.d.ts.map +1 -0
  402. package/lib/typescript/components/icons/Basicproficon.d.ts +5 -0
  403. package/lib/typescript/components/icons/Basicproficon.d.ts.map +1 -0
  404. package/lib/typescript/components/icons/Basicprofile.d.ts +5 -0
  405. package/lib/typescript/components/icons/Basicprofile.d.ts.map +1 -0
  406. package/lib/typescript/components/icons/Checkbox.d.ts +5 -0
  407. package/lib/typescript/components/icons/Checkbox.d.ts.map +1 -0
  408. package/lib/typescript/components/icons/Checkmark.d.ts +5 -0
  409. package/lib/typescript/components/icons/Checkmark.d.ts.map +1 -0
  410. package/lib/typescript/components/icons/Contentanalysis.d.ts +5 -0
  411. package/lib/typescript/components/icons/Contentanalysis.d.ts.map +1 -0
  412. package/lib/typescript/components/icons/Contenticon.d.ts +5 -0
  413. package/lib/typescript/components/icons/Contenticon.d.ts.map +1 -0
  414. package/lib/typescript/components/icons/EnochE.d.ts +5 -0
  415. package/lib/typescript/components/icons/EnochE.d.ts.map +1 -0
  416. package/lib/typescript/components/icons/Personalityicon.d.ts +5 -0
  417. package/lib/typescript/components/icons/Personalityicon.d.ts.map +1 -0
  418. package/lib/typescript/components/icons/Personalityprofile.d.ts +5 -0
  419. package/lib/typescript/components/icons/Personalityprofile.d.ts.map +1 -0
  420. package/lib/typescript/components/icons/Personalitytraits.d.ts +5 -0
  421. package/lib/typescript/components/icons/Personalitytraits.d.ts.map +1 -0
  422. package/lib/typescript/components/icons/Userpreferences.d.ts +5 -0
  423. package/lib/typescript/components/icons/Userpreferences.d.ts.map +1 -0
  424. package/lib/typescript/components/icons/index.d.ts +12 -0
  425. package/lib/typescript/components/icons/index.d.ts.map +1 -0
  426. package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +1 -1
  427. package/lib/typescript/config/api.d.ts +24 -0
  428. package/lib/typescript/config/api.d.ts.map +1 -0
  429. package/lib/typescript/context/AuthContext.d.ts +34 -0
  430. package/lib/typescript/context/AuthContext.d.ts.map +1 -0
  431. package/lib/typescript/hooks/useConnectedAccounts.d.ts +11 -0
  432. package/lib/typescript/hooks/useConnectedAccounts.d.ts.map +1 -0
  433. package/lib/typescript/hooks/useConnections.d.ts +10 -5
  434. package/lib/typescript/hooks/useConnections.d.ts.map +1 -1
  435. package/lib/typescript/hooks/useUserConnections.d.ts +12 -0
  436. package/lib/typescript/hooks/useUserConnections.d.ts.map +1 -0
  437. package/lib/typescript/index.d.ts +24 -6
  438. package/lib/typescript/index.d.ts.map +1 -1
  439. package/lib/typescript/services/apiClient.d.ts +91 -0
  440. package/lib/typescript/services/apiClient.d.ts.map +1 -0
  441. package/lib/typescript/services/apiKeyService.d.ts.map +1 -1
  442. package/lib/typescript/services/authService.d.ts +216 -0
  443. package/lib/typescript/services/authService.d.ts.map +1 -0
  444. package/lib/typescript/services/biometricPinService.d.ts +29 -0
  445. package/lib/typescript/services/biometricPinService.d.ts.map +1 -0
  446. package/lib/typescript/services/connectedAccountsService.d.ts +56 -0
  447. package/lib/typescript/services/connectedAccountsService.d.ts.map +1 -0
  448. package/lib/typescript/services/googleAuthService.d.ts +63 -0
  449. package/lib/typescript/services/googleAuthService.d.ts.map +1 -0
  450. package/lib/typescript/services/imageCompressionService.d.ts +37 -0
  451. package/lib/typescript/services/imageCompressionService.d.ts.map +1 -0
  452. package/lib/typescript/services/jwtStorageService.d.ts +86 -0
  453. package/lib/typescript/services/jwtStorageService.d.ts.map +1 -0
  454. package/lib/typescript/services/mobileTrainingService.d.ts +45 -0
  455. package/lib/typescript/services/mobileTrainingService.d.ts.map +1 -0
  456. package/lib/typescript/services/pinEncryptionService.d.ts +17 -0
  457. package/lib/typescript/services/pinEncryptionService.d.ts.map +1 -0
  458. package/lib/typescript/services/pinStorageUtils.d.ts +25 -0
  459. package/lib/typescript/services/pinStorageUtils.d.ts.map +1 -0
  460. package/lib/typescript/services/platformAuthService.d.ts +34 -109
  461. package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
  462. package/lib/typescript/services/storageService.d.ts +128 -0
  463. package/lib/typescript/services/storageService.d.ts.map +1 -0
  464. package/lib/typescript/services/trainingApiHelpers.d.ts +38 -0
  465. package/lib/typescript/services/trainingApiHelpers.d.ts.map +1 -0
  466. package/lib/typescript/services/userConnectionsService.d.ts +90 -0
  467. package/lib/typescript/services/userConnectionsService.d.ts.map +1 -0
  468. package/lib/typescript/services/youtubeMigrationService.d.ts +12 -0
  469. package/lib/typescript/services/youtubeMigrationService.d.ts.map +1 -0
  470. package/lib/typescript/theme/index.d.ts +416 -0
  471. package/lib/typescript/theme/index.d.ts.map +1 -0
  472. package/lib/typescript/types/index.d.ts +39 -0
  473. package/lib/typescript/types/index.d.ts.map +1 -1
  474. package/lib/typescript/utils/eventUtils.d.ts +108 -0
  475. package/lib/typescript/utils/eventUtils.d.ts.map +1 -0
  476. package/lib/typescript/utils/haptics.d.ts +11 -0
  477. package/lib/typescript/utils/haptics.d.ts.map +1 -0
  478. package/lib/typescript/utils/imagePreloader.d.ts +2 -0
  479. package/lib/typescript/utils/imagePreloader.d.ts.map +1 -0
  480. package/package.json +158 -145
  481. package/src/api/index.ts +41 -0
  482. package/src/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
  483. package/src/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  484. package/src/assets/icons/Facebookicon.png +0 -0
  485. package/src/assets/icons/Gmail.png +0 -0
  486. package/src/assets/icons/Linkedinicon.png +0 -0
  487. package/src/assets/icons/Redditicon.png +0 -0
  488. package/src/assets/icons/YouTubeicon2.png +0 -0
  489. package/src/assets/icons/YouTubeicon3.png +0 -0
  490. package/src/assets/icons/farcaster.png +0 -0
  491. package/src/assets/icons/instagram.png +0 -0
  492. package/src/assets/icons/pinterest.png +0 -0
  493. package/src/assets/icons/swerv_logo.png +0 -0
  494. package/src/assets/icons/twitter.jpg +0 -0
  495. package/src/assets/images/Checkbox.svg +3 -0
  496. package/src/assets/images/EnochE.svg +19 -0
  497. package/src/assets/images/Enochicon1.png +0 -0
  498. package/src/assets/images/Face_ID_logo.png +0 -0
  499. package/src/assets/images/Facebookicon.png +0 -0
  500. package/src/assets/images/Gmail.png +0 -0
  501. package/src/assets/images/Googlelogo.png +0 -0
  502. package/src/assets/images/Linkedinicon.png +0 -0
  503. package/src/assets/images/Onairoslogo.png +0 -0
  504. package/src/assets/images/Personalityprofile.svg +3 -0
  505. package/src/assets/images/Personalitytraits.svg +3 -0
  506. package/src/assets/images/Redditicon.png +0 -0
  507. package/src/assets/images/Userpreferences.svg +3 -0
  508. package/src/assets/images/YouTubeicon3.png +0 -0
  509. package/src/assets/images/arrow.svg +20 -0
  510. package/src/assets/images/basicproficon.svg +43 -0
  511. package/src/assets/images/basicprofile.svg +3 -0
  512. package/src/assets/images/checkmark.svg +4 -0
  513. package/src/assets/images/contentanalysis.svg +3 -0
  514. package/src/assets/images/contenticon.svg +23 -0
  515. package/src/assets/images/persona1.png +0 -0
  516. package/src/assets/images/persona2.png +0 -0
  517. package/src/assets/images/persona3.png +0 -0
  518. package/src/assets/images/persona4.png +0 -0
  519. package/src/assets/images/persona5.png +0 -0
  520. package/src/assets/images/personalityicon.svg +18 -0
  521. package/src/assets/images/x-close.svg +3 -0
  522. package/src/components/BodyText.tsx +33 -0
  523. package/src/components/BrandMark.tsx +62 -0
  524. package/src/components/CodeInput.tsx +32 -0
  525. package/src/components/EmailInput.tsx +31 -0
  526. package/src/components/ExistingUserDataConfirmation.tsx +507 -0
  527. package/src/components/GoogleButton.tsx +55 -0
  528. package/src/components/HeadingGroup.tsx +49 -0
  529. package/src/components/ModalHeader.tsx +125 -0
  530. package/src/components/ModalSheet.tsx +57 -0
  531. package/src/components/Onairos.tsx +422 -424
  532. package/src/components/OnairosButton.tsx +339 -359
  533. package/src/components/OnairosSignInButton.tsx +166 -0
  534. package/src/components/Overlay.tsx +506 -506
  535. package/src/components/PersonaImage.tsx +79 -0
  536. package/src/components/PersonaLoadingScreen.tsx +201 -0
  537. package/src/components/PersonalizationConsentScreen.tsx +410 -0
  538. package/src/components/PinCreationScreen.tsx +492 -0
  539. package/src/components/PinInput.tsx +555 -343
  540. package/src/components/PlatformConnectorsStep.tsx +892 -0
  541. package/src/components/PlatformToggle.tsx +226 -0
  542. package/src/components/PrimaryButton.tsx +214 -0
  543. package/src/components/SignInMatchAnimation.tsx +225 -0
  544. package/src/components/SignInStep.tsx +217 -0
  545. package/src/components/TrainingModal.tsx +1047 -737
  546. package/src/components/UniversalOnboarding.tsx +2888 -1820
  547. package/src/components/VerificationStep.tsx +198 -0
  548. package/src/components/WelcomeScreen.tsx +473 -0
  549. package/src/components/icons/Basicproficon.tsx +30 -0
  550. package/src/components/icons/Basicprofile.tsx +17 -0
  551. package/src/components/icons/Checkbox.tsx +17 -0
  552. package/src/components/icons/Checkmark.tsx +24 -0
  553. package/src/components/icons/Contentanalysis.tsx +17 -0
  554. package/src/components/icons/Contenticon.tsx +30 -0
  555. package/src/components/icons/EnochE.tsx +39 -0
  556. package/src/components/icons/Personalityicon.tsx +22 -0
  557. package/src/components/icons/Personalityprofile.tsx +17 -0
  558. package/src/components/icons/Personalitytraits.tsx +17 -0
  559. package/src/components/icons/Userpreferences.tsx +17 -0
  560. package/src/components/icons/index.ts +12 -0
  561. package/src/components/onboarding/OAuthWebView.tsx +232 -838
  562. package/src/config/api.ts +25 -0
  563. package/src/context/AuthContext.tsx +393 -0
  564. package/src/hooks/useConnectedAccounts.ts +139 -0
  565. package/src/hooks/useConnections.ts +129 -131
  566. package/src/hooks/useUserConnections.ts +166 -0
  567. package/src/index.ts +94 -49
  568. package/src/services/apiClient.ts +337 -0
  569. package/src/services/apiKeyService.ts +9 -11
  570. package/src/services/authService.ts +1008 -0
  571. package/src/services/biometricPinService.ts +193 -0
  572. package/src/services/connectedAccountsService.ts +290 -0
  573. package/src/services/googleAuthService.ts +279 -0
  574. package/src/services/imageCompressionService.ts +303 -0
  575. package/src/services/jwtStorageService.ts +257 -0
  576. package/src/services/mobileTrainingService.ts +204 -0
  577. package/src/services/pinEncryptionService.ts +76 -0
  578. package/src/services/pinStorageUtils.ts +97 -0
  579. package/src/services/platformAuthService.ts +1346 -1113
  580. package/src/services/storageService.ts +452 -0
  581. package/src/services/trainingApiHelpers.ts +67 -0
  582. package/src/services/userConnectionsService.ts +557 -0
  583. package/src/services/youtubeMigrationService.ts +454 -0
  584. package/src/theme/index.ts +239 -0
  585. package/src/types/index.ts +265 -238
  586. package/src/utils/eventUtils.ts +303 -0
  587. package/src/utils/haptics.ts +59 -0
  588. package/src/utils/imagePreloader.ts +2 -0
  589. package/README.md +0 -375
  590. package/lib/commonjs/assets/images/email.png +0 -0
  591. package/lib/commonjs/assets/images/linkedin.png +0 -0
  592. package/lib/commonjs/assets/images/reddit.png +0 -0
  593. package/lib/commonjs/assets/images/youtube.png +0 -0
  594. package/lib/commonjs/components/UniversalOnboarding.tsx.new +0 -455
  595. package/lib/module/assets/images/email.png +0 -0
  596. package/lib/module/assets/images/linkedin.png +0 -0
  597. package/lib/module/assets/images/reddit.png +0 -0
  598. package/lib/module/assets/images/youtube.png +0 -0
  599. package/lib/module/components/UniversalOnboarding.tsx.new +0 -455
  600. package/src/assets/images/email.png +0 -0
  601. package/src/assets/images/linkedin.png +0 -0
  602. package/src/assets/images/reddit.png +0 -0
  603. package/src/assets/images/youtube.png +0 -0
  604. package/src/components/UniversalOnboarding.tsx.new +0 -455
@@ -1,390 +1,743 @@
1
- import AsyncStorage from '@react-native-async-storage/async-storage';
2
- import { makeDeveloperRequest, getApiConfig, storeJWT, extractUsernameFromJWT } from './apiKeyService';
3
-
4
- // ๐Ÿ”‘ CRITICAL: Use two-tier authentication system
5
- // - Developer API key for email verification requests
6
- // - JWT tokens for user-authenticated requests after email verification
7
-
8
- /**
9
- * Initialize the platform auth service
10
- * This service now uses the two-tier authentication system
1
+ /**
2
+ * Platform Authentication Service
3
+ * Handles OAuth flows for different platforms
11
4
  */
12
- export const initializePlatformAuthService = async () => {
13
- try {
14
- // Check if app is already initialized with API key
15
- const existingConfig = getApiConfig();
16
- if (existingConfig && existingConfig.apiKey) {
17
- console.log('๐Ÿ”‘ Platform auth service using existing app configuration');
18
- console.log(`โœ… Environment: ${existingConfig.environment}`);
19
- return;
20
- }
21
5
 
22
- // If no app initialization, we can't proceed
23
- console.error('โŒ Platform auth service requires app-level API key initialization');
24
- throw new Error('Platform auth service requires app-level API key initialization. Please call initializeApiKey() first.');
25
- } catch (error) {
26
- console.error('โŒ Failed to initialize platform auth service:', error);
27
- throw error;
28
- }
29
- };
6
+ import { GoogleSignin, statusCodes } from '@react-native-google-signin/google-signin';
7
+ import AsyncStorage from '@react-native-async-storage/async-storage';
8
+ import { API_CONFIG, getApiHeaders } from '../config/api';
30
9
 
31
- // Configuration for each platform's authentication
32
- let PLATFORM_AUTH_CONFIG = {
10
+ // ๐Ÿ”‘ CRITICAL: Using the same client ID for both web and iOS to avoid audience errors
11
+ const WEB_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
12
+ const IOS_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
13
+ // OAuth configuration for different platforms
14
+ const OAUTH_CONFIG = {
33
15
  instagram: {
34
- hasNativeSDK: false,
35
- // Instagram uses OAuth WebView flow
36
- authEndpoint: '/instagram/authorize',
37
- color: '#E1306C'
16
+ authUrl: 'https://api.instagram.com/oauth/authorize',
17
+ clientId: 'demo_instagram_client_id',
18
+ redirectUri: 'onairosevents://auth/callback',
19
+ scope: 'user_profile,user_media',
20
+ responseType: 'code',
21
+ hasNativeSDK: false
38
22
  },
39
23
  youtube: {
40
- hasNativeSDK: true,
41
- // Native Google Sign-In SDK enabled
42
- nativeSDKPackage: '@react-native-google-signin/google-signin',
43
- authEndpoint: '/youtube/authorize',
44
- color: '#FF0000',
24
+ authUrl: 'https://api2.onairos.uk/youtube/authorize',
45
25
  clientId: '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com',
46
26
  redirectUri: 'onairosevents://auth/callback',
47
27
  scope: 'https://www.googleapis.com/auth/youtube.readonly',
48
- responseType: 'code'
28
+ responseType: 'code',
29
+ hasNativeSDK: true // Changed to true for native SDK
49
30
  },
50
31
  reddit: {
51
- hasNativeSDK: false,
52
- authEndpoint: '/reddit/authorize',
53
- color: '#FF4500'
32
+ authUrl: 'https://api2.onairos.uk/reddit/authorize',
33
+ clientId: 'demo_reddit_client_id',
34
+ redirectUri: 'onairosevents://auth/callback',
35
+ scope: 'identity,read',
36
+ responseType: 'code',
37
+ hasNativeSDK: false
54
38
  },
55
39
  pinterest: {
56
- hasNativeSDK: false,
57
- authEndpoint: '/pinterest/authorize',
58
- color: '#E60023'
40
+ authUrl: 'https://api2.onairos.uk/pinterest/authorize',
41
+ clientId: 'demo_pinterest_client_id',
42
+ redirectUri: 'onairosevents://auth/callback',
43
+ scope: 'boards:read,pins:read',
44
+ responseType: 'code',
45
+ hasNativeSDK: false
46
+ },
47
+ facebook: {
48
+ authUrl: 'https://www.facebook.com/v12.0/dialog/oauth',
49
+ clientId: 'demo_facebook_client_id',
50
+ redirectUri: 'onairosevents://auth/callback',
51
+ scope: 'public_profile,email',
52
+ responseType: 'code',
53
+ hasNativeSDK: false
54
+ },
55
+ // GitHub connector is temporarily commented out
56
+ // github: {
57
+ // authUrl: 'https://github.com/login/oauth/authorize',
58
+ // clientId: 'demo_github_client_id',
59
+ // redirectUri: 'onairosevents://auth/callback',
60
+ // scope: 'repo,user',
61
+ // responseType: 'code',
62
+ // hasNativeSDK: false
63
+ // },
64
+ linkedin: {
65
+ authUrl: 'https://api2.onairos.uk/linkedin/authorize',
66
+ clientId: '',
67
+ // No client ID needed - backend handles OAuth
68
+ redirectUri: 'onairosevents://auth/callback',
69
+ scope: 'openid profile email',
70
+ // Updated to OpenID Connect scopes as per your backend
71
+ responseType: 'code',
72
+ hasNativeSDK: false // LinkedIn has no modern native SDK
73
+ },
74
+ gmail: {
75
+ authUrl: 'https://api2.onairos.uk/gmail/authorize',
76
+ clientId: 'demo_gmail_client_id',
77
+ redirectUri: 'onairosevents://auth/callback',
78
+ scope: 'https://www.googleapis.com/auth/gmail.readonly',
79
+ responseType: 'code',
80
+ hasNativeSDK: false
59
81
  },
60
82
  email: {
83
+ // Email doesn't use OAuth but we still need to handle it in the flow
61
84
  hasNativeSDK: false,
62
- authEndpoint: '/gmail/authorize',
63
- color: '#4285F4'
85
+ authUrl: 'https://api2.onairos.uk/email/authorize' // Proxy endpoint for email verification
64
86
  }
65
87
  };
66
88
 
67
- /**
68
- * Checks if a native SDK is available for the given platform
89
+ /**
90
+ * Check if the platform has a native SDK
69
91
  */
70
92
  export const hasNativeSDK = platform => {
71
- const config = PLATFORM_AUTH_CONFIG[platform];
72
- return (config === null || config === void 0 ? void 0 : config.hasNativeSDK) || false;
93
+ var _OAUTH_CONFIG$platfor;
94
+ return ((_OAUTH_CONFIG$platfor = OAUTH_CONFIG[platform]) === null || _OAUTH_CONFIG$platfor === void 0 ? void 0 : _OAUTH_CONFIG$platfor.hasNativeSDK) || false;
73
95
  };
74
96
 
75
- /**
76
- * Gets the auth endpoint URL for a platform
97
+ /**
98
+ * Initiate OAuth flow for a platform
77
99
  */
78
- export const getAuthEndpoint = platform => {
79
- const config = PLATFORM_AUTH_CONFIG[platform];
80
- return (config === null || config === void 0 ? void 0 : config.authEndpoint) || '';
100
+ export const initiateOAuth = async (platform, username) => {
101
+ try {
102
+ console.log(`๐Ÿš€ [OAUTH] Starting OAuth for platform: ${platform}, username: "${username}"`);
103
+
104
+ // Validate username
105
+ if (!username || username.trim() === '') {
106
+ console.error(`โŒ [OAUTH] Username is required for ${platform} OAuth`);
107
+ return null;
108
+ }
109
+
110
+ // For platforms that don't need OAuth (like email), handle differently
111
+ if (platform === 'email') {
112
+ console.log('๐Ÿ“ง [OAUTH] Email platform selected, returning mock auth URL');
113
+ return 'https://api2.onairos.uk/email/authorize?action=verify';
114
+ }
115
+
116
+ // Construct the proxy URL
117
+ const proxyUrl = `https://api2.onairos.uk/${platform}/authorize`;
118
+ console.log(`๐ŸŒ [OAUTH] Proxy URL: ${proxyUrl}`);
119
+ const requestBody = {
120
+ session: {
121
+ username: username.trim(),
122
+ platform: platform,
123
+ timestamp: new Date().toISOString()
124
+ }
125
+ };
126
+ console.log(`๐Ÿ“ค [OAUTH] Request body:`, requestBody);
127
+ console.log(`๐Ÿ”‘ [OAUTH] Headers:`, getApiHeaders());
128
+
129
+ // Make a POST request to the proxy
130
+ const response = await fetch(proxyUrl, {
131
+ method: 'POST',
132
+ headers: getApiHeaders(),
133
+ body: JSON.stringify(requestBody)
134
+ });
135
+ console.log(`๐Ÿ“ก [OAUTH] Response status: ${response.status} ${response.statusText}`);
136
+ if (!response.ok) {
137
+ const errorText = await response.text();
138
+ console.error(`โŒ [OAUTH] Error initiating OAuth for ${platform}: ${response.status} - ${errorText}`);
139
+ return null;
140
+ }
141
+ const data = await response.json();
142
+ console.log(`๐Ÿ“‹ [OAUTH] Response data for ${platform}:`, data);
143
+
144
+ // Get the authorization URL from the response
145
+ // Different platforms might use different keys (e.g., pinterestURL, youtubeURL)
146
+ const urlKey = `${platform}URL`;
147
+ const authUrl = data[urlKey] || data.url || null;
148
+ console.log(`๐Ÿ”— [OAUTH] Auth URL for ${platform} (key: ${urlKey}):`, authUrl);
149
+ return authUrl;
150
+ } catch (error) {
151
+ console.error(`Error initiating OAuth for ${platform}:`, error);
152
+ return null;
153
+ }
81
154
  };
82
155
 
83
- /**
84
- * Gets the color associated with a platform
156
+ /**
157
+ * Initialize Google Sign-In configuration with enhanced refresh token support
158
+ * Updated with CRITICAL parameters for refresh token generation
85
159
  */
86
- export const getPlatformColor = platform => {
87
- const config = PLATFORM_AUTH_CONFIG[platform];
88
- return (config === null || config === void 0 ? void 0 : config.color) || '#000000';
160
+ const initializeGoogleSignIn = () => {
161
+ GoogleSignin.configure({
162
+ webClientId: WEB_CLIENT_ID,
163
+ // โœ… CRITICAL: Web client ID for refresh tokens
164
+ iosClientId: IOS_CLIENT_ID,
165
+ // โœ… iOS client ID for native auth
166
+
167
+ // ๐Ÿ”‘ CRITICAL: These parameters are REQUIRED for refresh tokens
168
+ offlineAccess: true,
169
+ // โ† CRITICAL: Enables refresh tokens
170
+ forceCodeForRefreshToken: true,
171
+ // โ† CRITICAL: Forces refresh token generation
172
+
173
+ // โœ… Enhanced scopes for YouTube
174
+ scopes: ['https://www.googleapis.com/auth/youtube.readonly', 'openid', 'profile', 'email'],
175
+ // โœ… Clear settings to avoid conflicts
176
+ hostedDomain: '',
177
+ accountName: ''
178
+ });
89
179
  };
90
180
 
91
- /**
92
- * Initiates the OAuth flow for a platform
93
- * @param platform The platform to authenticate with
94
- * @param username The username to associate with the authentication
95
- * @param appName The app name to use for the OAuth session (optional)
96
- * @returns A Promise that resolves to the OAuth URL to open in a WebView or null if using native SDK
181
+ /**
182
+ * Force YouTube reconnection with consent screen to get refresh tokens
183
+ * This is the key function to fix YouTube token expiry issues
97
184
  */
98
- export const initiateOAuth = async (platform, username, appName) => {
185
+ export const forceYouTubeReconnectionWithConsent = async username => {
99
186
  try {
100
- console.log('๐Ÿš€ Initiating OAuth for platform:', platform);
101
- console.log('๐Ÿ‘ค Username:', username);
102
- console.log('๐Ÿ“ฑ App name:', appName);
103
-
104
- // Check if the platform is supported
105
- if (!PLATFORM_AUTH_CONFIG[platform]) {
106
- console.error('โŒ Unsupported platform:', platform);
107
- throw new Error(`Unsupported platform: ${platform}`);
108
- }
187
+ var _userInfo$data, _userInfo$data2, _userInfo$data3;
188
+ console.log('๐Ÿ”„ FORCING fresh YouTube consent for refresh token...');
189
+ console.log('๐Ÿ‘ค User:', username);
109
190
 
110
- // Check if platform has a native SDK
111
- if (PLATFORM_AUTH_CONFIG[platform].hasNativeSDK) {
112
- console.log('๐Ÿ“ฑ Platform uses native SDK, returning null');
113
- // Return null to indicate that we should use the native SDK
114
- return null;
191
+ // Step 1: โœ… CRITICAL: Complete sign out (clears all cached consent)
192
+ try {
193
+ await GoogleSignin.signOut();
194
+ console.log('โœ… Signed out - consent cache cleared');
195
+ } catch (signOutError) {
196
+ console.log('โ„น๏ธ Sign out not needed:', signOutError);
115
197
  }
116
- console.log('๐ŸŒ Platform uses OAuth WebView flow');
117
- console.log('๐Ÿ”— Auth endpoint:', PLATFORM_AUTH_CONFIG[platform].authEndpoint);
118
-
119
- // Pre-flight connectivity check
120
- console.log('๐Ÿ” Performing pre-flight connectivity check...');
121
- const connectivityResult = await testApiConnectivity();
122
- if (!connectivityResult.success) {
123
- console.error('โŒ Pre-flight connectivity check failed:', connectivityResult.error);
124
- throw new Error(`Cannot reach authentication server: ${connectivityResult.error}`);
198
+
199
+ // Step 2: โœ… CRITICAL: Clear cached tokens if available
200
+ try {
201
+ const existingTokens = await GoogleSignin.getTokens();
202
+ if (existingTokens.accessToken) {
203
+ await GoogleSignin.clearCachedAccessToken(existingTokens.accessToken);
204
+ console.log('โœ… Token cache cleared');
205
+ }
206
+ } catch (clearError) {
207
+ console.log('โ„น๏ธ No token cache to clear');
125
208
  }
126
- console.log('โœ… Pre-flight connectivity check passed');
127
209
 
128
- // Handle Instagram with specific API format
129
- if (platform === 'instagram') {
130
- const state = 'djksbfds';
131
- const jsonData = {
210
+ // Step 3: โœ… CRITICAL: Configure Google Sign-In for FORCED consent
211
+ console.log('๐Ÿ”ง Configuring Google Sign-In for forced consent...');
212
+ GoogleSignin.configure({
213
+ webClientId: WEB_CLIENT_ID,
214
+ // โœ… CRITICAL: Web client ID for refresh tokens
215
+ iosClientId: IOS_CLIENT_ID,
216
+ // โœ… iOS client ID for native auth
217
+
218
+ // ๐Ÿ”‘ FORCE REFRESH TOKEN SETTINGS:
219
+ offlineAccess: true,
220
+ // Request offline access
221
+ forceCodeForRefreshToken: true,
222
+ // Force refresh token generation
223
+
224
+ // ๐Ÿ”‘ FORCE CONSENT SCREEN:
225
+ scopes: ['https://www.googleapis.com/auth/youtube.readonly', 'openid', 'profile', 'email'],
226
+ // โœ… CRITICAL: Clear settings to force fresh consent
227
+ hostedDomain: '',
228
+ accountName: ''
229
+ });
230
+
231
+ // Step 4: โœ… Check Play Services
232
+ await GoogleSignin.hasPlayServices();
233
+ console.log('โœ… Play Services available');
234
+
235
+ // Step 5: โœ… CRITICAL: Sign in (this SHOULD show consent screen)
236
+ console.log('๐Ÿ” Initiating sign-in - consent screen should appear...');
237
+ console.log('๐Ÿ“ฑ User should see: "Allow [App] to access your YouTube account when you\'re not using the app?"');
238
+ const userInfo = await GoogleSignin.signIn();
239
+ console.log('โœ… Sign-in completed - checking for refresh token...');
240
+ console.log('๐Ÿ‘ค User email:', (_userInfo$data = userInfo.data) === null || _userInfo$data === void 0 || (_userInfo$data = _userInfo$data.user) === null || _userInfo$data === void 0 ? void 0 : _userInfo$data.email);
241
+
242
+ // Step 6: โœ… Get tokens after consent
243
+ const tokens = await GoogleSignin.getTokens();
244
+ const currentUser = await GoogleSignin.getCurrentUser();
245
+ console.log('๐Ÿ“‹ FULL userInfo object from forceYouTubeReconnectionWithConsent:');
246
+ console.log(JSON.stringify(userInfo, null, 2));
247
+ console.log('๐Ÿ“‹ FULL tokens object from forceYouTubeReconnectionWithConsent:');
248
+ console.log(JSON.stringify(tokens, null, 2));
249
+ console.log('๐Ÿ“‹ FULL currentUser object from forceYouTubeReconnectionWithConsent:');
250
+ console.log(JSON.stringify(currentUser, null, 2));
251
+ console.log('๐Ÿ” Token analysis:');
252
+ console.log('- Access token:', tokens.accessToken ? `${tokens.accessToken.substring(0, 20)}...` : 'Missing');
253
+ console.log('- ID token:', tokens.idToken ? 'Present' : 'Missing');
254
+ console.log('- ServerAuthCode (userInfo):', (_userInfo$data2 = userInfo.data) !== null && _userInfo$data2 !== void 0 && _userInfo$data2.serverAuthCode ? `${userInfo.data.serverAuthCode.substring(0, 20)}...` : 'Missing');
255
+ console.log('- ServerAuthCode (currentUser):', currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode ? `${currentUser.serverAuthCode.substring(0, 20)}...` : 'Missing');
256
+
257
+ // Step 7: โœ… Extract refresh capability
258
+ const refreshToken = ((_userInfo$data3 = userInfo.data) === null || _userInfo$data3 === void 0 ? void 0 : _userInfo$data3.serverAuthCode) || (currentUser === null || currentUser === void 0 ? void 0 : currentUser.serverAuthCode);
259
+ if (refreshToken) {
260
+ var _userInfo$data0, _userInfo$data1, _userInfo$data10, _userInfo$data11, _userInfo$data12, _userInfo$data13;
261
+ console.log('โœ… SUCCESS: Got refresh token after consent!');
262
+ console.log('๐Ÿ”‘ Refresh token type:', refreshToken.startsWith('4/') ? 'serverAuthCode' : 'refreshToken');
263
+ console.log('๐Ÿ”‘ Refresh token preview:', `${refreshToken.substring(0, 20)}...`);
264
+
265
+ // Step 8: โœ… Get YouTube channel info
266
+ let channelName = 'Unknown Channel';
267
+ let channelId = null;
268
+ try {
269
+ console.log('๐Ÿ“บ Fetching YouTube channel information...');
270
+ const channelResponse = await fetch('https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true', {
271
+ headers: {
272
+ 'Authorization': `Bearer ${tokens.accessToken}`,
273
+ 'Accept': 'application/json'
274
+ }
275
+ });
276
+ if (channelResponse.ok) {
277
+ const channelData = await channelResponse.json();
278
+ if (channelData.items && channelData.items.length > 0) {
279
+ channelName = channelData.items[0].snippet.title;
280
+ channelId = channelData.items[0].id;
281
+ console.log('โœ… YouTube channel found:', channelName, 'ID:', channelId);
282
+ } else {
283
+ var _userInfo$data4, _userInfo$data5;
284
+ console.log('โš ๏ธ No YouTube channel found for user');
285
+ channelName = ((_userInfo$data4 = userInfo.data) === null || _userInfo$data4 === void 0 || (_userInfo$data4 = _userInfo$data4.user) === null || _userInfo$data4 === void 0 ? void 0 : _userInfo$data4.name) || ((_userInfo$data5 = userInfo.data) === null || _userInfo$data5 === void 0 || (_userInfo$data5 = _userInfo$data5.user) === null || _userInfo$data5 === void 0 ? void 0 : _userInfo$data5.email) || 'No Channel';
286
+ }
287
+ } else {
288
+ var _userInfo$data6, _userInfo$data7;
289
+ console.log('โš ๏ธ Failed to fetch YouTube channel info:', channelResponse.status);
290
+ channelName = ((_userInfo$data6 = userInfo.data) === null || _userInfo$data6 === void 0 || (_userInfo$data6 = _userInfo$data6.user) === null || _userInfo$data6 === void 0 ? void 0 : _userInfo$data6.name) || ((_userInfo$data7 = userInfo.data) === null || _userInfo$data7 === void 0 || (_userInfo$data7 = _userInfo$data7.user) === null || _userInfo$data7 === void 0 ? void 0 : _userInfo$data7.email) || 'Unknown Channel';
291
+ }
292
+ } catch (channelError) {
293
+ var _userInfo$data8, _userInfo$data9;
294
+ console.log('โš ๏ธ Error fetching YouTube channel info:', channelError);
295
+ channelName = ((_userInfo$data8 = userInfo.data) === null || _userInfo$data8 === void 0 || (_userInfo$data8 = _userInfo$data8.user) === null || _userInfo$data8 === void 0 ? void 0 : _userInfo$data8.name) || ((_userInfo$data9 = userInfo.data) === null || _userInfo$data9 === void 0 || (_userInfo$data9 = _userInfo$data9.user) === null || _userInfo$data9 === void 0 ? void 0 : _userInfo$data9.email) || 'Unknown Channel';
296
+ }
297
+
298
+ // Step 9: โœ… Get authentication token
299
+ let authToken = (await AsyncStorage.getItem('onairos_jwt_token')) || (await AsyncStorage.getItem('enoch_token')) || (await AsyncStorage.getItem('auth_token'));
300
+ if (!authToken || authToken.trim().length < 20) {
301
+ console.log('๐Ÿ” Creating authentication token for YouTube connection...');
302
+ // Create token logic here if needed
303
+ authToken = 'temp_token_for_youtube_connection';
304
+ }
305
+
306
+ // Step 10: โœ… Send comprehensive data to backend
307
+ const backendPayload = {
132
308
  session: {
133
- oauthState: state,
134
- username: username || 'Avatar'
309
+ username: username,
310
+ platform: 'youtube',
311
+ timestamp: new Date().toISOString(),
312
+ channelName: channelName,
313
+ channelId: channelId,
314
+ forceConsent: true // Flag to indicate this was forced consent
315
+ },
316
+ googleUser: (_userInfo$data0 = userInfo.data) === null || _userInfo$data0 === void 0 ? void 0 : _userInfo$data0.user,
317
+ accessToken: tokens.accessToken,
318
+ idToken: tokens.idToken,
319
+ refreshToken: refreshToken,
320
+ // โœ… CRITICAL: The refresh token!
321
+ serverAuthCode: refreshToken,
322
+ // โœ… Same as refresh token
323
+
324
+ // โœ… CRITICAL: Additional compatibility fields for backend
325
+ refresh_token: refreshToken,
326
+ // Snake case version
327
+ server_auth_code: refreshToken,
328
+ // Snake case version
329
+ authCode: refreshToken,
330
+ // Alternative naming
331
+
332
+ userAccountInfo: {
333
+ username: username,
334
+ email: (_userInfo$data1 = userInfo.data) === null || _userInfo$data1 === void 0 || (_userInfo$data1 = _userInfo$data1.user) === null || _userInfo$data1 === void 0 ? void 0 : _userInfo$data1.email,
335
+ authToken: authToken,
336
+ channelName: channelName,
337
+ channelId: channelId,
338
+ userIdentifier: authToken ? `user-${authToken.substring(0, 10)}` : `youtube-${(_userInfo$data10 = userInfo.data) === null || _userInfo$data10 === void 0 || (_userInfo$data10 = _userInfo$data10.user) === null || _userInfo$data10 === void 0 ? void 0 : _userInfo$data10.email}`,
339
+ googleId: (_userInfo$data11 = userInfo.data) === null || _userInfo$data11 === void 0 || (_userInfo$data11 = _userInfo$data11.user) === null || _userInfo$data11 === void 0 ? void 0 : _userInfo$data11.id,
340
+ // โœ… CRITICAL: Also include refresh token in userAccountInfo
341
+ refreshToken: refreshToken,
342
+ serverAuthCode: refreshToken
343
+ },
344
+ tokenExpiry: new Date(Date.now() + 3600 * 1000).toISOString(),
345
+ // 1 hour from now
346
+ requestRefreshToken: true,
347
+ debugInfo: {
348
+ hasRefreshToken: true,
349
+ refreshTokenType: refreshToken.startsWith('4/') ? 'serverAuthCode' : 'refreshToken',
350
+ configuredForRefresh: true,
351
+ forcedConsent: true,
352
+ consentMethod: 'signOut_and_configure',
353
+ refreshTokenValue: refreshToken // Include actual value for debugging
135
354
  }
136
355
  };
137
- console.log('๐Ÿ“ค Sending Instagram OAuth request:', jsonData);
138
- const response = await makeDeveloperRequest(PLATFORM_AUTH_CONFIG[platform].authEndpoint, {
139
- method: 'POST',
140
- body: JSON.stringify(jsonData)
356
+ console.log('๐Ÿ“ค Sending comprehensive payload with REFRESH TOKEN to backend:', {
357
+ hasAccessToken: !!backendPayload.accessToken,
358
+ hasRefreshToken: !!backendPayload.refreshToken,
359
+ hasServerAuthCode: !!backendPayload.serverAuthCode,
360
+ refreshTokenType: backendPayload.debugInfo.refreshTokenType,
361
+ userEmail: (_userInfo$data12 = userInfo.data) === null || _userInfo$data12 === void 0 || (_userInfo$data12 = _userInfo$data12.user) === null || _userInfo$data12 === void 0 ? void 0 : _userInfo$data12.email,
362
+ forcedConsent: true
141
363
  });
142
- console.log('๐Ÿ“ก Instagram OAuth response status:', response.status);
143
- if (!response.ok) {
144
- const errorText = await response.text();
145
- console.error('โŒ Instagram OAuth API error:', errorText);
146
- throw new Error(`Instagram OAuth API error: ${response.status} - ${errorText}`);
147
- }
148
- const responseData = await response.json();
149
- console.log('๐Ÿ“ฅ Instagram OAuth response data:', responseData);
150
- if (responseData.instagramURL) {
151
- console.log('โœ… Instagram OAuth URL received:', responseData.instagramURL);
152
364
 
153
- // Validate the URL before returning
154
- if (await validateOAuthUrl(responseData.instagramURL)) {
155
- return responseData.instagramURL;
365
+ // Step 11: โœ… Send to backend with ENHANCED LOGGING
366
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] ===== SENDING REAUTH SIGNAL TO BACKEND =====');
367
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] Endpoint: https://api2.onairos.uk/youtube/native-auth');
368
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] Method: POST');
369
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] Headers:', {
370
+ 'Content-Type': 'application/json',
371
+ 'Authorization': authToken ? `${authToken.substring(0, 20)}...` : 'NO AUTH TOKEN'
372
+ });
373
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] Payload Summary:', {
374
+ hasAccessToken: !!backendPayload.accessToken,
375
+ hasRefreshToken: !!backendPayload.refreshToken,
376
+ hasServerAuthCode: !!backendPayload.serverAuthCode,
377
+ refreshTokenType: backendPayload.debugInfo.refreshTokenType,
378
+ userEmail: (_userInfo$data13 = userInfo.data) === null || _userInfo$data13 === void 0 || (_userInfo$data13 = _userInfo$data13.user) === null || _userInfo$data13 === void 0 ? void 0 : _userInfo$data13.email,
379
+ channelName: channelName,
380
+ forcedConsent: true,
381
+ requestRefreshToken: true
382
+ });
383
+ console.log('๐Ÿš€ [YOUTUBE REAUTH] FULL PAYLOAD:', JSON.stringify(backendPayload, null, 2));
384
+ const backendResponse = await fetch('https://api2.onairos.uk/youtube/native-auth', {
385
+ method: 'POST',
386
+ headers: {
387
+ 'Content-Type': 'application/json',
388
+ ...(authToken && {
389
+ 'Authorization': authToken
390
+ })
391
+ },
392
+ body: JSON.stringify(backendPayload)
393
+ });
394
+ console.log('๐Ÿ“ก [YOUTUBE REAUTH] Response Status:', backendResponse.status);
395
+ console.log('๐Ÿ“ก [YOUTUBE REAUTH] Response Status Text:', backendResponse.statusText);
396
+ console.log('๐Ÿ“ก [YOUTUBE REAUTH] Response Headers:', backendResponse.headers);
397
+ if (backendResponse.ok) {
398
+ var _responseData$validat, _responseData$tempora;
399
+ const responseData = await backendResponse.json();
400
+ console.log('โœ… [YOUTUBE REAUTH] Backend Response SUCCESS:', JSON.stringify(responseData, null, 2));
401
+
402
+ // Enhanced verification with detailed logging and temporary mode detection (exact backend fields)
403
+ const isTemporaryMode = ((_responseData$validat = responseData.validation) === null || _responseData$validat === void 0 ? void 0 : _responseData$validat.isTemporaryMode) === true || ((_responseData$tempora = responseData.temporaryMode) === null || _responseData$tempora === void 0 ? void 0 : _responseData$tempora.enabled) === true || responseData.isTemporaryMode === true || responseData.message && responseData.message.includes('temporary access token mode');
404
+ if (isTemporaryMode) {
405
+ console.log('๐Ÿ”„ [YOUTUBE REAUTH] YouTube connected in temporary mode');
406
+ console.log('โœ… [YOUTUBE REAUTH] Training will work, but connection expires in ~1 hour');
407
+ console.log('๐ŸŽ‰ [YOUTUBE REAUTH] SUCCESS: Temporary YouTube connection established!');
408
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Connection Details:');
409
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Mode: Temporary (expires ~1 hour)');
410
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Training Ready: Yes');
411
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Refresh token sent:', refreshToken ? 'Yes' : 'No');
412
+ } else if (responseData.hasRefreshToken || responseData.refreshTokenReceived) {
413
+ console.log('โœ… [YOUTUBE REAUTH] Backend CONFIRMED refresh token received');
414
+ console.log('โœ… [YOUTUBE REAUTH] Response hasRefreshToken:', responseData.hasRefreshToken);
415
+ console.log('๐ŸŽ‰ [YOUTUBE REAUTH] SUCCESS: Full YouTube connection with refresh tokens!');
416
+
417
+ // CRITICAL: Print the refresh token that was sent for debugging
418
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] REFRESH TOKEN SENT TO BACKEND:');
419
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Full refresh token:', refreshToken);
420
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Refresh token type:', refreshToken.startsWith('4/') ? 'serverAuthCode' : 'refreshToken');
421
+ console.log('๐Ÿ”‘ [YOUTUBE REAUTH] Refresh token length:', refreshToken.length);
156
422
  } else {
157
- throw new Error('Received invalid Instagram OAuth URL');
423
+ console.warn('โš ๏ธ [YOUTUBE REAUTH] Backend did NOT confirm refresh token reception');
424
+ console.warn('โš ๏ธ [YOUTUBE REAUTH] Response data:', responseData);
425
+ console.warn('โš ๏ธ [YOUTUBE REAUTH] Expected hasRefreshToken or refreshTokenReceived in response');
426
+ return false;
427
+ }
428
+
429
+ // CRITICAL: Signal training system to restart with new connection
430
+ console.log('๐Ÿ”„ [YOUTUBE REAUTH] Signaling training system to restart...');
431
+ try {
432
+ await triggerTrainingRestart(username, authToken);
433
+ console.log('โœ… [YOUTUBE REAUTH] Training restart signal sent successfully');
434
+ } catch (restartError) {
435
+ console.warn('โš ๏ธ [YOUTUBE REAUTH] Training restart signal failed:', restartError);
436
+ console.warn('โš ๏ธ [YOUTUBE REAUTH] User may need to manually restart training');
158
437
  }
438
+ return true;
439
+ } else {
440
+ const errorData = await backendResponse.text();
441
+ console.error('โŒ [YOUTUBE REAUTH] Backend processing FAILED:', backendResponse.status, errorData);
442
+ console.error('โŒ [YOUTUBE REAUTH] This means the reauth signal was not processed');
443
+ return false;
159
444
  }
160
- console.error('โŒ No Instagram URL found in response');
161
- throw new Error('No Instagram URL found in response');
445
+ } else {
446
+ console.error('โŒ CRITICAL: No refresh token even after consent screen');
447
+ console.error('โŒ This means consent screen did not appear or user denied permissions');
448
+ console.error('๐Ÿ’ก Solutions:');
449
+ console.error(' 1. Try the revoke method: forceYouTubeReconnectionWithRevoke()');
450
+ console.error(' 2. Check Google Console OAuth configuration');
451
+ console.error(' 3. Ensure user clicks "Allow" on consent screen');
452
+ return false;
162
453
  }
454
+ } catch (error) {
455
+ console.error('โŒ Error forcing YouTube consent:', error);
456
+ if (error.code === statusCodes.SIGN_IN_CANCELLED) {
457
+ console.error('โŒ User cancelled sign-in - no refresh token obtained');
458
+ console.error('๐Ÿ’ก User must click "Allow" to get refresh token');
459
+ } else if (error.code === statusCodes.IN_PROGRESS) {
460
+ console.error('โŒ Sign-in already in progress');
461
+ } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
462
+ console.error('โŒ Google Play Services not available');
463
+ }
464
+ return false;
465
+ }
466
+ };
163
467
 
164
- // Prepare the request body for other platforms
165
- const jsonData = {
166
- session: {
167
- oauthState: 'djksbfds',
168
- // Use same state for all platforms
169
- username: username || 'Avatar',
170
- appName: appName || 'DefaultApp'
171
- }
172
- };
173
- console.log(`๐Ÿ“ค Sending ${platform} OAuth request:`, jsonData);
468
+ /**
469
+ * Alternative method: Force consent by revoking existing permissions
470
+ */
471
+ export const forceYouTubeReconnectionWithRevoke = async username => {
472
+ try {
473
+ var _userInfo$data14;
474
+ console.log('๐Ÿ”„ FORCING YouTube consent via REVOKE method...');
475
+ console.log('๐Ÿ‘ค User:', username);
174
476
 
175
- // Make the authenticated request to get the OAuth URL
176
- const response = await makeDeveloperRequest(PLATFORM_AUTH_CONFIG[platform].authEndpoint, {
177
- method: 'POST',
178
- body: JSON.stringify(jsonData)
179
- });
180
- console.log(`๐Ÿ“ก ${platform} OAuth response status:`, response.status);
181
- if (!response.ok) {
182
- const errorText = await response.text();
183
- console.error(`โŒ ${platform} OAuth API error:`, errorText);
184
- throw new Error(`${platform} OAuth API error: ${response.status} - ${errorText}`);
477
+ // Step 1: Initialize Google Sign-In
478
+ initializeGoogleSignIn();
479
+ await GoogleSignin.hasPlayServices();
480
+
481
+ // Step 2: โœ… CRITICAL: Revoke existing permissions (forces fresh consent)
482
+ try {
483
+ await GoogleSignin.revokeAccess();
484
+ console.log('โœ… Revoked existing permissions - fresh consent REQUIRED');
485
+ } catch (revokeError) {
486
+ console.log('โ„น๏ธ No existing permissions to revoke:', revokeError);
185
487
  }
186
488
 
187
- // Parse the response
188
- const data = await response.json();
189
- console.log(`๐Ÿ“ฅ ${platform} OAuth response data:`, data);
489
+ // Step 3: Sign out completely
490
+ await GoogleSignin.signOut();
491
+ console.log('โœ… Signed out completely');
190
492
 
191
- // Extra logging for Gmail to help debug
192
- if (platform === 'email') {
193
- console.log('๐Ÿ” Gmail OAuth response keys:', Object.keys(data));
194
- console.log('๐Ÿ” Gmail OAuth full response:', JSON.stringify(data, null, 2));
195
- }
493
+ // Step 4: โœ… Now sign in again (will DEFINITELY show consent screen)
494
+ console.log('๐Ÿ” Signing in after revoke - consent screen MUST appear...');
495
+ const userInfo = await GoogleSignin.signIn();
196
496
 
197
- // Check if the response contains the OAuth URL based on platform
198
- let oauthUrl = null;
199
- switch (platform) {
200
- case 'reddit':
201
- oauthUrl = data.redditURL;
202
- break;
203
- case 'pinterest':
204
- oauthUrl = data.pinterestURL;
205
- break;
206
- case 'youtube':
207
- oauthUrl = data.youtubeURL;
208
- break;
209
- case 'email':
210
- // Gmail might return under different field names
211
- oauthUrl = data.emailURL || data.gmailURL || data.authUrl || data.url;
212
- break;
213
- default:
214
- oauthUrl = data.url;
215
- break;
216
- }
217
- if (!oauthUrl) {
218
- console.error(`โŒ No OAuth URL found in response for ${platform}. Response:`, data);
219
- throw new Error(`No OAuth URL found in response for ${platform}`);
220
- }
221
- console.log(`โœ… ${platform} OAuth URL received:`, oauthUrl);
497
+ // Step 5: โœ… User will definitely see consent screen now
498
+ const tokens = await GoogleSignin.getTokens();
499
+ const currentUser = await GoogleSignin.getCurrentUser();
500
+ const refreshToken = ((_userInfo$data14 = userInfo.data) === null || _userInfo$data14 === void 0 ? void 0 : _userInfo$data14.serverAuthCode) || (currentUser === null || currentUser === void 0 ? void 0 : currentUser.serverAuthCode);
501
+ if (refreshToken) {
502
+ console.log('โœ… SUCCESS: Got refresh token after REVOKE + consent!');
503
+ console.log('๐Ÿ”‘ Refresh token preview:', `${refreshToken.substring(0, 20)}...`);
222
504
 
223
- // Validate the URL before returning
224
- if (await validateOAuthUrl(oauthUrl)) {
225
- return oauthUrl;
505
+ // Continue with the same backend submission logic as above
506
+ // (Similar to forceYouTubeReconnectionWithConsent)
507
+
508
+ return true;
226
509
  } else {
227
- throw new Error(`Received invalid ${platform} OAuth URL`);
510
+ console.error('โŒ Still no refresh token after revoke method');
511
+ return false;
228
512
  }
229
513
  } catch (error) {
230
- console.error(`Error initiating OAuth for ${platform}:`, error);
231
- throw error;
514
+ console.error('โŒ Error with revoke method:', error);
515
+ return false;
232
516
  }
233
517
  };
234
518
 
235
- /**
236
- * Validates an OAuth URL to ensure it's reachable
237
- * @param url The OAuth URL to validate
238
- * @returns Promise<boolean> indicating if the URL is valid and reachable
519
+ /**
520
+ * Fix YouTube connection for a specific user (like nicholase50)
239
521
  */
240
- const validateOAuthUrl = async url => {
522
+ export const fixUserYouTubeConnection = async username => {
523
+ console.log(`๐Ÿ”ง Fixing YouTube connection for user: ${username}`);
524
+
525
+ // Method 1: Try forced consent via configuration
526
+ console.log('๐Ÿ”„ Method 1: Trying forced consent via configuration...');
527
+ let success = await forceYouTubeReconnectionWithConsent(username);
528
+ if (success) {
529
+ console.log(`โœ… ${username} YouTube connection fixed via Method 1!`);
530
+ return true;
531
+ }
532
+
533
+ // Method 2: Try forced consent via revoke
534
+ console.log('๐Ÿ”„ Method 2: Trying forced consent via revoke...');
535
+ success = await forceYouTubeReconnectionWithRevoke(username);
536
+ if (success) {
537
+ console.log(`โœ… ${username} YouTube connection fixed via Method 2!`);
538
+ return true;
539
+ }
540
+ console.error(`โŒ Failed to fix ${username} YouTube connection with both methods`);
541
+ return false;
542
+ };
543
+
544
+ /**
545
+ * Get fresh tokens using refresh token
546
+ */
547
+ const refreshGoogleTokens = async () => {
241
548
  try {
242
- console.log('๐Ÿ” Validating OAuth URL:', url);
549
+ console.log('๐Ÿ”„ Attempting to refresh Google tokens...');
243
550
 
244
- // Basic URL format validation
245
- if (!url || typeof url !== 'string') {
246
- console.error('โŒ Invalid URL format:', url);
247
- return false;
551
+ // Check if user is signed in
552
+ const currentUser = await GoogleSignin.getCurrentUser();
553
+ if (!currentUser) {
554
+ console.log('โŒ User not signed in to Google, cannot refresh tokens');
555
+ return null;
248
556
  }
249
557
 
250
- // Check if URL starts with https
251
- if (!url.startsWith('https://')) {
252
- console.error('โŒ URL must use HTTPS:', url);
253
- return false;
254
- }
558
+ // Get fresh tokens
559
+ const tokens = await GoogleSignin.getTokens();
560
+ console.log('โœ… Successfully refreshed Google tokens');
561
+ return {
562
+ accessToken: tokens.accessToken,
563
+ idToken: tokens.idToken
564
+ };
565
+ } catch (error) {
566
+ console.error('โŒ Failed to refresh Google tokens:', error);
255
567
 
256
- // Try to parse the URL
568
+ // If refresh fails, try to sign in again
257
569
  try {
258
- new URL(url);
259
- } catch (parseError) {
260
- console.error('โŒ URL parsing failed:', parseError);
261
- return false;
570
+ console.log('๐Ÿ”„ Refresh failed, attempting re-authentication...');
571
+ const userInfo = await GoogleSignin.signIn();
572
+ const tokens = await GoogleSignin.getTokens();
573
+ console.log('โœ… Re-authentication successful');
574
+ return {
575
+ accessToken: tokens.accessToken,
576
+ idToken: tokens.idToken
577
+ };
578
+ } catch (signInError) {
579
+ console.error('โŒ Re-authentication also failed:', signInError);
580
+ return null;
262
581
  }
582
+ }
583
+ };
584
+
585
+ /**
586
+ * Debug YouTube tokens to verify refresh token availability
587
+ */
588
+ const debugYouTubeTokens = async () => {
589
+ try {
590
+ var _currentUser$user;
591
+ const tokens = await GoogleSignin.getTokens();
592
+ const currentUser = await GoogleSignin.getCurrentUser();
593
+ console.log('๐Ÿ” YouTube Token Debug:', {
594
+ accessToken: tokens.accessToken ? `${tokens.accessToken.substring(0, 20)}...` : 'Missing',
595
+ idToken: tokens.idToken ? 'Present' : 'Missing',
596
+ serverAuthCode: currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode ? `${currentUser.serverAuthCode.substring(0, 20)}...` : 'Missing',
597
+ userEmail: (currentUser === null || currentUser === void 0 || (_currentUser$user = currentUser.user) === null || _currentUser$user === void 0 ? void 0 : _currentUser$user.email) || 'Missing'
598
+ });
599
+ return {
600
+ hasRefreshToken: !!(currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode),
601
+ refreshTokenType: currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode ? 'serverAuthCode' : 'none'
602
+ };
603
+ } catch (error) {
604
+ console.error('โŒ Debug tokens failed:', error);
605
+ return {
606
+ hasRefreshToken: false,
607
+ refreshTokenType: 'error'
608
+ };
609
+ }
610
+ };
611
+
612
+ /**
613
+ * Force fresh YouTube reconnection with proper refresh token
614
+ */
615
+ export const reconnectYouTube = async username => {
616
+ try {
617
+ console.log('๐Ÿ”„ Forcing fresh YouTube reconnection for refresh token...');
263
618
 
264
- // Make a HEAD request to check if the URL is reachable
265
- const controller = new AbortController();
266
- const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
619
+ // 1. Sign out completely to force fresh consent
620
+ try {
621
+ await GoogleSignin.signOut();
622
+ console.log('โœ… Signed out from Google');
623
+ } catch (signOutError) {
624
+ console.log('โ„น๏ธ Already signed out or sign out failed:', signOutError);
625
+ }
267
626
 
627
+ // 2. Clear any cached tokens
268
628
  try {
269
- const response = await fetch(url, {
270
- method: 'HEAD',
271
- signal: controller.signal
272
- });
273
- clearTimeout(timeoutId);
629
+ const currentTokens = await GoogleSignin.getTokens();
630
+ if (currentTokens.accessToken) {
631
+ await GoogleSignin.clearCachedAccessToken(currentTokens.accessToken);
632
+ console.log('โœ… Cleared cached access token');
633
+ }
634
+ } catch (clearError) {
635
+ console.log('โ„น๏ธ Token clearing failed or not needed:', clearError);
636
+ }
274
637
 
275
- // Accept any response that's not a network error
276
- // OAuth pages might return various status codes
277
- console.log('โœ… OAuth URL validation successful, status:', response.status);
278
- return true;
279
- } catch (fetchError) {
280
- clearTimeout(timeoutId);
281
- if (fetchError.name === 'AbortError') {
282
- console.warn('โš ๏ธ OAuth URL validation timeout, but proceeding anyway');
283
- return true; // Allow timeout as URLs might be slow to respond
638
+ // 3. Re-authenticate with fresh consent
639
+ const result = await initiateNativeAuth('youtube', username);
640
+ if (result) {
641
+ console.log('โœ… YouTube reconnected successfully with refresh token');
642
+
643
+ // 4. Verify we now have a refresh token
644
+ const debugInfo = await debugYouTubeTokens();
645
+ if (debugInfo.hasRefreshToken) {
646
+ console.log('โœ… Refresh token confirmed:', debugInfo.refreshTokenType);
647
+ } else {
648
+ console.warn('โš ๏ธ Still no refresh token after reconnection');
284
649
  }
285
- console.warn('โš ๏ธ OAuth URL validation failed, but proceeding anyway:', fetchError.message);
286
- return true; // Allow network errors as they might be temporary
650
+ return true;
651
+ } else {
652
+ console.error('โŒ YouTube reconnection failed');
653
+ return false;
287
654
  }
288
655
  } catch (error) {
289
- console.warn('โš ๏ธ OAuth URL validation error, but proceeding anyway:', error);
290
- return true; // Allow validation errors to not block the flow
656
+ console.error('โŒ YouTube reconnection error:', error);
657
+ return false;
291
658
  }
292
659
  };
293
660
 
294
- /**
295
- * Initiates the native SDK authentication flow for a platform
296
- * @param platform The platform to authenticate with
297
- * @returns A Promise that resolves to the authentication result
661
+ /**
662
+ * Initiate native authentication for platforms with SDKs
298
663
  */
299
664
  export const initiateNativeAuth = async (platform, username) => {
300
665
  if (platform === 'youtube') {
301
666
  console.log('๐Ÿ”— Initiating native Google Sign-In for YouTube');
667
+
668
+ // Validate username for YouTube
669
+ if (!username || username.trim() === '') {
670
+ console.error('โŒ [YOUTUBE AUTH] Username is required for YouTube authentication');
671
+ return false;
672
+ }
302
673
  try {
303
- var _currentUser$user, _userInfo$user4, _userInfo$user6, _userInfo$user7, _userInfo$user8;
304
- // Check if Google Sign-In package is available
305
- let GoogleSignin, statusCodes;
306
- try {
307
- const googleSignInModule = require('@react-native-google-signin/google-signin');
308
- GoogleSignin = googleSignInModule.GoogleSignin;
309
- statusCodes = googleSignInModule.statusCodes;
310
- } catch (importError) {
311
- console.error('โŒ Google Sign-In package not available:', importError);
312
- throw new Error('Google Sign-In SDK not installed. Please install @react-native-google-signin/google-signin');
313
- }
674
+ var _userInfo$data15, _currentUser$user2, _userInfo$data16, _userInfo$data17, _userInfo$data24, _userInfo$data27, _userInfo$data28, _userInfo$data29, _userInfo$data30, _authToken, _userInfo$data31;
675
+ // Initialize Google Sign-In if not already done
676
+ // โœ… CRITICAL: Initialize with CORRECT iOS Client ID
677
+ initializeGoogleSignIn();
314
678
 
315
- // Configure Google Sign-In with better error handling
316
- try {
317
- const youtubeConfig = PLATFORM_AUTH_CONFIG.youtube;
318
- const webClientId = youtubeConfig.clientId || '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
319
- const iosClientId = youtubeConfig.iosClientId || webClientId;
320
- await GoogleSignin.configure({
321
- webClientId: webClientId,
322
- iosClientId: iosClientId,
323
- scopes: ['https://www.googleapis.com/auth/youtube.readonly'],
324
- offlineAccess: true,
325
- hostedDomain: '',
326
- forceCodeForRefreshToken: true,
327
- accountName: ''
328
- });
329
- console.log('โœ… Google Sign-In configured successfully with client ID:', webClientId.substring(0, 20) + '...');
330
- } catch (configError) {
331
- console.error('โŒ Google Sign-In configuration failed:', configError);
332
- throw new Error(`Google Sign-In configuration failed: ${configError.message || configError}`);
333
- }
679
+ // Check if Google Play Services are available
680
+ await GoogleSignin.hasPlayServices();
334
681
 
335
- // Check if Google Play Services are available (Android only)
682
+ // โœ… CRITICAL: Force sign out first to ensure fresh consent
336
683
  try {
337
- await GoogleSignin.hasPlayServices({
338
- showPlayServicesUpdateDialog: true
339
- });
340
- console.log('โœ… Google Play Services available');
341
- } catch (playServicesError) {
342
- console.error('โŒ Google Play Services error:', playServicesError);
343
- throw new Error(`Google Play Services not available: ${playServicesError.message || playServicesError}`);
684
+ await GoogleSignin.signOut();
685
+ console.log('๐Ÿ”„ Signed out to force fresh consent');
686
+ } catch (signOutError) {
687
+ console.log('โ„น๏ธ Sign out not needed or failed:', signOutError);
344
688
  }
345
689
 
346
- // Sign in with Google
347
- let userInfo;
348
- try {
349
- var _userInfo$user;
350
- userInfo = await GoogleSignin.signIn();
351
- console.log('โœ… Google Sign-In successful:', (_userInfo$user = userInfo.user) === null || _userInfo$user === void 0 ? void 0 : _userInfo$user.email);
352
- } catch (signInError) {
353
- console.error('โŒ Google Sign-In failed:', signInError);
354
-
355
- // Handle specific error codes
356
- if (signInError.code === statusCodes.SIGN_IN_CANCELLED) {
357
- throw new Error('Google Sign-In was cancelled by user');
358
- } else if (signInError.code === statusCodes.IN_PROGRESS) {
359
- throw new Error('Google Sign-In already in progress');
360
- } else if (signInError.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
361
- throw new Error('Google Play Services not available or outdated');
362
- } else {
363
- throw new Error(`Google Sign-In failed: ${signInError.message || signInError}`);
364
- }
365
- }
690
+ // Sign in with Google (this will show consent screen due to our config)
691
+ const userInfo = await GoogleSignin.signIn();
692
+ console.log('โœ… Google Sign-In successful:', (_userInfo$data15 = userInfo.data) === null || _userInfo$data15 === void 0 || (_userInfo$data15 = _userInfo$data15.user) === null || _userInfo$data15 === void 0 ? void 0 : _userInfo$data15.email);
693
+ console.log('๐Ÿ“‹ FULL userInfo object:');
694
+ console.log(JSON.stringify(userInfo, null, 2));
366
695
 
367
696
  // Get access token for API calls
368
697
  const tokens = await GoogleSignin.getTokens();
369
698
  console.log('๐Ÿ”‘ Got Google tokens');
699
+ console.log('๐Ÿ“‹ FULL tokens object:');
700
+ console.log(JSON.stringify(tokens, null, 2));
370
701
 
371
- // Get current user info with refresh token
702
+ // CRITICAL: Get the current user info which contains the refresh token
372
703
  const currentUser = await GoogleSignin.getCurrentUser();
373
- console.log('๐Ÿ‘ค Current user info:', currentUser === null || currentUser === void 0 || (_currentUser$user = currentUser.user) === null || _currentUser$user === void 0 ? void 0 : _currentUser$user.email);
704
+ console.log('๐Ÿ‘ค Current user info:', currentUser === null || currentUser === void 0 || (_currentUser$user2 = currentUser.user) === null || _currentUser$user2 === void 0 ? void 0 : _currentUser$user2.email);
705
+ console.log('๐Ÿ“‹ FULL currentUser object:');
706
+ console.log(JSON.stringify(currentUser, null, 2));
374
707
 
375
- // Extract refresh token from server auth code
708
+ // โœ… CRITICAL: Extract refresh token properly using serverAuthCode
376
709
  let refreshToken = null;
710
+ console.log('๐Ÿ” REFRESH TOKEN EXTRACTION:');
711
+ console.log('- userInfo.data?.serverAuthCode:', (_userInfo$data16 = userInfo.data) !== null && _userInfo$data16 !== void 0 && _userInfo$data16.serverAuthCode ? `Present: ${userInfo.data.serverAuthCode.substring(0, 20)}...` : 'Missing');
712
+ console.log('- currentUser?.serverAuthCode:', currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode ? `Present: ${currentUser.serverAuthCode.substring(0, 20)}...` : 'Missing');
713
+ console.log('- tokens.idToken:', tokens.idToken ? `Present: ${tokens.idToken.substring(0, 20)}...` : 'Missing');
714
+ console.log('- tokens.accessToken:', tokens.accessToken ? `Present: ${tokens.accessToken.substring(0, 20)}...` : 'Missing');
715
+
716
+ // The serverAuthCode is the refresh token mechanism for React Native Google Sign-In
377
717
  if (currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode) {
378
- console.log('๐Ÿ”„ Server auth code available for refresh token');
379
718
  refreshToken = currentUser.serverAuthCode;
719
+ console.log('โœ… Got serverAuthCode (refresh token mechanism)');
720
+ console.log('๐Ÿ”‘ Refresh token preview:', `${refreshToken.substring(0, 20)}...`);
721
+ } else if ((_userInfo$data17 = userInfo.data) !== null && _userInfo$data17 !== void 0 && _userInfo$data17.serverAuthCode) {
722
+ refreshToken = userInfo.data.serverAuthCode;
723
+ console.log('โœ… Got serverAuthCode from sign-in response');
724
+ console.log('๐Ÿ”‘ Refresh token preview:', `${refreshToken.substring(0, 20)}...`);
380
725
  }
726
+
727
+ // โœ… CRITICAL: Verify refresh token availability
381
728
  if (!refreshToken) {
382
- console.warn('โš ๏ธ No refresh token available - token refresh may fail later');
729
+ console.error('โŒ CRITICAL: No refresh token available - YouTube connection will fail when token expires');
730
+ console.error('๐Ÿ’ก User needs to reconnect with proper consent screen');
731
+ console.error('๐Ÿ’ก Check Google Sign-In configuration: offlineAccess, forceCodeForRefreshToken');
732
+
733
+ // Still continue but warn about the issue
734
+ console.warn('โš ๏ธ Continuing without refresh token - connection may fail later');
383
735
  } else {
384
736
  console.log('โœ… Refresh token available for YouTube connection');
737
+ console.log('๐Ÿ”‘ Refresh token type:', refreshToken.startsWith('4/') ? 'serverAuthCode' : 'refreshToken');
385
738
  }
386
739
 
387
- // Fetch YouTube channel information
740
+ // Fetch YouTube channel information using the access token
388
741
  let channelName = 'Unknown Channel';
389
742
  let channelId = null;
390
743
  try {
@@ -400,28 +753,60 @@ export const initiateNativeAuth = async (platform, username) => {
400
753
  if (channelData.items && channelData.items.length > 0) {
401
754
  channelName = channelData.items[0].snippet.title;
402
755
  channelId = channelData.items[0].id;
403
- console.log('โœ… YouTube channel found:', channelName);
756
+ console.log('โœ… YouTube channel found:', channelName, 'ID:', channelId);
757
+ } else {
758
+ var _userInfo$data18, _userInfo$data19;
759
+ console.log('โš ๏ธ No YouTube channel found for user');
760
+ channelName = ((_userInfo$data18 = userInfo.data) === null || _userInfo$data18 === void 0 || (_userInfo$data18 = _userInfo$data18.user) === null || _userInfo$data18 === void 0 ? void 0 : _userInfo$data18.name) || ((_userInfo$data19 = userInfo.data) === null || _userInfo$data19 === void 0 || (_userInfo$data19 = _userInfo$data19.user) === null || _userInfo$data19 === void 0 ? void 0 : _userInfo$data19.email) || 'No Channel';
404
761
  }
762
+ } else {
763
+ var _userInfo$data20, _userInfo$data21;
764
+ console.log('โš ๏ธ Failed to fetch YouTube channel info:', channelResponse.status);
765
+ channelName = ((_userInfo$data20 = userInfo.data) === null || _userInfo$data20 === void 0 || (_userInfo$data20 = _userInfo$data20.user) === null || _userInfo$data20 === void 0 ? void 0 : _userInfo$data20.name) || ((_userInfo$data21 = userInfo.data) === null || _userInfo$data21 === void 0 || (_userInfo$data21 = _userInfo$data21.user) === null || _userInfo$data21 === void 0 ? void 0 : _userInfo$data21.email) || 'Unknown Channel';
405
766
  }
406
767
  } catch (channelError) {
407
- var _userInfo$user2, _userInfo$user3;
768
+ var _userInfo$data22, _userInfo$data23;
408
769
  console.log('โš ๏ธ Error fetching YouTube channel info:', channelError);
409
- channelName = ((_userInfo$user2 = userInfo.user) === null || _userInfo$user2 === void 0 ? void 0 : _userInfo$user2.name) || ((_userInfo$user3 = userInfo.user) === null || _userInfo$user3 === void 0 ? void 0 : _userInfo$user3.email) || 'Unknown Channel';
770
+ channelName = ((_userInfo$data22 = userInfo.data) === null || _userInfo$data22 === void 0 || (_userInfo$data22 = _userInfo$data22.user) === null || _userInfo$data22 === void 0 ? void 0 : _userInfo$data22.name) || ((_userInfo$data23 = userInfo.data) === null || _userInfo$data23 === void 0 || (_userInfo$data23 = _userInfo$data23.user) === null || _userInfo$data23 === void 0 ? void 0 : _userInfo$data23.email) || 'Unknown Channel';
410
771
  }
411
772
 
412
- // Get authentication info
773
+ // Get stored authentication info to link YouTube data to user account
413
774
  let authToken = (await AsyncStorage.getItem('onairos_jwt_token')) || (await AsyncStorage.getItem('enoch_token')) || (await AsyncStorage.getItem('auth_token'));
414
775
  const storedUsername = await AsyncStorage.getItem('onairos_username');
415
- const finalUsername = storedUsername || username || ((_userInfo$user4 = userInfo.user) === null || _userInfo$user4 === void 0 ? void 0 : _userInfo$user4.email) || 'youtube_user';
776
+ const finalUsername = storedUsername || username || ((_userInfo$data24 = userInfo.data) === null || _userInfo$data24 === void 0 || (_userInfo$data24 = _userInfo$data24.user) === null || _userInfo$data24 === void 0 ? void 0 : _userInfo$data24.email) || 'youtube_user';
416
777
 
417
- // Create auth token if needed
778
+ // If no auth token exists, create one now to ensure YouTube data is linked to user account
418
779
  if (!authToken || authToken.trim().length < 20) {
419
- console.log('๐Ÿ” Creating authentication token for YouTube...');
780
+ console.log('๐Ÿ” No valid authentication token found, creating one for YouTube authentication...');
420
781
  try {
421
- var _userInfo$user5;
422
- const fallbackEmail = ((_userInfo$user5 = userInfo.user) === null || _userInfo$user5 === void 0 ? void 0 : _userInfo$user5.email) || `${finalUsername}@youtube.temp`;
782
+ var _userInfo$data25;
783
+ // Create user accounts and get proper Enoch token
784
+ const fallbackEmail = ((_userInfo$data25 = userInfo.data) === null || _userInfo$data25 === void 0 || (_userInfo$data25 = _userInfo$data25.user) === null || _userInfo$data25 === void 0 ? void 0 : _userInfo$data25.email) || `${finalUsername}@youtube.temp`;
785
+
786
+ // Step 1: Create Enoch user first
787
+ console.log('๐Ÿ” Step 1: Creating Enoch user for YouTube auth...');
788
+ try {
789
+ var _userInfo$data26;
790
+ const enochRegisterResponse = await fetch('https://api2.onairos.uk/enoch/users/register', {
791
+ method: 'POST',
792
+ headers: {
793
+ 'Content-Type': 'application/json'
794
+ },
795
+ body: JSON.stringify({
796
+ email: fallbackEmail,
797
+ name: finalUsername,
798
+ photoUrl: ((_userInfo$data26 = userInfo.data) === null || _userInfo$data26 === void 0 || (_userInfo$data26 = _userInfo$data26.user) === null || _userInfo$data26 === void 0 ? void 0 : _userInfo$data26.photo) || ''
799
+ })
800
+ });
801
+ console.log('๐Ÿ“ก Enoch register response status:', enochRegisterResponse.status);
802
+ const enochResponseData = await enochRegisterResponse.json();
803
+ console.log('๐Ÿ”— Enoch user creation response:', enochResponseData);
804
+ } catch (enochError) {
805
+ console.warn('โš ๏ธ Enoch user creation failed (continuing):', enochError);
806
+ }
423
807
 
424
- // Create user accounts and get JWT token
808
+ // Step 2: Create Onairos account to get JWT token
809
+ console.log('๐Ÿ” Step 2: Creating Onairos account for YouTube auth...');
425
810
  const onairosSignupResponse = await fetch('https://api2.onairos.uk/register/enoch', {
426
811
  method: 'POST',
427
812
  headers: {
@@ -433,249 +818,244 @@ export const initiateNativeAuth = async (platform, username) => {
433
818
  name: finalUsername
434
819
  })
435
820
  });
821
+ console.log('๐Ÿ“ก Onairos register response status:', onairosSignupResponse.status);
436
822
  if (onairosSignupResponse.ok) {
437
823
  var _onairosResponseData$;
438
824
  const onairosResponseData = await onairosSignupResponse.json();
439
-
440
- // Extract token from response
441
- authToken = onairosResponseData.token || ((_onairosResponseData$ = onairosResponseData.data) === null || _onairosResponseData$ === void 0 ? void 0 : _onairosResponseData$.token) || onairosResponseData.jwt;
825
+ console.log('๐Ÿ”— Onairos account creation response:', onairosResponseData);
826
+
827
+ // Extract the token from the response
828
+ if (onairosResponseData.token) {
829
+ authToken = onairosResponseData.token;
830
+ } else if ((_onairosResponseData$ = onairosResponseData.data) !== null && _onairosResponseData$ !== void 0 && _onairosResponseData$.token) {
831
+ authToken = onairosResponseData.data.token;
832
+ } else if (onairosResponseData.jwt) {
833
+ authToken = onairosResponseData.jwt;
834
+ }
442
835
  if (authToken) {
443
- // Store tokens
836
+ // Store the Enoch token in all the standard locations
444
837
  await AsyncStorage.setItem('onairos_jwt_token', authToken);
445
838
  await AsyncStorage.setItem('enoch_token', authToken);
446
839
  await AsyncStorage.setItem('auth_token', authToken);
447
840
  await AsyncStorage.setItem('onairos_username', onairosResponseData.username || finalUsername);
448
- console.log('โœ… Successfully created and stored authentication token');
841
+ console.log('โœ… Successfully created and stored Enoch authentication token for YouTube');
842
+ console.log('๐Ÿ”‘ Enoch token preview:', `${authToken.substring(0, 20)}...`);
449
843
  }
844
+ } else {
845
+ const errorText = await onairosSignupResponse.text();
846
+ console.warn('โš ๏ธ Could not create Enoch auth token for YouTube:', errorText);
450
847
  }
451
848
  } catch (tokenError) {
452
- console.warn('โš ๏ธ Error creating auth token:', tokenError);
849
+ console.warn('โš ๏ธ Error creating Enoch auth token for YouTube:', tokenError);
850
+ // Continue without token - backend will handle gracefully
453
851
  }
852
+ } else {
853
+ console.log('โœ… Found existing authentication token for YouTube auth');
854
+ console.log('๐Ÿ”‘ Token preview:', `${authToken.substring(0, 20)}...`);
454
855
  }
455
856
  console.log('๐Ÿ”— Linking YouTube data to user:', finalUsername);
857
+ console.log('๐Ÿ”‘ Using auth token for linking:', authToken ? `${authToken.substring(0, 20)}...` : 'No token');
456
858
  console.log('๐Ÿ“บ YouTube channel name:', channelName);
457
859
 
458
- // Send tokens to backend for YouTube data processing
860
+ // โœ… CRITICAL: Enhanced payload with comprehensive refresh token data
861
+ const backendPayload = {
862
+ session: {
863
+ username: finalUsername,
864
+ platform: 'youtube',
865
+ timestamp: new Date().toISOString(),
866
+ channelName: channelName,
867
+ channelId: channelId
868
+ },
869
+ googleUser: (_userInfo$data27 = userInfo.data) === null || _userInfo$data27 === void 0 ? void 0 : _userInfo$data27.user,
870
+ accessToken: tokens.accessToken,
871
+ idToken: tokens.idToken,
872
+ refreshToken: refreshToken,
873
+ // โœ… CRITICAL: Include refresh token
874
+ serverAuthCode: refreshToken,
875
+ // โœ… Alternative refresh mechanism (same as refreshToken)
876
+
877
+ // โœ… CRITICAL: Additional compatibility fields for backend
878
+ refresh_token: refreshToken,
879
+ // Snake case version
880
+ server_auth_code: refreshToken,
881
+ // Snake case version
882
+ authCode: refreshToken,
883
+ // Alternative naming
884
+
885
+ // Include user account linking information
886
+ userAccountInfo: {
887
+ username: finalUsername,
888
+ email: (_userInfo$data28 = userInfo.data) === null || _userInfo$data28 === void 0 || (_userInfo$data28 = _userInfo$data28.user) === null || _userInfo$data28 === void 0 ? void 0 : _userInfo$data28.email,
889
+ authToken: authToken,
890
+ channelName: channelName,
891
+ channelId: channelId,
892
+ // CRITICAL: Include user identifier that matches your database
893
+ userIdentifier: authToken ? `user-${authToken.substring(0, 10)}` : `youtube-${(_userInfo$data29 = userInfo.data) === null || _userInfo$data29 === void 0 || (_userInfo$data29 = _userInfo$data29.user) === null || _userInfo$data29 === void 0 ? void 0 : _userInfo$data29.email}`,
894
+ googleId: (_userInfo$data30 = userInfo.data) === null || _userInfo$data30 === void 0 || (_userInfo$data30 = _userInfo$data30.user) === null || _userInfo$data30 === void 0 ? void 0 : _userInfo$data30.id,
895
+ appleUserId: (_authToken = authToken) !== null && _authToken !== void 0 && _authToken.includes('apple') ? authToken.split('.')[1] : null,
896
+ // โœ… CRITICAL: Also include refresh token in userAccountInfo
897
+ refreshToken: refreshToken,
898
+ serverAuthCode: refreshToken
899
+ },
900
+ // Token expiry information
901
+ tokenExpiry: new Date(Date.now() + 3600 * 1000).toISOString(),
902
+ // 1 hour from now
903
+ // Force refresh token request
904
+ requestRefreshToken: true,
905
+ // โœ… CRITICAL: Debug information for backend
906
+ debugInfo: {
907
+ hasRefreshToken: !!refreshToken,
908
+ refreshTokenType: refreshToken ? refreshToken.startsWith('4/') ? 'serverAuthCode' : 'refreshToken' : 'none',
909
+ configuredForRefresh: true,
910
+ forcedConsent: true,
911
+ refreshTokenValue: refreshToken // Include actual value for debugging
912
+ }
913
+ };
914
+ console.log('๐Ÿ“ค BACKEND PAYLOAD SUMMARY:');
915
+ console.log('- hasAccessToken:', !!backendPayload.accessToken);
916
+ console.log('- hasRefreshToken:', !!backendPayload.refreshToken);
917
+ console.log('- hasServerAuthCode:', !!backendPayload.serverAuthCode);
918
+ console.log('- refreshTokenType:', backendPayload.debugInfo.refreshTokenType);
919
+ console.log('- userEmail:', (_userInfo$data31 = userInfo.data) === null || _userInfo$data31 === void 0 || (_userInfo$data31 = _userInfo$data31.user) === null || _userInfo$data31 === void 0 ? void 0 : _userInfo$data31.email);
920
+ console.log('- channelName:', channelName);
921
+ console.log('๐Ÿ“‹ COMPLETE BACKEND PAYLOAD:');
922
+ console.log(JSON.stringify(backendPayload, null, 2));
923
+
924
+ // Send the tokens to your backend for YouTube data processing with ENHANCED LOGGING
925
+ console.log('๐Ÿ“ค Sending YouTube auth to backend with refresh token:', !!refreshToken);
459
926
  const backendResponse = await fetch('https://api2.onairos.uk/youtube/native-auth', {
460
927
  method: 'POST',
461
928
  headers: {
462
929
  'Content-Type': 'application/json',
463
930
  ...(authToken && {
464
- 'Authorization': `Bearer ${authToken}`
465
- })
931
+ 'Authorization': authToken
932
+ }) // Include auth token if available
466
933
  },
467
- body: JSON.stringify({
468
- session: {
469
- username: finalUsername,
470
- platform: 'youtube',
471
- timestamp: new Date().toISOString(),
472
- channelName: channelName,
473
- channelId: channelId
474
- },
475
- googleUser: userInfo.user,
476
- accessToken: tokens.accessToken,
477
- idToken: tokens.idToken,
478
- refreshToken: refreshToken,
479
- // CRITICAL: Include refresh token
480
- serverAuthCode: currentUser === null || currentUser === void 0 ? void 0 : currentUser.serverAuthCode,
481
- userAccountInfo: {
482
- username: finalUsername,
483
- email: (_userInfo$user6 = userInfo.user) === null || _userInfo$user6 === void 0 ? void 0 : _userInfo$user6.email,
484
- authToken: authToken,
485
- channelName: channelName,
486
- channelId: channelId,
487
- userIdentifier: authToken ? `user-${authToken.substring(0, 10)}` : `youtube-${(_userInfo$user7 = userInfo.user) === null || _userInfo$user7 === void 0 ? void 0 : _userInfo$user7.email}`,
488
- googleId: (_userInfo$user8 = userInfo.user) === null || _userInfo$user8 === void 0 ? void 0 : _userInfo$user8.id
489
- },
490
- tokenExpiry: new Date(Date.now() + 3600 * 1000).toISOString(),
491
- // 1 hour from now
492
- requestRefreshToken: true
493
- })
934
+ body: JSON.stringify(backendPayload)
494
935
  });
936
+ console.log('๐Ÿ“ก Backend response status:', backendResponse.status);
937
+ console.log('๐Ÿ“ก Backend response headers:', backendResponse.headers);
495
938
  if (backendResponse.ok) {
939
+ var _responseData$validat2, _responseData$tempora2;
496
940
  const responseData = await backendResponse.json();
497
- console.log('โœ… YouTube connection processed by backend:', responseData);
941
+ console.log('โœ… YouTube connection successful');
942
+ console.log('๐Ÿ“‹ COMPLETE BACKEND RESPONSE:');
943
+ console.log(JSON.stringify(responseData, null, 2));
944
+
945
+ // โœ… Enhanced verification with temporary mode detection (exact backend fields)
946
+ const isTemporaryMode = ((_responseData$validat2 = responseData.validation) === null || _responseData$validat2 === void 0 ? void 0 : _responseData$validat2.isTemporaryMode) === true || ((_responseData$tempora2 = responseData.temporaryMode) === null || _responseData$tempora2 === void 0 ? void 0 : _responseData$tempora2.enabled) === true || responseData.isTemporaryMode === true || responseData.message && responseData.message.includes('temporary access token mode');
947
+ if (isTemporaryMode) {
948
+ console.log('๐Ÿ”„ [YOUTUBE AUTH] YouTube connected in temporary mode');
949
+ console.log('โœ… [YOUTUBE AUTH] Training will work, but connection expires in ~1 hour');
950
+ console.log('โ„น๏ธ [YOUTUBE AUTH] User can reconnect later for refresh tokens if needed');
951
+ } else if (responseData.hasRefreshToken || responseData.refreshTokenReceived) {
952
+ console.log('โœ… [YOUTUBE AUTH] Backend confirmed refresh token received');
953
+ console.log('โœ… [YOUTUBE AUTH] Full YouTube connection with persistent access');
954
+ } else {
955
+ console.warn('โš ๏ธ [YOUTUBE AUTH] Backend did not confirm refresh token');
956
+ console.warn('๐Ÿ” [YOUTUBE AUTH] Response data keys:', Object.keys(responseData));
957
+ console.warn('โš ๏ธ [YOUTUBE AUTH] Connection may fail when tokens expire');
958
+ }
498
959
  return true;
499
960
  } else {
500
961
  const errorData = await backendResponse.text();
501
- console.error('โŒ Backend processing failed:', backendResponse.status, errorData);
962
+ console.error('โŒ YouTube auth failed:', backendResponse.status);
963
+ console.error('๐Ÿ“‹ BACKEND ERROR RESPONSE:');
964
+ console.error(errorData);
502
965
  return false;
503
966
  }
504
967
  } catch (error) {
505
968
  console.error('โŒ Google Sign-In error:', error);
506
- const {
507
- statusCodes: StatusCodes
508
- } = require('@react-native-google-signin/google-signin');
509
- if (error.code === StatusCodes.SIGN_IN_CANCELLED) {
969
+ if (error.code === statusCodes.SIGN_IN_CANCELLED) {
510
970
  console.log('User cancelled Google Sign-In');
511
- } else if (error.code === StatusCodes.IN_PROGRESS) {
971
+ } else if (error.code === statusCodes.IN_PROGRESS) {
512
972
  console.log('Google Sign-In already in progress');
513
- } else if (error.code === StatusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
973
+ } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
514
974
  console.log('Google Play Services not available');
515
975
  }
516
976
  return false;
517
977
  }
518
978
  }
519
- return false;
520
- };
521
-
522
- /**
523
- * Handles the OAuth callback
524
- * @param url The callback URL
525
- * @returns The authorization code extracted from the URL
526
- */
527
- export const handleOAuthCallback = url => {
528
- try {
529
- // Parse the URL
530
- const parsedUrl = new URL(url);
531
979
 
532
- // Extract the authorization code
533
- return parsedUrl.searchParams.get('code');
534
- } catch (error) {
535
- console.error('Error handling OAuth callback:', error);
536
- return null;
980
+ // Instagram is commented out in the UI, but keeping the code for future use
981
+ if (platform === 'instagram') {
982
+ // Simulate Facebook Login SDK for Instagram
983
+ console.log('Initiating Facebook Login for Instagram');
984
+ return new Promise(resolve => {
985
+ setTimeout(() => {
986
+ console.log('Facebook Login completed successfully');
987
+ resolve(true);
988
+ }, 1000);
989
+ });
537
990
  }
991
+ return false;
538
992
  };
539
993
 
540
- /**
541
- * Checks if a URL is an OAuth callback
542
- * @param url The URL to check
543
- * @returns True if the URL is an OAuth callback
994
+ /**
995
+ * Check if a URL is an OAuth callback
544
996
  */
545
997
  export const isOAuthCallback = url => {
546
- // Check if the URL starts with our redirect URI
547
- return url.startsWith('onairosanime://auth/');
998
+ return url.includes('auth/callback') || url.includes('code=');
548
999
  };
549
1000
 
550
- /**
551
- * Test connectivity to the Onairos API server
1001
+ /**
1002
+ * Exchange authorization code for access token
1003
+ * This would typically be done on a server, but we're simulating it here
552
1004
  */
553
- export const testApiConnectivity = async () => {
1005
+ export const exchangeCodeForToken = async (code, platform) => {
1006
+ console.log(`Exchanging code for token for platform: ${platform}`);
554
1007
  try {
555
- console.log('๐Ÿ” Testing connectivity to Onairos API...');
556
-
557
- // Test multiple endpoints for better reliability
558
- const testEndpoints = ['https://api2.onairos.uk/health', 'https://api2.onairos.uk' // Base URL
559
- ];
560
- let lastError = null;
561
- for (const endpoint of testEndpoints) {
562
- try {
563
- console.log(`๐Ÿ” Testing endpoint: ${endpoint}`);
564
- const controller = new AbortController();
565
- const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
566
-
567
- const response = await fetch(endpoint, {
568
- method: 'GET',
569
- headers: {
570
- 'Content-Type': 'application/json',
571
- 'User-Agent': 'OnairosReactNative/1.0'
572
- },
573
- signal: controller.signal
574
- });
575
- clearTimeout(timeoutId);
576
- console.log(`๐ŸŒ API connectivity test response for ${endpoint}:`, response.status);
577
- if (response.ok || response.status === 404) {
578
- // Accept 404 as it means the server is reachable
579
- console.log('โœ… API server is reachable');
580
- return {
581
- success: true
582
- };
583
- } else {
584
- console.log(`โš ๏ธ API server responded with status ${response.status} for ${endpoint}`);
585
- lastError = `API server error: ${response.status}`;
586
- // Continue to next endpoint
587
- }
588
- } catch (fetchError) {
589
- console.log(`โŒ Failed to reach ${endpoint}:`, fetchError);
590
- if (fetchError.name === 'AbortError') {
591
- lastError = 'Connection timeout - API server took too long to respond';
592
- } else if (fetchError.message.includes('Network request failed')) {
593
- lastError = 'Network error - check your internet connection';
594
- } else if (fetchError.message.includes('not connected to the internet')) {
595
- lastError = 'No internet connection';
596
- } else {
597
- lastError = `Network error: ${fetchError.message}`;
598
- }
1008
+ // Use the proxy server to exchange the code for a token
1009
+ const tokenUrl = `https://api2.onairos.uk/${platform}/token`;
599
1010
 
600
- // Continue to next endpoint
601
- }
1011
+ // Make a POST request to the proxy
1012
+ const response = await fetch(tokenUrl, {
1013
+ method: 'POST',
1014
+ headers: {
1015
+ 'Content-Type': 'application/json'
1016
+ },
1017
+ body: JSON.stringify({
1018
+ code: code,
1019
+ platform: platform
1020
+ })
1021
+ });
1022
+ if (!response.ok) {
1023
+ console.error(`Error exchanging code for token: ${response.status}`);
1024
+ throw new Error(`Token exchange failed with status ${response.status}`);
602
1025
  }
603
- console.error('โŒ All API connectivity tests failed');
604
- return {
605
- success: false,
606
- error: lastError || 'Cannot reach API server'
607
- };
1026
+ const data = await response.json();
1027
+ console.log(`Token exchange successful for ${platform}`);
1028
+ return data;
608
1029
  } catch (error) {
609
- console.error('โŒ API connectivity test failed:', error);
610
- return {
611
- success: false,
612
- error: error instanceof Error ? error.message : 'Unknown error'
613
- };
614
- }
615
- };
1030
+ console.error(`Error exchanging code for token:`, error);
616
1031
 
617
- /**
618
- * ๐Ÿ”„ REFRESH GOOGLE TOKENS
619
- */
620
- export const refreshGoogleTokens = async () => {
621
- try {
622
- console.log('๐Ÿ”„ Attempting to refresh Google tokens...');
623
- const {
624
- GoogleSignin
625
- } = require('@react-native-google-signin/google-signin');
626
- const currentUser = await GoogleSignin.getCurrentUser();
627
- if (!currentUser) {
628
- console.log('โŒ User not signed in to Google, cannot refresh tokens');
629
- return null;
630
- }
631
- const tokens = await GoogleSignin.getTokens();
632
- console.log('โœ… Successfully refreshed Google tokens');
1032
+ // Fallback to simulation if the API call fails
1033
+ console.log('Falling back to simulated token response');
633
1034
  return {
634
- accessToken: tokens.accessToken,
635
- idToken: tokens.idToken
1035
+ access_token: `${platform}_access_token_${Math.random().toString(36).substring(7)}`,
1036
+ refresh_token: `${platform}_refresh_token_${Math.random().toString(36).substring(7)}`,
1037
+ expires_in: 3600
636
1038
  };
637
- } catch (error) {
638
- console.error('โŒ Failed to refresh Google tokens:', error);
639
-
640
- // If refresh fails, try to sign in again
641
- try {
642
- console.log('๐Ÿ”„ Refresh failed, attempting re-authentication...');
643
- const {
644
- GoogleSignin
645
- } = require('@react-native-google-signin/google-signin');
646
- const userInfo = await GoogleSignin.signIn();
647
- const tokens = await GoogleSignin.getTokens();
648
- console.log('โœ… Re-authentication successful');
649
- return {
650
- accessToken: tokens.accessToken,
651
- idToken: tokens.idToken
652
- };
653
- } catch (signInError) {
654
- console.error('โŒ Re-authentication also failed:', signInError);
655
- return null;
656
- }
657
1039
  }
658
1040
  };
659
1041
 
660
- /**
661
- * ๐Ÿ”„ REFRESH YOUTUBE TOKENS
1042
+ /**
1043
+ * Refresh YouTube tokens when they expire
1044
+ * This should be called when the backend reports token expiry
662
1045
  */
663
1046
  export const refreshYouTubeTokens = async () => {
664
1047
  try {
665
- var _currentUser$user2;
1048
+ var _currentUser$user3;
666
1049
  console.log('๐Ÿ”„ Refreshing YouTube tokens...');
667
1050
 
668
1051
  // Get fresh tokens from Google SDK
669
- const freshTokens = await refreshGoogleTokens();
1052
+ const freshTokens = await GoogleSignin.getTokens();
670
1053
  if (!freshTokens) {
671
1054
  console.error('โŒ Failed to get fresh tokens from Google SDK');
672
1055
  return false;
673
1056
  }
674
1057
 
675
1058
  // Get current user info
676
- const {
677
- GoogleSignin
678
- } = require('@react-native-google-signin/google-signin');
679
1059
  const currentUser = await GoogleSignin.getCurrentUser();
680
1060
  if (!currentUser) {
681
1061
  console.error('โŒ No current Google user found');
@@ -694,14 +1074,15 @@ export const refreshYouTubeTokens = async () => {
694
1074
  method: 'POST',
695
1075
  headers: {
696
1076
  'Content-Type': 'application/json',
697
- 'Authorization': `Bearer ${authToken}`
1077
+ 'Authorization': authToken
698
1078
  },
699
1079
  body: JSON.stringify({
700
1080
  accessToken: freshTokens.accessToken,
701
1081
  idToken: freshTokens.idToken,
702
1082
  refreshToken: currentUser.serverAuthCode,
703
- userEmail: (_currentUser$user2 = currentUser.user) === null || _currentUser$user2 === void 0 ? void 0 : _currentUser$user2.email,
1083
+ userEmail: (_currentUser$user3 = currentUser.user) === null || _currentUser$user3 === void 0 ? void 0 : _currentUser$user3.email,
704
1084
  tokenExpiry: new Date(Date.now() + 3600 * 1000).toISOString(),
1085
+ // 1 hour from now
705
1086
  timestamp: new Date().toISOString()
706
1087
  })
707
1088
  });
@@ -720,322 +1101,180 @@ export const refreshYouTubeTokens = async () => {
720
1101
  }
721
1102
  };
722
1103
 
723
- /**
724
- * ๐ŸŽฏ ENHANCED OAUTH CALLBACK HANDLER
1104
+ /**
1105
+ * Trigger training restart after YouTube re-authentication
1106
+ * This signals the backend to restart training with the new refresh token
725
1107
  */
726
- export const handleOAuthCallbackUrl = url => {
1108
+ const triggerTrainingRestart = async (username, authToken) => {
727
1109
  try {
728
- console.log('๐Ÿ” Processing OAuth callback URL:', url);
729
-
730
- // Parse the URL
731
- const parsedUrl = new URL(url);
732
-
733
- // Extract platform and code
734
- const platform = parsedUrl.searchParams.get('platform') || parsedUrl.pathname.split('/').find(segment => ['instagram', 'youtube', 'reddit', 'pinterest', 'email'].includes(segment));
735
- const code = parsedUrl.searchParams.get('code');
736
- const error = parsedUrl.searchParams.get('error');
737
- if (error) {
738
- console.error('โŒ OAuth error in callback:', error);
739
- return {
740
- success: false
741
- };
742
- }
743
- if (code && platform) {
744
- console.log(`โœ… OAuth callback processed: ${platform} with code: ${code.substring(0, 10)}...`);
745
- return {
746
- platform,
747
- code,
748
- success: true
749
- };
1110
+ console.log('๐Ÿ”„ [TRAINING RESTART] Triggering training restart for user:', username);
1111
+ const response = await fetch('https://api2.onairos.uk/mobile-training/restart', {
1112
+ method: 'POST',
1113
+ headers: {
1114
+ 'Content-Type': 'application/json',
1115
+ 'Authorization': authToken
1116
+ },
1117
+ body: JSON.stringify({
1118
+ username: username,
1119
+ reason: 'youtube_reauth',
1120
+ platform: 'youtube',
1121
+ timestamp: new Date().toISOString(),
1122
+ requestNewTraining: true
1123
+ })
1124
+ });
1125
+ if (response.ok) {
1126
+ const responseData = await response.json();
1127
+ console.log('โœ… [TRAINING RESTART] Training restart successful:', responseData);
1128
+ } else {
1129
+ const errorData = await response.text();
1130
+ console.error('โŒ [TRAINING RESTART] Training restart failed:', response.status, errorData);
1131
+ throw new Error(`Training restart failed: ${response.status}`);
750
1132
  }
751
- console.warn('โš ๏ธ OAuth callback missing platform or code');
752
- return {
753
- success: false
754
- };
755
1133
  } catch (error) {
756
- console.error('โŒ Error processing OAuth callback:', error);
757
- return {
758
- success: false
759
- };
1134
+ console.error('โŒ [TRAINING RESTART] Error triggering training restart:', error);
1135
+ throw error;
760
1136
  }
761
1137
  };
762
1138
 
763
- /**
764
- * ๐Ÿ”ง UPDATE GOOGLE CLIENT IDS
765
- * Allows apps to configure their own Google client IDs
1139
+ /**
1140
+ * Test function to verify YouTube refresh token functionality
1141
+ * Call this in your app to test the YouTube connection
766
1142
  */
767
- export const updateGoogleClientIds = config => {
768
- console.log('๐Ÿ”ง Updating Google client IDs configuration');
769
- if (config.webClientId || config.iosClientId) {
770
- // Update the YouTube configuration
771
- PLATFORM_AUTH_CONFIG.youtube = {
772
- ...PLATFORM_AUTH_CONFIG.youtube,
773
- clientId: config.webClientId || PLATFORM_AUTH_CONFIG.youtube.clientId,
774
- iosClientId: config.iosClientId || PLATFORM_AUTH_CONFIG.youtube.iosClientId
775
- };
776
- console.log('โœ… Google client IDs updated successfully');
777
- console.log(' - Web Client ID:', config.webClientId ? config.webClientId.substring(0, 20) + '...' : 'not provided');
778
- console.log(' - iOS Client ID:', config.iosClientId ? config.iosClientId.substring(0, 20) + '...' : 'not provided');
1143
+ export const testYouTubeRefreshToken = async username => {
1144
+ console.log('๐Ÿงช Testing YouTube refresh token functionality...');
1145
+ console.log('๐Ÿ‘ค User:', username);
1146
+ try {
1147
+ // Test the debug function first
1148
+ const debugInfo = await debugYouTubeTokens();
1149
+ console.log('๐Ÿ” Current token status:', debugInfo);
1150
+ if (!debugInfo.hasRefreshToken) {
1151
+ console.log('โš ๏ธ No refresh token found - attempting to fix...');
1152
+ const success = await fixUserYouTubeConnection(username);
1153
+ if (success) {
1154
+ console.log('โœ… YouTube connection fixed! Testing again...');
1155
+ const newDebugInfo = await debugYouTubeTokens();
1156
+ console.log('๐Ÿ” New token status:', newDebugInfo);
1157
+ } else {
1158
+ console.error('โŒ Failed to fix YouTube connection');
1159
+ }
1160
+ } else {
1161
+ console.log('โœ… Refresh token already available');
1162
+ }
1163
+ } catch (error) {
1164
+ console.error('โŒ Error testing YouTube refresh token:', error);
779
1165
  }
780
1166
  };
781
1167
 
782
- /**
783
- * Request email verification using developer API key
784
- * @param email Email address to verify
785
- * @param testMode Whether to use test mode
786
- * @returns Promise with verification result
1168
+ /**
1169
+ * Request email verification code
787
1170
  */
788
1171
  export const requestEmailVerification = async (email, testMode = false) => {
789
1172
  try {
790
1173
  console.log('๐Ÿ“ง Requesting email verification for:', email);
791
- const response = await makeDeveloperRequest('/email/verification', {
1174
+ const response = await fetch(`${API_CONFIG.BASE_URL}/email/verification`, {
792
1175
  method: 'POST',
1176
+ headers: getApiHeaders(),
793
1177
  body: JSON.stringify({
794
1178
  email,
795
1179
  action: 'request',
796
1180
  testMode
797
1181
  })
798
1182
  });
799
- const data = await response.json();
800
- if (response.ok && data.success) {
801
- console.log('โœ… Email verification requested successfully');
1183
+ const result = await response.json();
1184
+ if (response.ok) {
802
1185
  return {
803
1186
  success: true,
804
- message: data.message || 'Verification code sent to your email'
1187
+ message: result.message || 'Verification code sent to your email'
805
1188
  };
806
1189
  } else {
807
- console.error('โŒ Email verification request failed:', data.error);
808
1190
  return {
809
1191
  success: false,
810
- error: data.error || 'Failed to send verification code'
1192
+ error: result.message || 'Failed to send verification code'
811
1193
  };
812
1194
  }
813
1195
  } catch (error) {
814
1196
  console.error('โŒ Error requesting email verification:', error);
815
1197
  return {
816
1198
  success: false,
817
- error: error instanceof Error ? error.message : 'Network error'
1199
+ error: 'Network error. Please check your connection and try again.'
818
1200
  };
819
1201
  }
820
1202
  };
821
1203
 
822
- /**
823
- * Verify email code and store JWT token
824
- * @param email Email address
825
- * @param code Verification code
826
- * @param testMode Whether to use test mode
827
- * @returns Promise with verification result and JWT token
1204
+ /**
1205
+ * Verify email code
828
1206
  */
829
1207
  export const verifyEmailCode = async (email, code, testMode = false) => {
830
1208
  try {
831
1209
  console.log('๐Ÿ” Verifying email code for:', email);
832
- const response = await makeDeveloperRequest('/email/verification', {
1210
+ const response = await fetch(`${API_CONFIG.BASE_URL}/email/verification`, {
833
1211
  method: 'POST',
1212
+ headers: getApiHeaders(),
834
1213
  body: JSON.stringify({
835
1214
  email,
836
- action: 'verify',
837
1215
  code,
1216
+ action: 'verify',
838
1217
  testMode
839
1218
  })
840
1219
  });
841
- const data = await response.json();
842
- if (response.ok && data.success) {
843
- console.log('โœ… Email verification successful');
844
-
845
- // Store JWT token if received
846
- if (data.token || data.jwtToken) {
847
- const jwtToken = data.token || data.jwtToken;
848
- await storeJWT(jwtToken);
849
- console.log('๐ŸŽซ JWT token stored successfully');
850
- }
1220
+ const result = await response.json();
1221
+ if (response.ok) {
851
1222
  return {
852
1223
  success: true,
853
- message: data.message || 'Email verified successfully',
854
- existingUser: data.existingUser || false,
855
- token: data.token || data.jwtToken
1224
+ message: result.message || 'Email verified successfully',
1225
+ existingUser: result.existingUser || false,
1226
+ token: result.token
856
1227
  };
857
1228
  } else {
858
- console.error('โŒ Email verification failed:', data.error);
859
1229
  return {
860
1230
  success: false,
861
- error: data.error || 'Invalid verification code'
1231
+ error: result.message || 'Invalid verification code'
862
1232
  };
863
1233
  }
864
1234
  } catch (error) {
865
1235
  console.error('โŒ Error verifying email code:', error);
866
1236
  return {
867
1237
  success: false,
868
- error: error instanceof Error ? error.message : 'Network error'
1238
+ error: 'Network error. Please check your connection and try again.'
869
1239
  };
870
1240
  }
871
1241
  };
872
1242
 
873
- /**
874
- * Check email verification status
875
- * @param email Email address
876
- * @param testMode Whether to use test mode
877
- * @returns Promise with status result
1243
+ /**
1244
+ * Check email verification status
878
1245
  */
879
1246
  export const checkEmailVerificationStatus = async (email, testMode = false) => {
880
1247
  try {
881
- console.log('๐Ÿ” Checking email verification status for:', email);
882
- const response = await makeDeveloperRequest('/email/verification/status', {
1248
+ const response = await fetch(`${API_CONFIG.BASE_URL}/email/verification/status`, {
883
1249
  method: 'POST',
1250
+ headers: getApiHeaders(),
884
1251
  body: JSON.stringify({
885
1252
  email,
886
1253
  testMode
887
1254
  })
888
1255
  });
889
- const data = await response.json();
890
- if (response.ok && data.success) {
891
- return {
892
- success: true,
893
- isPending: data.isPending || false
894
- };
895
- } else {
896
- return {
897
- success: false,
898
- error: data.error || 'Failed to check verification status'
899
- };
900
- }
901
- } catch (error) {
902
- console.error('โŒ Error checking email verification status:', error);
1256
+ const result = await response.json();
903
1257
  return {
904
- success: false,
905
- error: error instanceof Error ? error.message : 'Network error'
1258
+ success: response.ok,
1259
+ isPending: result.isPending || false,
1260
+ message: result.message
906
1261
  };
907
- }
908
- };
909
-
910
- /**
911
- * Disconnect a platform (uses developer API key)
912
- * @param platform Platform to disconnect
913
- * @param username Username associated with the platform
914
- * @returns Promise with disconnect result
915
- */
916
- export const disconnectPlatform = async (platform, username) => {
917
- try {
918
- console.log('๐Ÿ”Œ Disconnecting platform:', platform, 'for user:', username);
919
-
920
- // Make authenticated API call to disconnect platform
921
- const response = await makeDeveloperRequest('/revoke', {
922
- method: 'POST',
923
- body: JSON.stringify({
924
- platform,
925
- username
926
- })
927
- });
928
- const data = await response.json();
929
- if (response.ok && data.success) {
930
- console.log(`โœ… ${platform} disconnected successfully`);
931
- return {
932
- success: true
933
- };
934
- } else {
935
- console.error(`โŒ Failed to disconnect ${platform}:`, data.error);
936
- return {
937
- success: false,
938
- error: data.error || 'Failed to disconnect platform'
939
- };
940
- }
941
1262
  } catch (error) {
942
- console.error(`โŒ Error disconnecting ${platform}:`, error);
943
- return {
944
- success: false,
945
- error: error instanceof Error ? error.message : 'Network error'
946
- };
947
- }
948
- };
949
-
950
- /**
951
- * Store PIN for user (uses JWT authentication and extracts username from JWT)
952
- * @param pin User PIN
953
- * @param username Optional username (if not provided, extracts from JWT)
954
- * @returns Promise with result
955
- */
956
- export const storePIN = async (pin, username) => {
957
- try {
958
- // Extract username from JWT if not provided
959
- const userToStore = username || extractUsernameFromJWT();
960
- if (!userToStore) {
961
- console.error('โŒ No username available - either provide username or ensure JWT token is valid');
962
- return {
963
- success: false,
964
- error: 'No username available for PIN storage'
965
- };
966
- }
967
- console.log('๐Ÿ” Storing PIN for user:', userToStore);
968
-
969
- // Make authenticated request to store PIN (using developer API key for now)
970
- const response = await makeDeveloperRequest('/store-pin/web', {
971
- method: 'POST',
972
- headers: {
973
- 'Content-Type': 'application/json'
974
- },
975
- body: JSON.stringify({
976
- username: userToStore,
977
- pin
978
- })
979
- });
980
- const data = await response.json();
981
- if (response.ok && data.success) {
982
- console.log('โœ… PIN stored successfully for user:', userToStore);
983
- return {
984
- success: true
985
- };
986
- } else {
987
- console.error('โŒ Failed to store PIN:', data.error);
988
- return {
989
- success: false,
990
- error: data.error || 'Failed to store PIN'
991
- };
992
- }
993
- } catch (error) {
994
- console.error('โŒ Error storing PIN:', error);
1263
+ console.error('โŒ Error checking email verification status:', error);
995
1264
  return {
996
1265
  success: false,
997
- error: error instanceof Error ? error.message : 'Network error'
1266
+ isPending: false,
1267
+ error: 'Network error'
998
1268
  };
999
1269
  }
1000
1270
  };
1001
1271
 
1002
- /**
1003
- * ๐ŸŽซ GET STORED JWT TOKEN
1004
- * Helper function to retrieve stored JWT token from email verification or other sources
1272
+ /**
1273
+ * Initialize platform auth service
1005
1274
  */
1006
- export const getStoredJwtToken = async () => {
1007
- try {
1008
- console.log('๐ŸŽซ Retrieving stored JWT token...');
1009
-
1010
- // Try different storage keys in order of preference
1011
- const tokenSources = ['email_verification_token', 'onairos_jwt_token', 'enoch_token', 'auth_token'];
1012
- for (const source of tokenSources) {
1013
- const token = await AsyncStorage.getItem(source);
1014
- if (token && token.length > 20) {
1015
- console.log(`โœ… JWT token found in ${source}:`, token.substring(0, 20) + '...');
1016
- return token;
1017
- }
1018
- }
1019
- console.warn('โš ๏ธ No JWT token found in storage');
1020
- return null;
1021
- } catch (error) {
1022
- console.error('โŒ Error retrieving JWT token:', error);
1023
- return null;
1024
- }
1025
- };
1026
-
1027
- /**
1028
- * ๐ŸŽซ CLEAR STORED TOKENS
1029
- * Helper function to clear all stored tokens (useful for logout)
1030
- */
1031
- export const clearStoredTokens = async () => {
1032
- try {
1033
- console.log('๐Ÿงน Clearing all stored tokens...');
1034
- const tokenKeys = ['email_verification_token', 'onairos_jwt_token', 'enoch_token', 'auth_token', 'email_verification_email', 'email_verification_request_id', 'email_verification_request_email', 'token_timestamp', 'user_pin_stored', 'pin_storage_timestamp'];
1035
- await Promise.all(tokenKeys.map(key => AsyncStorage.removeItem(key)));
1036
- console.log('โœ… All tokens cleared successfully');
1037
- } catch (error) {
1038
- console.error('โŒ Error clearing tokens:', error);
1039
- }
1275
+ export const initializePlatformAuthService = () => {
1276
+ console.log('๐Ÿ”ง Platform auth service initialized');
1277
+ // Initialize Google Sign-In
1278
+ initializeGoogleSignIn();
1040
1279
  };
1041
1280
  //# sourceMappingURL=platformAuthService.js.map