@onairos/react-native 3.7.2 → 3.7.3
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.
- package/lib/commonjs/api/index.js +219 -9
- package/lib/commonjs/components/BodyText.js +27 -9
- package/lib/commonjs/components/BrandMark.js +111 -10
- package/lib/commonjs/components/CodeInput.js +116 -9
- package/lib/commonjs/components/EmailInput.js +30 -8
- package/lib/commonjs/components/GoogleButton.js +56 -9
- package/lib/commonjs/components/HeadingGroup.js +43 -9
- package/lib/commonjs/components/LLMDataInputModal.js +664 -14
- package/lib/commonjs/components/ModalHeader.js +99 -9
- package/lib/commonjs/components/ModalSheet.js +47 -9
- package/lib/commonjs/components/Onairos.js +380 -14
- package/lib/commonjs/components/OnairosButton.js +313 -13
- package/lib/commonjs/components/OnairosSignInButton.js +130 -12
- package/lib/commonjs/components/Overlay.js +465 -13
- package/lib/commonjs/components/PersonaImage.js +137 -10
- package/lib/commonjs/components/PersonaLoadingScreen.js +318 -12
- package/lib/commonjs/components/PersonalizationConsentScreen.js +467 -13
- package/lib/commonjs/components/PinCreationScreen.js +403 -12
- package/lib/commonjs/components/PinInput.js +464 -9
- package/lib/commonjs/components/PlatformConnectorsStep.js +1311 -23
- package/lib/commonjs/components/PlatformList.js +137 -10
- package/lib/commonjs/components/PlatformToggle.js +180 -9
- package/lib/commonjs/components/PrimaryButton.js +180 -10
- package/lib/commonjs/components/SignInMatchAnimation.js +197 -9
- package/lib/commonjs/components/SignInStep.js +345 -12
- package/lib/commonjs/components/UniversalOnboarding.js +2780 -30
- package/lib/commonjs/components/VerificationStep.js +176 -11
- package/lib/commonjs/components/WelcomeScreen.js +461 -22
- package/lib/commonjs/components/icons/Basicproficon.js +37 -8
- package/lib/commonjs/components/icons/Basicprofile.js +21 -8
- package/lib/commonjs/components/icons/Checkbox.js +21 -8
- package/lib/commonjs/components/icons/Checkmark.js +27 -8
- package/lib/commonjs/components/icons/Contentanalysis.js +21 -8
- package/lib/commonjs/components/icons/Contenticon.js +39 -8
- package/lib/commonjs/components/icons/EnochE.js +41 -8
- package/lib/commonjs/components/icons/Personalityicon.js +30 -8
- package/lib/commonjs/components/icons/Personalityprofile.js +21 -8
- package/lib/commonjs/components/icons/Personalitytraits.js +21 -8
- package/lib/commonjs/components/icons/Userpreferences.js +21 -8
- package/lib/commonjs/components/icons/index.js +84 -17
- package/lib/commonjs/components/onboarding/OAuthWebView.js +1754 -18
- package/lib/commonjs/components/onboarding/OnboardingHeader.js +74 -10
- package/lib/commonjs/components/onboarding/PinInput.js +283 -10
- package/lib/commonjs/components/onboarding/PlatformConnector.js +249 -11
- package/lib/commonjs/config/PLATFORM_APIS.md +849 -0
- package/lib/commonjs/config/api.js +56 -7
- package/lib/commonjs/constants/index.js +120 -7
- package/lib/commonjs/context/AuthContext.js +345 -10
- package/lib/commonjs/hooks/useConnectedAccounts.js +111 -9
- package/lib/commonjs/hooks/useConnections.js +102 -8
- package/lib/commonjs/hooks/useCredentials.js +178 -10
- package/lib/commonjs/hooks/useUserConnections.js +148 -10
- package/lib/commonjs/index.js +439 -34
- package/lib/commonjs/services/apiClient.js +298 -8
- package/lib/commonjs/services/biometricPinService.js +180 -8
- package/lib/commonjs/services/chatGPTConversationExtractor.js +155 -8
- package/lib/commonjs/services/chatGPTConversationService.js +275 -9
- package/lib/commonjs/services/claudeConversationExtractor.js +103 -8
- package/lib/commonjs/services/claudeConversationService.js +158 -9
- package/lib/commonjs/services/connectedAccountsService.js +310 -10
- package/lib/commonjs/services/googleAuthService.js +252 -11
- package/lib/commonjs/services/hingeDataExtractor.js +105 -8
- package/lib/commonjs/services/hingeDataService.js +150 -9
- package/lib/commonjs/services/imageCompressionService.js +260 -7
- package/lib/commonjs/services/instagramDataExtractor.js +126 -8
- package/lib/commonjs/services/instagramDataService.js +163 -9
- package/lib/commonjs/services/jwtStorageService.js +276 -7
- package/lib/commonjs/services/linkedinDOMExtractor.js +245 -7
- package/lib/commonjs/services/linkedinProfileService.js +222 -9
- package/lib/commonjs/services/linkedinScrapingService.js +230 -8
- package/lib/commonjs/services/llmDataStorage.js +294 -8
- package/lib/commonjs/services/mobileTrainingService.js +186 -8
- package/lib/commonjs/services/netflixDataExtractor.js +120 -8
- package/lib/commonjs/services/netflixDataService.js +198 -9
- package/lib/commonjs/services/pinEncryptionService.js +84 -8
- package/lib/commonjs/services/pinStorageUtils.js +105 -7
- package/lib/commonjs/services/platformAuthService.js +1484 -12
- package/lib/commonjs/services/sephoraDataExtractor.js +140 -8
- package/lib/commonjs/services/sephoraDataService.js +200 -9
- package/lib/commonjs/services/spotifyDataExtractor.js +148 -8
- package/lib/commonjs/services/spotifyDataService.js +241 -9
- package/lib/commonjs/services/storageService.js +404 -8
- package/lib/commonjs/services/telegramDataExtractor.js +115 -8
- package/lib/commonjs/services/telegramDataService.js +499 -9
- package/lib/commonjs/services/trainingApiHelpers.js +73 -7
- package/lib/commonjs/services/userConnectionsService.js +340 -10
- package/lib/commonjs/services/youtubeMigrationService.js +416 -10
- package/lib/commonjs/theme/index.js +250 -7
- package/lib/commonjs/types/ambient.d.js +2 -1
- package/lib/commonjs/types/declarations.d.js +2 -1
- package/lib/commonjs/types/index.js +6 -1
- package/lib/commonjs/types/node-fix.d.js +2 -1
- package/lib/commonjs/types/node-override.d.js +2 -1
- package/lib/commonjs/types/opacity.d.js +2 -1
- package/lib/commonjs/types.js +14 -1
- package/lib/commonjs/utils/Portal.js +98 -8
- package/lib/commonjs/utils/api.js +130 -9
- package/lib/commonjs/utils/assetRegistry.js +210 -35
- package/lib/commonjs/utils/auth.js +112 -9
- package/lib/commonjs/utils/connectorTests.js +613 -29
- package/lib/commonjs/utils/crypto.js +62 -8
- package/lib/commonjs/utils/debugHelper.js +64 -1
- package/lib/commonjs/utils/encryption.js +76 -7
- package/lib/commonjs/utils/eventUtils.js +288 -1
- package/lib/commonjs/utils/haptics.js +66 -9
- package/lib/commonjs/utils/imagePreloader.js +6 -1
- package/lib/commonjs/utils/networkDiagnostics.js +226 -8
- package/lib/commonjs/utils/onairosApi.js +350 -9
- package/lib/commonjs/utils/programmaticFlow.js +117 -9
- package/lib/commonjs/utils/retryHelper.js +220 -1
- package/lib/commonjs/utils/secureStorage.js +349 -10
- package/lib/commonjs/utils/webviewScripts/chatgpt.js +551 -1
- package/lib/commonjs/utils/webviewScripts/claude.js +376 -1
- package/lib/commonjs/utils/webviewScripts/hinge.js +411 -1
- package/lib/commonjs/utils/webviewScripts/index.js +698 -15
- package/lib/commonjs/utils/webviewScripts/instagram.js +454 -1
- package/lib/commonjs/utils/webviewScripts/linkedin.js +880 -1
- package/lib/commonjs/utils/webviewScripts/netflix.js +382 -1
- package/lib/commonjs/utils/webviewScripts/sephora.js +516 -1
- package/lib/commonjs/utils/webviewScripts/spotify.js +419 -1
- package/lib/commonjs/utils/webviewScripts/telegram.js +678 -1
- package/lib/module/api/index.js +211 -1
- package/lib/module/components/BodyText.js +20 -1
- package/lib/module/components/BrandMark.js +104 -1
- package/lib/module/components/CodeInput.js +109 -1
- package/lib/module/components/EmailInput.js +23 -1
- package/lib/module/components/GoogleButton.js +49 -1
- package/lib/module/components/HeadingGroup.js +36 -1
- package/lib/module/components/LLMDataInputModal.js +656 -7
- package/lib/module/components/ModalHeader.js +92 -1
- package/lib/module/components/ModalSheet.js +39 -1
- package/lib/module/components/Onairos.js +373 -1
- package/lib/module/components/OnairosButton.js +305 -1
- package/lib/module/components/OnairosSignInButton.js +121 -1
- package/lib/module/components/Overlay.js +456 -1
- package/lib/module/components/PersonaImage.js +129 -1
- package/lib/module/components/PersonaLoadingScreen.js +310 -1
- package/lib/module/components/PersonalizationConsentScreen.js +460 -1
- package/lib/module/components/PinCreationScreen.js +396 -1
- package/lib/module/components/PinInput.js +456 -1
- package/lib/module/components/PlatformConnectorsStep.js +1302 -6
- package/lib/module/components/PlatformList.js +129 -1
- package/lib/module/components/PlatformToggle.js +173 -1
- package/lib/module/components/PrimaryButton.js +172 -1
- package/lib/module/components/SignInMatchAnimation.js +189 -1
- package/lib/module/components/SignInStep.js +338 -1
- package/lib/module/components/UniversalOnboarding.js +2770 -1
- package/lib/module/components/VerificationStep.js +168 -1
- package/lib/module/components/WelcomeScreen.js +453 -1
- package/lib/module/components/icons/Basicproficon.js +30 -1
- package/lib/module/components/icons/Basicprofile.js +14 -1
- package/lib/module/components/icons/Checkbox.js +14 -1
- package/lib/module/components/icons/Checkmark.js +20 -1
- package/lib/module/components/icons/Contentanalysis.js +14 -1
- package/lib/module/components/icons/Contenticon.js +32 -1
- package/lib/module/components/icons/EnochE.js +34 -1
- package/lib/module/components/icons/Personalityicon.js +23 -1
- package/lib/module/components/icons/Personalityprofile.js +14 -1
- package/lib/module/components/icons/Personalitytraits.js +14 -1
- package/lib/module/components/icons/Userpreferences.js +14 -1
- package/lib/module/components/icons/index.js +13 -1
- package/lib/module/components/onboarding/OAuthWebView.js +1746 -1
- package/lib/module/components/onboarding/OnboardingHeader.js +66 -1
- package/lib/module/components/onboarding/PinInput.js +274 -1
- package/lib/module/components/onboarding/PlatformConnector.js +240 -1
- package/lib/module/config/PLATFORM_APIS.md +849 -0
- package/lib/module/config/api.js +47 -1
- package/lib/module/constants/index.js +114 -1
- package/lib/module/context/AuthContext.js +335 -1
- package/lib/module/hooks/useConnectedAccounts.js +106 -1
- package/lib/module/hooks/useConnections.js +95 -1
- package/lib/module/hooks/useCredentials.js +171 -6
- package/lib/module/hooks/useUserConnections.js +140 -1
- package/lib/module/index.js +172 -1
- package/lib/module/services/apiClient.js +295 -1
- package/lib/module/services/biometricPinService.js +169 -1
- package/lib/module/services/chatGPTConversationExtractor.js +149 -1
- package/lib/module/services/chatGPTConversationService.js +268 -1
- package/lib/module/services/claudeConversationExtractor.js +97 -1
- package/lib/module/services/claudeConversationService.js +151 -1
- package/lib/module/services/connectedAccountsService.js +293 -1
- package/lib/module/services/googleAuthService.js +241 -1
- package/lib/module/services/hingeDataExtractor.js +99 -1
- package/lib/module/services/hingeDataService.js +143 -1
- package/lib/module/services/imageCompressionService.js +250 -1
- package/lib/module/services/instagramDataExtractor.js +120 -1
- package/lib/module/services/instagramDataService.js +156 -1
- package/lib/module/services/jwtStorageService.js +257 -1
- package/lib/module/services/linkedinDOMExtractor.js +234 -1
- package/lib/module/services/linkedinProfileService.js +210 -1
- package/lib/module/services/linkedinScrapingService.js +219 -1
- package/lib/module/services/llmDataStorage.js +277 -1
- package/lib/module/services/mobileTrainingService.js +173 -1
- package/lib/module/services/netflixDataExtractor.js +114 -1
- package/lib/module/services/netflixDataService.js +191 -1
- package/lib/module/services/pinEncryptionService.js +74 -6
- package/lib/module/services/pinStorageUtils.js +93 -1
- package/lib/module/services/platformAuthService.js +1461 -1
- package/lib/module/services/sephoraDataExtractor.js +134 -1
- package/lib/module/services/sephoraDataService.js +193 -1
- package/lib/module/services/spotifyDataExtractor.js +142 -1
- package/lib/module/services/spotifyDataService.js +234 -1
- package/lib/module/services/storageService.js +383 -1
- package/lib/module/services/telegramDataExtractor.js +109 -1
- package/lib/module/services/telegramDataService.js +493 -1
- package/lib/module/services/trainingApiHelpers.js +67 -1
- package/lib/module/services/userConnectionsService.js +329 -1
- package/lib/module/services/youtubeMigrationService.js +405 -1
- package/lib/module/theme/index.js +245 -1
- package/lib/module/types.js +10 -1
- package/lib/module/utils/Portal.js +90 -1
- package/lib/module/utils/api.js +118 -1
- package/lib/module/utils/assetRegistry.js +200 -34
- package/lib/module/utils/auth.js +100 -1
- package/lib/module/utils/connectorTests.js +600 -27
- package/lib/module/utils/crypto.js +54 -1
- package/lib/module/utils/debugHelper.js +54 -1
- package/lib/module/utils/encryption.js +67 -1
- package/lib/module/utils/eventUtils.js +270 -1
- package/lib/module/utils/haptics.js +59 -8
- package/lib/module/utils/imagePreloader.js +3 -1
- package/lib/module/utils/networkDiagnostics.js +217 -1
- package/lib/module/utils/onairosApi.js +333 -1
- package/lib/module/utils/programmaticFlow.js +111 -1
- package/lib/module/utils/retryHelper.js +211 -1
- package/lib/module/utils/secureStorage.js +330 -6
- package/lib/module/utils/webviewScripts/chatgpt.js +545 -1
- package/lib/module/utils/webviewScripts/claude.js +370 -1
- package/lib/module/utils/webviewScripts/hinge.js +405 -1
- package/lib/module/utils/webviewScripts/index.js +434 -1
- package/lib/module/utils/webviewScripts/instagram.js +448 -1
- package/lib/module/utils/webviewScripts/linkedin.js +874 -1
- package/lib/module/utils/webviewScripts/netflix.js +376 -1
- package/lib/module/utils/webviewScripts/sephora.js +510 -1
- package/lib/module/utils/webviewScripts/spotify.js +413 -1
- package/lib/module/utils/webviewScripts/telegram.js +672 -1
- package/package.json +2 -2
|
@@ -1 +1,405 @@
|
|
|
1
|
-
function _0x4b8d(_0x725da6,_0x4b8d47){_0x725da6=_0x725da6-0x0;const _0x393fd9=_0x725d();let _0x5616a0=_0x393fd9[_0x725da6];return _0x5616a0;}import{GoogleSignin}from'@react-native-google-signin/google-signin';import{Alert}from'react-native';import AsyncStorage from'@react-native-async-storage/async-storage';import{API_CONFIG}from'../config/api';const WEB_CLIENT_ID=_0x4b8d(0x0),IOS_CLIENT_ID=_0x4b8d(0x0),configureGoogleSignInForRefreshTokens=()=>{const _0x2e225a={'qwsvs':'https://www.googleapis.com/auth/youtube.readonly','FmLfg':'openid','LjxAI':_0x4b8d(0x1)};GoogleSignin[_0x4b8d(0x2)]({'webClientId':WEB_CLIENT_ID,'iosClientId':IOS_CLIENT_ID,'offlineAccess':!![],'forceCodeForRefreshToken':!![],'scopes':[_0x2e225a[_0x4b8d(0x3)],_0x2e225a[_0x4b8d(0x4)],_0x2e225a[_0x4b8d(0x5)],_0x4b8d(0x6)],'hostedDomain':'','accountName':''});};export const checkYouTubeMigrationNeeded=async _0x144b07=>{const _0x1d4515={'bggGh':_0x4b8d(0x7),'EOipS':function(_0x2585ec,_0x52d451){return _0x2585ec===_0x52d451;},'gTVUv':function(_0x40c631,_0x1e8176){return _0x40c631===_0x1e8176;},'Vpxcg':function(_0x25748c,_0x3110a2){return _0x25748c===_0x3110a2;},'PtfSU':function(_0x157778,_0x217287){return _0x157778===_0x217287;},'kJBvM':_0x4b8d(0x8),'ognYc':_0x4b8d(0x9),'gRKzY':'🔧\x20User\x20needs\x20YouTube\x20migration\x20for\x20refresh\x20token','NDtzN':'NEZuf','HfjRD':'✅\x20YouTube\x20connection\x20fully\x20working\x20with\x20refresh\x20tokens','hFyao':function(_0x27dcaf,_0x6df21a){return _0x27dcaf!==_0x6df21a;},'nWrUt':_0x4b8d(0xa),'Dandp':_0x4b8d(0xb),'oufai':_0x4b8d(0xc)};try{const _0x3fb48a=await fetch(API_CONFIG[_0x4b8d(0xd)]+_0x4b8d(0xe)+_0x144b07),_0x3ab737=await _0x3fb48a[_0x4b8d(0xf)]();if(_0x3ab737[_0x4b8d(0x10)]&&_0x3ab737[_0x4b8d(0x11)]){var _0x23645d,_0x52a57b,_0x5679c3;const _0x1abc5f=_0x1d4515['EOipS'](_0x1d4515[_0x4b8d(0x12)](_0x23645d=_0x3ab737[_0x4b8d(0x11)],null)||_0x1d4515[_0x4b8d(0x12)](_0x23645d,void 0x0)?void 0x0:_0x23645d[_0x4b8d(0x13)],!![])||(_0x1d4515[_0x4b8d(0x14)](_0x52a57b=_0x3ab737[_0x4b8d(0x15)],null)||_0x1d4515[_0x4b8d(0x12)](_0x52a57b,void 0x0)?void 0x0:_0x52a57b[_0x4b8d(0x16)])===!![]||_0x1d4515[_0x4b8d(0x17)](_0x3ab737[_0x4b8d(0x13)],!![])||_0x3ab737[_0x4b8d(0x18)]&&_0x3ab737[_0x4b8d(0x18)]['includes'](_0x4b8d(0x19)),_0x4dc2f2=_0x3ab737[_0x4b8d(0x11)]['needsReconnection'],_0x4cdabb=_0x3ab737['validation']['hasRefreshToken'];console[_0x4b8d(0x1a)](_0x4b8d(0x1b),{'username':_0x144b07,'needsReconnection':_0x4dc2f2,'hasRefreshToken':_0x4cdabb,'isTemporaryMode':_0x1abc5f,'temporaryModeEnabled':_0x1d4515[_0x4b8d(0x17)](_0x5679c3=_0x3ab737[_0x4b8d(0x15)],null)||_0x1d4515[_0x4b8d(0x1c)](_0x5679c3,void 0x0)?void 0x0:_0x5679c3[_0x4b8d(0x16)],'message':_0x3ab737['message']});if(_0x1abc5f)return console[_0x4b8d(0x1a)](_0x4b8d(0x7)),console[_0x4b8d(0x1a)](_0x1d4515['kJBvM']),![];else return _0x4dc2f2?_0x4b8d(0x9)!==_0x1d4515[_0x4b8d(0x1d)]?(_0x21b714[_0x4b8d(0x1a)](_0x4b8d(0x1e)),![]):(console[_0x4b8d(0x1a)](_0x1d4515[_0x4b8d(0x1f)]),!![]):_0x1d4515['NDtzN']==='NEZuf'?(console[_0x4b8d(0x1a)](_0x1d4515[_0x4b8d(0x20)]),![]):(_0x1dd509['log'](_0x4b8d(0x21)),!![]);}return![];}catch(_0x2f39a1){return _0x1d4515[_0x4b8d(0x22)](_0x1d4515[_0x4b8d(0x23)],_0x1d4515[_0x4b8d(0x24)])?(console[_0x4b8d(0x25)](_0x1d4515['oufai'],_0x2f39a1),![]):(_0x2ea87e['log'](_0x1d4515['bggGh']),_0x53765c[_0x4b8d(0x1a)](_0x4b8d(0x8)),![]);}};export const getYouTubeConnectionStatus=async _0x3c2243=>{const _0x517199={'obZfB':'migration_token_placeholder','oLKLT':function(_0x20ccb7,_0x5a9258){return _0x20ccb7===_0x5a9258;},'suFKb':function(_0x5c4909,_0x5823e1){return _0x5c4909===_0x5823e1;},'qVGhM':function(_0x1268c2,_0x4dda93){return _0x1268c2===_0x4dda93;},'ZHqvN':function(_0x28a487,_0x19519e){return _0x28a487===_0x19519e;},'iqLoa':function(_0x25cd8a,_0x48eddb){return _0x25cd8a===_0x48eddb;},'UauFl':function(_0x59bbe1,_0x69b7b0){return _0x59bbe1===_0x69b7b0;},'kscvY':function(_0x464718,_0x24ead5){return _0x464718===_0x24ead5;},'iWiOP':_0x4b8d(0x26),'CiLzB':_0x4b8d(0x27),'DICIb':function(_0x48573a,_0x352d95){return _0x48573a&&_0x352d95;},'hXLhn':_0x4b8d(0x28),'LJXHC':_0x4b8d(0x29),'XCAEP':'ℹ️\x20No\x20token\x20cache\x20to\x20clear','aInXj':_0x4b8d(0x2a),'izFcx':function(_0x1dca7c,_0x345d73){return _0x1dca7c===_0x345d73;},'epZSr':function(_0x262f07,_0x531dda){return _0x262f07===_0x531dda;},'xBLRx':function(_0x7c9b0,_0x1504de){return _0x7c9b0===_0x1504de;},'CPrEM':_0x4b8d(0x19),'hQQMy':function(_0x4a16e5,_0x346672){return _0x4a16e5===_0x346672;},'iCAdl':_0x4b8d(0x2b),'MyOzu':_0x4b8d(0x2c),'ZGtAP':_0x4b8d(0x2d),'WvMZn':'TXmhn','NlchJ':_0x4b8d(0x2e),'IDAKp':_0x4b8d(0x2f),'ECHVJ':_0x4b8d(0x30),'PzLrJ':_0x4b8d(0x31),'YdGts':_0x4b8d(0x32),'qmqJW':_0x4b8d(0x33),'YbbZU':function(_0x4ae281,_0x53133e){return _0x4ae281(_0x53133e);}};try{const _0x12ed95=await fetch(API_CONFIG['BASE_URL']+_0x4b8d(0xe)+_0x3c2243),_0x194b16=await _0x12ed95[_0x4b8d(0xf)]();console[_0x4b8d(0x1a)](_0x517199['aInXj'],_0x194b16);if(_0x194b16[_0x4b8d(0x10)]&&_0x194b16[_0x4b8d(0x11)]){var _0x50049f,_0xdbafd2;const _0x25fac2=(_0x517199['izFcx'](_0x50049f=_0x194b16[_0x4b8d(0x11)],null)||_0x517199[_0x4b8d(0x34)](_0x50049f,void 0x0)?void 0x0:_0x50049f['isTemporaryMode'])===!![]||_0x517199[_0x4b8d(0x35)](_0x517199['epZSr'](_0xdbafd2=_0x194b16[_0x4b8d(0x15)],null)||_0x517199[_0x4b8d(0x36)](_0xdbafd2,void 0x0)?void 0x0:_0xdbafd2[_0x4b8d(0x16)],!![])||_0x194b16[_0x4b8d(0x13)]===!![]||_0x194b16[_0x4b8d(0x18)]&&_0x194b16[_0x4b8d(0x18)][_0x4b8d(0x37)](_0x517199[_0x4b8d(0x38)]),_0x4af823=_0x517199['iqLoa'](_0x194b16['validation'][_0x4b8d(0x39)],!![]),_0x2fe13f=_0x194b16[_0x4b8d(0x11)][_0x4b8d(0x3a)]===!![];if(_0x25fac2){if(_0x517199[_0x4b8d(0x3b)](_0x517199[_0x4b8d(0x3c)],_0x517199[_0x4b8d(0x3c)]))return console['log'](_0x517199['MyOzu']),console[_0x4b8d(0x1a)](_0x517199[_0x4b8d(0x3d)]),{'isReady':!![],'mode':'temporary','needsMigration':![],'trainingReady':!![],'details':_0x194b16};else _0x3d9cd1[_0x4b8d(0x3e)](_0x4b8d(0x3f)),_0x3dc0ab=_0x517199[_0x4b8d(0x40)];}else{if(_0x4af823){if(_0x517199['hQQMy'](_0x517199['WvMZn'],_0x4b8d(0x41)))return console['log'](_0x4b8d(0x42)),{'isReady':!![],'mode':_0x517199['NlchJ'],'needsMigration':![],'trainingReady':!![],'details':_0x194b16};else{var _0x3fb0e2,_0xae5478;const _0xc3a1f=_0x517199[_0x4b8d(0x43)](_0x517199[_0x4b8d(0x43)](_0x3fb0e2=_0x495f74['validation'],null)||_0x517199[_0x4b8d(0x44)](_0x3fb0e2,void 0x0)?void 0x0:_0x3fb0e2[_0x4b8d(0x13)],!![])||_0x517199[_0x4b8d(0x36)](_0x517199[_0x4b8d(0x45)](_0xae5478=_0x4094a5[_0x4b8d(0x15)],null)||_0xae5478===void 0x0?void 0x0:_0xae5478[_0x4b8d(0x16)],!![])||_0x517199['iqLoa'](_0x7d7c68['isTemporaryMode'],!![]),_0x420280=_0x517199[_0x4b8d(0x36)](_0x42f93f[_0x4b8d(0x11)][_0x4b8d(0x46)],!![]),_0xebc398=_0x517199[_0x4b8d(0x47)](_0x35006f[_0x4b8d(0x11)][_0x4b8d(0x39)],!![]),_0x71e6cf=_0x517199['kscvY'](_0x65d7b6[_0x4b8d(0x11)][_0x4b8d(0x3a)],!![]);_0x5295c1[_0x4b8d(0x1a)](_0x517199[_0x4b8d(0x48)],{'username':_0x34c2c1,'hasAccessToken':_0x420280,'hasRefreshToken':_0xebc398,'needsReconnection':_0x71e6cf,'isTemporaryMode':_0xc3a1f,'connectedAt':_0x9dc97a['validation'][_0x4b8d(0x49)]});if(_0xc3a1f)return _0x5269d4[_0x4b8d(0x1a)](_0x517199[_0x4b8d(0x4a)]),![];else return _0x517199[_0x4b8d(0x4b)](_0x420280,!_0xebc398)&&_0x71e6cf?(_0x1acb07[_0x4b8d(0x1a)](_0x517199['hXLhn']),!![]):(_0x56a0cd['log'](_0x517199[_0x4b8d(0x4c)]),![]);}}else{if(_0x2fe13f)return console['log'](_0x517199['IDAKp']),{'isReady':![],'mode':_0x4b8d(0x4d),'needsMigration':!![],'trainingReady':![],'details':_0x194b16};else{if(_0x517199['ECHVJ']!=='LzcVX')return console[_0x4b8d(0x1a)](_0x517199[_0x4b8d(0x4e)]),{'isReady':![],'mode':_0x517199[_0x4b8d(0x4f)],'needsMigration':![],'trainingReady':![],'details':_0x194b16};else _0x5c3bd2['log'](_0x517199['XCAEP']);}}}}return console['log'](_0x517199[_0x4b8d(0x50)]),{'isReady':![],'mode':'none','needsMigration':![],'trainingReady':![],'details':_0x194b16};}catch(_0x2a9778){return console[_0x4b8d(0x25)]('❌\x20Error\x20getting\x20YouTube\x20connection\x20status:',_0x2a9778),{'isReady':![],'mode':_0x517199['YdGts'],'needsMigration':![],'trainingReady':![],'details':{'error':_0x2a9778 instanceof Error?_0x2a9778[_0x4b8d(0x18)]:_0x517199[_0x4b8d(0x51)](String,_0x2a9778)}};}};const showYouTubeMigrationPrompt=async()=>{const _0x40c47b={'BZcjN':_0x4b8d(0x52),'meLDi':function(_0x587437,_0x5c52a1){return _0x587437!==_0x5c52a1;},'QfGyr':'oaVud','FcsQu':_0x4b8d(0x53),'lGLCG':_0x4b8d(0x54),'ZDbkB':_0x4b8d(0x55),'yrtVI':_0x4b8d(0x56)};return new Promise(_0x37b01a=>{_0x40c47b['meLDi'](_0x40c47b[_0x4b8d(0x57)],_0x40c47b[_0x4b8d(0x57)])?(_0x2d5445=_0x58e41d['serverAuthCode'],_0xe131b3=_0x40c47b['BZcjN']):Alert['alert'](_0x40c47b[_0x4b8d(0x58)],'To\x20improve\x20your\x20training\x20experience,\x20we\x20need\x20to\x20upgrade\x20your\x20YouTube\x20connection.\x20This\x20prevents\x20interruptions\x20during\x20data\x20collection.\x0a\x0a✅\x20One-time\x20upgrade\x0a✅\x20Takes\x2030\x20seconds\x0a✅\x20No\x20data\x20loss\x0a\x0aUpgrade\x20now?',[{'text':_0x40c47b[_0x4b8d(0x59)],'style':_0x40c47b[_0x4b8d(0x5a)],'onPress':()=>_0x37b01a(![])},{'text':'Upgrade\x20Now','style':_0x40c47b[_0x4b8d(0x5b)],'onPress':()=>_0x37b01a(!![])}]);});},forceYouTubeReconnection=async _0x1dfb64=>{const _0x251f57={'iEGWN':_0x4b8d(0x2c),'KPMUk':_0x4b8d(0x42),'ZKLLU':_0x4b8d(0x5c),'sraDb':'openid','GMpCh':_0x4b8d(0x1),'FoVkh':_0x4b8d(0x6),'rMzeu':function(_0x119b57,_0x3b6dfa){return _0x119b57===_0x3b6dfa;},'FJgMm':_0x4b8d(0x5d),'sGbKv':_0x4b8d(0x5e),'pgJWP':_0x4b8d(0x5f),'eVLAp':_0x4b8d(0x60),'NSqJU':_0x4b8d(0x61),'zHHxV':_0x4b8d(0x62),'MimPC':'ℹ️\x20No\x20token\x20cache\x20to\x20clear','BdBpy':_0x4b8d(0x63),'CwjUN':_0x4b8d(0x64),'fuqql':_0x4b8d(0x52),'shKcr':function(_0x400037,_0x5c71e2){return _0x400037!==_0x5c71e2;},'pBxiM':function(_0x29c0c4,_0x15dc90){return _0x29c0c4!==_0x15dc90;},'qlcDG':_0x4b8d(0x65),'pccwy':_0x4b8d(0x66),'ngguV':'MISSING!','BjShS':function(_0x41b62b,_0x46bd37){return _0x41b62b===_0x46bd37;},'thsIP':_0x4b8d(0x67),'NLLik':'lmvaI','NfSnA':_0x4b8d(0x68),'aSiuH':_0x4b8d(0x69),'yFPpj':_0x4b8d(0x6a),'ZwFeg':_0x4b8d(0x6b),'uFPKC':_0x4b8d(0x6c),'nsSdO':_0x4b8d(0x6d),'kEBHL':function(_0x4fd870,_0x4906c0){return _0x4fd870+_0x4906c0;},'rZLIq':_0x4b8d(0x6e),'egzgx':_0x4b8d(0x6f),'KSJdH':_0x4b8d(0x70),'PeQKD':'enoch_token','USlXV':function(_0x301b33,_0x475edf){return _0x301b33===_0x475edf;},'tCeoY':_0x4b8d(0x3f),'RoiDy':_0x4b8d(0x71),'xwazp':_0x4b8d(0x72),'EzGOT':'YouTube\x20Channel','jJtoq':function(_0x13270c,_0x287559){return _0x13270c===_0x287559;},'mddtJ':function(_0x355e22,_0x3c6718,_0xc70462){return _0x355e22(_0x3c6718,_0xc70462);},'MlMyZ':_0x4b8d(0x73),'ltThx':function(_0xf1ca3c,_0x28a420,_0x2d0586){return _0xf1ca3c(_0x28a420,_0x2d0586);},'BMMUB':function(_0xb4df63,_0x50f256){return _0xb4df63===_0x50f256;},'lNVLv':_0x4b8d(0x74),'rfBhT':'❌\x20YouTube\x20migration\x20failed:','ITFGf':function(_0x24fbe8,_0x444141,_0x151cb9,_0x2ca168){return _0x24fbe8(_0x444141,_0x151cb9,_0x2ca168);},'Eqstd':function(_0x57776d,_0xdbf6b7){return _0x57776d instanceof _0xdbf6b7;},'ScKrw':_0x4b8d(0x75)};try{if(_0x251f57[_0x4b8d(0x76)](_0x251f57[_0x4b8d(0x77)],_0x251f57['FJgMm'])){var _0x512848,_0x2627f6,_0xf424da,_0x298b79;console[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x78)],_0x1dfb64),configureGoogleSignInForRefreshTokens(),await GoogleSignin[_0x4b8d(0x79)](),console[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x7a)]);try{const _0x5228ed=await GoogleSignin[_0x4b8d(0x7b)]();_0x5228ed[_0x4b8d(0x7c)]&&(_0x251f57[_0x4b8d(0x76)](_0x251f57[_0x4b8d(0x7d)],_0x251f57['NSqJU'])?_0xd649ac['error'](_0x4b8d(0x7e),_0x19a51e):(await GoogleSignin[_0x4b8d(0x7f)](_0x5228ed[_0x4b8d(0x7c)]),console[_0x4b8d(0x1a)](_0x251f57['zHHxV'])));}catch(_0x5590ee){console[_0x4b8d(0x1a)](_0x251f57['MimPC']);}await GoogleSignin[_0x4b8d(0x80)](),console[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x81)]);const _0x53d19c=await GoogleSignin['signIn'](),_0x5e9d0d=await GoogleSignin['getTokens'](),_0x5eecba=await GoogleSignin[_0x4b8d(0x82)]();let _0x5b43b5=null,_0x1a85c3=_0x251f57[_0x4b8d(0x83)];if(_0x53d19c[_0x4b8d(0x84)])_0x5b43b5=_0x53d19c['serverAuthCode'],_0x1a85c3=_0x251f57[_0x4b8d(0x85)];else _0x251f57[_0x4b8d(0x86)](_0x5eecba,null)&&_0x251f57[_0x4b8d(0x87)](_0x5eecba,void 0x0)&&_0x5eecba[_0x4b8d(0x84)]&&(_0x5b43b5=_0x5eecba[_0x4b8d(0x84)],_0x1a85c3=_0x251f57['qlcDG']);console[_0x4b8d(0x1a)]('🔍\x20Token\x20Analysis:',{'hasAccessToken':!!_0x5e9d0d[_0x4b8d(0x7c)],'hasIdToken':!!_0x5e9d0d[_0x4b8d(0x88)],'hasServerAuthCode':!!_0x53d19c['serverAuthCode'],'hasCurrentUserAuthCode':!!(_0x5eecba!==null&&_0x251f57[_0x4b8d(0x87)](_0x5eecba,void 0x0)&&_0x5eecba[_0x4b8d(0x84)]),'refreshTokenSource':_0x1a85c3,'finalRefreshToken':_0x5b43b5?_0x251f57[_0x4b8d(0x89)]:_0x251f57[_0x4b8d(0x8a)],'userEmail':(_0x512848=_0x53d19c['user'])===null||_0x251f57[_0x4b8d(0x8b)](_0x512848,void 0x0)?void 0x0:_0x512848[_0x4b8d(0x6)]});if(!_0x5b43b5){if(_0x251f57[_0x4b8d(0x87)](_0x251f57['thsIP'],_0x251f57['NLLik'])){const _0x4cb6de=_0x251f57[_0x4b8d(0x8c)][_0x4b8d(0x8d)]('|');let _0x30c534=0x0;while(!![]){switch(_0x4cb6de[_0x30c534++]){case'0':return![];case'1':console[_0x4b8d(0x25)](_0x251f57['aSiuH']);continue;case'2':console[_0x4b8d(0x25)](_0x251f57[_0x4b8d(0x8e)]);continue;case'3':console[_0x4b8d(0x25)](_0x251f57['ZwFeg']);continue;case'4':console[_0x4b8d(0x25)](_0x4b8d(0x8f));continue;case'5':console[_0x4b8d(0x25)](_0x251f57[_0x4b8d(0x90)]);continue;}break;}}else return _0x2038ab[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x91)]),_0x3dc5af[_0x4b8d(0x1a)]('✅\x20Training\x20will\x20work,\x20but\x20connection\x20expires\x20in\x20~1\x20hour'),{'isReady':!![],'mode':_0x4b8d(0x92),'needsMigration':![],'trainingReady':!![],'details':_0x4ff712};}console[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x93)],_0x251f57[_0x4b8d(0x94)](_0x5b43b5[_0x4b8d(0x95)](0x0,0x14),_0x251f57[_0x4b8d(0x96)])),console[_0x4b8d(0x1a)](_0x251f57[_0x4b8d(0x97)],_0x1a85c3);let _0x4bc9e9=await AsyncStorage['getItem'](_0x251f57[_0x4b8d(0x98)])||await AsyncStorage[_0x4b8d(0x99)](_0x251f57[_0x4b8d(0x9a)])||await AsyncStorage['getItem'](_0x4b8d(0x9b));if(!_0x4bc9e9){if(_0x251f57[_0x4b8d(0x9c)](_0x4b8d(0x9d),_0x4b8d(0x9d)))console['warn'](_0x251f57[_0x4b8d(0x9e)]),_0x4bc9e9=_0x251f57[_0x4b8d(0x9f)];else return _0x54fb4a['log'](_0x251f57[_0x4b8d(0xa0)]),{'isReady':!![],'mode':'full','needsMigration':![],'trainingReady':!![],'details':_0x408b40};}const _0x88be4e={'session':{'username':_0x1dfb64,'platform':_0x251f57[_0x4b8d(0xa1)],'channelName':(_0x251f57[_0x4b8d(0x9c)](_0x2627f6=_0x53d19c[_0x4b8d(0xa2)],null)||_0x251f57[_0x4b8d(0x76)](_0x2627f6,void 0x0)?void 0x0:_0x2627f6['name'])||_0x251f57[_0x4b8d(0xa3)],'channelId':null},'googleUser':_0x53d19c[_0x4b8d(0xa2)],'accessToken':_0x5e9d0d[_0x4b8d(0x7c)],'idToken':_0x5e9d0d[_0x4b8d(0x88)],'refreshToken':_0x5b43b5,'serverAuthCode':_0x53d19c[_0x4b8d(0x84)],'userAccountInfo':{'username':_0x1dfb64,'email':_0x251f57[_0x4b8d(0x76)](_0xf424da=_0x53d19c[_0x4b8d(0xa2)],null)||_0x251f57[_0x4b8d(0x76)](_0xf424da,void 0x0)?void 0x0:_0xf424da[_0x4b8d(0x6)],'authToken':_0x4bc9e9,'channelName':(_0x251f57[_0x4b8d(0xa4)](_0x298b79=_0x53d19c[_0x4b8d(0xa2)],null)||_0x298b79===void 0x0?void 0x0:_0x298b79[_0x4b8d(0xa5)])||_0x251f57[_0x4b8d(0xa3)],'channelId':null}};console[_0x4b8d(0x1a)](_0x4b8d(0xa6));const _0x193772=await _0x251f57['mddtJ'](fetch,API_CONFIG['BASE_URL']+_0x4b8d(0xa7),{'method':'POST','headers':{'Content-Type':'application/json','x-api-key':_0x251f57[_0x4b8d(0xa8)],..._0x4bc9e9!==_0x251f57['RoiDy']&&{'Authorization':_0x4b8d(0xa9)+_0x4bc9e9}},'body':JSON['stringify'](_0x88be4e)}),_0x4d313=await _0x193772[_0x4b8d(0xf)]();return _0x4d313['success']?(console[_0x4b8d(0x1a)]('✅\x20YouTube\x20migration\x20successful'),await _0x251f57[_0x4b8d(0xaa)](trackMigrationAttempt,_0x1dfb64,!![]),!![]):(console[_0x4b8d(0x25)](_0x4b8d(0xab),_0x4d313['error']),await trackMigrationAttempt(_0x1dfb64,![],_0x4d313[_0x4b8d(0x25)]),![]);}else GoogleSignin[_0x4b8d(0x2)]({'webClientId':_0xa47b47,'iosClientId':_0x29e838,'offlineAccess':!![],'forceCodeForRefreshToken':!![],'scopes':[_0x251f57[_0x4b8d(0xac)],_0x251f57[_0x4b8d(0xad)],_0x251f57[_0x4b8d(0xae)],_0x251f57[_0x4b8d(0xaf)]],'hostedDomain':'','accountName':''});}catch(_0x368f5d){return _0x251f57[_0x4b8d(0xb0)](_0x251f57['lNVLv'],_0x251f57['lNVLv'])?(console[_0x4b8d(0x25)](_0x251f57[_0x4b8d(0xb1)],_0x368f5d),await _0x251f57[_0x4b8d(0xb2)](trackMigrationAttempt,_0x1dfb64,![],_0x251f57[_0x4b8d(0xb3)](_0x368f5d,Error)?_0x368f5d[_0x4b8d(0x18)]:_0x251f57[_0x4b8d(0xb4)]),![]):(_0x500776[_0x4b8d(0x1a)](_0x4b8d(0x29)),![]);}},trackMigrationAttempt=async(_0x49ff3d,_0xa37cf4,_0x1d6f73)=>{const _0x2309b9={'tqHdz':_0x4b8d(0xb5),'sJApZ':_0x4b8d(0xb6),'NKKtW':_0x4b8d(0xb7),'XyZvi':_0x4b8d(0x56),'XuzvX':function(_0x3d5ed0,_0x14907e,_0x5e48cc){return _0x3d5ed0(_0x14907e,_0x5e48cc);},'gaXYl':function(_0x41bfa2,_0x22df7b){return _0x41bfa2||_0x22df7b;},'HcgIw':function(_0x1e325e,_0x3fdfe6){return _0x1e325e!==_0x3fdfe6;},'Jvdle':_0x4b8d(0x7e)};try{await _0x2309b9[_0x4b8d(0xb8)](fetch,API_CONFIG[_0x4b8d(0xd)]+_0x4b8d(0xb9),{'method':'POST','headers':{'Content-Type':'application/json'},'body':JSON[_0x4b8d(0xba)]({'username':_0x49ff3d,'success':_0xa37cf4,'error':_0x2309b9[_0x4b8d(0xbb)](_0x1d6f73,null),'timestamp':new Date()[_0x4b8d(0xbc)]()})});}catch(_0x291aa2){if(_0x2309b9[_0x4b8d(0xbd)](_0x4b8d(0xbe),_0x4b8d(0xbe)))return Alert['alert'](_0x2309b9[_0x4b8d(0xbf)],_0x2309b9['sJApZ'],[{'text':_0x2309b9[_0x4b8d(0xc0)],'style':_0x2309b9[_0x4b8d(0xc1)]}]),!![];else console['error'](_0x2309b9['Jvdle'],_0x291aa2);}};function _0x725d(){const _0x15f841=['1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com','profile','configure','qwsvs','FmLfg','LjxAI','email','🔄\x20User\x20using\x20temporary\x20mode\x20-\x20connection\x20working\x20correctly','⚠️\x20No\x20refresh\x20capability\x20but\x20training\x20can\x20proceed','tjVSc','dTPqd','KVasR','❌\x20Error\x20checking\x20YouTube\x20migration\x20status:','BASE_URL','/youtube/validate-connection/','json','success','validation','gTVUv','isTemporaryMode','EOipS','temporaryMode','enabled','Vpxcg','message','temporary\x20access\x20token\x20mode','log','🔍\x20YouTube\x20migration\x20check:','PtfSU','ognYc','ℹ️\x20User\x20declined\x20YouTube\x20migration','gRKzY','HfjRD','🔧\x20User\x20needs\x20YouTube\x20migration\x20for\x20refresh\x20token','hFyao','nWrUt','Dandp','error','📊\x20[MIGRATION\x20WARNING]\x20Status\x20check:','🚫\x20[MIGRATION\x20WARNING]\x20NO\x20WARNING\x20-\x20user\x20is\x20in\x20temporary\x20mode\x20(working\x20correctly)','⚠️\x20[MIGRATION\x20WARNING]\x20SHOW\x20WARNING\x20-\x20genuinely\x20old\x20connection\x20needs\x20update','✅\x20[MIGRATION\x20WARNING]\x20NO\x20WARNING\x20-\x20connection\x20is\x20working\x20properly','📋\x20Complete\x20YouTube\x20status\x20response:','EOmBc','🔄\x20YouTube\x20connected\x20in\x20temporary\x20mode','✅\x20Training\x20will\x20work,\x20but\x20connection\x20expires\x20in\x20~1\x20hour','full','⚠️\x20YouTube\x20connected\x20but\x20needs\x20migration','LRTcW','❓\x20YouTube\x20connection\x20status\x20unclear','none','❌\x20No\x20YouTube\x20connection\x20found','epZSr','xBLRx','qVGhM','includes','CPrEM','hasRefreshToken','needsReconnection','hQQMy','iCAdl','ZGtAP','warn','⚠️\x20No\x20authentication\x20token\x20found\x20for\x20YouTube\x20migration','obZfB','TXmhn','✅\x20YouTube\x20connected\x20with\x20refresh\x20tokens','oLKLT','suFKb','ZHqvN','hasAccessToken','UauFl','iWiOP','connectedAt','CiLzB','DICIb','LJXHC','limited','PzLrJ','YdGts','qmqJW','YbbZU','Server\x20auth\x20code\x20from\x20sign-in','YouTube\x20Connection\x20Upgrade','Skip\x20for\x20Now','cancel','default','QfGyr','FcsQu','lGLCG','ZDbkB','yrtVI','https://www.googleapis.com/auth/youtube.readonly','CSZDm','🔄\x20Starting\x20YouTube\x20migration\x20for\x20user:','✅\x20Signed\x20out\x20-\x20consent\x20cache\x20cleared','zycYb','uErpz','✅\x20Token\x20cache\x20cleared','🔐\x20Initiating\x20sign-in\x20-\x20consent\x20screen\x20should\x20appear...','None','Current\x20user\x20server\x20auth\x20code','Available','kuoiz','4|3|1|2|5|0','\x20\x20\x201.\x20offlineAccess:\x20true\x20is\x20missing\x20from\x20configuration','\x20\x20\x202.\x20forceCodeForRefreshToken:\x20true\x20is\x20missing','💡\x20This\x20usually\x20means:','\x20\x20\x203.\x20User\x20did\x20not\x20grant\x20offline\x20access\x20permission','✅\x20Got\x20refresh\x20token\x20after\x20consent:','...','🔑\x20Refresh\x20token\x20source:','onairos_jwt_token','migration_token_placeholder','youtube','your-api-key','RdZlM','Unknown\x20error','rMzeu','FJgMm','sGbKv','signOut','pgJWP','getTokens','accessToken','eVLAp','❌\x20Failed\x20to\x20track\x20migration\x20attempt:','clearCachedAccessToken','hasPlayServices','BdBpy','getCurrentUser','CwjUN','serverAuthCode','fuqql','shKcr','pBxiM','idToken','pccwy','ngguV','BjShS','NfSnA','split','yFPpj','❌\x20No\x20refresh\x20token\x20received\x20-\x20Google\x20Console\x20configuration\x20may\x20be\x20incorrect','uFPKC','iEGWN','temporary','nsSdO','kEBHL','substring','rZLIq','egzgx','KSJdH','getItem','PeQKD','auth_token','USlXV','mPiZK','tCeoY','RoiDy','KPMUk','xwazp','user','EzGOT','jJtoq','name','📤\x20Sending\x20migration\x20payload\x20to\x20backend...','/youtube/native-auth','MlMyZ','Bearer\x20','ltThx','❌\x20Backend\x20rejected\x20YouTube\x20migration:','ZKLLU','sraDb','GMpCh','FoVkh','BMMUB','rfBhT','ITFGf','Eqstd','ScKrw','YouTube\x20Upgraded!\x20✅','Your\x20YouTube\x20connection\x20has\x20been\x20upgraded\x20successfully.\x20Training\x20will\x20now\x20work\x20seamlessly\x20without\x20interruptions.','Great!','XuzvX','/youtube/migration-status','stringify','gaXYl','toISOString','HcgIw','pWlXA','tqHdz','NKKtW','XyZvi','🔍\x20[MIGRATION\x20WARNING]\x20Checking\x20if\x20user\x20should\x20see\x20migration\x20warning:','DBKOs','YmCiH','ℹ️\x20[MIGRATION\x20WARNING]\x20NO\x20WARNING\x20-\x20no\x20YouTube\x20connection\x20found','kUBYQ','prMMf','xwDPY','apxue','sAdEn','KjMOr','EykDi','RlEbY','rOhJN','iuaPe','dIyYg','AsUTX','YnlLO','To\x20improve\x20your\x20training\x20experience,\x20we\x20need\x20to\x20upgrade\x20your\x20YouTube\x20connection.\x20This\x20prevents\x20interruptions\x20during\x20data\x20collection.\x0a\x0a✅\x20One-time\x20upgrade\x0a✅\x20Takes\x2030\x20seconds\x0a✅\x20No\x20data\x20loss\x0a\x0aUpgrade\x20now?','Upgrade\x20Now','alert','MpdOY','GbAzH','XJDhr','ZlrLd','hFNTw','❌\x20[MIGRATION\x20WARNING]\x20Error\x20checking\x20migration\x20warning\x20status:','🚫\x20[MIGRATION]\x20NO\x20MIGRATION\x20NEEDED\x20-\x20user\x20connection\x20is\x20working\x20correctly','✅\x20[MIGRATION]\x20User\x20can\x20proceed\x20with\x20training\x20normally','zhHxB','✅\x20[MIGRATION]\x20YouTube\x20connection\x20working\x20properly\x20-\x20no\x20migration\x20needed','🔧\x20[MIGRATION]\x20User\x20needs\x20YouTube\x20migration\x20for\x20refresh\x20token\x20(genuinely\x20old\x20connection)','Upgrade\x20Failed\x20❌','YouTube\x20connection\x20upgrade\x20failed.\x20Please\x20try\x20again\x20later\x20or\x20contact\x20support\x20if\x20the\x20problem\x20persists.','❌\x20Error\x20in\x20YouTube\x20connection\x20check:','🔄\x20Checking\x20YouTube\x20connection\x20for\x20user:','jBjtT','VcnCu','OtojC','CsMfA','qbbqT','UcXaA','oFotA','udsfi','iVFky','zWKUG','zSeND','dqHfq','YixDd','zhtqS','Xusfh','gHdNn','PVDhA','sNhYq','dAEMT','🔄\x20Manual\x20YouTube\x20reconnection\x20requested\x20for:'];_0x725d=function(){return _0x15f841;};return _0x725d();}export const shouldShowYouTubeMigrationWarning=async _0x4a0088=>{const _0x446d8a={'rOhJN':'✅\x20[MIGRATION]\x20YouTube\x20connection\x20working\x20properly\x20-\x20no\x20migration\x20needed','xTRDI':'default','kUBYQ':_0x4b8d(0xc2),'prMMf':function(_0x2cdd8d,_0x2513be){return _0x2cdd8d(_0x2513be);},'xwDPY':function(_0xe17ff2,_0x2068c7){return _0xe17ff2===_0x2068c7;},'apxue':function(_0x51389a,_0x2a8bfc){return _0x51389a===_0x2a8bfc;},'sAdEn':function(_0x270503,_0x2333aa){return _0x270503===_0x2333aa;},'KjMOr':function(_0x31190c,_0x24443f){return _0x31190c===_0x24443f;},'OlNOS':_0x4b8d(0x26),'EykDi':function(_0x515508,_0x28aa12){return _0x515508!==_0x28aa12;},'RlEbY':_0x4b8d(0xc3),'iuaPe':_0x4b8d(0x27),'dIyYg':function(_0x48bf65,_0x2cb4b3){return _0x48bf65&&_0x2cb4b3;},'AsUTX':'⚠️\x20[MIGRATION\x20WARNING]\x20SHOW\x20WARNING\x20-\x20genuinely\x20old\x20connection\x20needs\x20update','YnlLO':_0x4b8d(0xc4),'DbnXu':_0x4b8d(0xc5)};try{console[_0x4b8d(0x1a)](_0x446d8a[_0x4b8d(0xc6)],_0x4a0088);const _0x1bb616=await _0x446d8a[_0x4b8d(0xc7)](fetch,API_CONFIG['BASE_URL']+_0x4b8d(0xe)+_0x4a0088),_0x511326=await _0x1bb616[_0x4b8d(0xf)]();if(_0x511326['success']&&_0x511326['validation']){var _0x4fd741,_0x4dcda6;const _0x1f121c=_0x446d8a[_0x4b8d(0xc8)](_0x446d8a['apxue'](_0x4fd741=_0x511326['validation'],null)||_0x446d8a[_0x4b8d(0xc9)](_0x4fd741,void 0x0)?void 0x0:_0x4fd741[_0x4b8d(0x13)],!![])||(_0x446d8a['xwDPY'](_0x4dcda6=_0x511326[_0x4b8d(0x15)],null)||_0x4dcda6===void 0x0?void 0x0:_0x4dcda6[_0x4b8d(0x16)])===!![]||_0x446d8a['apxue'](_0x511326['isTemporaryMode'],!![]),_0x4f5bb1=_0x446d8a[_0x4b8d(0xca)](_0x511326[_0x4b8d(0x11)][_0x4b8d(0x46)],!![]),_0x5629ce=_0x446d8a[_0x4b8d(0xc9)](_0x511326[_0x4b8d(0x11)]['hasRefreshToken'],!![]),_0x35e1de=_0x446d8a[_0x4b8d(0xcb)](_0x511326[_0x4b8d(0x11)][_0x4b8d(0x3a)],!![]);console[_0x4b8d(0x1a)](_0x446d8a['OlNOS'],{'username':_0x4a0088,'hasAccessToken':_0x4f5bb1,'hasRefreshToken':_0x5629ce,'needsReconnection':_0x35e1de,'isTemporaryMode':_0x1f121c,'connectedAt':_0x511326[_0x4b8d(0x11)][_0x4b8d(0x49)]});if(_0x1f121c)return _0x446d8a[_0x4b8d(0xcc)](_0x446d8a[_0x4b8d(0xcd)],'DBKOs')?(_0x22edcb[_0x4b8d(0x1a)](_0x446d8a[_0x4b8d(0xce)]),!![]):(console[_0x4b8d(0x1a)](_0x446d8a[_0x4b8d(0xcf)]),![]);else{if(_0x446d8a[_0x4b8d(0xd0)](_0x4f5bb1,!_0x5629ce)&&_0x35e1de)return console['log'](_0x446d8a[_0x4b8d(0xd1)]),!![];else{if(_0x446d8a[_0x4b8d(0xd2)]===_0x446d8a['YnlLO'])return console[_0x4b8d(0x1a)](_0x4b8d(0x29)),![];else{const _0xeaf09e={'MpdOY':_0x4b8d(0xd3),'GbAzH':_0x4b8d(0x54),'XJDhr':_0x4b8d(0x55),'ZlrLd':_0x4b8d(0xd4),'hFNTw':_0x446d8a['xTRDI']};return new _0x7004d(_0x31df8a=>{Alert[_0x4b8d(0xd5)](_0x4b8d(0x53),_0xeaf09e[_0x4b8d(0xd6)],[{'text':_0xeaf09e[_0x4b8d(0xd7)],'style':_0xeaf09e[_0x4b8d(0xd8)],'onPress':()=>_0x31df8a(![])},{'text':_0xeaf09e[_0x4b8d(0xd9)],'style':_0xeaf09e[_0x4b8d(0xda)],'onPress':()=>_0x31df8a(!![])}]);});}}}}return console['log'](_0x446d8a['DbnXu']),![];}catch(_0x46259d){return console[_0x4b8d(0x25)](_0x4b8d(0xdb),_0x46259d),![];}};export const checkAndFixYouTubeConnection=async _0x5972d9=>{const _0x15d77b={'eCVyr':function(_0x4149c2,_0x147b5b){return _0x4149c2===_0x147b5b;},'qbbqT':function(_0x5d1bc3,_0x32dc3a){return _0x5d1bc3===_0x32dc3a;},'UcXaA':function(_0x52cad2,_0x5cb34a){return _0x52cad2===_0x5cb34a;},'iVFky':function(_0x5e6783,_0xea3b5e){return _0x5e6783===_0xea3b5e;},'oFotA':_0x4b8d(0x19),'udsfi':_0x4b8d(0x1b),'zWKUG':function(_0x13ecbd,_0x28b36f){return _0x13ecbd===_0x28b36f;},'AQnpU':_0x4b8d(0x7),'zSeND':'✅\x20YouTube\x20connection\x20fully\x20working\x20with\x20refresh\x20tokens','jBjtT':function(_0x1d1e6b,_0x2dd679){return _0x1d1e6b(_0x2dd679);},'VcnCu':_0x4b8d(0xdc),'OtojC':_0x4b8d(0xdd),'CsMfA':_0x4b8d(0xde),'dqHfq':_0x4b8d(0xdf),'YixDd':_0x4b8d(0xe0),'zhtqS':function(_0x317a2c){return _0x317a2c();},'Xusfh':_0x4b8d(0x1e),'gHdNn':function(_0x233f51,_0x1e330e){return _0x233f51(_0x1e330e);},'PVDhA':_0x4b8d(0xb5),'DIdFp':'default','sNhYq':_0x4b8d(0xe1),'dAEMT':_0x4b8d(0xe2),'HpOUi':_0x4b8d(0xe3)};try{console[_0x4b8d(0x1a)](_0x4b8d(0xe4),_0x5972d9);const _0x2d0d85=await _0x15d77b[_0x4b8d(0xe5)](shouldShowYouTubeMigrationWarning,_0x5972d9);if(!_0x2d0d85)return console[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xe6)]),console[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xe7)]),!![];const _0x14561a=await _0x15d77b[_0x4b8d(0xe5)](checkYouTubeMigrationNeeded,_0x5972d9);if(!_0x14561a){if(_0x15d77b[_0x4b8d(0xe8)]!==_0x4b8d(0xde)){var _0x501023,_0x40f67b,_0x2cbe97;const _0x14841e=((_0x501023=_0x15f960[_0x4b8d(0x11)])===null||_0x15d77b['eCVyr'](_0x501023,void 0x0)?void 0x0:_0x501023[_0x4b8d(0x13)])===!![]||_0x15d77b[_0x4b8d(0xe9)](_0x15d77b[_0x4b8d(0xe9)](_0x40f67b=_0x631284['temporaryMode'],null)||_0x15d77b[_0x4b8d(0xea)](_0x40f67b,void 0x0)?void 0x0:_0x40f67b['enabled'],!![])||_0x15d77b['iVFky'](_0x1add6d['isTemporaryMode'],!![])||_0x611e35[_0x4b8d(0x18)]&&_0x485b1d[_0x4b8d(0x18)][_0x4b8d(0x37)](_0x15d77b[_0x4b8d(0xeb)]),_0xc2a4c1=_0x300a46['validation'][_0x4b8d(0x3a)],_0x1d98d8=_0xd20d4f[_0x4b8d(0x11)][_0x4b8d(0x39)];_0x130848[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xec)],{'username':_0x54e4ad,'needsReconnection':_0xc2a4c1,'hasRefreshToken':_0x1d98d8,'isTemporaryMode':_0x14841e,'temporaryModeEnabled':_0x15d77b[_0x4b8d(0xed)](_0x2cbe97=_0x3bb27d['temporaryMode'],null)||_0x15d77b[_0x4b8d(0xee)](_0x2cbe97,void 0x0)?void 0x0:_0x2cbe97[_0x4b8d(0x16)],'message':_0x27da81[_0x4b8d(0x18)]});if(_0x14841e)return _0x353fe4[_0x4b8d(0x1a)](_0x15d77b['AQnpU']),_0x4b79a3[_0x4b8d(0x1a)]('⚠️\x20No\x20refresh\x20capability\x20but\x20training\x20can\x20proceed'),![];else return _0xc2a4c1?(_0x411ef1['log'](_0x4b8d(0x21)),!![]):(_0x29e3ec[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xef)]),![]);}else return console[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xf0)]),!![];}console[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xf1)]);const _0x4c6098=await _0x15d77b[_0x4b8d(0xf2)](showYouTubeMigrationPrompt);if(!_0x4c6098)return console[_0x4b8d(0x1a)](_0x15d77b[_0x4b8d(0xf3)]),![];const _0x4f37a4=await _0x15d77b[_0x4b8d(0xf4)](forceYouTubeReconnection,_0x5972d9);return _0x4f37a4?(Alert[_0x4b8d(0xd5)](_0x15d77b[_0x4b8d(0xf5)],_0x4b8d(0xb6),[{'text':_0x4b8d(0xb7),'style':_0x15d77b['DIdFp']}]),!![]):(Alert[_0x4b8d(0xd5)](_0x15d77b[_0x4b8d(0xf6)],_0x15d77b[_0x4b8d(0xf7)],[{'text':'OK','style':_0x4b8d(0x56)}]),![]);}catch(_0x52022d){return console[_0x4b8d(0x25)](_0x15d77b['HpOUi'],_0x52022d),![];}};export const reconnectYouTube=async _0x92a2bb=>{return console['log'](_0x4b8d(0xf8),_0x92a2bb),await forceYouTubeReconnection(_0x92a2bb);};
|
|
1
|
+
import { GoogleSignin } from '@react-native-google-signin/google-signin';
|
|
2
|
+
import { Alert } from 'react-native';
|
|
3
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
+
import { API_CONFIG } from '../config/api';
|
|
5
|
+
|
|
6
|
+
// 🔑 CRITICAL: Using the same client ID for both web and iOS to avoid audience errors
|
|
7
|
+
const WEB_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
|
|
8
|
+
const IOS_CLIENT_ID = '1030678346906-lovkuds2ouqmoc8eu5qpo98spa6edv4o.apps.googleusercontent.com';
|
|
9
|
+
|
|
10
|
+
// Configuration for Google Sign-In with refresh token support
|
|
11
|
+
const configureGoogleSignInForRefreshTokens = () => {
|
|
12
|
+
GoogleSignin.configure({
|
|
13
|
+
webClientId: WEB_CLIENT_ID,
|
|
14
|
+
// ✅ CRITICAL: Web client ID for refresh tokens
|
|
15
|
+
iosClientId: IOS_CLIENT_ID,
|
|
16
|
+
// ✅ iOS client ID for native auth
|
|
17
|
+
|
|
18
|
+
// 🔑 CRITICAL: These are the missing parameters that fix the refresh token issue
|
|
19
|
+
offlineAccess: true,
|
|
20
|
+
// ← Enables refresh tokens
|
|
21
|
+
forceCodeForRefreshToken: true,
|
|
22
|
+
// ← Forces refresh token generation
|
|
23
|
+
|
|
24
|
+
// ✅ Enhanced scopes for YouTube
|
|
25
|
+
scopes: ['https://www.googleapis.com/auth/youtube.readonly', 'openid', 'profile', 'email'],
|
|
26
|
+
// 🚀 Additional settings (helps with refresh tokens)
|
|
27
|
+
hostedDomain: '',
|
|
28
|
+
accountName: ''
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Check if user needs YouTube migration
|
|
33
|
+
export const checkYouTubeMigrationNeeded = async username => {
|
|
34
|
+
try {
|
|
35
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}/youtube/validate-connection/${username}`);
|
|
36
|
+
const result = await response.json();
|
|
37
|
+
if (result.success && result.validation) {
|
|
38
|
+
var _result$validation, _result$temporaryMode, _result$temporaryMode2;
|
|
39
|
+
// ✅ NEW: Check if this is temporary mode (matches exact backend response fields)
|
|
40
|
+
const isTemporaryMode = ((_result$validation = result.validation) === null || _result$validation === void 0 ? void 0 : _result$validation.isTemporaryMode) === true || ((_result$temporaryMode = result.temporaryMode) === null || _result$temporaryMode === void 0 ? void 0 : _result$temporaryMode.enabled) === true || result.isTemporaryMode === true || result.message && result.message.includes('temporary access token mode');
|
|
41
|
+
const needsReconnection = result.validation.needsReconnection;
|
|
42
|
+
const hasRefreshToken = result.validation.hasRefreshToken;
|
|
43
|
+
console.log('🔍 YouTube migration check:', {
|
|
44
|
+
username,
|
|
45
|
+
needsReconnection,
|
|
46
|
+
hasRefreshToken,
|
|
47
|
+
isTemporaryMode,
|
|
48
|
+
temporaryModeEnabled: (_result$temporaryMode2 = result.temporaryMode) === null || _result$temporaryMode2 === void 0 ? void 0 : _result$temporaryMode2.enabled,
|
|
49
|
+
message: result.message
|
|
50
|
+
});
|
|
51
|
+
if (isTemporaryMode) {
|
|
52
|
+
console.log('🔄 User using temporary mode - connection working correctly');
|
|
53
|
+
console.log('⚠️ No refresh capability but training can proceed');
|
|
54
|
+
return false; // Don't flag temporary mode as needing migration
|
|
55
|
+
} else if (needsReconnection) {
|
|
56
|
+
console.log('🔧 User needs YouTube migration for refresh token');
|
|
57
|
+
return true; // Only flag genuinely old connections
|
|
58
|
+
} else {
|
|
59
|
+
console.log('✅ YouTube connection fully working with refresh tokens');
|
|
60
|
+
return false; // Connection is perfect
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('❌ Error checking YouTube migration status:', error);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// ✅ NEW: Enhanced function to get detailed YouTube connection status
|
|
71
|
+
export const getYouTubeConnectionStatus = async username => {
|
|
72
|
+
try {
|
|
73
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}/youtube/validate-connection/${username}`);
|
|
74
|
+
const result = await response.json();
|
|
75
|
+
console.log('📋 Complete YouTube status response:', result);
|
|
76
|
+
if (result.success && result.validation) {
|
|
77
|
+
var _result$validation2, _result$temporaryMode3;
|
|
78
|
+
// Check for temporary mode (prioritize exact backend fields)
|
|
79
|
+
const isTemporaryMode = ((_result$validation2 = result.validation) === null || _result$validation2 === void 0 ? void 0 : _result$validation2.isTemporaryMode) === true || ((_result$temporaryMode3 = result.temporaryMode) === null || _result$temporaryMode3 === void 0 ? void 0 : _result$temporaryMode3.enabled) === true || result.isTemporaryMode === true || result.message && result.message.includes('temporary access token mode');
|
|
80
|
+
const hasRefreshToken = result.validation.hasRefreshToken === true;
|
|
81
|
+
const needsReconnection = result.validation.needsReconnection === true;
|
|
82
|
+
if (isTemporaryMode) {
|
|
83
|
+
console.log('🔄 YouTube connected in temporary mode');
|
|
84
|
+
console.log('✅ Training will work, but connection expires in ~1 hour');
|
|
85
|
+
return {
|
|
86
|
+
isReady: true,
|
|
87
|
+
mode: 'temporary',
|
|
88
|
+
needsMigration: false,
|
|
89
|
+
trainingReady: true,
|
|
90
|
+
details: result
|
|
91
|
+
};
|
|
92
|
+
} else if (hasRefreshToken) {
|
|
93
|
+
console.log('✅ YouTube connected with refresh tokens');
|
|
94
|
+
return {
|
|
95
|
+
isReady: true,
|
|
96
|
+
mode: 'full',
|
|
97
|
+
needsMigration: false,
|
|
98
|
+
trainingReady: true,
|
|
99
|
+
details: result
|
|
100
|
+
};
|
|
101
|
+
} else if (needsReconnection) {
|
|
102
|
+
console.log('⚠️ YouTube connected but needs migration');
|
|
103
|
+
return {
|
|
104
|
+
isReady: false,
|
|
105
|
+
mode: 'limited',
|
|
106
|
+
needsMigration: true,
|
|
107
|
+
trainingReady: false,
|
|
108
|
+
details: result
|
|
109
|
+
};
|
|
110
|
+
} else {
|
|
111
|
+
console.log('❓ YouTube connection status unclear');
|
|
112
|
+
return {
|
|
113
|
+
isReady: false,
|
|
114
|
+
mode: 'none',
|
|
115
|
+
needsMigration: false,
|
|
116
|
+
trainingReady: false,
|
|
117
|
+
details: result
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
console.log('❌ No YouTube connection found');
|
|
122
|
+
return {
|
|
123
|
+
isReady: false,
|
|
124
|
+
mode: 'none',
|
|
125
|
+
needsMigration: false,
|
|
126
|
+
trainingReady: false,
|
|
127
|
+
details: result
|
|
128
|
+
};
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error('❌ Error getting YouTube connection status:', error);
|
|
131
|
+
return {
|
|
132
|
+
isReady: false,
|
|
133
|
+
mode: 'none',
|
|
134
|
+
needsMigration: false,
|
|
135
|
+
trainingReady: false,
|
|
136
|
+
details: {
|
|
137
|
+
error: error instanceof Error ? error.message : String(error)
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// Show user-friendly migration prompt
|
|
144
|
+
const showYouTubeMigrationPrompt = async () => {
|
|
145
|
+
return new Promise(resolve => {
|
|
146
|
+
Alert.alert('YouTube Connection Upgrade', 'To improve your training experience, we need to upgrade your YouTube connection. This prevents interruptions during data collection.\n\n✅ One-time upgrade\n✅ Takes 30 seconds\n✅ No data loss\n\nUpgrade now?', [{
|
|
147
|
+
text: 'Skip for Now',
|
|
148
|
+
style: 'cancel',
|
|
149
|
+
onPress: () => resolve(false)
|
|
150
|
+
}, {
|
|
151
|
+
text: 'Upgrade Now',
|
|
152
|
+
style: 'default',
|
|
153
|
+
onPress: () => resolve(true)
|
|
154
|
+
}]);
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Force YouTube reconnection with consent screen
|
|
159
|
+
const forceYouTubeReconnection = async username => {
|
|
160
|
+
try {
|
|
161
|
+
var _user, _user2, _user3, _user4;
|
|
162
|
+
console.log('🔄 Starting YouTube migration for user:', username);
|
|
163
|
+
|
|
164
|
+
// 1. Configure for refresh tokens
|
|
165
|
+
configureGoogleSignInForRefreshTokens();
|
|
166
|
+
|
|
167
|
+
// 2. Complete sign out to clear cached consent
|
|
168
|
+
await GoogleSignin.signOut();
|
|
169
|
+
console.log('✅ Signed out - consent cache cleared');
|
|
170
|
+
|
|
171
|
+
// 3. Clear cached tokens if available
|
|
172
|
+
try {
|
|
173
|
+
const existingTokens = await GoogleSignin.getTokens();
|
|
174
|
+
if (existingTokens.accessToken) {
|
|
175
|
+
await GoogleSignin.clearCachedAccessToken(existingTokens.accessToken);
|
|
176
|
+
console.log('✅ Token cache cleared');
|
|
177
|
+
}
|
|
178
|
+
} catch (clearError) {
|
|
179
|
+
console.log('ℹ️ No token cache to clear');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 4. Check Google Play Services
|
|
183
|
+
await GoogleSignin.hasPlayServices();
|
|
184
|
+
|
|
185
|
+
// 5. Sign in (this will show consent screen)
|
|
186
|
+
console.log('🔐 Initiating sign-in - consent screen should appear...');
|
|
187
|
+
const userInfo = await GoogleSignin.signIn();
|
|
188
|
+
|
|
189
|
+
// 6. Get tokens after consent
|
|
190
|
+
const tokens = await GoogleSignin.getTokens();
|
|
191
|
+
const currentUser = await GoogleSignin.getCurrentUser();
|
|
192
|
+
|
|
193
|
+
// 7. Analyze tokens thoroughly (serverAuthCode is the refresh token mechanism in React Native)
|
|
194
|
+
let finalRefreshToken = null;
|
|
195
|
+
let refreshTokenSource = 'None';
|
|
196
|
+
|
|
197
|
+
// Check for server auth code from sign-in response (primary method)
|
|
198
|
+
if (userInfo.serverAuthCode) {
|
|
199
|
+
finalRefreshToken = userInfo.serverAuthCode;
|
|
200
|
+
refreshTokenSource = 'Server auth code from sign-in';
|
|
201
|
+
}
|
|
202
|
+
// Check current user server auth code (backup method)
|
|
203
|
+
else if (currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode) {
|
|
204
|
+
finalRefreshToken = currentUser.serverAuthCode;
|
|
205
|
+
refreshTokenSource = 'Current user server auth code';
|
|
206
|
+
}
|
|
207
|
+
console.log('🔍 Token Analysis:', {
|
|
208
|
+
hasAccessToken: !!tokens.accessToken,
|
|
209
|
+
hasIdToken: !!tokens.idToken,
|
|
210
|
+
hasServerAuthCode: !!userInfo.serverAuthCode,
|
|
211
|
+
hasCurrentUserAuthCode: !!(currentUser !== null && currentUser !== void 0 && currentUser.serverAuthCode),
|
|
212
|
+
refreshTokenSource: refreshTokenSource,
|
|
213
|
+
finalRefreshToken: finalRefreshToken ? 'Available' : 'MISSING!',
|
|
214
|
+
userEmail: (_user = userInfo.user) === null || _user === void 0 ? void 0 : _user.email
|
|
215
|
+
});
|
|
216
|
+
if (!finalRefreshToken) {
|
|
217
|
+
console.error('❌ No refresh token received - Google Console configuration may be incorrect');
|
|
218
|
+
console.error('💡 This usually means:');
|
|
219
|
+
console.error(' 1. offlineAccess: true is missing from configuration');
|
|
220
|
+
console.error(' 2. forceCodeForRefreshToken: true is missing');
|
|
221
|
+
console.error(' 3. User did not grant offline access permission');
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
console.log('✅ Got refresh token after consent:', finalRefreshToken.substring(0, 20) + '...');
|
|
225
|
+
console.log('🔑 Refresh token source:', refreshTokenSource);
|
|
226
|
+
|
|
227
|
+
// 8. Get existing authentication token
|
|
228
|
+
let authToken = (await AsyncStorage.getItem('onairos_jwt_token')) || (await AsyncStorage.getItem('enoch_token')) || (await AsyncStorage.getItem('auth_token'));
|
|
229
|
+
if (!authToken) {
|
|
230
|
+
console.warn('⚠️ No authentication token found for YouTube migration');
|
|
231
|
+
authToken = 'migration_token_placeholder';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// 9. Send enhanced payload to backend
|
|
235
|
+
const backendPayload = {
|
|
236
|
+
session: {
|
|
237
|
+
username: username,
|
|
238
|
+
platform: 'youtube',
|
|
239
|
+
channelName: ((_user2 = userInfo.user) === null || _user2 === void 0 ? void 0 : _user2.name) || 'YouTube Channel',
|
|
240
|
+
channelId: null
|
|
241
|
+
},
|
|
242
|
+
googleUser: userInfo.user,
|
|
243
|
+
accessToken: tokens.accessToken,
|
|
244
|
+
idToken: tokens.idToken,
|
|
245
|
+
refreshToken: finalRefreshToken,
|
|
246
|
+
serverAuthCode: userInfo.serverAuthCode,
|
|
247
|
+
userAccountInfo: {
|
|
248
|
+
username: username,
|
|
249
|
+
email: (_user3 = userInfo.user) === null || _user3 === void 0 ? void 0 : _user3.email,
|
|
250
|
+
authToken: authToken,
|
|
251
|
+
channelName: ((_user4 = userInfo.user) === null || _user4 === void 0 ? void 0 : _user4.name) || 'YouTube Channel',
|
|
252
|
+
channelId: null
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
console.log('📤 Sending migration payload to backend...');
|
|
256
|
+
|
|
257
|
+
// 10. Send to backend
|
|
258
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}/youtube/native-auth`, {
|
|
259
|
+
method: 'POST',
|
|
260
|
+
headers: {
|
|
261
|
+
'Content-Type': 'application/json',
|
|
262
|
+
'x-api-key': 'your-api-key',
|
|
263
|
+
// Use your existing API key if needed
|
|
264
|
+
...(authToken !== 'migration_token_placeholder' && {
|
|
265
|
+
'Authorization': `Bearer ${authToken}`
|
|
266
|
+
})
|
|
267
|
+
},
|
|
268
|
+
body: JSON.stringify(backendPayload)
|
|
269
|
+
});
|
|
270
|
+
const result = await response.json();
|
|
271
|
+
if (result.success) {
|
|
272
|
+
console.log('✅ YouTube migration successful');
|
|
273
|
+
|
|
274
|
+
// Track migration success
|
|
275
|
+
await trackMigrationAttempt(username, true);
|
|
276
|
+
return true;
|
|
277
|
+
} else {
|
|
278
|
+
console.error('❌ Backend rejected YouTube migration:', result.error);
|
|
279
|
+
await trackMigrationAttempt(username, false, result.error);
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error('❌ YouTube migration failed:', error);
|
|
284
|
+
await trackMigrationAttempt(username, false, error instanceof Error ? error.message : 'Unknown error');
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// Track migration attempts for monitoring
|
|
290
|
+
const trackMigrationAttempt = async (username, success, error) => {
|
|
291
|
+
try {
|
|
292
|
+
await fetch(`${API_CONFIG.BASE_URL}/youtube/migration-status`, {
|
|
293
|
+
method: 'POST',
|
|
294
|
+
headers: {
|
|
295
|
+
'Content-Type': 'application/json'
|
|
296
|
+
},
|
|
297
|
+
body: JSON.stringify({
|
|
298
|
+
username,
|
|
299
|
+
success,
|
|
300
|
+
error: error || null,
|
|
301
|
+
timestamp: new Date().toISOString()
|
|
302
|
+
})
|
|
303
|
+
});
|
|
304
|
+
} catch (trackError) {
|
|
305
|
+
console.error('❌ Failed to track migration attempt:', trackError);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// ✅ NEW: Explicit function to check if user should see migration warnings
|
|
310
|
+
export const shouldShowYouTubeMigrationWarning = async username => {
|
|
311
|
+
try {
|
|
312
|
+
console.log('🔍 [MIGRATION WARNING] Checking if user should see migration warning:', username);
|
|
313
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}/youtube/validate-connection/${username}`);
|
|
314
|
+
const result = await response.json();
|
|
315
|
+
if (result.success && result.validation) {
|
|
316
|
+
var _result$validation3, _result$temporaryMode4;
|
|
317
|
+
// Check for temporary mode (prioritize exact backend fields)
|
|
318
|
+
const isTemporaryMode = ((_result$validation3 = result.validation) === null || _result$validation3 === void 0 ? void 0 : _result$validation3.isTemporaryMode) === true || ((_result$temporaryMode4 = result.temporaryMode) === null || _result$temporaryMode4 === void 0 ? void 0 : _result$temporaryMode4.enabled) === true || result.isTemporaryMode === true;
|
|
319
|
+
const hasAccessToken = result.validation.hasAccessToken === true;
|
|
320
|
+
const hasRefreshToken = result.validation.hasRefreshToken === true;
|
|
321
|
+
const needsReconnection = result.validation.needsReconnection === true;
|
|
322
|
+
console.log('📊 [MIGRATION WARNING] Status check:', {
|
|
323
|
+
username,
|
|
324
|
+
hasAccessToken,
|
|
325
|
+
hasRefreshToken,
|
|
326
|
+
needsReconnection,
|
|
327
|
+
isTemporaryMode,
|
|
328
|
+
connectedAt: result.validation.connectedAt
|
|
329
|
+
});
|
|
330
|
+
if (isTemporaryMode) {
|
|
331
|
+
console.log('🚫 [MIGRATION WARNING] NO WARNING - user is in temporary mode (working correctly)');
|
|
332
|
+
return false; // Don't show migration warning
|
|
333
|
+
} else if (hasAccessToken && !hasRefreshToken && needsReconnection) {
|
|
334
|
+
console.log('⚠️ [MIGRATION WARNING] SHOW WARNING - genuinely old connection needs update');
|
|
335
|
+
return true; // Show migration warning for genuinely broken connections
|
|
336
|
+
} else {
|
|
337
|
+
console.log('✅ [MIGRATION WARNING] NO WARNING - connection is working properly');
|
|
338
|
+
return false; // Don't show warning for working connections
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
console.log('ℹ️ [MIGRATION WARNING] NO WARNING - no YouTube connection found');
|
|
342
|
+
return false; // Don't show warning if no connection
|
|
343
|
+
} catch (error) {
|
|
344
|
+
console.error('❌ [MIGRATION WARNING] Error checking migration warning status:', error);
|
|
345
|
+
return false; // Don't show warning on error
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// Main function to check and fix YouTube connection
|
|
350
|
+
export const checkAndFixYouTubeConnection = async username => {
|
|
351
|
+
try {
|
|
352
|
+
console.log('🔄 Checking YouTube connection for user:', username);
|
|
353
|
+
|
|
354
|
+
// 1. First check if user should see migration warning at all
|
|
355
|
+
const shouldShowWarning = await shouldShowYouTubeMigrationWarning(username);
|
|
356
|
+
if (!shouldShowWarning) {
|
|
357
|
+
console.log('🚫 [MIGRATION] NO MIGRATION NEEDED - user connection is working correctly');
|
|
358
|
+
console.log('✅ [MIGRATION] User can proceed with training normally');
|
|
359
|
+
return true; // Return success - no migration needed
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// 2. Double-check migration is actually needed (for safety)
|
|
363
|
+
const needsMigration = await checkYouTubeMigrationNeeded(username);
|
|
364
|
+
if (!needsMigration) {
|
|
365
|
+
console.log('✅ [MIGRATION] YouTube connection working properly - no migration needed');
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
console.log('🔧 [MIGRATION] User needs YouTube migration for refresh token (genuinely old connection)');
|
|
369
|
+
|
|
370
|
+
// 2. Show user-friendly prompt
|
|
371
|
+
const userConfirmed = await showYouTubeMigrationPrompt();
|
|
372
|
+
if (!userConfirmed) {
|
|
373
|
+
console.log('ℹ️ User declined YouTube migration');
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// 3. Attempt migration
|
|
378
|
+
const migrationSuccess = await forceYouTubeReconnection(username);
|
|
379
|
+
if (migrationSuccess) {
|
|
380
|
+
// Show success message
|
|
381
|
+
Alert.alert('YouTube Upgraded! ✅', 'Your YouTube connection has been upgraded successfully. Training will now work seamlessly without interruptions.', [{
|
|
382
|
+
text: 'Great!',
|
|
383
|
+
style: 'default'
|
|
384
|
+
}]);
|
|
385
|
+
return true;
|
|
386
|
+
} else {
|
|
387
|
+
// Show failure message
|
|
388
|
+
Alert.alert('Upgrade Failed ❌', 'YouTube connection upgrade failed. Please try again later or contact support if the problem persists.', [{
|
|
389
|
+
text: 'OK',
|
|
390
|
+
style: 'default'
|
|
391
|
+
}]);
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
} catch (error) {
|
|
395
|
+
console.error('❌ Error in YouTube connection check:', error);
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
// Optional: Reconnect function for manual use
|
|
401
|
+
export const reconnectYouTube = async username => {
|
|
402
|
+
console.log('🔄 Manual YouTube reconnection requested for:', username);
|
|
403
|
+
return await forceYouTubeReconnection(username);
|
|
404
|
+
};
|
|
405
|
+
//# sourceMappingURL=youtubeMigrationService.js.map
|