@truworth/twc-auth 3.0.6 → 3.0.8
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/build/src/contexts/AuthContext.js +2 -0
- package/build/src/screens/CreatePassword/index.js +4 -1
- package/build/src/screens/EnterMobile/hooks/internal/useEnterMobile.js +4 -1
- package/build/src/screens/EnterMobile/index.js +7 -6
- package/build/src/screens/EnterMobile/index.native.js +3 -3
- package/build/src/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.js +5 -5
- package/build/src/screens/LoginWithMobileOTP/index.js +2 -2
- package/build/src/screens/LoginWithMobileOTP/index.native.js +2 -2
- package/build/src/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.js +10 -7
- package/build/src/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.native.js +6 -0
- package/build/src/screens/PartnerSSO/PartnerLogin/hooks/internal/usePartnerLogin.js +2 -0
- package/build/src/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.js +14 -10
- package/build/src/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.native.js +6 -0
- package/build/types/contexts/AuthContext.d.ts +2 -0
- package/build/types/contexts/type.d.ts +4 -4
- package/build/types/navigator/index.native.d.ts +1 -1
- package/build/types/screens/EnterMobile/types.d.ts +2 -2
- package/build/types/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.d.ts +2 -2
- package/build/types/screens/LoginWithMobileOTP/index.d.ts +2 -2
- package/build/types/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.native.d.ts +2 -0
- package/build/types/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.native.d.ts +2 -0
- package/package.json +1 -2
|
@@ -23,6 +23,8 @@ const AuthPackageContext = React.createContext(null);
|
|
|
23
23
|
* Wraps both AuthContext (public) and AuthPackageContext (internal).
|
|
24
24
|
*
|
|
25
25
|
* @param children - React children to be rendered inside the provider
|
|
26
|
+
* @param router - Router adapter for navigation in web apps only
|
|
27
|
+
* @param basePath - Base path for web routes where the auth module is mounted (default: '')
|
|
26
28
|
* @param LogoComponent - Optional component for branding/logo in auth flows
|
|
27
29
|
* @param session - Initial session containing token & sessionTimeout (if available)
|
|
28
30
|
* @param supportEmail - Optional support email for auth flows
|
|
@@ -5,7 +5,10 @@ import { ScreenLayout } from "../../components/ScreenLayout";
|
|
|
5
5
|
import { PasswordCriteria } from "../../components/PasswordCriteria";
|
|
6
6
|
const CreatePassword = ({ userDetails, handleBack, onContinue }) => {
|
|
7
7
|
const { countryCode, email } = userDetails;
|
|
8
|
-
const { password, confirmPassword, handlePassword, handleConfirmPassword, passwordVisible, setPasswordVisible, confirmPasswordVisible, setConfirmPasswordVisible, criteria, setCriteria, maxLength, setMaxLength, handleSkip, isContinueDisabled } = useCreatePassword(
|
|
8
|
+
const { password, confirmPassword, handlePassword, handleConfirmPassword, passwordVisible, setPasswordVisible, confirmPasswordVisible, setConfirmPasswordVisible, criteria, setCriteria, maxLength, setMaxLength, handleSkip, isContinueDisabled } = useCreatePassword({
|
|
9
|
+
initialPassword: userDetails.password,
|
|
10
|
+
initialConfirmPassword: userDetails.confirmPassword,
|
|
11
|
+
});
|
|
9
12
|
return (_jsx(ScreenLayout, { title: _jsxs(Flex, { justify: "between", align: "center", children: [_jsx(Typography, { type: "heading", size: "h5", children: "Create your Password" }), countryCode == '91' &&
|
|
10
13
|
_jsx(Button, { label: "Skip Now", variant: "link", onClick: () => handleSkip({ onResult: () => onContinue('', '') }) })] }), subTitle: "Use a password that's easy to remember and fulfills all the requirements listed below.", buttonProps: {
|
|
11
14
|
label: 'Continue',
|
|
@@ -37,7 +37,10 @@ const useEnterMobile = () => {
|
|
|
37
37
|
if (!mobileExist) {
|
|
38
38
|
onRegistrationMethodChange(RegistrationMethod.MOBILE);
|
|
39
39
|
}
|
|
40
|
-
onValidate({
|
|
40
|
+
onValidate({
|
|
41
|
+
mobileExist,
|
|
42
|
+
memberId: linkedAccounts?.[0]?.memberId ?? ''
|
|
43
|
+
});
|
|
41
44
|
}
|
|
42
45
|
catch (err) {
|
|
43
46
|
const errorMessage = err?.response?.data?.errors?.[0]?.message ?? 'Something went wrong';
|
|
@@ -15,6 +15,7 @@ const EnterMobile = ({ onPressBack }) => {
|
|
|
15
15
|
const [showVerifyLinkPrimaryEmailModal, setShowVerifyLinkPrimaryEmailModal] = useState(false);
|
|
16
16
|
const [showVerifyLinkPrimaryMobileModal, setShowVerifyLinkPrimaryMobileModal] = useState(false);
|
|
17
17
|
const [email, setEmail] = useState('');
|
|
18
|
+
const [memberId, setMemberId] = useState('');
|
|
18
19
|
const [sessionToken, setSessionToken] = useState('');
|
|
19
20
|
const [selectedCountry, setSelectedCountry] = useState({
|
|
20
21
|
countryCode: "in",
|
|
@@ -26,9 +27,9 @@ const EnterMobile = ({ onPressBack }) => {
|
|
|
26
27
|
const { loading, phone, isValidPhone, countryCode, setCountryCode, existingAccounts, showExistingAccountsSheet, setShowExistingAccountsSheet, handleValidatePhone, handleEnterMobile, } = useEnterMobile();
|
|
27
28
|
const handleSubmit = () => {
|
|
28
29
|
handleValidatePhone({
|
|
29
|
-
onValidate: ({ mobileExist,
|
|
30
|
-
if (mobileExist &&
|
|
31
|
-
|
|
30
|
+
onValidate: ({ mobileExist, memberId }) => {
|
|
31
|
+
if (mobileExist && memberId) {
|
|
32
|
+
setMemberId(memberId);
|
|
32
33
|
setShowLoginWithMobileOTPModal(true);
|
|
33
34
|
}
|
|
34
35
|
else {
|
|
@@ -55,7 +56,7 @@ const EnterMobile = ({ onPressBack }) => {
|
|
|
55
56
|
setCountryCode(country.phoneCode);
|
|
56
57
|
setSelectedCountry(country);
|
|
57
58
|
} }) }) }) }) }), showLoginWithMobileOTPModal &&
|
|
58
|
-
_jsx(LoginWithMobileOTPModal, {
|
|
59
|
+
_jsx(LoginWithMobileOTPModal, { memberId: memberId, phone: phone, show: showLoginWithMobileOTPModal, hide: () => setShowLoginWithMobileOTPModal(false) }), showExistingAccountsSheet &&
|
|
59
60
|
_jsx(ExistingAccountsSheet, { phone: phone, visible: showExistingAccountsSheet, existingAccounts: existingAccounts, onInitiateAccountLinking: ({ sessionToken, email }) => {
|
|
60
61
|
setSessionToken(sessionToken);
|
|
61
62
|
setEmail(email);
|
|
@@ -75,7 +76,7 @@ const VerifyLinkPrimaryAccountEmailOTPModal = ({ show, hide, email, sessionToken
|
|
|
75
76
|
const VerifyLinkPrimaryAccountMobileOTPModal = ({ show, hide, phone, sessionToken }) => {
|
|
76
77
|
return (_jsx(ResponsiveModal, { title: "Verify Mobile Number", open: show, onClose: hide, maskClosable: false, showCloseButton: false, size: 'sm', children: _jsx(VerifyLinkPrimaryAccountMobileOTP, { phone: phone, sessionToken: sessionToken }) }));
|
|
77
78
|
};
|
|
78
|
-
const LoginWithMobileOTPModal = ({ show, hide,
|
|
79
|
-
return (_jsx(ResponsiveModal, { open: show, onClose: hide, title: _jsx(Typography, { type: "heading", size: "h6", className: "text-center mb-0", children: "Verify Mobile Number" }), showCloseButton: false, maskClosable: false, size: 'sm', children: _jsx(LoginWithMobileOTP, { phone: phone,
|
|
79
|
+
const LoginWithMobileOTPModal = ({ show, hide, memberId, phone }) => {
|
|
80
|
+
return (_jsx(ResponsiveModal, { open: show, onClose: hide, title: _jsx(Typography, { type: "heading", size: "h6", className: "text-center mb-0", children: "Verify Mobile Number" }), showCloseButton: false, maskClosable: false, size: 'sm', children: _jsx(LoginWithMobileOTP, { phone: phone, memberId: memberId }) }));
|
|
80
81
|
};
|
|
81
82
|
export default EnterMobile;
|
|
@@ -23,11 +23,11 @@ const EnterMobile = ({ navigation }) => {
|
|
|
23
23
|
const handleSubmit = () => {
|
|
24
24
|
Keyboard.dismiss();
|
|
25
25
|
handleValidatePhone({
|
|
26
|
-
onValidate: ({ mobileExist,
|
|
27
|
-
if (mobileExist &&
|
|
26
|
+
onValidate: ({ mobileExist, memberId }) => {
|
|
27
|
+
if (mobileExist && memberId) {
|
|
28
28
|
navigation.navigate('LoginWithMobileOTP', {
|
|
29
29
|
phone,
|
|
30
|
-
|
|
30
|
+
memberId
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
@@ -3,7 +3,7 @@ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackage
|
|
|
3
3
|
import { axiosClient } from "../../../../api/axiosClient";
|
|
4
4
|
import { useInterval } from "../../../../hooks/internal/useTimer";
|
|
5
5
|
import { showMessage } from "../../../../helpers/show-message";
|
|
6
|
-
const useLoginWithMobileOTP = ({ phone,
|
|
6
|
+
const useLoginWithMobileOTP = ({ phone, source, memberId }) => {
|
|
7
7
|
const [timer, setTimer] = useState(180);
|
|
8
8
|
const [status, setStatus] = useState('timer');
|
|
9
9
|
const [sessionToken, setSessionToken] = useState('');
|
|
@@ -19,7 +19,7 @@ const useLoginWithMobileOTP = ({ phone, email, source }) => {
|
|
|
19
19
|
axiosClient({
|
|
20
20
|
url: '/auth/login/mobile/v2',
|
|
21
21
|
method: 'POST',
|
|
22
|
-
data: { phone,
|
|
22
|
+
data: { phone, source, memberId },
|
|
23
23
|
}).then((res) => {
|
|
24
24
|
setSessionToken(res.data.sessionToken);
|
|
25
25
|
setStatus('timer');
|
|
@@ -28,7 +28,7 @@ const useLoginWithMobileOTP = ({ phone, email, source }) => {
|
|
|
28
28
|
console.log(err);
|
|
29
29
|
showMessage({ message: err.response.data.errors[0].message || "Verification failed" });
|
|
30
30
|
});
|
|
31
|
-
}, [phone,
|
|
31
|
+
}, [phone, source, memberId]);
|
|
32
32
|
const verifyOtp = useCallback((otp) => {
|
|
33
33
|
if (!sessionToken) {
|
|
34
34
|
showMessage({ message: "Session expired. Please resend OTP." });
|
|
@@ -58,10 +58,10 @@ const useLoginWithMobileOTP = ({ phone, email, source }) => {
|
|
|
58
58
|
});
|
|
59
59
|
}, [sessionToken]);
|
|
60
60
|
useEffect(() => {
|
|
61
|
-
if (
|
|
61
|
+
if (memberId && phone && source) {
|
|
62
62
|
sendOtp();
|
|
63
63
|
}
|
|
64
|
-
}, [
|
|
64
|
+
}, [memberId, phone, source, sendOtp]);
|
|
65
65
|
return {
|
|
66
66
|
timer,
|
|
67
67
|
status,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { VerifyMobileOTP } from '../../components/VerifyMobileOTP';
|
|
3
3
|
import { useLoginWithMobileOTP } from './hooks/internal/useLoginWithMobileOTP';
|
|
4
|
-
const LoginWithMobileOTP = ({ phone,
|
|
5
|
-
const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone,
|
|
4
|
+
const LoginWithMobileOTP = ({ phone, memberId }) => {
|
|
5
|
+
const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone, memberId, source: 'web' });
|
|
6
6
|
return (_jsx(VerifyMobileOTP, { timer: timer, phone: phone, status: status, validateOTP: verifyOtp, resendOTP: sendOtp }));
|
|
7
7
|
};
|
|
8
8
|
export default LoginWithMobileOTP;
|
|
@@ -3,8 +3,8 @@ import { VerifyMobileOTP } from '../../components/VerifyMobileOTP';
|
|
|
3
3
|
import { useLoginWithMobileOTP } from './hooks/internal/useLoginWithMobileOTP';
|
|
4
4
|
import { Platform } from 'react-native';
|
|
5
5
|
const LoginWithMobileOTP = ({ route }) => {
|
|
6
|
-
const { phone,
|
|
7
|
-
const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone,
|
|
6
|
+
const { phone, memberId } = route.params;
|
|
7
|
+
const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone, memberId, source: Platform.OS });
|
|
8
8
|
return (_jsx(VerifyMobileOTP, { timer: timer, phone: phone, status: status, validateOTP: verifyOtp, resendOTP: sendOtp }));
|
|
9
9
|
};
|
|
10
10
|
export default LoginWithMobileOTP;
|
package/build/src/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.js
CHANGED
|
@@ -27,11 +27,13 @@ const PartnerLoginWebComponent = ({ partner: partnerProp }) => {
|
|
|
27
27
|
const [token, setToken] = useState('');
|
|
28
28
|
const [path, setPath] = useState(undefined);
|
|
29
29
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
30
|
-
// Clear localStorage
|
|
30
|
+
// Clear only auth-related localStorage keys on mount to avoid wiping host app state
|
|
31
31
|
useEffect(() => {
|
|
32
32
|
if (typeof window !== 'undefined') {
|
|
33
33
|
try {
|
|
34
|
-
localStorage.
|
|
34
|
+
localStorage.removeItem('clientId');
|
|
35
|
+
localStorage.removeItem('authMethod');
|
|
36
|
+
localStorage.removeItem('profileData');
|
|
35
37
|
}
|
|
36
38
|
catch (e) {
|
|
37
39
|
// Ignore localStorage errors
|
|
@@ -57,11 +59,12 @@ const PartnerLoginWebComponent = ({ partner: partnerProp }) => {
|
|
|
57
59
|
const { isLoading, error } = usePartnerLogin({ partner, token, path });
|
|
58
60
|
// If there's an error, redirect back after a delay
|
|
59
61
|
useEffect(() => {
|
|
60
|
-
if (error)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
62
|
+
if (!error)
|
|
63
|
+
return;
|
|
64
|
+
const timeoutId = setTimeout(() => {
|
|
65
|
+
navigator.back();
|
|
66
|
+
}, 2000);
|
|
67
|
+
return () => clearTimeout(timeoutId);
|
|
65
68
|
}, [error, navigator]);
|
|
66
69
|
return (_jsx(Flex, { justify: 'center', align: 'center', className: 'h-[100vh]', children: _jsxs("div", { className: 'text-center', children: [_jsx(LoadingAnimation, { height: 230, width: 250 }), error ? (_jsxs(_Fragment, { children: [_jsx(Typography, { size: 'h6', type: 'heading', color: 'error', children: error }), _jsx(Typography, { size: 'small', type: 'body', color: 'gray-400', className: 'mt-2', children: "Redirecting back..." })] })) : (_jsx(_Fragment, { children: _jsx(Typography, { size: 'h6', type: 'heading', color: 'gray-400', children: "Authenticating and Redirecting ..." }) }))] }) }));
|
|
67
70
|
};
|
|
@@ -40,6 +40,8 @@ const usePartnerLogin = ({ partner, token, path }) => {
|
|
|
40
40
|
const errorMessage = err?.response?.data?.errors?.[0]?.message || 'Authentication failed';
|
|
41
41
|
setError(errorMessage);
|
|
42
42
|
showMessage({ message: errorMessage });
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
43
45
|
setIsLoading(false);
|
|
44
46
|
}
|
|
45
47
|
};
|
|
@@ -46,7 +46,20 @@ const PartnerRegistrationWebComponent = ({ partner: partnerProp }) => {
|
|
|
46
46
|
const [isHuman, setIsHuman] = useState(!isProduction);
|
|
47
47
|
const [termsAndConditions, setTermsAndConditions] = useState(false);
|
|
48
48
|
const [emailExists, setEmailExists] = useState(false);
|
|
49
|
-
//
|
|
49
|
+
// Clear only auth-related localStorage keys on mount to avoid wiping host app state
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (typeof window !== 'undefined') {
|
|
52
|
+
try {
|
|
53
|
+
localStorage.removeItem('clientId');
|
|
54
|
+
localStorage.removeItem('authMethod');
|
|
55
|
+
localStorage.removeItem('profileData');
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
console.warn('Failed to clear auth localStorage keys:', e);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
// Extract query params on mount and when they change
|
|
50
63
|
useEffect(() => {
|
|
51
64
|
const query = navigator.query;
|
|
52
65
|
// Use prop if provided, otherwise try query params
|
|
@@ -59,15 +72,6 @@ const PartnerRegistrationWebComponent = ({ partner: partnerProp }) => {
|
|
|
59
72
|
if (typeof query.path === 'string') {
|
|
60
73
|
setPath(query.path);
|
|
61
74
|
}
|
|
62
|
-
// Clear localStorage on partner registration (clean slate)
|
|
63
|
-
if (typeof window !== 'undefined') {
|
|
64
|
-
try {
|
|
65
|
-
localStorage.clear();
|
|
66
|
-
}
|
|
67
|
-
catch (e) {
|
|
68
|
-
console.warn('Failed to clear localStorage:', e);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
75
|
}, [navigator.query, partnerProp]);
|
|
72
76
|
// Update partner if prop changes
|
|
73
77
|
useEffect(() => {
|
|
@@ -21,6 +21,8 @@ declare const AuthPackageContext: React.Context<AuthPackageContextValue | null>;
|
|
|
21
21
|
* Wraps both AuthContext (public) and AuthPackageContext (internal).
|
|
22
22
|
*
|
|
23
23
|
* @param children - React children to be rendered inside the provider
|
|
24
|
+
* @param router - Router adapter for navigation in web apps only
|
|
25
|
+
* @param basePath - Base path for web routes where the auth module is mounted (default: '')
|
|
24
26
|
* @param LogoComponent - Optional component for branding/logo in auth flows
|
|
25
27
|
* @param session - Initial session containing token & sessionTimeout (if available)
|
|
26
28
|
* @param supportEmail - Optional support email for auth flows
|
|
@@ -32,8 +32,8 @@ interface AppConfig {
|
|
|
32
32
|
}
|
|
33
33
|
interface AuthContextProps {
|
|
34
34
|
children: React.ReactNode;
|
|
35
|
-
/** Router adapter for navigation - must be provided by host app */
|
|
36
|
-
router
|
|
35
|
+
/** Router adapter for navigation - must be provided by web host app */
|
|
36
|
+
router?: RouterAdapter;
|
|
37
37
|
/** Base path where the auth module is mounted (e.g., '' for root or '/auth') */
|
|
38
38
|
basePath?: string;
|
|
39
39
|
LogoComponent?: React.ComponentType | React.ReactElement;
|
|
@@ -65,9 +65,9 @@ interface AuthContextValue {
|
|
|
65
65
|
interface AuthPackageContextValue {
|
|
66
66
|
token: string;
|
|
67
67
|
/** Router adapter for navigation */
|
|
68
|
-
router
|
|
68
|
+
router?: RouterAdapter;
|
|
69
69
|
/** Base path where the auth module is mounted */
|
|
70
|
-
basePath
|
|
70
|
+
basePath?: string;
|
|
71
71
|
LogoComponent?: React.ComponentType | React.ReactElement;
|
|
72
72
|
appConfig: AppConfig;
|
|
73
73
|
socialLoginConfig?: Partial<Record<SocialLoginsEnum, {
|
|
@@ -32,13 +32,13 @@ interface VerifyLinkedMobileModalProps {
|
|
|
32
32
|
interface LoginWithMobileOTPModalProps {
|
|
33
33
|
show: boolean;
|
|
34
34
|
hide: () => void;
|
|
35
|
-
|
|
35
|
+
memberId: string;
|
|
36
36
|
phone: string;
|
|
37
37
|
}
|
|
38
38
|
type ValidatePhoneParams = {
|
|
39
39
|
onValidate: (args: {
|
|
40
40
|
mobileExist: boolean;
|
|
41
|
-
|
|
41
|
+
memberId: string;
|
|
42
42
|
}) => void;
|
|
43
43
|
};
|
|
44
44
|
export type { Members, ValidatePhoneParams, MultipleAccount, VerifyLinkedEmailModalProps, VerifyLinkedMobileModalProps, LoginWithMobileOTPModalProps };
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"description": "Truworth Auth Package for React Native and Web",
|
|
7
|
-
"version": "3.0.
|
|
7
|
+
"version": "3.0.8",
|
|
8
8
|
"main": "build/src/index.js",
|
|
9
9
|
"types": "build/types/index.d.ts",
|
|
10
10
|
"files": [
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
"lottie-react": "^2.4.1",
|
|
50
50
|
"lottie-react-native": "6.7.2",
|
|
51
51
|
"moment": "^2.30.1",
|
|
52
|
-
"next": "15.5.9",
|
|
53
52
|
"react": "18.3.1",
|
|
54
53
|
"react-dom": "^18.2.0",
|
|
55
54
|
"react-google-login": "^5.2.2",
|