@onairos/react-native 3.0.49 → 3.0.51
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/components/EmailVerificationModal.js +317 -0
- package/lib/commonjs/components/EmailVerificationModal.js.map +1 -0
- package/lib/commonjs/components/TrainingModal.js +66 -75
- package/lib/commonjs/components/TrainingModal.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +30 -5
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/index.js +60 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/services/platformAuthService.js +505 -53
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- package/lib/module/components/EmailVerificationModal.js +308 -0
- package/lib/module/components/EmailVerificationModal.js.map +1 -0
- package/lib/module/components/TrainingModal.js +66 -75
- package/lib/module/components/TrainingModal.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +31 -6
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/services/platformAuthService.js +496 -52
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/typescript/components/EmailVerificationModal.d.ts +10 -0
- package/lib/typescript/components/EmailVerificationModal.d.ts.map +1 -0
- package/lib/typescript/components/TrainingModal.d.ts.map +1 -1
- package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/services/platformAuthService.d.ts +57 -1
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/components/EmailVerificationModal.tsx +356 -0
- package/src/components/TrainingModal.tsx +69 -73
- package/src/components/UniversalOnboarding.tsx +31 -6
- package/src/index.ts +14 -1
- package/src/services/platformAuthService.ts +527 -55
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmailVerificationModal.d.ts","sourceRoot":"","sources":["../../../src/components/EmailVerificationModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAgBrD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,sBAAsB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAsNxE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrainingModal.d.ts","sourceRoot":"","sources":["../../../src/components/TrainingModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAiB3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"TrainingModal.d.ts","sourceRoot":"","sources":["../../../src/components/TrainingModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAiB3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAgQtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniversalOnboarding.d.ts","sourceRoot":"","sources":["../../../src/components/UniversalOnboarding.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AA2BxE,OAAO,KAAK,EAAE,wBAAwB,EAAoB,MAAM,UAAU,CAAC;AAS3E,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"UniversalOnboarding.d.ts","sourceRoot":"","sources":["../../../src/components/UniversalOnboarding.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AA2BxE,OAAO,KAAK,EAAE,wBAAwB,EAAoB,MAAM,UAAU,CAAC;AAS3E,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA8tBlE,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* A React Native implementation for Onairos personalized data integration
|
|
4
4
|
*/
|
|
5
5
|
export type { OnairosButtonProps, DataTier, UniversalOnboardingProps, ConnectionStatus, PlatformListProps, PinInputProps, TrainingModalProps, OAuthWebViewProps, PlatformConfig, ApiResponse, CredentialsResult, OverlayProps, BiometricOptions, PinRequirements, } from './types';
|
|
6
|
+
export type { EmailVerificationModalProps } from './components/EmailVerificationModal';
|
|
6
7
|
export type { StorageOptions, OnairosCredentials } from './utils/secureStorage';
|
|
7
8
|
export type { OAuthConfig } from './services/oauthService';
|
|
8
9
|
export type { ApiErrorType, ApiError } from './utils/onairosApi';
|
|
@@ -11,7 +12,8 @@ export { storeCredentials, getCredentials, hasCredentials, deleteCredentials, up
|
|
|
11
12
|
export { validateCredentials, createAccount, authenticate, refreshToken, getPlatformData, getUserProfile, updatePlatformConnections, } from './utils/onairosApi';
|
|
12
13
|
export { rsaEncrypt, sha256, base64ToBuffer, } from './utils/crypto';
|
|
13
14
|
export { logDebug, logError, isDebugMode, } from './utils/debugHelper';
|
|
14
|
-
export { connectPlatform,
|
|
15
|
+
export { connectPlatform, initializeOAuthService, cleanupOAuthService, storePlatformConnection, } from './services/oauthService';
|
|
16
|
+
export { updateGoogleClientIds, refreshYouTubeTokens, hasNativeSDK, testApiConnectivity, requestEmailVerification, verifyEmailCode, checkEmailVerificationStatus, disconnectPlatform, } from './services/platformAuthService';
|
|
15
17
|
export { onairosApi } from './api';
|
|
16
18
|
export { OAuthService } from './services/oauthService';
|
|
17
19
|
export * from './utils/secureStorage';
|
|
@@ -28,6 +30,7 @@ export { OnboardingHeader } from './components/onboarding/OnboardingHeader';
|
|
|
28
30
|
export { PlatformList } from './components/PlatformList';
|
|
29
31
|
export { PinInput } from './components/PinInput';
|
|
30
32
|
export { TrainingModal } from './components/TrainingModal';
|
|
33
|
+
export { EmailVerificationModal } from './components/EmailVerificationModal';
|
|
31
34
|
export { Overlay } from './components/Overlay';
|
|
32
35
|
export { UniversalOnboarding } from './components/UniversalOnboarding';
|
|
33
36
|
export { OnairosButton } from './components/OnairosButton';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,kBAAkB,EAClB,QAAQ,EACR,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjH,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,UAAU,EACV,MAAM,EACN,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ export declare const initiateOAuth: (platform: string, username: string, appName
|
|
|
23
23
|
* @param platform The platform to authenticate with
|
|
24
24
|
* @returns A Promise that resolves to the authentication result
|
|
25
25
|
*/
|
|
26
|
-
export declare const initiateNativeAuth: (platform: string) => Promise<boolean>;
|
|
26
|
+
export declare const initiateNativeAuth: (platform: string, username?: string) => Promise<boolean>;
|
|
27
27
|
/**
|
|
28
28
|
* Handles the OAuth callback
|
|
29
29
|
* @param url The callback URL
|
|
@@ -43,4 +43,60 @@ export declare const testApiConnectivity: () => Promise<{
|
|
|
43
43
|
success: boolean;
|
|
44
44
|
error?: string;
|
|
45
45
|
}>;
|
|
46
|
+
/**
|
|
47
|
+
* 🔄 REFRESH GOOGLE TOKENS
|
|
48
|
+
*/
|
|
49
|
+
export declare const refreshGoogleTokens: () => Promise<{
|
|
50
|
+
accessToken: string;
|
|
51
|
+
idToken?: string;
|
|
52
|
+
} | null>;
|
|
53
|
+
/**
|
|
54
|
+
* 🔄 REFRESH YOUTUBE TOKENS
|
|
55
|
+
*/
|
|
56
|
+
export declare const refreshYouTubeTokens: () => Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* 🎯 ENHANCED OAUTH CALLBACK HANDLER
|
|
59
|
+
*/
|
|
60
|
+
export declare const handleOAuthCallbackUrl: (url: string) => {
|
|
61
|
+
platform?: string;
|
|
62
|
+
code?: string;
|
|
63
|
+
success: boolean;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* 🔧 UPDATE GOOGLE CLIENT IDS
|
|
67
|
+
* Allows apps to configure their own Google client IDs
|
|
68
|
+
*/
|
|
69
|
+
export declare const updateGoogleClientIds: (config: {
|
|
70
|
+
webClientId?: string;
|
|
71
|
+
iosClientId?: string;
|
|
72
|
+
}) => void;
|
|
73
|
+
/**
|
|
74
|
+
* 📧 EMAIL VERIFICATION FUNCTIONS
|
|
75
|
+
* Using the correct Onairos email verification endpoints
|
|
76
|
+
*/
|
|
77
|
+
export declare const requestEmailVerification: (email: string) => Promise<{
|
|
78
|
+
success: boolean;
|
|
79
|
+
message?: string;
|
|
80
|
+
error?: string;
|
|
81
|
+
}>;
|
|
82
|
+
export declare const verifyEmailCode: (email: string, code: string) => Promise<{
|
|
83
|
+
success: boolean;
|
|
84
|
+
message?: string;
|
|
85
|
+
error?: string;
|
|
86
|
+
}>;
|
|
87
|
+
export declare const checkEmailVerificationStatus: (email: string) => Promise<{
|
|
88
|
+
success: boolean;
|
|
89
|
+
isPending?: boolean;
|
|
90
|
+
message?: string;
|
|
91
|
+
error?: string;
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* 🔌 UNIVERSAL PLATFORM DISCONNECTION
|
|
95
|
+
* Backend confirmed this endpoint is fully implemented
|
|
96
|
+
*/
|
|
97
|
+
export declare const disconnectPlatform: (platform: string, username: string) => Promise<{
|
|
98
|
+
success: boolean;
|
|
99
|
+
message?: string;
|
|
100
|
+
error?: string;
|
|
101
|
+
}>;
|
|
46
102
|
//# sourceMappingURL=platformAuthService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platformAuthService.d.ts","sourceRoot":"","sources":["../../../src/services/platformAuthService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"platformAuthService.d.ts","sourceRoot":"","sources":["../../../src/services/platformAuthService.ts"],"names":[],"mappings":"AAiDA;;GAEG;AACH,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,OAG/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,aAAc,MAAM,KAAG,MAGlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MAGnD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAAoB,MAAM,YAAY,MAAM,YAAY,MAAM,KAAG,QAAQ,MAAM,GAAG,IAAI,CAwH/G,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,aAAa,MAAM,KAAG,QAAQ,OAAO,CAwL7F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,KAAG,MAAM,GAAG,IAW1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,OAG7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBxF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuCpG,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAa,QAAQ,OAAO,CA2D5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAgCxG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,WAAY;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,SAYA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,UAAiB,MAAM,KAAG,QAAQ;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAmCA,CAAC;AAEF,eAAO,MAAM,eAAe,UAAiB,MAAM,QAAQ,MAAM,KAAG,QAAQ;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAmCA,CAAC;AAEF,eAAO,MAAM,4BAA4B,UAAiB,MAAM,KAAG,QAAQ;IACzE,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAkCA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,YAAY,MAAM,KAAG,QAAQ;IACpF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAuCA,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onairos/react-native",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.51",
|
|
4
4
|
"description": "Onairos React Native SDK for social media authentication and AI model training",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"registry": "https://registry.npmjs.org/"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
+
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
66
67
|
"@react-native-community/netinfo": "^9.0.0",
|
|
67
68
|
"@react-native-google-signin/google-signin": "^14.0.1",
|
|
68
69
|
"axios": "^1.6.2",
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import React, { useState, useCallback } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
ActivityIndicator,
|
|
8
|
+
Modal,
|
|
9
|
+
SafeAreaView,
|
|
10
|
+
TouchableWithoutFeedback,
|
|
11
|
+
TextInput,
|
|
12
|
+
Alert,
|
|
13
|
+
} from 'react-native';
|
|
14
|
+
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
15
|
+
import { requestEmailVerification, verifyEmailCode, checkEmailVerificationStatus } from '../services/platformAuthService';
|
|
16
|
+
|
|
17
|
+
export interface EmailVerificationModalProps {
|
|
18
|
+
visible: boolean;
|
|
19
|
+
email: string;
|
|
20
|
+
onClose: () => void;
|
|
21
|
+
onVerificationComplete: (email: string, isExistingUser: boolean) => void;
|
|
22
|
+
onVerificationFailed: (error: string) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
26
|
+
visible,
|
|
27
|
+
email,
|
|
28
|
+
onClose,
|
|
29
|
+
onVerificationComplete,
|
|
30
|
+
onVerificationFailed,
|
|
31
|
+
}) => {
|
|
32
|
+
const [step, setStep] = useState<'request' | 'verify'>('request');
|
|
33
|
+
const [verificationCode, setVerificationCode] = useState<string>('');
|
|
34
|
+
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
35
|
+
const [codeSent, setCodeSent] = useState<boolean>(false);
|
|
36
|
+
|
|
37
|
+
const handleRequestVerification = useCallback(async () => {
|
|
38
|
+
if (!email) {
|
|
39
|
+
Alert.alert('Error', 'Email address is required');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setIsLoading(true);
|
|
44
|
+
try {
|
|
45
|
+
console.log('📧 Requesting email verification for:', email);
|
|
46
|
+
|
|
47
|
+
// First check if there's already a pending verification
|
|
48
|
+
const statusCheck = await checkEmailVerificationStatus(email);
|
|
49
|
+
if (statusCheck.success && statusCheck.isPending) {
|
|
50
|
+
console.log('✅ Email verification already pending');
|
|
51
|
+
setCodeSent(true);
|
|
52
|
+
setStep('verify');
|
|
53
|
+
setIsLoading(false);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Request new verification code
|
|
58
|
+
const result = await requestEmailVerification(email);
|
|
59
|
+
|
|
60
|
+
if (result.success) {
|
|
61
|
+
console.log('✅ Email verification code requested successfully');
|
|
62
|
+
setCodeSent(true);
|
|
63
|
+
setStep('verify');
|
|
64
|
+
Alert.alert(
|
|
65
|
+
'Verification Code Sent',
|
|
66
|
+
result.message || 'Please check your email for the verification code.\n\nNote: In testing mode, any code will work.',
|
|
67
|
+
[{ text: 'OK', style: 'default' }]
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
console.error('❌ Failed to request verification code:', result.error);
|
|
71
|
+
Alert.alert('Error', result.error || 'Failed to send verification code');
|
|
72
|
+
onVerificationFailed(result.error || 'Failed to send verification code');
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('❌ Error requesting verification:', error);
|
|
76
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
77
|
+
Alert.alert('Error', errorMessage);
|
|
78
|
+
onVerificationFailed(errorMessage);
|
|
79
|
+
} finally {
|
|
80
|
+
setIsLoading(false);
|
|
81
|
+
}
|
|
82
|
+
}, [email, onVerificationFailed]);
|
|
83
|
+
|
|
84
|
+
const handleVerifyCode = useCallback(async () => {
|
|
85
|
+
if (!verificationCode.trim()) {
|
|
86
|
+
Alert.alert('Error', 'Please enter the verification code');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
setIsLoading(true);
|
|
91
|
+
try {
|
|
92
|
+
console.log('🔍 Verifying email code for:', email);
|
|
93
|
+
|
|
94
|
+
const result = await verifyEmailCode(email, verificationCode.trim());
|
|
95
|
+
|
|
96
|
+
if (result.success) {
|
|
97
|
+
console.log('✅ Email verification successful');
|
|
98
|
+
|
|
99
|
+
// In a real implementation, you would determine if this is an existing user
|
|
100
|
+
// based on the verification response or additional API calls
|
|
101
|
+
// For now, we'll assume new users need full onboarding
|
|
102
|
+
const isExistingUser = false; // This should be determined by your backend logic
|
|
103
|
+
|
|
104
|
+
Alert.alert(
|
|
105
|
+
'Email Verified',
|
|
106
|
+
result.message || 'Your email has been verified successfully!',
|
|
107
|
+
[{
|
|
108
|
+
text: 'Continue',
|
|
109
|
+
onPress: () => {
|
|
110
|
+
onVerificationComplete(email, isExistingUser);
|
|
111
|
+
}
|
|
112
|
+
}]
|
|
113
|
+
);
|
|
114
|
+
} else {
|
|
115
|
+
console.error('❌ Email verification failed:', result.error);
|
|
116
|
+
Alert.alert('Verification Failed', result.error || 'Invalid verification code. Please try again.');
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error('❌ Error verifying code:', error);
|
|
120
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
121
|
+
Alert.alert('Error', errorMessage);
|
|
122
|
+
} finally {
|
|
123
|
+
setIsLoading(false);
|
|
124
|
+
}
|
|
125
|
+
}, [email, verificationCode, onVerificationComplete]);
|
|
126
|
+
|
|
127
|
+
const handleResendCode = useCallback(async () => {
|
|
128
|
+
setVerificationCode('');
|
|
129
|
+
await handleRequestVerification();
|
|
130
|
+
}, [handleRequestVerification]);
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<Modal
|
|
134
|
+
visible={visible}
|
|
135
|
+
transparent
|
|
136
|
+
animationType="slide"
|
|
137
|
+
statusBarTranslucent
|
|
138
|
+
onRequestClose={onClose}
|
|
139
|
+
>
|
|
140
|
+
<TouchableWithoutFeedback onPress={onClose}>
|
|
141
|
+
<View style={styles.modalOverlay}>
|
|
142
|
+
<TouchableWithoutFeedback onPress={e => e.stopPropagation()}>
|
|
143
|
+
<View style={styles.modalContent}>
|
|
144
|
+
<SafeAreaView style={styles.container}>
|
|
145
|
+
<View style={styles.header}>
|
|
146
|
+
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
|
|
147
|
+
<Icon name="close" size={24} color="#666" />
|
|
148
|
+
</TouchableOpacity>
|
|
149
|
+
<Text style={styles.headerTitle}>Email Verification</Text>
|
|
150
|
+
<View style={styles.placeholder} />
|
|
151
|
+
</View>
|
|
152
|
+
|
|
153
|
+
<View style={styles.content}>
|
|
154
|
+
{step === 'request' ? (
|
|
155
|
+
<>
|
|
156
|
+
<View style={styles.iconContainer}>
|
|
157
|
+
<Icon name="email" size={48} color="#4CAF50" />
|
|
158
|
+
</View>
|
|
159
|
+
|
|
160
|
+
<Text style={styles.title}>Verify Your Email</Text>
|
|
161
|
+
<Text style={styles.subtitle}>
|
|
162
|
+
We need to verify your email address to continue
|
|
163
|
+
</Text>
|
|
164
|
+
|
|
165
|
+
<View style={styles.emailContainer}>
|
|
166
|
+
<Text style={styles.emailLabel}>Email Address:</Text>
|
|
167
|
+
<Text style={styles.emailText}>{email}</Text>
|
|
168
|
+
</View>
|
|
169
|
+
|
|
170
|
+
<TouchableOpacity
|
|
171
|
+
style={[styles.button, isLoading && styles.buttonDisabled]}
|
|
172
|
+
onPress={handleRequestVerification}
|
|
173
|
+
disabled={isLoading}
|
|
174
|
+
>
|
|
175
|
+
{isLoading ? (
|
|
176
|
+
<ActivityIndicator size="small" color="#fff" />
|
|
177
|
+
) : (
|
|
178
|
+
<Text style={styles.buttonText}>Send Verification Code</Text>
|
|
179
|
+
)}
|
|
180
|
+
</TouchableOpacity>
|
|
181
|
+
</>
|
|
182
|
+
) : (
|
|
183
|
+
<>
|
|
184
|
+
<View style={styles.iconContainer}>
|
|
185
|
+
<Icon name="verified" size={48} color="#4CAF50" />
|
|
186
|
+
</View>
|
|
187
|
+
|
|
188
|
+
<Text style={styles.title}>Enter Verification Code</Text>
|
|
189
|
+
<Text style={styles.subtitle}>
|
|
190
|
+
We've sent a 6-digit code to {email}
|
|
191
|
+
</Text>
|
|
192
|
+
|
|
193
|
+
<Text style={styles.testingNote}>
|
|
194
|
+
🔍 Testing Mode: Any code will work for verification
|
|
195
|
+
</Text>
|
|
196
|
+
|
|
197
|
+
<TextInput
|
|
198
|
+
style={styles.codeInput}
|
|
199
|
+
value={verificationCode}
|
|
200
|
+
onChangeText={setVerificationCode}
|
|
201
|
+
placeholder="Enter 6-digit code"
|
|
202
|
+
keyboardType="number-pad"
|
|
203
|
+
maxLength={6}
|
|
204
|
+
autoFocus
|
|
205
|
+
textAlign="center"
|
|
206
|
+
/>
|
|
207
|
+
|
|
208
|
+
<TouchableOpacity
|
|
209
|
+
style={[styles.button, isLoading && styles.buttonDisabled]}
|
|
210
|
+
onPress={handleVerifyCode}
|
|
211
|
+
disabled={isLoading || !verificationCode.trim()}
|
|
212
|
+
>
|
|
213
|
+
{isLoading ? (
|
|
214
|
+
<ActivityIndicator size="small" color="#fff" />
|
|
215
|
+
) : (
|
|
216
|
+
<Text style={styles.buttonText}>Verify Code</Text>
|
|
217
|
+
)}
|
|
218
|
+
</TouchableOpacity>
|
|
219
|
+
|
|
220
|
+
<TouchableOpacity
|
|
221
|
+
style={styles.resendButton}
|
|
222
|
+
onPress={handleResendCode}
|
|
223
|
+
disabled={isLoading}
|
|
224
|
+
>
|
|
225
|
+
<Text style={styles.resendButtonText}>
|
|
226
|
+
Didn't receive the code? Resend
|
|
227
|
+
</Text>
|
|
228
|
+
</TouchableOpacity>
|
|
229
|
+
</>
|
|
230
|
+
)}
|
|
231
|
+
</View>
|
|
232
|
+
</SafeAreaView>
|
|
233
|
+
</View>
|
|
234
|
+
</TouchableWithoutFeedback>
|
|
235
|
+
</View>
|
|
236
|
+
</TouchableWithoutFeedback>
|
|
237
|
+
</Modal>
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const styles = StyleSheet.create({
|
|
242
|
+
modalOverlay: {
|
|
243
|
+
flex: 1,
|
|
244
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
245
|
+
justifyContent: 'center',
|
|
246
|
+
alignItems: 'center',
|
|
247
|
+
},
|
|
248
|
+
modalContent: {
|
|
249
|
+
backgroundColor: '#fff',
|
|
250
|
+
borderRadius: 16,
|
|
251
|
+
width: '90%',
|
|
252
|
+
maxWidth: 400,
|
|
253
|
+
maxHeight: '80%',
|
|
254
|
+
},
|
|
255
|
+
container: {
|
|
256
|
+
padding: 24,
|
|
257
|
+
},
|
|
258
|
+
header: {
|
|
259
|
+
flexDirection: 'row',
|
|
260
|
+
alignItems: 'center',
|
|
261
|
+
justifyContent: 'space-between',
|
|
262
|
+
marginBottom: 24,
|
|
263
|
+
},
|
|
264
|
+
closeButton: {
|
|
265
|
+
padding: 8,
|
|
266
|
+
},
|
|
267
|
+
headerTitle: {
|
|
268
|
+
fontSize: 18,
|
|
269
|
+
fontWeight: '600',
|
|
270
|
+
color: '#000',
|
|
271
|
+
},
|
|
272
|
+
placeholder: {
|
|
273
|
+
width: 40,
|
|
274
|
+
},
|
|
275
|
+
content: {
|
|
276
|
+
alignItems: 'center',
|
|
277
|
+
},
|
|
278
|
+
iconContainer: {
|
|
279
|
+
marginBottom: 16,
|
|
280
|
+
},
|
|
281
|
+
title: {
|
|
282
|
+
fontSize: 24,
|
|
283
|
+
fontWeight: '600',
|
|
284
|
+
color: '#000',
|
|
285
|
+
textAlign: 'center',
|
|
286
|
+
marginBottom: 8,
|
|
287
|
+
},
|
|
288
|
+
subtitle: {
|
|
289
|
+
fontSize: 16,
|
|
290
|
+
color: '#666',
|
|
291
|
+
textAlign: 'center',
|
|
292
|
+
marginBottom: 24,
|
|
293
|
+
},
|
|
294
|
+
emailContainer: {
|
|
295
|
+
backgroundColor: '#f5f5f5',
|
|
296
|
+
padding: 16,
|
|
297
|
+
borderRadius: 8,
|
|
298
|
+
marginBottom: 24,
|
|
299
|
+
width: '100%',
|
|
300
|
+
},
|
|
301
|
+
emailLabel: {
|
|
302
|
+
fontSize: 14,
|
|
303
|
+
color: '#666',
|
|
304
|
+
marginBottom: 4,
|
|
305
|
+
},
|
|
306
|
+
emailText: {
|
|
307
|
+
fontSize: 16,
|
|
308
|
+
fontWeight: '500',
|
|
309
|
+
color: '#000',
|
|
310
|
+
},
|
|
311
|
+
testingNote: {
|
|
312
|
+
fontSize: 14,
|
|
313
|
+
color: '#FF9800',
|
|
314
|
+
textAlign: 'center',
|
|
315
|
+
marginBottom: 16,
|
|
316
|
+
backgroundColor: '#FFF3E0',
|
|
317
|
+
padding: 8,
|
|
318
|
+
borderRadius: 4,
|
|
319
|
+
},
|
|
320
|
+
codeInput: {
|
|
321
|
+
borderWidth: 1,
|
|
322
|
+
borderColor: '#ddd',
|
|
323
|
+
borderRadius: 8,
|
|
324
|
+
padding: 16,
|
|
325
|
+
fontSize: 18,
|
|
326
|
+
fontWeight: '600',
|
|
327
|
+
letterSpacing: 4,
|
|
328
|
+
marginBottom: 24,
|
|
329
|
+
width: '100%',
|
|
330
|
+
},
|
|
331
|
+
button: {
|
|
332
|
+
backgroundColor: '#4CAF50',
|
|
333
|
+
paddingVertical: 16,
|
|
334
|
+
paddingHorizontal: 32,
|
|
335
|
+
borderRadius: 8,
|
|
336
|
+
width: '100%',
|
|
337
|
+
alignItems: 'center',
|
|
338
|
+
marginBottom: 16,
|
|
339
|
+
},
|
|
340
|
+
buttonDisabled: {
|
|
341
|
+
opacity: 0.5,
|
|
342
|
+
},
|
|
343
|
+
buttonText: {
|
|
344
|
+
color: '#fff',
|
|
345
|
+
fontSize: 16,
|
|
346
|
+
fontWeight: '600',
|
|
347
|
+
},
|
|
348
|
+
resendButton: {
|
|
349
|
+
paddingVertical: 8,
|
|
350
|
+
},
|
|
351
|
+
resendButtonText: {
|
|
352
|
+
color: '#4CAF50',
|
|
353
|
+
fontSize: 14,
|
|
354
|
+
textDecorationLine: 'underline',
|
|
355
|
+
},
|
|
356
|
+
});
|
|
@@ -74,14 +74,12 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
74
74
|
|
|
75
75
|
console.log('📤 Sending training data:', trainingData);
|
|
76
76
|
|
|
77
|
-
//
|
|
78
|
-
// TODO: Uncomment when real authentication is available
|
|
79
|
-
/*
|
|
77
|
+
// Call the actual training API - backend confirmed this is working
|
|
80
78
|
const response = await fetch('https://api2.onairos.uk/enoch/trainModel/mobile', {
|
|
81
79
|
method: 'POST',
|
|
82
80
|
headers: {
|
|
83
81
|
'Content-Type': 'application/json',
|
|
84
|
-
'Authorization': `Bearer ${userToken}`
|
|
82
|
+
'Authorization': `Bearer ${userToken || 'temp-token'}` // Backend has JWT auth working
|
|
85
83
|
},
|
|
86
84
|
body: JSON.stringify(trainingData)
|
|
87
85
|
});
|
|
@@ -96,13 +94,11 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
96
94
|
console.error('Training start failed:', result.error);
|
|
97
95
|
setTrainingStatus(`Error: ${result.error}`);
|
|
98
96
|
setHasError(true);
|
|
97
|
+
// Fallback to simulation if API call fails
|
|
98
|
+
console.log('🚀 Falling back to simulated training');
|
|
99
|
+
setTrainingStatus('Training model...');
|
|
100
|
+
setInternalProgress(20);
|
|
99
101
|
}
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
// Simulate successful training start
|
|
103
|
-
console.log('🚀 Training Started (simulated)');
|
|
104
|
-
setTrainingStatus('Training model...');
|
|
105
|
-
setInternalProgress(20);
|
|
106
102
|
|
|
107
103
|
} catch (error) {
|
|
108
104
|
console.error('Training start error:', error);
|
|
@@ -118,70 +114,70 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
118
114
|
console.log('Setting up socket connection for training...');
|
|
119
115
|
console.log('🧑💻 User info available:', userInfo);
|
|
120
116
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
// Initialize real socket connection - backend confirmed this is working
|
|
118
|
+
try {
|
|
119
|
+
// Initialize socket connection
|
|
120
|
+
socketRef.current = io('https://api2.onairos.uk', {
|
|
121
|
+
transports: ['websocket'],
|
|
122
|
+
autoConnect: false
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Socket event listeners
|
|
126
|
+
socketRef.current.on('connect', () => {
|
|
127
|
+
console.log('✅ Socket connected for training');
|
|
128
|
+
setSocketConnected(true);
|
|
129
|
+
const socketId = socketRef.current?.id;
|
|
130
|
+
if (socketId) {
|
|
131
|
+
startEnochTraining(socketId);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
socketRef.current.on('disconnect', () => {
|
|
136
|
+
console.log('❌ Socket disconnected');
|
|
137
|
+
setSocketConnected(false);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
socketRef.current.on('trainingCompleted', (data) => {
|
|
141
|
+
console.log('✅ Training Complete:', data);
|
|
142
|
+
setTrainingStatus('Running test inference...');
|
|
143
|
+
setInternalProgress(60);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
socketRef.current.on('inferenceCompleted', (data) => {
|
|
147
|
+
console.log('🧠 Inference Complete:', data);
|
|
148
|
+
setTrainingStatus('Uploading to S3...');
|
|
149
|
+
setInternalProgress(80);
|
|
150
|
+
setUserTraits(data.traits);
|
|
151
|
+
setInferenceResults(data.inferenceResults);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
socketRef.current.on('modelStandby', (data) => {
|
|
155
|
+
console.log('🎉 All Complete:', data);
|
|
156
|
+
setIsTrainingComplete(true);
|
|
157
|
+
setTrainingStatus('Complete!');
|
|
158
|
+
setInternalProgress(100);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
socketRef.current.on('trainingUpdate', (data) => {
|
|
162
|
+
if (data.error) {
|
|
163
|
+
console.error('Training update error:', data.error);
|
|
164
|
+
setTrainingStatus(`Error: ${data.error}`);
|
|
165
|
+
setHasError(true);
|
|
166
|
+
} else if (data.progress) {
|
|
167
|
+
setInternalProgress(data.progress);
|
|
168
|
+
setTrainingStatus(data.status || 'Training in progress...');
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Connect to socket
|
|
173
|
+
socketRef.current.connect();
|
|
174
|
+
} catch (socketError) {
|
|
175
|
+
console.error('Socket connection failed, falling back to simulation:', socketError);
|
|
176
|
+
// Fallback to simulation if socket fails
|
|
177
|
+
console.log('🔌 Falling back to simulated socket connection...');
|
|
133
178
|
setSocketConnected(true);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
startEnochTraining(socketId);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
socketRef.current.on('disconnect', () => {
|
|
141
|
-
console.log('❌ Socket disconnected');
|
|
142
|
-
setSocketConnected(false);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
socketRef.current.on('trainingCompleted', (data) => {
|
|
146
|
-
console.log('✅ Training Complete:', data);
|
|
147
|
-
setTrainingStatus('Running test inference...');
|
|
148
|
-
setInternalProgress(60);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
socketRef.current.on('inferenceCompleted', (data) => {
|
|
152
|
-
console.log('🧠 Inference Complete:', data);
|
|
153
|
-
setTrainingStatus('Uploading to S3...');
|
|
154
|
-
setInternalProgress(80);
|
|
155
|
-
setUserTraits(data.traits);
|
|
156
|
-
setInferenceResults(data.inferenceResults);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
socketRef.current.on('modelStandby', (data) => {
|
|
160
|
-
console.log('🎉 All Complete:', data);
|
|
161
|
-
setIsTrainingComplete(true);
|
|
162
|
-
setTrainingStatus('Complete!');
|
|
163
|
-
setInternalProgress(100);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
socketRef.current.on('trainingUpdate', (data) => {
|
|
167
|
-
if (data.error) {
|
|
168
|
-
console.error('Training update error:', data.error);
|
|
169
|
-
setTrainingStatus(`Error: ${data.error}`);
|
|
170
|
-
setHasError(true);
|
|
171
|
-
} else if (data.progress) {
|
|
172
|
-
setInternalProgress(data.progress);
|
|
173
|
-
setTrainingStatus(data.status || 'Training in progress...');
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// Connect to socket
|
|
178
|
-
socketRef.current.connect();
|
|
179
|
-
*/
|
|
180
|
-
|
|
181
|
-
// Simulate socket connection and training for now
|
|
182
|
-
console.log('🔌 Simulating socket connection...');
|
|
183
|
-
setSocketConnected(true);
|
|
184
|
-
startEnochTraining('simulated-socket-id');
|
|
179
|
+
startEnochTraining('simulated-socket-id');
|
|
180
|
+
}
|
|
185
181
|
|
|
186
182
|
// Cleanup function
|
|
187
183
|
return () => {
|