@truworth/twc-auth 1.1.0 → 1.2.1

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 (202) hide show
  1. package/README.md +239 -306
  2. package/build/assets/animation/redirect-home.json +1101 -0
  3. package/build/assets/cross_icon copy.svg +5 -0
  4. package/build/assets/cross_icon.svg +5 -0
  5. package/build/assets/gender-diversity.svg +22 -0
  6. package/build/assets/logo.svg +55 -0
  7. package/build/assets/okay_icon copy.svg +3 -0
  8. package/build/assets/okay_icon.svg +3 -0
  9. package/build/src/api/axiosClient/index.js +5 -0
  10. package/build/src/api/axiosClient/index.native.js +5 -0
  11. package/build/src/components/AdvancedTransitionWrapper/index.js +380 -0
  12. package/build/src/components/AdvancedTransitionWrapper/index.native.js +10 -0
  13. package/build/src/components/AdvancedTransitionWrapper/types.js +1 -0
  14. package/build/src/components/ConfirmationModal/index.js +11 -0
  15. package/build/src/components/ConfirmationModal/index.native.js +15 -0
  16. package/build/src/components/ConfirmationModal/types.js +1 -0
  17. package/build/src/components/EmailOTPVerify/index.js +20 -0
  18. package/build/src/components/EmailOTPVerify/index.native.js +26 -0
  19. package/build/src/components/EmailOTPVerify/type.js +1 -0
  20. package/build/src/components/IonIcon/index.js +11 -0
  21. package/build/src/components/IonIcon/index.native.js +9 -0
  22. package/build/src/components/IonIcon/types.js +1 -0
  23. package/build/src/components/OTPStatusLabel/index.js +10 -0
  24. package/build/src/components/OTPStatusLabel/index.native.js +21 -0
  25. package/build/src/components/OTPStatusLabel/types.js +1 -0
  26. package/build/src/components/PasswordCriteria/hooks/usePasswordCriteria.js +78 -0
  27. package/build/src/components/PasswordCriteria/index.js +47 -0
  28. package/build/src/components/PasswordCriteria/index.native.js +19 -0
  29. package/build/src/components/PasswordCriteria/types.js +1 -0
  30. package/build/src/components/ScreenLayout/index.js +12 -0
  31. package/build/src/components/ScreenLayout/index.native.js +18 -0
  32. package/build/src/components/ScreenLayout/types.js +1 -0
  33. package/build/src/components/SupportDetails/index.js +9 -0
  34. package/build/src/components/SupportDetails/index.native.js +6 -0
  35. package/build/src/components/VerifyOTP/index.js +23 -0
  36. package/build/src/components/VerifyOTP/index.native.js +38 -0
  37. package/build/src/components/VerifyOTP/types.js +1 -0
  38. package/build/src/constants/cdn-url/index.js +1 -0
  39. package/build/src/constants/cdn-url/index.native.js +5 -0
  40. package/build/src/contexts/AuthContext.js +184 -0
  41. package/build/src/contexts/type.js +1 -0
  42. package/build/src/helpers/Network.js +93 -0
  43. package/build/src/helpers/Validation.js +12 -0
  44. package/build/src/helpers/show-message/index.js +19 -0
  45. package/build/src/helpers/show-message/index.native.js +14 -0
  46. package/build/src/helpers/show-message/types.js +1 -0
  47. package/build/src/helpers/types.js +1 -0
  48. package/build/src/hooks/internal/useAuthPackageContext.js +9 -0
  49. package/build/src/hooks/internal/useTimer.js +40 -0
  50. package/build/src/hooks/useAuthContext.js +10 -0
  51. package/build/src/hooks/useRequest.js +38 -0
  52. package/build/src/index.js +12 -0
  53. package/build/src/navigator/index.js +10 -0
  54. package/build/src/navigator/index.native.js +16 -0
  55. package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.js +38 -0
  56. package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.native.js +6 -0
  57. package/build/src/screens/CountryCode/components/CountryCodeDropdown/types.js +1 -0
  58. package/build/src/screens/CountryCode/hooks/internal/useCountryCode.js +38 -0
  59. package/build/src/screens/CountryCode/index.js +10 -0
  60. package/build/src/screens/CountryCode/index.native.js +37 -0
  61. package/build/src/screens/CountryCode/type.js +1 -0
  62. package/build/src/screens/CreatePassword/hooks/internal/useCreatePassword.js +52 -0
  63. package/build/src/screens/CreatePassword/index.js +43 -0
  64. package/build/src/screens/CreatePassword/index.native.js +32 -0
  65. package/build/src/screens/CreatePassword/type.js +1 -0
  66. package/build/src/screens/EnterEmail/hooks/internal/useEnterEmail.js +86 -0
  67. package/build/src/screens/EnterEmail/index.js +30 -0
  68. package/build/src/screens/EnterEmail/index.native.js +34 -0
  69. package/build/src/screens/EnterPassword/hooks/internal/useEnterPassword.js +47 -0
  70. package/build/src/screens/EnterPassword/index.js +22 -0
  71. package/build/src/screens/EnterPassword/index.native.js +23 -0
  72. package/build/src/screens/EnterPassword/types.js +1 -0
  73. package/build/src/screens/Login/components/LoginWebComponent/index.js +44 -0
  74. package/build/src/screens/Login/components/LoginWebComponent/index.native.js +6 -0
  75. package/build/src/screens/Login/index.js +10 -0
  76. package/build/src/screens/Login/index.native.js +6 -0
  77. package/build/src/screens/SignUp/components/SignUpForm/index.js +181 -0
  78. package/build/src/screens/SignUp/components/SignUpForm/index.native.js +6 -0
  79. package/build/src/screens/SignUp/components/SignUpForm/type.js +1 -0
  80. package/build/src/screens/SignUp/components/SignUpWebComponent/index.js +82 -0
  81. package/build/src/screens/SignUp/components/SignUpWebComponent/index.native.js +6 -0
  82. package/build/src/screens/SignUp/components/SignUpWebComponent/types.js +1 -0
  83. package/build/src/screens/SignUp/hooks/internal/useSignUp.js +138 -0
  84. package/build/src/screens/SignUp/index.js +6 -0
  85. package/build/src/screens/SignUp/index.native.js +185 -0
  86. package/build/src/screens/SignUp/types.js +1 -0
  87. package/build/src/screens/UserConsent/hooks/internal/useConsent.js +48 -0
  88. package/build/src/screens/UserConsent/index.js +69 -0
  89. package/build/src/screens/UserConsent/index.native.js +46 -0
  90. package/build/src/screens/UserConsent/types.js +1 -0
  91. package/build/src/screens/VerifyEmail/hooks/internal/useVerifyEmail.js +69 -0
  92. package/build/src/screens/VerifyEmail/index.js +8 -0
  93. package/build/src/screens/VerifyEmail/index.native.js +14 -0
  94. package/build/src/screens/VerifyEmail/types.js +1 -0
  95. package/build/src/screens/VerifyMobile/hooks/internal/useVerifyMobile.js +73 -0
  96. package/build/src/screens/VerifyMobile/index.js +8 -0
  97. package/build/src/screens/VerifyMobile/index.native.js +9 -0
  98. package/build/src/screens/VerifyMobile/types.js +1 -0
  99. package/build/src/screens/Welcome/hooks/internal/useWelcome.js +21 -0
  100. package/build/src/screens/Welcome/index.js +28 -0
  101. package/build/src/screens/Welcome/index.native.js +41 -0
  102. package/build/src/types/types.js +1 -0
  103. package/build/types/api/axiosClient/index.d.ts +1 -0
  104. package/build/types/api/axiosClient/index.native.d.ts +1 -0
  105. package/build/types/components/AdvancedTransitionWrapper/index.d.ts +3 -0
  106. package/build/types/components/AdvancedTransitionWrapper/index.native.d.ts +5 -0
  107. package/build/types/components/AdvancedTransitionWrapper/types.d.ts +25 -0
  108. package/build/types/components/ConfirmationModal/index.d.ts +3 -0
  109. package/build/types/components/ConfirmationModal/index.native.d.ts +3 -0
  110. package/build/types/components/ConfirmationModal/types.d.ts +13 -0
  111. package/build/types/components/EmailOTPVerify/index.d.ts +3 -0
  112. package/build/types/components/EmailOTPVerify/index.native.d.ts +3 -0
  113. package/build/types/components/EmailOTPVerify/type.d.ts +9 -0
  114. package/build/types/components/IonIcon/index.d.ts +3 -0
  115. package/build/types/components/IonIcon/index.native.d.ts +4 -0
  116. package/build/types/components/IonIcon/types.d.ts +6 -0
  117. package/build/types/components/OTPStatusLabel/index.d.ts +2 -0
  118. package/build/types/components/OTPStatusLabel/index.native.d.ts +3 -0
  119. package/build/types/components/OTPStatusLabel/types.d.ts +6 -0
  120. package/build/types/components/PasswordCriteria/hooks/usePasswordCriteria.d.ts +13 -0
  121. package/build/types/components/PasswordCriteria/index.d.ts +3 -0
  122. package/build/types/components/PasswordCriteria/index.native.d.ts +3 -0
  123. package/build/types/components/PasswordCriteria/types.d.ts +15 -0
  124. package/build/types/components/ScreenLayout/index.d.ts +3 -0
  125. package/build/types/components/ScreenLayout/index.native.d.ts +3 -0
  126. package/build/types/components/ScreenLayout/types.d.ts +12 -0
  127. package/build/types/components/SupportDetails/index.d.ts +2 -0
  128. package/build/types/components/SupportDetails/index.native.d.ts +2 -0
  129. package/build/types/components/VerifyOTP/index.d.ts +3 -0
  130. package/build/types/components/VerifyOTP/index.native.d.ts +3 -0
  131. package/build/types/components/VerifyOTP/types.d.ts +10 -0
  132. package/build/types/constants/cdn-url/index.d.ts +1 -0
  133. package/build/types/constants/cdn-url/index.native.d.ts +3 -0
  134. package/build/types/contexts/AuthContext.d.ts +36 -0
  135. package/build/types/contexts/type.d.ts +58 -0
  136. package/build/types/helpers/Network.d.ts +5 -0
  137. package/build/types/helpers/Validation.d.ts +2 -0
  138. package/build/types/helpers/show-message/index.d.ts +3 -0
  139. package/build/types/helpers/show-message/index.native.d.ts +3 -0
  140. package/build/types/helpers/show-message/types.d.ts +2 -0
  141. package/build/types/helpers/types.d.ts +13 -0
  142. package/build/types/hooks/internal/useAuthPackageContext.d.ts +1 -0
  143. package/build/types/hooks/internal/useTimer.d.ts +3 -0
  144. package/build/types/hooks/useAuthContext.d.ts +2 -0
  145. package/build/types/hooks/useRequest.d.ts +5 -0
  146. package/build/types/index.d.ts +8 -0
  147. package/build/types/navigator/index.d.ts +2 -0
  148. package/build/types/navigator/index.native.d.ts +36 -0
  149. package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.d.ts +3 -0
  150. package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.native.d.ts +2 -0
  151. package/build/types/screens/CountryCode/components/CountryCodeDropdown/types.d.ts +17 -0
  152. package/build/types/screens/CountryCode/hooks/internal/useCountryCode.d.ts +12 -0
  153. package/build/types/screens/CountryCode/index.d.ts +2 -0
  154. package/build/types/screens/CountryCode/index.native.d.ts +2 -0
  155. package/build/types/screens/CountryCode/type.d.ts +11 -0
  156. package/build/types/screens/CreatePassword/hooks/internal/useCreatePassword.d.ts +26 -0
  157. package/build/types/screens/CreatePassword/index.d.ts +3 -0
  158. package/build/types/screens/CreatePassword/index.native.d.ts +4 -0
  159. package/build/types/screens/CreatePassword/type.d.ts +43 -0
  160. package/build/types/screens/EnterEmail/hooks/internal/useEnterEmail.d.ts +24 -0
  161. package/build/types/screens/EnterEmail/index.d.ts +7 -0
  162. package/build/types/screens/EnterEmail/index.native.d.ts +4 -0
  163. package/build/types/screens/EnterPassword/hooks/internal/useEnterPassword.d.ts +20 -0
  164. package/build/types/screens/EnterPassword/index.d.ts +3 -0
  165. package/build/types/screens/EnterPassword/index.native.d.ts +4 -0
  166. package/build/types/screens/EnterPassword/types.d.ts +5 -0
  167. package/build/types/screens/Login/components/LoginWebComponent/index.d.ts +2 -0
  168. package/build/types/screens/Login/components/LoginWebComponent/index.native.d.ts +2 -0
  169. package/build/types/screens/Login/index.d.ts +2 -0
  170. package/build/types/screens/Login/index.native.d.ts +2 -0
  171. package/build/types/screens/SignUp/components/SignUpForm/index.d.ts +3 -0
  172. package/build/types/screens/SignUp/components/SignUpForm/index.native.d.ts +2 -0
  173. package/build/types/screens/SignUp/components/SignUpForm/type.d.ts +9 -0
  174. package/build/types/screens/SignUp/components/SignUpWebComponent/index.d.ts +2 -0
  175. package/build/types/screens/SignUp/components/SignUpWebComponent/index.native.d.ts +2 -0
  176. package/build/types/screens/SignUp/components/SignUpWebComponent/types.d.ts +24 -0
  177. package/build/types/screens/SignUp/hooks/internal/useSignUp.d.ts +50 -0
  178. package/build/types/screens/SignUp/index.d.ts +2 -0
  179. package/build/types/screens/SignUp/index.native.d.ts +4 -0
  180. package/build/types/screens/SignUp/types.d.ts +18 -0
  181. package/build/types/screens/UserConsent/hooks/internal/useConsent.d.ts +10 -0
  182. package/build/types/screens/UserConsent/index.d.ts +3 -0
  183. package/build/types/screens/UserConsent/index.native.d.ts +4 -0
  184. package/build/types/screens/UserConsent/types.d.ts +27 -0
  185. package/build/types/screens/VerifyEmail/hooks/internal/useVerifyEmail.d.ts +19 -0
  186. package/build/types/screens/VerifyEmail/index.d.ts +3 -0
  187. package/build/types/screens/VerifyEmail/index.native.d.ts +4 -0
  188. package/build/types/screens/VerifyEmail/types.d.ts +8 -0
  189. package/build/types/screens/VerifyMobile/hooks/internal/useVerifyMobile.d.ts +14 -0
  190. package/build/types/screens/VerifyMobile/index.d.ts +3 -0
  191. package/build/types/screens/VerifyMobile/index.native.d.ts +4 -0
  192. package/build/types/screens/VerifyMobile/types.d.ts +5 -0
  193. package/build/types/screens/Welcome/hooks/internal/useWelcome.d.ts +14 -0
  194. package/build/types/screens/Welcome/index.d.ts +4 -0
  195. package/build/types/screens/Welcome/index.native.d.ts +4 -0
  196. package/build/types/types/types.d.ts +90 -0
  197. package/get-metro-config.js +40 -0
  198. package/get-next-config.js +26 -0
  199. package/package.json +86 -38
  200. package/dist/index.esm.js +0 -2028
  201. package/dist/index.umd.js +0 -70
  202. package/dist/vite.svg +0 -1
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { Dimensions, Platform, ScrollView, Text, TouchableOpacity, View } from "react-native";
4
+ import { Layout } from "@ui-kitten/components";
5
+ import { Header, Colors, CustomKeyboardAvoidingView } from "@truworth/twc-rn-common";
6
+ import { ScreenLayout } from "../ScreenLayout";
7
+ import { OTPStatusLabel } from "../OTPStatusLabel/index.native";
8
+ import OTPInputView from "@twotalltotems/react-native-otp-input";
9
+ const EmailOTPVerify = ({ status, validateOTP, resendOTP, resendOTPCounter, email }) => {
10
+ const [otp, setOTP] = useState('');
11
+ useEffect(() => {
12
+ if (otp && otp.length === 6) {
13
+ validateOTP?.(otp);
14
+ }
15
+ }, [otp]);
16
+ return (_jsxs(Layout, { style: { flex: 1, backgroundColor: '#fff' }, children: [_jsx(Header, {}), _jsxs(CustomKeyboardAvoidingView, { behavior: Platform.OS === 'ios' ? 'padding' : undefined, keyboardVerticalOffset: Platform.OS === 'ios' ? 100 : 0, children: [_jsx(ScrollView, { showsVerticalScrollIndicator: false, children: _jsxs(ScreenLayout, { hideHeader: true, title: _jsxs(_Fragment, { children: ["OTP sent to ", '\n', _jsx(Text, { style: { fontSize: 20 }, children: email })] }), children: [_jsx(View, { style: { justifyContent: 'center', flexDirection: 'row', marginBottom: 30, position: 'relative' }, children: _jsx(OTPInputView, { pinCount: 6, autoFocusOnLoad: false, codeInputFieldStyle: {
17
+ fontSize: 20, color: 'black',
18
+ height: 45, width: 30,
19
+ borderWidth: 0, borderBottomWidth: 1,
20
+ }, codeInputHighlightStyle: { borderColor: '#03DAC6' }, style: {
21
+ height: 50,
22
+ width: Dimensions.get('window').width - 100,
23
+ }, onCodeFilled: code => setOTP(code) }) }), resendOTPCounter < 3 &&
24
+ _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center' }, children: [_jsxs(Text, { style: { fontSize: 14, fontWeight: '500', color: Colors.gray.gray_400, lineHeight: 20 }, children: ["Did not receive OTP?", ' '] }), _jsx(TouchableOpacity, { activeOpacity: 0.8, onPress: resendOTP, children: _jsx(Text, { style: { fontSize: 14, fontWeight: '500', color: '#2cbaa4', lineHeight: 20 }, children: "Re-send OTP" }) })] })] }) }), _jsx(View, { style: { alignSelf: 'flex-end', width: '100%' }, children: _jsx(OTPStatusLabel, { status: status }) })] })] }));
25
+ };
26
+ export { EmailOTPVerify };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ const IonIcon = ({ name, size, className, ...props }) => {
3
+ const customElementProps = {
4
+ ...props,
5
+ name,
6
+ size,
7
+ class: className // For the custom element
8
+ };
9
+ return _jsx("ion-icon", { ...customElementProps });
10
+ };
11
+ export { IonIcon };
@@ -0,0 +1,9 @@
1
+ let __ionIconWarned = false;
2
+ const IonIcon = (_props) => {
3
+ if (__DEV__ && !__ionIconWarned) {
4
+ console.warn("[@truworth/twc-auth] IonIcon is web-only");
5
+ __ionIconWarned = true;
6
+ }
7
+ return null;
8
+ };
9
+ export { IonIcon };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ const OTPStatusLabel = () => {
3
+ if (process.env.NODE_ENV !== 'production') {
4
+ if (typeof window !== 'undefined') {
5
+ console.warn("[@truworth/twc-auth] We use only OTPStatusLabel for the app");
6
+ }
7
+ }
8
+ return null;
9
+ };
10
+ export { OTPStatusLabel };
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { isIphoneX } from "@truworth/twc-rn-common";
3
+ import { ActivityIndicator, Text, View } from "react-native";
4
+ import LinearGradient from "react-native-linear-gradient";
5
+ import OkayIcon from '../../../assets/okay_icon.svg';
6
+ import CrossIcon from '../../../assets/cross_icon.svg';
7
+ const OTPStatusLabel = ({ status, timer }) => {
8
+ switch (status) {
9
+ case 'timer':
10
+ return (_jsx(View, { style: { height: isIphoneX() ? 80 : 70, width: '100%', justifyContent: 'center' }, children: _jsx(LinearGradient, { colors: ['#b0bbbd', '#b0bbbd'], style: { flex: 1, justifyContent: 'center', alignItems: 'center' }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, children: _jsx(Text, { style: { textAlign: 'center', fontSize: 15, color: '#FFFFFF', textTransform: 'uppercase' }, children: timer && timer > 0 ? `${timer} seconds` : 'OTP expired' }) }) }));
11
+ case 'valid':
12
+ return (_jsx(View, { style: { height: isIphoneX() ? 80 : 70, width: '100%', justifyContent: 'center' }, children: _jsx(LinearGradient, { colors: ['#44cfb9', '#1EC2C9'], style: { flex: 1, alignItems: 'center', justifyContent: 'center' }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, children: _jsx(Text, { style: { textAlign: 'center', fontSize: 15, color: '#fff', textTransform: 'uppercase' }, children: _jsx(OkayIcon, {}) }) }) }));
13
+ case 'invalid':
14
+ return (_jsx(View, { style: { height: isIphoneX() ? 80 : 70, width: '100%', justifyContent: 'center' }, children: _jsx(LinearGradient, { colors: ['#F3698B', '#F18A8A'], style: { flex: 1, alignItems: 'center', justifyContent: 'center' }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, children: _jsx(Text, { style: { textAlign: 'center', fontSize: 15, color: '#fff', textTransform: 'uppercase' }, children: _jsx(CrossIcon, {}) }) }) }));
15
+ case 'loading':
16
+ return (_jsx(View, { style: { height: isIphoneX() ? 80 : 70, width: '100%', justifyContent: 'center' }, children: _jsx(LinearGradient, { colors: ['#b0bbbd', '#b0bbbd'], style: { flex: 1, alignItems: 'center', justifyContent: 'center' }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, children: _jsx(View, { style: { alignItems: 'center' }, children: _jsx(ActivityIndicator, { color: 'black' }) }) }) }));
17
+ default:
18
+ return null;
19
+ }
20
+ };
21
+ export { OTPStatusLabel };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,78 @@
1
+ import { useEffect, useState } from "react";
2
+ import { axiosClient } from "../../../api/axiosClient";
3
+ const defaultPolicy = {
4
+ minLength: 6,
5
+ maxLength: 30,
6
+ numbers: true,
7
+ uppercase: true,
8
+ lowercase: true,
9
+ specialCharacters: true,
10
+ };
11
+ const usePasswordCriteria = ({ email, password, onCriteriaChange, onMaxLengthChange }) => {
12
+ const { maxLength: defaultMaxLength, ...restDefaultPolicy } = defaultPolicy;
13
+ const [loading, setLoading] = useState(false);
14
+ const [passwordPolicy, setPasswordPolicy] = useState(restDefaultPolicy);
15
+ useEffect(() => {
16
+ if (!email) {
17
+ setPasswordPolicy(restDefaultPolicy);
18
+ onMaxLengthChange(defaultMaxLength);
19
+ setLoading(false);
20
+ return;
21
+ }
22
+ return getPasswordPolicy();
23
+ }, [email]);
24
+ const getPasswordPolicy = () => {
25
+ let isActive = true;
26
+ if (email) {
27
+ setPasswordPolicy(restDefaultPolicy);
28
+ onMaxLengthChange(defaultMaxLength);
29
+ setLoading(true);
30
+ axiosClient({
31
+ url: `/auth/password-policy?email=${encodeURIComponent(email)}`,
32
+ method: 'GET',
33
+ }).then(({ data }) => {
34
+ if (!isActive)
35
+ return;
36
+ const { maxLength, ...rest } = (data || {});
37
+ // Apply server-provided policy when present, falling back to defaults
38
+ setPasswordPolicy({
39
+ minLength: typeof rest.minLength === 'number' ? rest.minLength : restDefaultPolicy.minLength,
40
+ numbers: typeof rest.numbers === 'boolean' ? rest.numbers : restDefaultPolicy.numbers,
41
+ uppercase: typeof rest.uppercase === 'boolean' ? rest.uppercase : restDefaultPolicy.uppercase,
42
+ lowercase: typeof rest.lowercase === 'boolean' ? rest.lowercase : restDefaultPolicy.lowercase,
43
+ specialCharacters: typeof rest.specialCharacters === 'boolean' ? rest.specialCharacters : restDefaultPolicy.specialCharacters,
44
+ });
45
+ onMaxLengthChange(typeof maxLength === 'number' ? maxLength : defaultMaxLength);
46
+ }).catch(err => {
47
+ if (!isActive)
48
+ return;
49
+ console.warn('password-policy fetch failed', err);
50
+ setPasswordPolicy(restDefaultPolicy);
51
+ onMaxLengthChange(defaultMaxLength);
52
+ }).finally(() => isActive && setLoading(false));
53
+ }
54
+ return () => { isActive = false; };
55
+ };
56
+ useEffect(() => {
57
+ onCriteriaChange({
58
+ minLength: password.length >= passwordPolicy.minLength,
59
+ specialCharacters: passwordPolicy.specialCharacters ? /[!@#$%^&*(),.?":{}|<>]/.test(password) : true,
60
+ numbers: passwordPolicy.numbers ? /\d/.test(password) : true,
61
+ uppercase: passwordPolicy.uppercase ? /[A-Z]/.test(password) : true,
62
+ lowercase: passwordPolicy.lowercase ? /[a-z]/.test(password) : true,
63
+ });
64
+ }, [password, passwordPolicy]);
65
+ const renderLabel = (criteria) => {
66
+ switch (criteria) {
67
+ case 'minLength': return `min ${passwordPolicy.minLength} characters`;
68
+ case 'specialCharacters': return 'special character';
69
+ default: return criteria;
70
+ }
71
+ };
72
+ return {
73
+ loading,
74
+ passwordPolicy,
75
+ renderLabel,
76
+ };
77
+ };
78
+ export { usePasswordCriteria };
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useId, useMemo } from "react";
3
+ import { usePasswordCriteria } from "./hooks/usePasswordCriteria";
4
+ import { Check, X } from "lucide-react";
5
+ const PasswordCriteria = ({ email, password, criteria, onCriteriaChange, onMaxLengthChange }) => {
6
+ const id = useId();
7
+ const { passwordPolicy, renderLabel, } = usePasswordCriteria({ email, password, onCriteriaChange, onMaxLengthChange });
8
+ const activeRequirementKeys = useMemo(() => {
9
+ // Include minLength always; include other flags only if enabled by policy
10
+ return Object.keys(passwordPolicy).filter((key) => {
11
+ if (key === "minLength")
12
+ return true;
13
+ // @ts-ignore boolean flags present on policy
14
+ return Boolean(passwordPolicy[key]);
15
+ });
16
+ }, [passwordPolicy]);
17
+ const strengthScore = useMemo(() => {
18
+ return activeRequirementKeys.reduce((acc, key) => acc + (criteria[key] ? 1 : 0), 0);
19
+ }, [activeRequirementKeys, criteria]);
20
+ const maxScore = activeRequirementKeys.length || 1;
21
+ const getStrengthColor = (score) => {
22
+ const ratio = score / maxScore;
23
+ if (score === 0)
24
+ return "bg-border";
25
+ if (ratio < 0.4)
26
+ return "bg-red-500";
27
+ if (ratio < 0.7)
28
+ return "bg-orange-500";
29
+ if (ratio < 1)
30
+ return "bg-amber-500";
31
+ return "bg-emerald-500";
32
+ };
33
+ const getStrengthText = (score) => {
34
+ if (score === 0)
35
+ return "Enter a password";
36
+ const ratio = score / maxScore;
37
+ if (ratio < 0.4)
38
+ return "Weak password";
39
+ if (ratio < 0.8)
40
+ return "Medium password";
41
+ return "Strong password";
42
+ };
43
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "h-1 w-full overflow-hidden rounded-full bg-border", role: "progressbar", "aria-valuenow": strengthScore, "aria-valuemin": 0, "aria-valuemax": maxScore, "aria-label": "Password strength", children: _jsx("div", { className: `h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`, style: { width: `${(strengthScore / maxScore) * 100}%` } }) }), _jsxs("p", { id: `${id}-description`, className: "mt-2 text-sm font-medium text-foreground", children: [getStrengthText(strengthScore), ". Must contain:"] }), _jsx("ul", { className: "mt-2 space-y-1.5", "aria-label": "Password requirements", children: activeRequirementKeys.map((req, index) => (_jsxs("li", { className: "flex items-center gap-2", children: [criteria[req]
44
+ ? _jsx(Check, { size: 16, className: "text-emerald-500", "aria-hidden": "true" })
45
+ : _jsx(X, { size: 16, className: "text-muted-foreground/80", "aria-hidden": "true" }), _jsxs("span", { className: `text-xs ${criteria[req] ? "text-emerald-600" : "text-muted-foreground"}`, children: [renderLabel(req), _jsx("span", { className: "sr-only", children: criteria[req] ? " - Requirement met" : " - Requirement not met" })] })] }, index))) })] }));
46
+ };
47
+ export { PasswordCriteria };
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { LoadingPlaceholder, Colors } from '@truworth/twc-rn-common';
3
+ import { Text, View } from 'react-native';
4
+ import { usePasswordCriteria } from './hooks/usePasswordCriteria';
5
+ const { gray, utility } = Colors;
6
+ const PasswordCriteria = ({ email, password, criteria, onCriteriaChange, onMaxLengthChange }) => {
7
+ const { passwordPolicy, loading, renderLabel, } = usePasswordCriteria({ email, password, onCriteriaChange, onMaxLengthChange });
8
+ const getCriteriaColor = (isValid) => (isValid ? utility.success_main : gray.gray_600);
9
+ const getCriteriaBackground = (isValid) => (isValid ? utility.success_bg : gray.gray_100);
10
+ return (_jsx(View, { style: { flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', alignContent: 'space-between', marginTop: 8 }, children: Object.keys(passwordPolicy).map((item, index) => (loading
11
+ ? _jsx(LoadingPlaceholder, { height: 24, width: renderLabel(item).length * 8, borderRadius: 12, containerStyle: { marginRight: 8, marginTop: 8 } }, index)
12
+ : _jsx(Text, { style: {
13
+ fontSize: 12, fontWeight: '500', marginRight: 8, marginTop: 8, borderRadius: 32,
14
+ paddingVertical: 4, paddingHorizontal: 12,
15
+ backgroundColor: getCriteriaBackground(criteria[item]),
16
+ color: getCriteriaColor(criteria[item]),
17
+ }, children: renderLabel(item) }, index))) }));
18
+ };
19
+ export { PasswordCriteria };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Typography } from "@truworth/twc-web-design";
3
+ import { AdvancedTransitionWrapper } from "../AdvancedTransitionWrapper";
4
+ import { ArrowLeft } from "lucide-react";
5
+ const ScreenLayout = ({ children, title, subTitle, buttonProps, onPressBack }) => {
6
+ return (_jsxs(AdvancedTransitionWrapper, { type: 'slide', duration: 0.5, children: [onPressBack &&
7
+ _jsx(Button, { label: "Back", size: "large", variant: "link", leftIcon: _jsx(ArrowLeft, {}), className: "p-0 h-auto", onClick: onPressBack }), Boolean(title) &&
8
+ _jsx(Typography, { type: 'heading', size: 'h5', className: 'mb-2 mt-6', children: title }), Boolean(subTitle) &&
9
+ _jsx(Typography, { type: 'body', size: 'large', className: "md:mb-8 mb-6 text-gray-400", children: subTitle }), children, Boolean(buttonProps) &&
10
+ _jsx(Button, { label: "Continue", isFullWidth: true, variant: 'primary', className: "mt-3", ...buttonProps })] }));
11
+ };
12
+ export { ScreenLayout };
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { View, Text } from 'react-native';
3
+ import { Colors, Header, RoundedButton } from '@truworth/twc-rn-common';
4
+ const { gray } = Colors;
5
+ const ScreenLayout = ({ children, title, subTitle, hideHeader, buttonProps, containerStyle, accessoryRight }) => {
6
+ return (_jsxs(_Fragment, { children: [!hideHeader &&
7
+ _jsx(Header, { accessoryRight: accessoryRight }), _jsxs(View, { style: [{ paddingVertical: 32, paddingHorizontal: 16 }, containerStyle], children: [Boolean(title) &&
8
+ _jsx(Text, { textBreakStrategy: 'simple', style: {
9
+ fontSize: 20, fontWeight: '600', color: gray.gray_900,
10
+ lineHeight: 32, marginBottom: 32,
11
+ }, children: title }), Boolean(subTitle) &&
12
+ _jsx(Text, { textBreakStrategy: 'simple', style: {
13
+ fontSize: 14, fontWeight: '500', color: gray.gray_400,
14
+ lineHeight: 20, marginTop: -24, marginBottom: 32,
15
+ }, children: subTitle }), children, Boolean(buttonProps) &&
16
+ _jsx(RoundedButton, { containerStyle: { marginTop: 32 }, type: buttonProps?.type ?? 'secondary', size: buttonProps?.size ?? 'large', ...buttonProps })] })] }));
17
+ };
18
+ export { ScreenLayout };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CircleHelpIcon } from 'lucide-react';
3
+ import { Flex, Typography } from "@truworth/twc-web-design";
4
+ import { useAuthPackageContext } from "../../hooks/internal/useAuthPackageContext";
5
+ const SupportDetails = () => {
6
+ const { appConfig } = useAuthPackageContext();
7
+ return (_jsxs(Flex, { padding: "sm", className: 'rounded-lg bg-gray-100 md:mt-8 mt-6 gap-3', children: [_jsx(CircleHelpIcon, { size: 20, className: "min-w-5 text-primary" }), _jsxs(Typography, { type: "body", size: "small", children: ["For any customer support\u2013related queries, please write to us at", _jsx("a", { href: `mailto:${appConfig.supportEmail}`, className: "text-primary block", children: _jsx("u", { children: appConfig.supportEmail }) })] })] }));
8
+ };
9
+ export { SupportDetails };
@@ -0,0 +1,6 @@
1
+ const SupportDetails = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] SupportDetails is web-only");
4
+ return null;
5
+ };
6
+ export { SupportDetails };
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Button, Flex, OTPInput, Typography } from "@truworth/twc-web-design";
4
+ const OTPVerify = ({ validateOTP, timer, resendOTP, phone, status, resendTextClassName }) => {
5
+ const [otp, setOtp] = useState('');
6
+ const [otpError, setOtpError] = useState(false);
7
+ useEffect(() => {
8
+ if (status === 'invalid') {
9
+ setOtpError(true);
10
+ setOtp('');
11
+ }
12
+ }, [status]);
13
+ const defaultPhoneDisplayText = (_jsxs(Typography, { type: 'body', size: 'large', className: 'mb-6 text-gray-400 text-center', children: ["OTP sent to", _jsx("span", { className: 'pl-2 text-secondary-dark', children: phone ? `XXXXXXX${phone.slice(-3)}` : 'your registered mobile number' })] }));
14
+ return (_jsxs(_Fragment, { children: [defaultPhoneDisplayText, _jsx(OTPInput, { value: otp, onChange: (code) => {
15
+ setOtp(code);
16
+ setOtpError(false);
17
+ }, error: otpError, maxLength: 6, className: `!w-auto ${otpError ? '!border-destructive' : ''}` }), otpError &&
18
+ _jsx(Typography, { type: "utility", size: "medium", className: "mt-4", color: "text-utility-danger-main", children: "Please enter the correct OTP." }), (timer <= 0) ?
19
+ _jsxs(Flex, { justify: 'between', align: 'center', className: 'mt-4', children: [_jsx(Typography, { type: 'utility', size: 'medium', className: resendTextClassName, children: "Didn't receive OTP?" }), _jsx(Button, { label: 'Resend Code', size: 'small', variant: 'link', onClick: () => resendOTP() })] })
20
+ :
21
+ _jsxs(Typography, { type: 'utility', size: 'medium', className: `mt-3 ${resendTextClassName}`, children: ["Resend Code in ", timer > 0 ? `${timer} seconds` : 'OTP expired'] }), _jsx(Button, { label: "Continue", isFullWidth: true, onClick: () => validateOTP?.(otp), disabled: otp ? otp?.length < 6 : true, className: "mt-6" })] }));
22
+ };
23
+ export { OTPVerify };
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Colors, CustomKeyboardAvoidingView, Header } from '@truworth/twc-rn-common';
4
+ import { Layout } from '@ui-kitten/components';
5
+ import { Dimensions, Platform, ScrollView, Text, TouchableOpacity, View, } from 'react-native';
6
+ import { useAuthPackageContext } from '../../hooks/internal/useAuthPackageContext';
7
+ import { OTPStatusLabel } from '../OTPStatusLabel/index.native';
8
+ import OTPInputView from '@twotalltotems/react-native-otp-input';
9
+ const { gray } = Colors;
10
+ const OTPVerify = ({ validateOTP, timer, status, resendOTP, phone }) => {
11
+ const [otp, setOTP] = useState('');
12
+ const { otpValue } = useAuthPackageContext();
13
+ useEffect(() => {
14
+ if (otp?.length === 6) {
15
+ validateOTP(otp);
16
+ }
17
+ }, [otp]);
18
+ useEffect(() => {
19
+ if (otpValue && otpValue.length == 6) {
20
+ setOTP(otpValue);
21
+ }
22
+ }, [otpValue]);
23
+ return (_jsxs(Layout, { style: { flex: 1, backgroundColor: '#FFFFFF' }, children: [_jsx(Header, {}), _jsxs(CustomKeyboardAvoidingView, { behavior: Platform.OS === 'ios' ? 'padding' : undefined, keyboardVerticalOffset: Platform.OS === 'ios' ? 100 : 0, children: [_jsxs(ScrollView, { style: { paddingHorizontal: 20, paddingTop: 32, flex: 1 }, children: [_jsxs(Text, { textBreakStrategy: 'simple', style: {
24
+ fontSize: 20, fontWeight: '600', color: gray.gray_900,
25
+ lineHeight: 32, marginBottom: 32,
26
+ }, children: ["OTP sent to ", '\n', phone ? phone.replace(/\d(?=\d{4})/g, 'x') : ''] }), _jsx(View, { style: { justifyContent: 'center', flexDirection: 'row', marginBottom: 30, position: 'relative' }, children: _jsx(OTPInputView, { pinCount: 6, autoFocusOnLoad: false, onCodeChanged: text => setOTP(text), codeInputFieldStyle: {
27
+ fontSize: 20, color: 'black', width: 30,
28
+ height: 45, borderWidth: 0, borderBottomWidth: 1,
29
+ }, codeInputHighlightStyle: { borderColor: '#03DAC6' }, style: {
30
+ height: 50,
31
+ width: Dimensions.get('window').width - 100,
32
+ }, code: otp ?? '', onCodeFilled: code => setOTP(code) }) }), timer <= 0 &&
33
+ _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center' }, children: [_jsxs(Text, { style: { fontSize: 12, color: '#000', fontWeight: '400', opacity: 0.5 }, children: ["Did not receive OTP?", ' '] }), _jsx(TouchableOpacity, { disabled: timer > 0, onPress: () => {
34
+ setOTP('');
35
+ resendOTP();
36
+ }, children: _jsx(Text, { style: { fontSize: 14, color: '#2cbaa4', fontWeight: '400', opacity: 1 }, children: "Re-send OTP" }) })] })] }), _jsx(View, { style: { width: '100%' }, children: _jsx(OTPStatusLabel, { status: status, timer: timer }) })] })] }));
37
+ };
38
+ export { OTPVerify };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { MEMBER_IMAGES_URL } from "@truworth/twc-web-common";
@@ -0,0 +1,5 @@
1
+ const CdnImageUrl = () => {
2
+ return null;
3
+ };
4
+ export { CdnImageUrl };
5
+ export default CdnImageUrl;
@@ -0,0 +1,184 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useEffect, useState, useMemo, useCallback } from 'react';
3
+ import { MEMBER_IMAGES_URL } from '../constants/cdn-url';
4
+ import { createHttpClient } from '../helpers/Network';
5
+ /**
6
+ * Public Auth Authentication Context
7
+ *
8
+ * Exposed to consumers of the Auth package.
9
+ * Provides access to user profile, client info, logout, and helper utilities.
10
+ */
11
+ const AuthContext = React.createContext(null);
12
+ /**
13
+ * Package Auth Authentication Context
14
+ *
15
+ * Not meant for public use. Contains lower-level auth state such as
16
+ * token, login/logout functions, and refresh session.
17
+ */
18
+ const AuthPackageContext = React.createContext(null);
19
+ /**
20
+ * AuthProvider
21
+ *
22
+ * Provides authentication state and actions to children.
23
+ * Wraps both AuthContext (public) and AuthPackageContext (internal).
24
+ *
25
+ * @param children - React children to be rendered inside the provider
26
+ * @param LogoComponent - Optional component for branding/logo in auth flows
27
+ * @param session - Initial session containing token & sessionTimeout (if available)
28
+ * @param supportEmail - Optional support email for auth flows
29
+ * @param appConfig - Optional app config for auth flows
30
+ * @param onLogin - Optional callback after successful login
31
+ * @param onLogout - Optional callback after successful logout
32
+ * @param onLaunchAuthSession - Optional callback after successfully launching the auth session. For example, it can be used to set the Firebase notification token or request Android permissions.
33
+ * @param onRefreshSession - Optional handler for refreshing user session
34
+ */
35
+ const AuthProvider = ({ children, LogoComponent, session, appConfig, onLogin, onLogout, onLaunchAuthSession, onRefreshSession }) => {
36
+ const [isLoadingProfile, setIsLoadingProfile] = useState(false);
37
+ const [member, setMember] = useState(null);
38
+ const [client, setClient] = useState(null);
39
+ const [registrationMethod, setRegistrationMethod] = useState(null);
40
+ const [token, setToken] = useState('');
41
+ const [otpValue, setOtpValue] = useState('');
42
+ const { request } = useMemo(() => createHttpClient({
43
+ token,
44
+ onRefreshSession: onRefreshSession
45
+ ? (t) => onRefreshSession({ token: t })
46
+ : undefined,
47
+ onLogout: async () => {
48
+ onLogout?.();
49
+ clearSession();
50
+ },
51
+ }), [token, onRefreshSession, onLogout]);
52
+ /**
53
+ * Sync local token state with session prop
54
+ */
55
+ useEffect(() => {
56
+ if (session?.token) {
57
+ setToken(session?.token);
58
+ }
59
+ }, [session?.token]);
60
+ /**
61
+ * fetch user profile if not already loaded.
62
+ */
63
+ useEffect(() => {
64
+ if (token && !member) {
65
+ getUserProfile();
66
+ }
67
+ }, [token, member]);
68
+ /**
69
+ * Logout user and clear authentication state.
70
+ * Falls back to default /auth/logout request
71
+ *
72
+ * @returns Promise<any> Resolves when logout is completed
73
+ */
74
+ const logout = useCallback(() => {
75
+ return new Promise((resolve, reject) => {
76
+ request({
77
+ url: '/auth/logout',
78
+ method: 'POST',
79
+ }).then((res) => {
80
+ clearSession();
81
+ onLogout?.();
82
+ resolve(res);
83
+ }).catch((err) => {
84
+ reject(err);
85
+ });
86
+ });
87
+ }, [request, onLogout]);
88
+ /**
89
+ * Fetch and update user profile and client data.
90
+ *
91
+ * @param token - Optional token for API request
92
+ * @returns Promise<any> Resolves with profile/config response
93
+ */
94
+ const getUserProfile = useCallback(() => {
95
+ if (isLoadingProfile)
96
+ return Promise.resolve(); // Prevent concurrent calls
97
+ setIsLoadingProfile(true);
98
+ return new Promise((resolve, reject) => {
99
+ request({
100
+ url: '/auth/config',
101
+ method: 'GET',
102
+ }).then((res) => {
103
+ const data = res?.data;
104
+ if (!data?.profile) {
105
+ console.warn('No profile data received from /auth/config');
106
+ return resolve(data);
107
+ }
108
+ const formatted = formatUserData(data);
109
+ setMember(formatted.profile);
110
+ setClient(formatted.client);
111
+ resolve(data);
112
+ }).catch((err) => {
113
+ reject(err);
114
+ });
115
+ }).finally(() => {
116
+ setIsLoadingProfile(false);
117
+ });
118
+ }, [request, isLoadingProfile]);
119
+ const clearSession = useCallback(() => {
120
+ setToken('');
121
+ setClient(null);
122
+ setMember(null);
123
+ setRegistrationMethod(null);
124
+ }, []);
125
+ /**
126
+ * Helper to normalize and format user profile data
127
+ * similar to legacy implementation.
128
+ *
129
+ * @param data - AuthConfigResponse from API
130
+ * @returns Object containing client and profile data
131
+ */
132
+ const formatUserData = useCallback((data) => {
133
+ const clientData = {
134
+ name: data.profile.clientName,
135
+ clientId: data.profile.clientId,
136
+ image: data.profile.clientImage,
137
+ partner: data.profile.partner,
138
+ directClient: data.profile.directClient
139
+ };
140
+ const profileData = {
141
+ ...data.profile,
142
+ firstName: data.profile.firstName,
143
+ lastName: data.profile.lastName,
144
+ image: data.profile?.image ? `${MEMBER_IMAGES_URL}${data.profile.image}` : '',
145
+ };
146
+ return { client: clientData, profile: profileData };
147
+ }, []);
148
+ const handleOtpReceived = (otp) => {
149
+ setOtpValue(otp);
150
+ setTimeout(() => setOtpValue(''), 0);
151
+ };
152
+ const AuthContextValues = {
153
+ isLoadingProfile,
154
+ member,
155
+ client,
156
+ logout,
157
+ onLaunchAuthSession,
158
+ getUserProfile,
159
+ onOtpReceived: handleOtpReceived,
160
+ };
161
+ const appConfigValue = {
162
+ appName: appConfig?.appName ?? 'The Wellness Corner',
163
+ supportEmail: appConfig?.supportEmail ?? 'support@thewellnesscorner.com',
164
+ privacyPolicyUrl: appConfig?.privacyPolicyUrl ?? 'https://thewellnesscorner.com/privacy-policy',
165
+ termsAndConditionsUrl: appConfig?.termsAndConditionsUrl ?? 'https://thewellnesscorner.com/privacy-policy'
166
+ };
167
+ const AuthPackageContextValues = {
168
+ token,
169
+ LogoComponent,
170
+ appConfig: appConfigValue,
171
+ registrationMethod,
172
+ onLaunchAuthSession,
173
+ onLogin,
174
+ logout,
175
+ refreshSession: onRefreshSession,
176
+ onTokenChange: (token) => setToken(token),
177
+ onRegistrationMethodChange: (method) => setRegistrationMethod(method),
178
+ otpValue,
179
+ };
180
+ return (_jsx(AuthContext.Provider, { value: AuthContextValues, children: _jsx(AuthPackageContext.Provider, { value: AuthPackageContextValues, children: children }) }));
181
+ };
182
+ export { AuthProvider };
183
+ export default AuthContext;
184
+ export { AuthPackageContext };
@@ -0,0 +1 @@
1
+ export {};