@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.
Files changed (22) hide show
  1. package/build/src/contexts/AuthContext.js +2 -0
  2. package/build/src/screens/CreatePassword/index.js +4 -1
  3. package/build/src/screens/EnterMobile/hooks/internal/useEnterMobile.js +4 -1
  4. package/build/src/screens/EnterMobile/index.js +7 -6
  5. package/build/src/screens/EnterMobile/index.native.js +3 -3
  6. package/build/src/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.js +5 -5
  7. package/build/src/screens/LoginWithMobileOTP/index.js +2 -2
  8. package/build/src/screens/LoginWithMobileOTP/index.native.js +2 -2
  9. package/build/src/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.js +10 -7
  10. package/build/src/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.native.js +6 -0
  11. package/build/src/screens/PartnerSSO/PartnerLogin/hooks/internal/usePartnerLogin.js +2 -0
  12. package/build/src/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.js +14 -10
  13. package/build/src/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.native.js +6 -0
  14. package/build/types/contexts/AuthContext.d.ts +2 -0
  15. package/build/types/contexts/type.d.ts +4 -4
  16. package/build/types/navigator/index.native.d.ts +1 -1
  17. package/build/types/screens/EnterMobile/types.d.ts +2 -2
  18. package/build/types/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.d.ts +2 -2
  19. package/build/types/screens/LoginWithMobileOTP/index.d.ts +2 -2
  20. package/build/types/screens/PartnerSSO/PartnerLogin/components/PartnerLoginWebComponent/index.native.d.ts +2 -0
  21. package/build/types/screens/PartnerSSO/PartnerRegistration/components/PartnerRegistrationWebComponent/index.native.d.ts +2 -0
  22. 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({ mobileExist, email: linkedAccounts?.[0]?.email ?? '' });
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, email }) => {
30
- if (mobileExist && email) {
31
- setEmail(email);
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, { email: email, phone: phone, show: showLoginWithMobileOTPModal, hide: () => setShowLoginWithMobileOTPModal(false) }), showExistingAccountsSheet &&
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, email, phone }) => {
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, email: email }) }));
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, email }) => {
27
- if (mobileExist && email) {
26
+ onValidate: ({ mobileExist, memberId }) => {
27
+ if (mobileExist && memberId) {
28
28
  navigation.navigate('LoginWithMobileOTP', {
29
29
  phone,
30
- email
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, email, source }) => {
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, email, source },
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, email, source]);
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 (email && source) {
61
+ if (memberId && phone && source) {
62
62
  sendOtp();
63
63
  }
64
- }, [email, source, sendOtp]);
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, email }) => {
5
- const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone, email, source: 'web' });
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, email } = route.params;
7
- const { timer, status, verifyOtp, sendOtp, } = useLoginWithMobileOTP({ phone, email, source: Platform.OS });
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;
@@ -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 only ONCE on initial mount
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.clear();
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
- setTimeout(() => {
62
- navigator.back();
63
- }, 2000);
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
  };
@@ -0,0 +1,6 @@
1
+ const PartnerLoginWebComponent = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] PartnerLoginWebComponent is web-only");
4
+ return null;
5
+ };
6
+ export { PartnerLoginWebComponent };
@@ -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
- // Extract query params on mount
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(() => {
@@ -0,0 +1,6 @@
1
+ const PartnerRegistrationWebComponent = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] PartnerRegistrationWebComponent is web-only");
4
+ return null;
5
+ };
6
+ export { PartnerRegistrationWebComponent };
@@ -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: RouterAdapter;
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: RouterAdapter;
68
+ router?: RouterAdapter;
69
69
  /** Base path where the auth module is mounted */
70
- basePath: string;
70
+ basePath?: string;
71
71
  LogoComponent?: React.ComponentType | React.ReactElement;
72
72
  appConfig: AppConfig;
73
73
  socialLoginConfig?: Partial<Record<SocialLoginsEnum, {
@@ -67,7 +67,7 @@ export type AuthStackParamList = {
67
67
  EnterMobile: undefined;
68
68
  LoginWithMobileOTP: {
69
69
  phone: string;
70
- email: string;
70
+ memberId: string;
71
71
  };
72
72
  VerifyLinkPrimaryAccountEmailOTP: {
73
73
  email: string;
@@ -32,13 +32,13 @@ interface VerifyLinkedMobileModalProps {
32
32
  interface LoginWithMobileOTPModalProps {
33
33
  show: boolean;
34
34
  hide: () => void;
35
- email: string;
35
+ memberId: string;
36
36
  phone: string;
37
37
  }
38
38
  type ValidatePhoneParams = {
39
39
  onValidate: (args: {
40
40
  mobileExist: boolean;
41
- email?: string;
41
+ memberId: string;
42
42
  }) => void;
43
43
  };
44
44
  export type { Members, ValidatePhoneParams, MultipleAccount, VerifyLinkedEmailModalProps, VerifyLinkedMobileModalProps, LoginWithMobileOTPModalProps };
@@ -1,7 +1,7 @@
1
- declare const useLoginWithMobileOTP: ({ phone, email, source }: {
1
+ declare const useLoginWithMobileOTP: ({ phone, source, memberId }: {
2
2
  phone: string;
3
- email: string;
4
3
  source: string;
4
+ memberId: string;
5
5
  }) => {
6
6
  timer: number;
7
7
  status: string;
@@ -1,5 +1,5 @@
1
- declare const LoginWithMobileOTP: ({ phone, email }: {
1
+ declare const LoginWithMobileOTP: ({ phone, memberId }: {
2
2
  phone: string;
3
- email: string;
3
+ memberId: string;
4
4
  }) => import("react/jsx-runtime").JSX.Element;
5
5
  export default LoginWithMobileOTP;
@@ -0,0 +1,2 @@
1
+ declare const PartnerLoginWebComponent: () => null;
2
+ export { PartnerLoginWebComponent };
@@ -0,0 +1,2 @@
1
+ declare const PartnerRegistrationWebComponent: () => null;
2
+ export { PartnerRegistrationWebComponent };
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.6",
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",