@onairos/react-native 3.7.1 → 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/assets/icons/spotify.png +0 -0
- package/lib/commonjs/assets/images/spotify.png +0 -0
- 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/assets/icons/spotify.png +0 -0
- package/lib/module/assets/images/spotify.png +0 -0
- 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,106 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { getConnectedAccountsSmart
|
|
3
|
+
// Keep legacy imports for any edge cases
|
|
4
|
+
} from '../services/connectedAccountsService';
|
|
5
|
+
import { useAuth } from '../context/AuthContext';
|
|
6
|
+
export const useConnectedAccounts = () => {
|
|
7
|
+
const {
|
|
8
|
+
user
|
|
9
|
+
} = useAuth();
|
|
10
|
+
const [connectedAccounts, setConnectedAccounts] = useState([]);
|
|
11
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
12
|
+
const [error, setError] = useState(null);
|
|
13
|
+
const fetchConnectedAccounts = useCallback(async () => {
|
|
14
|
+
if (!user) {
|
|
15
|
+
console.log('🔍 No user available for fetching connected accounts');
|
|
16
|
+
setIsLoading(false);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
setError(null);
|
|
22
|
+
console.log('🚀 [HOOK] Starting connected accounts fetch with new smart API...');
|
|
23
|
+
console.log('🚀 [HOOK] User info available:', {
|
|
24
|
+
email: user.email,
|
|
25
|
+
id: user.id,
|
|
26
|
+
name: user.name
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Use the new smart API function - makes only ONE request with intelligent fallbacks
|
|
30
|
+
const accounts = await getConnectedAccountsSmart(user.email,
|
|
31
|
+
// Primary identifier (email)
|
|
32
|
+
user.id,
|
|
33
|
+
// Secondary identifier (user ID)
|
|
34
|
+
user.name // Tertiary identifier (username)
|
|
35
|
+
);
|
|
36
|
+
console.log(`✅ [HOOK] Connected accounts loaded via smart API: ${accounts.length} accounts`);
|
|
37
|
+
setConnectedAccounts(accounts);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error('❌ [HOOK] Error fetching connected accounts:', err);
|
|
40
|
+
setError('Failed to load connected accounts');
|
|
41
|
+
} finally {
|
|
42
|
+
setIsLoading(false);
|
|
43
|
+
}
|
|
44
|
+
}, [user]);
|
|
45
|
+
const refreshAccounts = useCallback(async () => {
|
|
46
|
+
console.log('🔄 [HOOK] Refreshing connected accounts...');
|
|
47
|
+
await fetchConnectedAccounts();
|
|
48
|
+
}, [fetchConnectedAccounts]);
|
|
49
|
+
const addAccount = useCallback((platform, username) => {
|
|
50
|
+
// Create a temporary URL for the account
|
|
51
|
+
const tempUrl = `https://${platform.toLowerCase()}.com/${username}`;
|
|
52
|
+
const newAccount = {
|
|
53
|
+
platform,
|
|
54
|
+
username,
|
|
55
|
+
url: tempUrl
|
|
56
|
+
};
|
|
57
|
+
setConnectedAccounts(prev => {
|
|
58
|
+
// Check if account already exists
|
|
59
|
+
const exists = prev.some(acc => acc.platform.toLowerCase() === platform.toLowerCase());
|
|
60
|
+
if (exists) {
|
|
61
|
+
// Update existing account
|
|
62
|
+
return prev.map(acc => acc.platform.toLowerCase() === platform.toLowerCase() ? newAccount : acc);
|
|
63
|
+
} else {
|
|
64
|
+
// Add new account
|
|
65
|
+
return [...prev, newAccount];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
console.log('✅ [HOOK] Account added locally:', newAccount);
|
|
69
|
+
|
|
70
|
+
// TODO: In a real implementation, you would also send this to your backend
|
|
71
|
+
// Example:
|
|
72
|
+
// try {
|
|
73
|
+
// await saveConnectedAccount(user.id, platform, username);
|
|
74
|
+
// } catch (error) {
|
|
75
|
+
// console.error('Failed to save account to backend:', error);
|
|
76
|
+
// // Optionally revert the local change
|
|
77
|
+
// }
|
|
78
|
+
}, []);
|
|
79
|
+
const removeAccount = useCallback(platform => {
|
|
80
|
+
setConnectedAccounts(prev => prev.filter(acc => acc.platform.toLowerCase() !== platform.toLowerCase()));
|
|
81
|
+
console.log('✅ [HOOK] Account removed locally:', platform);
|
|
82
|
+
|
|
83
|
+
// TODO: In a real implementation, you would also remove this from your backend
|
|
84
|
+
// Example:
|
|
85
|
+
// try {
|
|
86
|
+
// await removeConnectedAccount(user.id, platform);
|
|
87
|
+
// } catch (error) {
|
|
88
|
+
// console.error('Failed to remove account from backend:', error);
|
|
89
|
+
// // Optionally revert the local change
|
|
90
|
+
// }
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
// Fetch accounts when component mounts or user changes
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
fetchConnectedAccounts();
|
|
96
|
+
}, [fetchConnectedAccounts]);
|
|
97
|
+
return {
|
|
98
|
+
connectedAccounts,
|
|
99
|
+
isLoading,
|
|
100
|
+
error,
|
|
101
|
+
refreshAccounts,
|
|
102
|
+
addAccount,
|
|
103
|
+
removeAccount
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=useConnectedAccounts.js.map
|
|
@@ -1 +1,95 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
import { initiateNativeAuth } from '../services/platformAuthService';
|
|
3
|
+
/**
|
|
4
|
+
* Hook for managing platform connections
|
|
5
|
+
* NOTE: This hook now only manages LOCAL state
|
|
6
|
+
* Consuming apps are responsible for syncing connection status to their backend
|
|
7
|
+
* (e.g., calling /enoch/users/update for Enoch apps)
|
|
8
|
+
*/
|
|
9
|
+
export const useConnections = () => {
|
|
10
|
+
const [connections, setConnections] = useState({});
|
|
11
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Connect a platform using OAuth or native SDK
|
|
15
|
+
* NOTE: Only manages local state - backend sync removed from SDK
|
|
16
|
+
*/
|
|
17
|
+
const connectPlatform = useCallback(async (platform, username) => {
|
|
18
|
+
try {
|
|
19
|
+
setIsConnecting(true);
|
|
20
|
+
|
|
21
|
+
// Determine if we should use native SDK or OAuth
|
|
22
|
+
const useNativeSDK = platform === 'youtube' || platform === 'instagram';
|
|
23
|
+
let success = false;
|
|
24
|
+
if (useNativeSDK) {
|
|
25
|
+
// Use native SDK
|
|
26
|
+
success = await initiateNativeAuth(platform, username);
|
|
27
|
+
} else {
|
|
28
|
+
// For demo purposes, we'll simulate a successful connection
|
|
29
|
+
await new Promise(resolve => setTimeout(() => resolve(undefined), 1000));
|
|
30
|
+
success = true;
|
|
31
|
+
}
|
|
32
|
+
if (success) {
|
|
33
|
+
// Update connections state locally only
|
|
34
|
+
// NOTE: Backend sync removed - consuming app should handle this
|
|
35
|
+
setConnections(prev => ({
|
|
36
|
+
...prev,
|
|
37
|
+
[platform]: {
|
|
38
|
+
userName: username,
|
|
39
|
+
connected: true
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
console.log(`✅ Platform ${platform} connected locally`);
|
|
43
|
+
console.log('ℹ️ NOTE: Backend sync removed from SDK - app should call /enoch/users/update if needed');
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(`Error connecting platform ${platform}:`, error);
|
|
49
|
+
return false;
|
|
50
|
+
} finally {
|
|
51
|
+
setIsConnecting(false);
|
|
52
|
+
}
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Disconnect a platform
|
|
57
|
+
* NOTE: Only manages local state - backend sync removed from SDK
|
|
58
|
+
*/
|
|
59
|
+
const disconnectPlatform = useCallback(async (platform, _username) => {
|
|
60
|
+
try {
|
|
61
|
+
// Update local state only
|
|
62
|
+
// NOTE: Backend sync removed - consuming app should handle this
|
|
63
|
+
setConnections(prev => {
|
|
64
|
+
const newConnections = {
|
|
65
|
+
...prev
|
|
66
|
+
};
|
|
67
|
+
delete newConnections[platform];
|
|
68
|
+
return newConnections;
|
|
69
|
+
});
|
|
70
|
+
console.log(`✅ Platform ${platform} disconnected locally`);
|
|
71
|
+
console.log('ℹ️ NOTE: Backend sync removed from SDK - app should call /enoch/users/update if needed');
|
|
72
|
+
return true;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error(`Error disconnecting platform ${platform}:`, error);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get current connection status
|
|
81
|
+
*/
|
|
82
|
+
const getConnectionStatus = useCallback(async () => {
|
|
83
|
+
// Returns local connection state
|
|
84
|
+
// Consuming app can fetch from backend if needed
|
|
85
|
+
return connections;
|
|
86
|
+
}, [connections]);
|
|
87
|
+
return {
|
|
88
|
+
connections,
|
|
89
|
+
connectPlatform,
|
|
90
|
+
disconnectPlatform,
|
|
91
|
+
getConnectionStatus,
|
|
92
|
+
isConnecting
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=useConnections.js.map
|
|
@@ -1,7 +1,172 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { STORAGE_KEYS } from '../constants';
|
|
3
|
+
import { API_CONFIG } from '../config/api';
|
|
1
4
|
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function _0x1885(){const _0x21ab7d=['warn','Error\x20checking\x20credentials:','ckEcq','function','nUDgO','WzCfe','NDfBT','error','gUySt','ntURV','getGenericPassword','ghSte','default','OSXuP','OPwkT','BKYPZ','Wpqqw','ICwBZ','NstCA','service','sIeHk','ndRWG','RAApC','kRvNB','OUpIE','smIXK','pNiwk','YehgK','Keychain\x20access\x20failed,\x20using\x20mock\x20storage','kyDMl','fZizU','HLPnk','gDlwc','ksXnH','kwgSA','setGenericPassword','OiWGi','qdmbm','ueFrl','uMYdK','WdEcs','Error\x20validating\x20credentials:','PJxlA','qPqCJ','cBpuc','LDNNs','voMMn','kKAvq','nBrWm','HSzgM','vVyfj','password','UBspr','tdXaY','BrlLx','NVjyr','Error\x20clearing\x20credentials:','gcjFf','avvLp','Error\x20getting\x20credentials:','BSSju','LYRVk','zYslM','eXPLm','lFbnf','IhGAN','NNPsn','accessControl','WkMaV','ACCESS_CONTROL','BIOMETRY_ANY','accessible','ACCESSIBLE','ctiKX','Error\x20storing\x20credentials:','VihHZ','ioSuS','NnAoi','YfPqj','GdBME','LKxaM','credentials','ePdjj','RnrKC','parse','zWovL','oJeLj','UwmIH','fkKkK','dqApj','XozdN','IoUWE','nudLa','toosq','WHEN_UNLOCKED','sYzBU','mjkjc','xmUPh','xZXjA','ZBCwK','VeYXE','fLLDx','BASE_URL','stringify','json','valid'];_0x1885=function(){return _0x21ab7d;};return _0x1885();}import{useCallback}from'react';function _0xbd5e(_0x1885e1,_0xbd5eda){_0x1885e1=_0x1885e1-0x0;const _0x11bd40=_0x1885();let _0x1f9907=_0x11bd40[_0x1885e1];return _0x1f9907;}import{STORAGE_KEYS}from'../constants';import{API_CONFIG}from'../config/api';const mockCredentialStorage={};let Keychain=null;try{Keychain=__ONAIROS_REQ_FUNC__(0x0);}catch(_0x3d3e11){console[_0xbd5e(0x0)]('react-native-keychain module not available in useCredentials, using mock storage');}const isKeychainAvailable=()=>{const _0x1e141e={'gUySt':_0xbd5e(0x1),'nUDgO':function(_0x4501ba,_0x4d8d06){return _0x4501ba===_0x4d8d06;},'WzCfe':'FGzFD','NDfBT':_0xbd5e(0x2),'ntURV':function(_0x17cc19,_0x3b91ab){return _0x17cc19===_0x3b91ab;},'ghSte':_0xbd5e(0x3)};try{return _0x1e141e[_0xbd5e(0x4)](_0x1e141e[_0xbd5e(0x5)],_0x1e141e[_0xbd5e(0x6)])?(_0x57ca71[_0xbd5e(0x7)](_0x1e141e[_0xbd5e(0x8)],_0x3b5455),![]):Keychain&&_0x1e141e[_0xbd5e(0x9)](typeof Keychain[_0xbd5e(0xa)],_0x1e141e[_0xbd5e(0xb)]);}catch(_0x3a7b34){return![];}},safeGetGenericPassword=async _0xf66f84=>{const _0x1a3502={'kRvNB':function(_0x319f6e,_0x5d2191){return _0x319f6e===_0x5d2191;},'sIeHk':_0xbd5e(0xc),'OUpIE':_0xbd5e(0x3),'kyDMl':'Keychain\x20access\x20failed,\x20using\x20mock\x20storage','Wpqqw':function(_0x11ced3,_0x36e604){return _0x11ced3===_0x36e604;},'ICwBZ':_0xbd5e(0xd),'ndRWG':function(_0x5a30bc){return _0x5a30bc();},'smIXK':function(_0x158bef,_0x3480ca){return _0x158bef!==_0x3480ca;},'RAApC':_0xbd5e(0xe),'pNiwk':_0xbd5e(0xf)};try{if(_0x1a3502[_0xbd5e(0x10)](_0x1a3502[_0xbd5e(0x11)],_0xbd5e(0x12))){const _0x292dd0=(_0x1a3502['kRvNB'](_0x3d90fe,null)||_0xfc0fd3===void 0x0?void 0x0:_0x501b1f[_0xbd5e(0x13)])||_0x1a3502[_0xbd5e(0x14)];return delete _0x3ba5c6[_0x292dd0],!![];}else{if(_0x1a3502[_0xbd5e(0x15)](isKeychainAvailable))return await Keychain[_0xbd5e(0xa)](_0xf66f84);else{if(_0x1a3502['smIXK'](_0x1a3502[_0xbd5e(0x16)],_0x1a3502[_0xbd5e(0x16)]))try{return Keychain&&_0x1a3502[_0xbd5e(0x17)](typeof Keychain[_0xbd5e(0xa)],_0x1a3502[_0xbd5e(0x18)]);}catch(_0x33e4f2){return![];}else{const _0x28f806=(_0x1a3502['Wpqqw'](_0xf66f84,null)||_0xf66f84===void 0x0?void 0x0:_0xf66f84[_0xbd5e(0x13)])||_0x1a3502[_0xbd5e(0x14)];return mockCredentialStorage[_0x28f806]||null;}}}}catch(_0x5c6df6){if(_0x1a3502[_0xbd5e(0x19)](_0x1a3502[_0xbd5e(0x1a)],_0xbd5e(0x1b))){console[_0xbd5e(0x0)](_0xbd5e(0x1c),_0x5c6df6);const _0x2fd4c1=(_0x1a3502[_0xbd5e(0x10)](_0xf66f84,null)||_0x1a3502[_0xbd5e(0x17)](_0xf66f84,void 0x0)?void 0x0:_0xf66f84[_0xbd5e(0x13)])||_0x1a3502[_0xbd5e(0x14)];return mockCredentialStorage[_0x2fd4c1]||null;}else{_0x10eb08[_0xbd5e(0x0)](_0x1a3502[_0xbd5e(0x1d)],_0x9e84fc);const _0x29a75f=(_0x3beb17===null||_0x305941===void 0x0?void 0x0:_0x10c056[_0xbd5e(0x13)])||_0xbd5e(0xc);return _0x622732[_0x29a75f]||null;}}},safeSetGenericPassword=async(_0x5603d7,_0xb44ca3,_0x2c4e77)=>{const _0x459907={'ueFrl':function(_0x513959,_0x47552b){return _0x513959(_0x47552b);},'gDlwc':function(_0x91a001,_0x30b53c){return _0x91a001!==_0x30b53c;},'ksXnH':_0xbd5e(0x1e),'kwgSA':_0xbd5e(0x1f),'OiWGi':function(_0x459fbc,_0x4c1046){return _0x459fbc===_0x4c1046;},'YEniN':function(_0x38c1c9,_0x3d18c6){return _0x38c1c9===_0x3d18c6;},'qdmbm':_0xbd5e(0xc),'lvOyI':_0xbd5e(0x1c),'uMYdK':function(_0x42ad16,_0x3bbb19){return _0x42ad16===_0x3bbb19;},'WdEcs':function(_0x2adf14,_0x44aa73){return _0x2adf14===_0x44aa73;}};try{if(_0x459907[_0xbd5e(0x20)](_0x459907[_0xbd5e(0x21)],_0x459907[_0xbd5e(0x22)])){if(isKeychainAvailable())return await Keychain[_0xbd5e(0x23)](_0x5603d7,_0xb44ca3,_0x2c4e77);else{const _0x20863a=(_0x459907[_0xbd5e(0x24)](_0x2c4e77,null)||_0x459907['YEniN'](_0x2c4e77,void 0x0)?void 0x0:_0x2c4e77[_0xbd5e(0x13)])||_0x459907[_0xbd5e(0x25)];return mockCredentialStorage[_0x20863a]={'username':_0x5603d7,'password':_0xb44ca3},!![];}}else Keychain=_0x459907[_0xbd5e(0x26)](_0x2cfa7e,0x0);}catch(_0x3f8f41){console[_0xbd5e(0x0)](_0x459907['lvOyI'],_0x3f8f41);const _0x206840=(_0x459907[_0xbd5e(0x27)](_0x2c4e77,null)||_0x459907[_0xbd5e(0x28)](_0x2c4e77,void 0x0)?void 0x0:_0x2c4e77['service'])||_0xbd5e(0xc);return mockCredentialStorage[_0x206840]={'username':_0x5603d7,'password':_0xb44ca3},!![];}},safeResetGenericPassword=async _0x514a85=>{const _0x3ae687={'HSzgM':'Keychain\x20access\x20failed,\x20using\x20mock\x20storage','kKAvq':function(_0x11cfd5,_0xabf96c){return _0x11cfd5===_0xabf96c;},'vVyfj':_0xbd5e(0xc),'BrlLx':_0xbd5e(0x29),'voMMn':function(_0x3a09c3){return _0x3a09c3();},'nBrWm':_0xbd5e(0x2a),'yXwTg':_0xbd5e(0x2b),'seqLS':_0xbd5e(0x2c),'UBspr':function(_0x23a388,_0xf617ee){return _0x23a388===_0xf617ee;},'tdXaY':_0xbd5e(0x2d)};try{if(_0x3ae687[_0xbd5e(0x2e)](isKeychainAvailable)){if(_0x3ae687[_0xbd5e(0x2f)](_0x3ae687[_0xbd5e(0x30)],_0x3ae687['yXwTg'])){_0x49be83[_0xbd5e(0x0)](_0x3ae687[_0xbd5e(0x31)],_0x160c11);const _0x41a1f8=(_0x46ecf1===null||_0x3ae687[_0xbd5e(0x2f)](_0x4764b3,void 0x0)?void 0x0:_0x666159['service'])||_0x3ae687[_0xbd5e(0x32)];return delete _0x35f505[_0x41a1f8],!![];}else return await Keychain['resetGenericPassword'](_0x514a85);}else{if('cBpuc'===_0x3ae687['seqLS']){const _0xf24794=(_0x514a85===null||_0x3ae687[_0xbd5e(0x2f)](_0x514a85,void 0x0)?void 0x0:_0x514a85[_0xbd5e(0x13)])||_0x3ae687[_0xbd5e(0x32)];return delete mockCredentialStorage[_0xf24794],!![];}else return _0x931c83['parse'](_0x1f95db[_0xbd5e(0x33)]);}}catch(_0x4fb492){if(_0x3ae687[_0xbd5e(0x34)]('LDNNs',_0x3ae687[_0xbd5e(0x35)])){console[_0xbd5e(0x0)](_0x3ae687[_0xbd5e(0x31)],_0x4fb492);const _0x52c3d6=(_0x514a85===null||_0x514a85===void 0x0?void 0x0:_0x514a85[_0xbd5e(0x13)])||_0xbd5e(0xc);return delete mockCredentialStorage[_0x52c3d6],!![];}else return _0xdca375[_0xbd5e(0x7)](_0x3ae687[_0xbd5e(0x36)],_0x3ddb97),{'success':![],'isValid':![]};}};export const useCredentials=()=>{const _0x520c0d={'WkMaV':function(_0x8c197d,_0x38b26b){return _0x8c197d===_0x38b26b;},'xmUPh':function(_0x10c988,_0x2e11a6){return _0x10c988===_0x2e11a6;},'zYslM':_0xbd5e(0x37),'eXPLm':function(_0x2486f3,_0xd7e244){return _0x2486f3(_0xd7e244);},'lFbnf':function(_0x1c3533,_0x3a7dc5){return _0x1c3533===_0x3a7dc5;},'QiSaR':'IhGAN','NNPsn':_0xbd5e(0x1),'ZBCwK':_0xbd5e(0x38),'VihHZ':function(_0x5edb21,_0x277c9a){return _0x5edb21===_0x277c9a;},'NnAoi':function(_0x3c10d2,_0x2413ef){return _0x3c10d2===_0x2413ef;},'LKxaM':function(_0x128923,_0x50e564){return _0x128923(_0x50e564);},'ePdjj':'hwMwo','zWovL':function(_0x1ed218,_0x30f1b6){return _0x1ed218!==_0x30f1b6;},'oJeLj':_0xbd5e(0x39),'UwmIH':_0xbd5e(0x3a),'fkKkK':_0xbd5e(0x3b),'upVaZ':'Keychain\x20access\x20failed,\x20using\x20mock\x20storage','XozdN':function(_0x2be174){return _0x2be174();},'IoUWE':_0xbd5e(0x3c),'toosq':function(_0x1f27be,_0x4848cf){return _0x1f27be===_0x4848cf;},'EfBUk':function(_0x4aa72a,_0x2f94ed,_0x5f7122,_0x543fc5){return _0x4aa72a(_0x2f94ed,_0x5f7122,_0x543fc5);},'xZXjA':_0xbd5e(0xc),'mjkjc':_0xbd5e(0x3d),'VeYXE':'ZdZxY','fLLDx':'XQwVZ','ctiKX':function(_0x53c5e5,_0x2fb5e1,_0x392777){return _0x53c5e5(_0x2fb5e1,_0x392777);}},_0x28a824=useCallback(async()=>{const _0x54d736={'qDrEf':_0xbd5e(0x3b)};try{if(_0x520c0d['xmUPh'](_0xbd5e(0x37),_0x520c0d[_0xbd5e(0x3e)])){const _0x2d1b17=await _0x520c0d[_0xbd5e(0x3f)](safeGetGenericPassword,{'service':STORAGE_KEYS['credentials']});return!!_0x2d1b17;}else return _0x28ee14[_0xbd5e(0x7)](_0x54d736['qDrEf'],_0x24b261),null;}catch(_0x4f74b6){if(_0x520c0d[_0xbd5e(0x40)](_0xbd5e(0x41),_0x520c0d['QiSaR']))return console[_0xbd5e(0x7)](_0x520c0d[_0xbd5e(0x42)],_0x4f74b6),![];else{var _0x571808,_0x257ec1;_0x285330[_0xbd5e(0x43)]=_0x520c0d[_0xbd5e(0x44)](_0x571808=Keychain[_0xbd5e(0x45)],null)||_0x520c0d[_0xbd5e(0x44)](_0x571808,void 0x0)?void 0x0:_0x571808[_0xbd5e(0x46)],_0x337909[_0xbd5e(0x47)]=_0x520c0d[_0xbd5e(0x44)](_0x257ec1=Keychain[_0xbd5e(0x48)],null)||_0x257ec1===void 0x0?void 0x0:_0x257ec1['WHEN_UNLOCKED'];}}},[]),_0x3c9037=_0x520c0d[_0xbd5e(0x49)](useCallback,async()=>{const _0x1de6e8={'GdBME':_0x520c0d['ZBCwK'],'RnrKC':_0xbd5e(0x4a),'dqApj':_0xbd5e(0x3)};if(_0x520c0d[_0xbd5e(0x4b)](_0xbd5e(0x4c),_0xbd5e(0x4c)))try{if(_0x520c0d[_0xbd5e(0x4d)](_0xbd5e(0x4e),'Ldpan'))_0xa9a14b[_0xbd5e(0x7)](_0x1de6e8[_0xbd5e(0x4f)],_0x4d3cde);else{const _0x1dfd8a=await _0x520c0d[_0xbd5e(0x50)](safeGetGenericPassword,{'service':STORAGE_KEYS[_0xbd5e(0x51)]});if(_0x1dfd8a)return _0x520c0d[_0xbd5e(0x44)]('ChBIQ',_0x520c0d[_0xbd5e(0x52)])?(_0x2f2941[_0xbd5e(0x7)](_0x1de6e8[_0xbd5e(0x53)],_0x4a62b7),![]):JSON[_0xbd5e(0x54)](_0x1dfd8a[_0xbd5e(0x33)]);return null;}}catch(_0xa03311){if(_0x520c0d[_0xbd5e(0x55)](_0x520c0d[_0xbd5e(0x56)],_0x520c0d[_0xbd5e(0x57)]))return console[_0xbd5e(0x7)](_0x520c0d[_0xbd5e(0x58)],_0xa03311),null;else{const _0x3936de=(_0x67bba7===null||_0x58558b===void 0x0?void 0x0:_0x406256[_0xbd5e(0x13)])||_0xbd5e(0xc);return _0x4ae58f[_0x3936de]={'username':_0xf3a188,'password':_0x60bb5a},!![];}}else return Keychain&&typeof Keychain[_0xbd5e(0xa)]===_0x1de6e8[_0xbd5e(0x59)];},[]),_0x2441a3=useCallback(async(_0x15fc1b,_0x2c936d,_0x2192d0)=>{const _0xcecf73={'sYzBU':_0x520c0d['upVaZ']};try{const _0x4515cb={'service':STORAGE_KEYS[_0xbd5e(0x51)]};if(_0x520c0d[_0xbd5e(0x5a)](isKeychainAvailable)){if(_0x520c0d['zWovL'](_0x520c0d[_0xbd5e(0x5b)],_0xbd5e(0x5c))){var _0x11afbf,_0x4a4b0b;_0x4515cb[_0xbd5e(0x43)]=_0x520c0d[_0xbd5e(0x5d)](_0x11afbf=Keychain[_0xbd5e(0x45)],null)||_0x11afbf===void 0x0?void 0x0:_0x11afbf[_0xbd5e(0x46)],_0x4515cb['accessible']=_0x520c0d['NnAoi'](_0x4a4b0b=Keychain[_0xbd5e(0x48)],null)||_0x4a4b0b===void 0x0?void 0x0:_0x4a4b0b[_0xbd5e(0x5e)];}else{_0x2f24fc['warn'](_0xcecf73[_0xbd5e(0x5f)],_0x4610f7);const _0x2c0578=(_0x219178===null||_0x234e69===void 0x0?void 0x0:_0x6ab576[_0xbd5e(0x13)])||_0xbd5e(0xc);return _0x4df6fd[_0x2c0578]={'username':_0x3a5e2e,'password':_0x5715dc},!![];}}return await _0x520c0d['EfBUk'](safeSetGenericPassword,_0x15fc1b,JSON['stringify']({'userPin':_0x2c936d,'accessToken':_0x2192d0}),_0x4515cb),!![];}catch(_0x2431df){return console[_0xbd5e(0x7)](_0xbd5e(0x4a),_0x2431df),![];}},[]),_0x5c3408=_0x520c0d[_0xbd5e(0x49)](useCallback,async()=>{try{if(_0x520c0d[_0xbd5e(0x4d)](_0x520c0d[_0xbd5e(0x60)],_0xbd5e(0x3d)))await safeResetGenericPassword({'service':STORAGE_KEYS[_0xbd5e(0x51)]});else{const _0x3030a3=(_0x520c0d[_0xbd5e(0x4d)](_0x300157,null)||_0x520c0d[_0xbd5e(0x61)](_0xb05381,void 0x0)?void 0x0:_0x1af2ac['service'])||_0x520c0d[_0xbd5e(0x62)];return _0x37d444[_0x3030a3]||null;}}catch(_0x5194ba){console[_0xbd5e(0x7)](_0x520c0d[_0xbd5e(0x63)],_0x5194ba);}},[]),_0x3e9666=_0x520c0d['ctiKX'](useCallback,async _0x25f5f3=>{if(_0x520c0d['VihHZ'](_0x520c0d[_0xbd5e(0x64)],_0x520c0d[_0xbd5e(0x64)]))try{if(_0x520c0d[_0xbd5e(0x65)]==='XQwVZ'){const _0x4ad782=await _0x520c0d[_0xbd5e(0x49)](fetch,API_CONFIG[_0xbd5e(0x66)]+'/validate',{'method':'POST','headers':{'Content-Type':'application/json'},'body':JSON[_0xbd5e(0x67)]({'username':_0x25f5f3})}),_0x502a53=await _0x4ad782[_0xbd5e(0x68)]();return{'success':!![],'isValid':_0x502a53[_0xbd5e(0x69)],'credentials':_0x502a53[_0xbd5e(0x51)]};}else _0x3789ff[_0xbd5e(0x0)]('react-native-keychain module not available in useCredentials, using mock storage');}catch(_0xbaecc6){return console[_0xbd5e(0x7)](_0xbd5e(0x29),_0xbaecc6),{'success':![],'isValid':![]};}else return![];},[]);return{'hasCredentials':_0x28a824,'getCredentials':_0x3c9037,'storeCredentials':_0x2441a3,'clearCredentials':_0x5c3408,'validateCredentials':_0x3e9666};};
|
|
5
|
+
// Create a mock storage for environments without Keychain access
|
|
6
|
+
const mockCredentialStorage = {};
|
|
7
|
+
|
|
8
|
+
// Try to import Keychain, but provide fallbacks if not available
|
|
9
|
+
let Keychain = null;
|
|
10
|
+
try {
|
|
11
|
+
Keychain = require('react-native-keychain');
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.warn('react-native-keychain module not available in useCredentials, using mock storage');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Check if Keychain is properly initialized and available
|
|
17
|
+
const isKeychainAvailable = () => {
|
|
18
|
+
try {
|
|
19
|
+
return Keychain && typeof Keychain.getGenericPassword === 'function';
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Safe wrapper for getGenericPassword
|
|
26
|
+
const safeGetGenericPassword = async options => {
|
|
27
|
+
try {
|
|
28
|
+
if (isKeychainAvailable()) {
|
|
29
|
+
return await Keychain.getGenericPassword(options);
|
|
30
|
+
} else {
|
|
31
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
32
|
+
return mockCredentialStorage[key] || null;
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.warn('Keychain access failed, using mock storage', error);
|
|
36
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
37
|
+
return mockCredentialStorage[key] || null;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Safe wrapper for setGenericPassword
|
|
42
|
+
const safeSetGenericPassword = async (username, password, options) => {
|
|
43
|
+
try {
|
|
44
|
+
if (isKeychainAvailable()) {
|
|
45
|
+
return await Keychain.setGenericPassword(username, password, options);
|
|
46
|
+
} else {
|
|
47
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
48
|
+
mockCredentialStorage[key] = {
|
|
49
|
+
username,
|
|
50
|
+
password
|
|
51
|
+
};
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn('Keychain access failed, using mock storage', error);
|
|
56
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
57
|
+
mockCredentialStorage[key] = {
|
|
58
|
+
username,
|
|
59
|
+
password
|
|
60
|
+
};
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Safe wrapper for resetGenericPassword
|
|
66
|
+
const safeResetGenericPassword = async options => {
|
|
67
|
+
try {
|
|
68
|
+
if (isKeychainAvailable()) {
|
|
69
|
+
return await Keychain.resetGenericPassword(options);
|
|
70
|
+
} else {
|
|
71
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
72
|
+
delete mockCredentialStorage[key];
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.warn('Keychain access failed, using mock storage', error);
|
|
77
|
+
const key = (options === null || options === void 0 ? void 0 : options.service) || 'default';
|
|
78
|
+
delete mockCredentialStorage[key];
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export const useCredentials = () => {
|
|
83
|
+
const hasCredentials = useCallback(async () => {
|
|
84
|
+
try {
|
|
85
|
+
const credentials = await safeGetGenericPassword({
|
|
86
|
+
service: STORAGE_KEYS.credentials
|
|
87
|
+
});
|
|
88
|
+
return !!credentials;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error('Error checking credentials:', error);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}, []);
|
|
94
|
+
const getCredentials = useCallback(async () => {
|
|
95
|
+
try {
|
|
96
|
+
const credentials = await safeGetGenericPassword({
|
|
97
|
+
service: STORAGE_KEYS.credentials
|
|
98
|
+
});
|
|
99
|
+
if (credentials) {
|
|
100
|
+
return JSON.parse(credentials.password);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Error getting credentials:', error);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}, []);
|
|
108
|
+
const storeCredentials = useCallback(async (username, userPin, accessToken) => {
|
|
109
|
+
try {
|
|
110
|
+
const options = {
|
|
111
|
+
service: STORAGE_KEYS.credentials
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// Only use secure storage options on real devices
|
|
115
|
+
if (isKeychainAvailable()) {
|
|
116
|
+
var _Keychain$ACCESS_CONT, _Keychain$ACCESSIBLE;
|
|
117
|
+
options.accessControl = (_Keychain$ACCESS_CONT = Keychain.ACCESS_CONTROL) === null || _Keychain$ACCESS_CONT === void 0 ? void 0 : _Keychain$ACCESS_CONT.BIOMETRY_ANY;
|
|
118
|
+
options.accessible = (_Keychain$ACCESSIBLE = Keychain.ACCESSIBLE) === null || _Keychain$ACCESSIBLE === void 0 ? void 0 : _Keychain$ACCESSIBLE.WHEN_UNLOCKED;
|
|
119
|
+
}
|
|
120
|
+
await safeSetGenericPassword(username, JSON.stringify({
|
|
121
|
+
userPin,
|
|
122
|
+
accessToken
|
|
123
|
+
}), options);
|
|
124
|
+
return true;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error('Error storing credentials:', error);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}, []);
|
|
130
|
+
const clearCredentials = useCallback(async () => {
|
|
131
|
+
try {
|
|
132
|
+
await safeResetGenericPassword({
|
|
133
|
+
service: STORAGE_KEYS.credentials
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('Error clearing credentials:', error);
|
|
137
|
+
}
|
|
138
|
+
}, []);
|
|
139
|
+
const validateCredentials = useCallback(async username => {
|
|
140
|
+
try {
|
|
141
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}/validate`, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: {
|
|
144
|
+
'Content-Type': 'application/json'
|
|
145
|
+
},
|
|
146
|
+
body: JSON.stringify({
|
|
147
|
+
username
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
const data = await response.json();
|
|
151
|
+
return {
|
|
152
|
+
success: true,
|
|
153
|
+
isValid: data.valid,
|
|
154
|
+
credentials: data.credentials
|
|
155
|
+
};
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error('Error validating credentials:', error);
|
|
158
|
+
return {
|
|
159
|
+
success: false,
|
|
160
|
+
isValid: false
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}, []);
|
|
164
|
+
return {
|
|
165
|
+
hasCredentials,
|
|
166
|
+
getCredentials,
|
|
167
|
+
storeCredentials,
|
|
168
|
+
clearCredentials,
|
|
169
|
+
validateCredentials
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=useCredentials.js.map
|
|
@@ -1 +1,140 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { getUserConnections, getUserConnectionsByUsername, getUserConnectionsByUserId, uploadProfilePicture } from '../services/userConnectionsService';
|
|
3
|
+
import { getAuthToken } from '../services/authService';
|
|
4
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
|
+
export const useUserConnections = () => {
|
|
6
|
+
const [connections, setConnections] = useState([]);
|
|
7
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load connections from API with authentication validation
|
|
12
|
+
*/
|
|
13
|
+
const loadConnections = useCallback(async () => {
|
|
14
|
+
try {
|
|
15
|
+
setIsLoading(true);
|
|
16
|
+
setError(null);
|
|
17
|
+
|
|
18
|
+
// ✅ CRITICAL: Validate authentication before making API calls
|
|
19
|
+
const authToken = await getAuthToken();
|
|
20
|
+
|
|
21
|
+
// Check for demo mode (reviewer bypass)
|
|
22
|
+
const reviewerToken = await AsyncStorage.getItem('onairos_jwt_token');
|
|
23
|
+
const isDemoMode = reviewerToken === 'reviewer-bypass-token';
|
|
24
|
+
if (!authToken && !isDemoMode) {
|
|
25
|
+
console.warn('⚠️ [CONNECTIONS HOOK] No authentication token available for connections refresh');
|
|
26
|
+
console.warn('⚠️ [CONNECTIONS HOOK] Skipping API call to prevent unauthenticated requests');
|
|
27
|
+
setConnections([]);
|
|
28
|
+
setError('Authentication required for connections');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (isDemoMode) {
|
|
32
|
+
console.log('🎯 [DEMO MODE] Reviewer bypass detected - skipping API call for demo');
|
|
33
|
+
// For demo mode, return empty connections - ResultsScreen will use fallback data
|
|
34
|
+
setConnections([]);
|
|
35
|
+
setError(null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// At this point, authToken must be valid (not null) because we've checked both cases above
|
|
40
|
+
if (!authToken) {
|
|
41
|
+
console.error('❌ [CONNECTIONS HOOK] Unexpected null token after validation');
|
|
42
|
+
setConnections([]);
|
|
43
|
+
setError('Authentication error');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.log('🔄 Loading user connections with authentication...');
|
|
47
|
+
console.log('🔑 [CONNECTIONS HOOK] Using auth token:', `${authToken.substring(0, 20)}...`);
|
|
48
|
+
const fetchedConnections = await getUserConnections();
|
|
49
|
+
setConnections(fetchedConnections);
|
|
50
|
+
console.log('✅ Connections loaded:', fetchedConnections.length);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to load connections';
|
|
53
|
+
console.error('❌ Error loading connections:', errorMessage);
|
|
54
|
+
setError(errorMessage);
|
|
55
|
+
|
|
56
|
+
// Set empty array on error - screens will handle their own fallbacks
|
|
57
|
+
setConnections([]);
|
|
58
|
+
} finally {
|
|
59
|
+
setIsLoading(false);
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Refresh connections with authentication validation
|
|
65
|
+
*/
|
|
66
|
+
const refreshConnections = useCallback(async () => {
|
|
67
|
+
console.log('🔄 [CONNECTIONS HOOK] Refreshing connections...');
|
|
68
|
+
await loadConnections();
|
|
69
|
+
console.log('✅ [CONNECTIONS HOOK] Connections refresh completed');
|
|
70
|
+
}, [loadConnections]);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get connections by username with authentication validation
|
|
74
|
+
*/
|
|
75
|
+
const getConnectionsByUsername = useCallback(async username => {
|
|
76
|
+
try {
|
|
77
|
+
// ✅ Validate authentication before making API calls
|
|
78
|
+
const authToken = await getAuthToken();
|
|
79
|
+
if (!authToken) {
|
|
80
|
+
console.warn('⚠️ [CONNECTIONS HOOK] No authentication token available for username connections');
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
console.log('🔍 Fetching connections by username:', username);
|
|
84
|
+
console.log('🔑 [CONNECTIONS HOOK] Using auth token:', `${authToken.substring(0, 20)}...`);
|
|
85
|
+
return await getUserConnectionsByUsername(username);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('❌ Error fetching connections by username:', error);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}, []);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get connections by user ID with authentication validation
|
|
94
|
+
*/
|
|
95
|
+
const getConnectionsByUserId = useCallback(async userId => {
|
|
96
|
+
try {
|
|
97
|
+
// ✅ Validate authentication before making API calls
|
|
98
|
+
const authToken = await getAuthToken();
|
|
99
|
+
if (!authToken) {
|
|
100
|
+
console.warn('⚠️ [CONNECTIONS HOOK] No authentication token available for user ID connections');
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
console.log('🔍 Fetching connections by userId:', userId);
|
|
104
|
+
console.log('🔑 [CONNECTIONS HOOK] Using auth token:', `${authToken.substring(0, 20)}...`);
|
|
105
|
+
return await getUserConnectionsByUserId(userId);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('❌ Error fetching connections by userId:', error);
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Upload profile picture
|
|
114
|
+
*/
|
|
115
|
+
const uploadUserProfilePicture = useCallback(async (imageData, fileType = 'jpg') => {
|
|
116
|
+
try {
|
|
117
|
+
console.log('📷 Uploading profile picture for user:');
|
|
118
|
+
const result = await uploadProfilePicture(imageData, fileType);
|
|
119
|
+
return result.success;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error('❌ Error uploading profile picture:', error);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}, []);
|
|
125
|
+
|
|
126
|
+
// Load connections on mount
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
loadConnections();
|
|
129
|
+
}, [loadConnections]);
|
|
130
|
+
return {
|
|
131
|
+
connections,
|
|
132
|
+
isLoading,
|
|
133
|
+
error,
|
|
134
|
+
refreshConnections,
|
|
135
|
+
getConnectionsByUsername,
|
|
136
|
+
getConnectionsByUserId,
|
|
137
|
+
uploadUserProfilePicture
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=useUserConnections.js.map
|