@truworth/twc-auth 1.2.10 → 1.2.12-beta.0
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/README.md +175 -13
- package/build/src/contexts/AuthContext.js +1 -1
- package/build/src/hooks/useRequest.js +1 -4
- package/build/src/screens/CountryCode/index.native.js +1 -1
- package/build/src/screens/EnterPassword/hooks/internal/useEnterPassword.js +3 -1
- package/build/src/screens/LoginWithEmailOTP/hooks/internal/useLoginWithEmailOTP.js +1 -3
- package/build/src/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.js +2 -1
- package/build/src/screens/ResetPassword/index.native.js +1 -1
- package/build/src/screens/SSOLogin/AuthenticationMethods/index.native.js +2 -2
- package/build/src/screens/SSOLogin/SSOCallback/hooks/internal/useSSOCallback.js +2 -1
- package/build/src/screens/SignUp/index.native.js +1 -1
- package/build/src/screens/UserConsent/index.js +2 -1
- package/build/src/screens/UserConsent/index.native.js +2 -1
- package/build/src/screens/VerifyLinkPrimaryAccountMobileOTP/hooks/internal/useVerifyLinkPrimaryAccountMobileOTP.js +2 -1
- package/build/src/screens/VerifyMobile/hooks/internal/useVerifyMobile.js +2 -1
- package/build/src/screens/Welcome/SocialAuth/hooks/useSocialAuth.native.js +5 -9
- package/build/src/screens/Welcome/SocialAuth/hooks/web/useFacebookAuth.web.js +3 -5
- package/build/src/screens/Welcome/SocialAuth/hooks/web/useGoogleAuth.web.js +3 -5
- package/package.json +15 -16
package/README.md
CHANGED
|
@@ -5,11 +5,11 @@ Truworth Auth Module - A comprehensive authentication solution for React Native
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
7
|
- [Installation](#installation)
|
|
8
|
-
- [React Native](#react-native)
|
|
9
|
-
- [Web](#web)
|
|
8
|
+
- [Mobile ( React Native )](#react-native)
|
|
9
|
+
- [Web ( Next.js )](#web)
|
|
10
10
|
- [Development](#development-configure-hot-reloading)
|
|
11
|
-
- [React Native Setup for Hot Reloading](#react-native-setup-for-hot-reloading)
|
|
12
|
-
- [Next.js Setup for Hot Reloading](#nextjs-setup-for-hot-reloading)
|
|
11
|
+
- [Mobile ( React Native Setup for Hot Reloading )](#react-native-setup-for-hot-reloading)
|
|
12
|
+
- [Web ( Next.js Setup for Hot Reloading )](#nextjs-setup-for-hot-reloading)
|
|
13
13
|
- [Usage](#usage)
|
|
14
14
|
- [API Reference](#api-reference)
|
|
15
15
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -115,6 +115,79 @@ Truworth Auth Module - A comprehensive authentication solution for React Native
|
|
|
115
115
|
react-dom@^18.2.0
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
+
## Running the Example Applications of the TWC-Auth Package
|
|
119
|
+
|
|
120
|
+
This repository includes example applications for both mobile (React Native) and web (Next.js).
|
|
121
|
+
|
|
122
|
+
### Running the Mobile App
|
|
123
|
+
|
|
124
|
+
1. **Navigate to the mobile app directory:**
|
|
125
|
+
```bash
|
|
126
|
+
cd apps/mobile
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
2. **Install dependencies:**
|
|
130
|
+
```bash
|
|
131
|
+
npm install
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
3. **Run on Android:**
|
|
135
|
+
```bash
|
|
136
|
+
npm run android
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
4. **Run on iOS:**
|
|
140
|
+
|
|
141
|
+
First, install the pods and build the application:
|
|
142
|
+
```bash
|
|
143
|
+
cd ios && pod install && cd ..
|
|
144
|
+
npm run build:ios
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then, run the application:
|
|
148
|
+
```bash
|
|
149
|
+
npm run ios
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Running the Web App
|
|
153
|
+
|
|
154
|
+
1. **Navigate to the web app directory:**
|
|
155
|
+
```bash
|
|
156
|
+
cd apps/web
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. **Create a `.env` file:**
|
|
160
|
+
|
|
161
|
+
Copy the example environment variables below into a new file named `.env` in the `apps/web` directory.
|
|
162
|
+
|
|
163
|
+
```shell
|
|
164
|
+
NEXT_PUBLIC_ENVIRONMENT=development/production
|
|
165
|
+
|
|
166
|
+
NODE_ENV=development/production
|
|
167
|
+
|
|
168
|
+
NEXT_PUBLIC_MEMBER_IMAGES_URL=<value>
|
|
169
|
+
|
|
170
|
+
NEXT_PUBLIC_TWC_API_BASE_URL=<value>
|
|
171
|
+
|
|
172
|
+
NEXT_PUBLIC_CDN_IMAGES_URL=<value>
|
|
173
|
+
|
|
174
|
+
NEXT_PUBLIC_GTM_ID=<value>
|
|
175
|
+
|
|
176
|
+
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=<value>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
3. **Install dependencies:**
|
|
180
|
+
```bash
|
|
181
|
+
npm install
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
4. **Run the development server:**
|
|
185
|
+
```bash
|
|
186
|
+
npm run dev
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
190
|
+
|
|
118
191
|
## Development: Configure Hot Reloading
|
|
119
192
|
|
|
120
193
|
### React Native Setup for Hot Reloading
|
|
@@ -195,30 +268,68 @@ const nextConfig = {
|
|
|
195
268
|
module.exports = nextConfig;
|
|
196
269
|
```
|
|
197
270
|
|
|
271
|
+
> **Note on CSS Imports:**
|
|
272
|
+
> When hot reloading the `@truworth/twc-web-design` package locally, you need to import the CSS from the `dist` folder in your `_app.tsx` file:
|
|
273
|
+
> ```typescript
|
|
274
|
+
> import "@truworth/twc-web-design/dist/main.css";
|
|
275
|
+
> ```
|
|
276
|
+
> When using the published version of the package, import the styles directly:
|
|
277
|
+
> ```typescript
|
|
278
|
+
> import "@truworth/twc-web-design/style.css";
|
|
279
|
+
> ```
|
|
280
|
+
|
|
198
281
|
## Usage
|
|
199
282
|
|
|
283
|
+
Below are examples of how to integrate and use the `AuthProvider` in your application.
|
|
284
|
+
|
|
200
285
|
### React Native
|
|
201
286
|
|
|
202
287
|
```tsx
|
|
203
|
-
import React
|
|
288
|
+
import React from "react";
|
|
204
289
|
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
|
205
290
|
import { NavigationContainer } from "@react-navigation/native";
|
|
206
291
|
import { AuthNavigator, AuthProvider } from "@truworth/twc-auth";
|
|
207
292
|
import type { LoginResponse } from "@truworth/twc-auth";
|
|
208
|
-
import
|
|
293
|
+
import { Image, Text } from 'react-native';
|
|
209
294
|
|
|
210
295
|
const { Navigator, Screen } = createNativeStackNavigator();
|
|
211
296
|
|
|
297
|
+
// A custom component to display your brand's logo on the auth screens.
|
|
298
|
+
const CustomLogo = () => <Image source={require('./path/to/your/logo.png')} style={{ width: 100, height: 50 }} />;
|
|
299
|
+
|
|
212
300
|
const ExampleAppNavigator = () => {
|
|
213
|
-
|
|
214
|
-
|
|
301
|
+
|
|
302
|
+
// Callback for when the user successfully logs in.
|
|
303
|
+
const onLogin = (result: LoginResponse) => {
|
|
304
|
+
console.log("Login successful:", result.token);
|
|
305
|
+
// TODO: Store token in secure storage & navigate to the main app screen.
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
// Callback for when the user logs out.
|
|
309
|
+
const onLogout = () => {
|
|
310
|
+
console.log("User logged out");
|
|
311
|
+
// TODO: Clear token from storage & navigate to the login screen.
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// Configuration for your app's branding and support details.
|
|
315
|
+
const appConfig = {
|
|
316
|
+
appName: 'Your App Name',
|
|
317
|
+
supportEmail: 'support@yourapp.com',
|
|
318
|
+
privacyPolicyUrl: 'https://yourapp.com/privacy',
|
|
319
|
+
termsAndConditionsUrl: 'https://yourapp.com/terms'
|
|
215
320
|
};
|
|
216
321
|
|
|
217
322
|
return (
|
|
218
323
|
<NavigationContainer>
|
|
219
|
-
<AuthProvider
|
|
324
|
+
<AuthProvider
|
|
325
|
+
onLogin={onLogin}
|
|
326
|
+
onLogout={onLogout}
|
|
327
|
+
appConfig={appConfig}
|
|
328
|
+
LogoComponent={CustomLogo}
|
|
329
|
+
>
|
|
220
330
|
<Navigator screenOptions={{ headerShown: false }}>
|
|
221
331
|
<Screen name="AuthNavigator" component={AuthNavigator} />
|
|
332
|
+
{/* Add your main app screens here after the auth flow */}
|
|
222
333
|
</Navigator>
|
|
223
334
|
</AuthProvider>
|
|
224
335
|
</NavigationContainer>
|
|
@@ -237,12 +348,33 @@ import type { LoginResponse } from "@truworth/twc-auth";
|
|
|
237
348
|
import type { AppProps } from "next/app";
|
|
238
349
|
|
|
239
350
|
export default function App({ Component, pageProps }: AppProps) {
|
|
351
|
+
|
|
352
|
+
// Callback for when the user successfully logs in.
|
|
240
353
|
const onLogin = (result: LoginResponse) => {
|
|
241
|
-
|
|
354
|
+
console.log("Login successful:", result.token);
|
|
355
|
+
// TODO: Store token (e.g., in an HTTP-only cookie) & redirect.
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
// Callback for when the user logs out.
|
|
359
|
+
const onLogout = () => {
|
|
360
|
+
console.log("User logged out");
|
|
361
|
+
// TODO: Clear token and redirect to the login page.
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// Configuration for your app's branding and support details.
|
|
365
|
+
const appConfig = {
|
|
366
|
+
appName: 'Your Web App',
|
|
367
|
+
supportEmail: 'support@yourwebapp.com',
|
|
368
|
+
privacyPolicyUrl: 'https://yourwebapp.com/privacy',
|
|
369
|
+
termsAndConditionsUrl: 'https://yourwebapp.com/terms'
|
|
242
370
|
};
|
|
243
371
|
|
|
244
372
|
return (
|
|
245
|
-
<AuthProvider
|
|
373
|
+
<AuthProvider
|
|
374
|
+
onLogin={onLogin}
|
|
375
|
+
onLogout={onLogout}
|
|
376
|
+
appConfig={appConfig}
|
|
377
|
+
>
|
|
246
378
|
<Component {...pageProps} />
|
|
247
379
|
</AuthProvider>
|
|
248
380
|
);
|
|
@@ -256,9 +388,39 @@ export default function App({ Component, pageProps }: AppProps) {
|
|
|
256
388
|
#### `useAuthContext()`
|
|
257
389
|
|
|
258
390
|
```typescript
|
|
259
|
-
const {
|
|
391
|
+
const {
|
|
392
|
+
token,
|
|
393
|
+
profile,
|
|
394
|
+
client,
|
|
395
|
+
isLoadingProfile,
|
|
396
|
+
logout,
|
|
397
|
+
onLaunchAuthSession,
|
|
398
|
+
getUserProfile,
|
|
399
|
+
onOtpReceived,
|
|
400
|
+
} = useAuthContext();
|
|
260
401
|
```
|
|
261
402
|
|
|
403
|
+
### Components
|
|
404
|
+
|
|
405
|
+
#### `<AuthProvider>`
|
|
406
|
+
|
|
407
|
+
The `AuthProvider` component provides authentication state and actions to its children. It should wrap the root of your application or the part of your app that requires authentication.
|
|
408
|
+
|
|
409
|
+
**Props**
|
|
410
|
+
|
|
411
|
+
| Prop | Type | Description |
|
|
412
|
+
| --------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
413
|
+
| `children` | `React.ReactNode` | React children to be rendered inside the provider. |
|
|
414
|
+
| `LogoComponent` | `React.ComponentType` | Optional component for branding/logo in auth flows. |
|
|
415
|
+
| `session` | `{ token: string }` | Initial session containing the auth token. |
|
|
416
|
+
| `appConfig` | `AppConfig` | Optional app configuration for auth flows (appName, supportEmail, privacyPolicyUrl, termsAndConditionsUrl). |
|
|
417
|
+
| `onLogin` | `(result: LoginResponse) => void` | Optional callback after a successful login. |
|
|
418
|
+
| `onLogout` | `() => void` | Optional callback after a successful logout. |
|
|
419
|
+
| `onLaunchAuthSession` | `() => void` | Optional callback after successfully launching the auth session. Can be used to set a Firebase notification token or request Android permissions, for example. |
|
|
420
|
+
| `onRefreshSession` | `(session: { token: string }) => void` | Optional handler for refreshing the user session. |
|
|
421
|
+
| `openChatSupport` | `() => void` | Optional callback to open chat support. |
|
|
422
|
+
| `socialLoginConfig` | `SocialLoginConfig` | Optional social login configuration. |
|
|
423
|
+
|
|
262
424
|
## Troubleshooting
|
|
263
425
|
|
|
264
426
|
### Common Issues
|
|
@@ -270,4 +432,4 @@ const { onLogin, logout, onLaunchAuthSession, LogoComponent } = useAuthContext()
|
|
|
270
432
|
- For Next.js, remove `.next` and restart: `rm -rf .next && next dev`
|
|
271
433
|
- For React Native: Ensure `babel.config.js` includes `plugins: ['react-native-reanimated/plugin']` as the last plugin
|
|
272
434
|
- For Next.js with Babel: Add `plugins: ['react-native-reanimated/plugin']` to your Babel config if using Babel (not needed with default SWC)
|
|
273
|
-
- For iOS CocoaPods issues: First try `cd ios && pod install` or clean the build folder in Xcode. Only use `pod deintegrate` as a last resort if other steps fail.
|
|
435
|
+
- For iOS CocoaPods issues: First try `cd ios && pod install` or clean the build folder in Xcode. Only use `pod deintegrate` as a last resort if other steps fail.
|
|
@@ -39,7 +39,7 @@ const AuthProvider = ({ children, LogoComponent, session, appConfig, onLogin, on
|
|
|
39
39
|
const [profile, setProfile] = useState(null);
|
|
40
40
|
const [client, setClient] = useState(null);
|
|
41
41
|
const [registrationMethod, setRegistrationMethod] = useState(null);
|
|
42
|
-
const [token, setToken] = useState('');
|
|
42
|
+
const [token, setToken] = useState(session?.token || '');
|
|
43
43
|
const [otpValue, setOtpValue] = useState('');
|
|
44
44
|
const { request } = useMemo(() => createHttpClient({
|
|
45
45
|
token,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import { showMessage } from '../helpers/show-message';
|
|
3
3
|
import { useAuthPackageContext } from './internal/useAuthPackageContext';
|
|
4
4
|
import { createHttpClient } from '../helpers/network';
|
|
@@ -10,9 +10,6 @@ const useRequest = () => {
|
|
|
10
10
|
onLogout: async () => logout(),
|
|
11
11
|
}), [token]);
|
|
12
12
|
const makeRequest = async ({ url, method, body, onSuccess, onFailure, ...axiosOptions }) => {
|
|
13
|
-
if (!token) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
13
|
try {
|
|
17
14
|
const response = await request({
|
|
18
15
|
url,
|
|
@@ -13,7 +13,7 @@ const CountryCode = () => {
|
|
|
13
13
|
const navigation = useNavigation();
|
|
14
14
|
const { countryCodes, searchCountry, onSearch } = useCountryCode();
|
|
15
15
|
const onSelect = (countryCode, iconCode) => {
|
|
16
|
-
navigation.
|
|
16
|
+
navigation.popTo(route.params?.prevRoute, {
|
|
17
17
|
...route.params,
|
|
18
18
|
countryCode,
|
|
19
19
|
iconCode,
|
|
@@ -49,7 +49,9 @@ const useEnterPassword = () => {
|
|
|
49
49
|
const errorMessage = error?.response?.data?.errors?.[0]?.message;
|
|
50
50
|
if (error?.response?.status === 400) {
|
|
51
51
|
setInvalidPassword(true);
|
|
52
|
-
|
|
52
|
+
if (source === 'web') {
|
|
53
|
+
showMessage({ message: errorMessage ?? 'Email and password do not match!' });
|
|
54
|
+
}
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
showMessage({ message: errorMessage ?? 'Something went wrong. Please try again.' });
|
|
@@ -45,9 +45,7 @@ const useLoginWithEmailOTP = ({ email, password, source, sessionToken, mfaEnable
|
|
|
45
45
|
}).then((res) => {
|
|
46
46
|
setStatus('valid');
|
|
47
47
|
const { token, member } = res.data;
|
|
48
|
-
|
|
49
|
-
onTokenChange(token);
|
|
50
|
-
}
|
|
48
|
+
onTokenChange(token);
|
|
51
49
|
onLogin({ token, member });
|
|
52
50
|
}).catch((error) => {
|
|
53
51
|
const errorCode = error?.response?.status;
|
|
@@ -7,7 +7,7 @@ const useLoginWithMobileOTP = ({ phone, email, source }) => {
|
|
|
7
7
|
const [timer, setTimer] = useState(180);
|
|
8
8
|
const [status, setStatus] = useState('timer');
|
|
9
9
|
const [sessionToken, setSessionToken] = useState('');
|
|
10
|
-
const { onLogin } = useAuthPackageContext();
|
|
10
|
+
const { onLogin, onTokenChange } = useAuthPackageContext();
|
|
11
11
|
useInterval(() => {
|
|
12
12
|
if (!timer) {
|
|
13
13
|
return;
|
|
@@ -42,6 +42,7 @@ const useLoginWithMobileOTP = ({ phone, email, source }) => {
|
|
|
42
42
|
}).then((res) => {
|
|
43
43
|
setStatus('valid');
|
|
44
44
|
const { token, member } = res.data;
|
|
45
|
+
onTokenChange(token);
|
|
45
46
|
onLogin({ token, member });
|
|
46
47
|
}).catch((error) => {
|
|
47
48
|
const errorCode = error?.response?.status;
|
|
@@ -13,7 +13,7 @@ const ResetPassword = ({ navigation, route }) => {
|
|
|
13
13
|
label: 'Continue',
|
|
14
14
|
onPress: () => {
|
|
15
15
|
handleContinue({
|
|
16
|
-
onResult: () => navigation.
|
|
16
|
+
onResult: () => navigation.popTo('EnterEmail')
|
|
17
17
|
});
|
|
18
18
|
},
|
|
19
19
|
disabled: isContinueDisabled
|
|
@@ -13,9 +13,9 @@ const { primary, gray } = Colors;
|
|
|
13
13
|
const SSOAuthenticationMethods = ({ route }) => {
|
|
14
14
|
const { client } = route.params;
|
|
15
15
|
const [aspectRatio, setAspectRatio] = useState(1);
|
|
16
|
-
const navigation = useNavigation();
|
|
17
16
|
const { loading, initiateSSOLogin } = useSSOAuthenticationMethods();
|
|
18
17
|
const { LogoComponent } = useAuthPackageContext();
|
|
18
|
+
const navigation = useNavigation();
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
if (client.image) {
|
|
21
21
|
Image.getSize(client.image, (width, height) => {
|
|
@@ -48,7 +48,7 @@ const SSOAuthenticationMethods = ({ route }) => {
|
|
|
48
48
|
return (_jsx(ScreenLayout, { title: "", containerStyle: { flex: 1, backgroundColor: primary.white }, children: _jsxs(View, { style: { flex: 1, justifyContent: 'center' }, children: [client.image ?
|
|
49
49
|
_jsx(FastImage, { source: { uri: client.image }, resizeMode: 'contain', style: { width: 180, aspectRatio: aspectRatio, alignSelf: 'center', marginTop: -150 } })
|
|
50
50
|
: renderLogo(), _jsx(Text, { style: { textAlign: 'center', fontSize: 24, fontWeight: '600', color: gray.gray_700, marginTop: 30 }, children: "Select how to sign-in" }), client?.ssoEnabled &&
|
|
51
|
-
_jsxs(_Fragment, { children: [_jsx(RoundedButton, { loading: loading, type: 'primary', label: 'Login with SSO', size: 'large', containerStyle: { marginTop: 40 }, onPress: () => initiateSSOLogin({ clientId: client.id, onSSOLoginInitiated }), leftIcon: 'key-outline' }), _jsx(Text, { style: { textAlign: 'center', fontSize: 14, color: gray.gray_700, marginTop: 20 }, children: "Recommended for quick access" }), _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: 30, marginHorizontal: 30 }, children: [_jsx(View, { style: { flex: 1, height: 1, backgroundColor: gray.gray_200 } }), _jsx(View, { children: _jsx(Text, { style: { width: 50, textAlign: 'center', color: gray.gray_500, fontSize: 16 }, children: "OR" }) }), _jsx(View, { style: { flex: 1, height: 1, backgroundColor: gray.gray_200 } })] })] }), _jsx(RoundedButton, { type: 'secondary', label: 'Login with Email & Password', size: 'large', containerStyle: { marginTop: 30 }, onPress: () => navigation.
|
|
51
|
+
_jsxs(_Fragment, { children: [_jsx(RoundedButton, { loading: loading, type: 'primary', label: 'Login with SSO', size: 'large', containerStyle: { marginTop: 40 }, onPress: () => initiateSSOLogin({ clientId: client.id, onSSOLoginInitiated }), leftIcon: 'key-outline' }), _jsx(Text, { style: { textAlign: 'center', fontSize: 14, color: gray.gray_700, marginTop: 20 }, children: "Recommended for quick access" }), _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: 30, marginHorizontal: 30 }, children: [_jsx(View, { style: { flex: 1, height: 1, backgroundColor: gray.gray_200 } }), _jsx(View, { children: _jsx(Text, { style: { width: 50, textAlign: 'center', color: gray.gray_500, fontSize: 16 }, children: "OR" }) }), _jsx(View, { style: { flex: 1, height: 1, backgroundColor: gray.gray_200 } })] })] }), _jsx(RoundedButton, { type: 'secondary', label: 'Login with Email & Password', size: 'large', containerStyle: { marginTop: 30 }, onPress: () => navigation.popTo('EnterEmail'), leftIcon: 'mail-outline' }), client?.mobileLoginEnabled &&
|
|
52
52
|
_jsx(RoundedButton, { type: 'text', label: 'Login with Mobile Number', size: 'large', containerStyle: { marginHorizontal: 16, marginTop: 30 }, onPress: () => navigation.navigate('EnterMobile'), leftIcon: 'phone-portrait-outline' })] }) }));
|
|
53
53
|
};
|
|
54
54
|
export default SSOAuthenticationMethods;
|
|
@@ -11,7 +11,7 @@ import { RegistrationMethod } from "../../../../../enums";
|
|
|
11
11
|
const useSSOCallback = ({ clientId, code }) => {
|
|
12
12
|
const [error, setError] = useState(null);
|
|
13
13
|
const [result, setResult] = useState(null);
|
|
14
|
-
const { onLogin, onRegistrationMethodChange } = useAuthPackageContext();
|
|
14
|
+
const { onLogin, onRegistrationMethodChange, onTokenChange } = useAuthPackageContext();
|
|
15
15
|
const processOAuthCallback = useCallback((code) => {
|
|
16
16
|
setError(null);
|
|
17
17
|
axiosClient({
|
|
@@ -24,6 +24,7 @@ const useSSOCallback = ({ clientId, code }) => {
|
|
|
24
24
|
setResult(res.data);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
+
onTokenChange(res?.data?.token);
|
|
27
28
|
return onLogin({ token: res?.data?.token, member: res?.data?.member });
|
|
28
29
|
}
|
|
29
30
|
}).catch((error) => {
|
|
@@ -171,7 +171,7 @@ const LinkedAccountsSheet = ({ visible, hide, linkedAccounts, countryCode, phone
|
|
|
171
171
|
shadowOpacity: 0.5,
|
|
172
172
|
shadowRadius: 3,
|
|
173
173
|
elevation: 3
|
|
174
|
-
}, children: [_jsx(RoundedButton, { label: "Go to Login", size: "large", onPress: () => navigation.
|
|
174
|
+
}, children: [_jsx(RoundedButton, { label: "Go to Login", size: "large", onPress: () => navigation.popTo('EnterEmail'), containerStyle: { marginBottom: 8 } }), openChatSupport &&
|
|
175
175
|
_jsxs(TouchableOpacity, { activeOpacity: 0.8, onPress: openChatSupport, style: {
|
|
176
176
|
flexDirection: 'row',
|
|
177
177
|
alignItems: 'center',
|
|
@@ -20,11 +20,12 @@ const UserConsent = ({ userDetails, handleBack }) => {
|
|
|
20
20
|
const [showVerifyMobileModal, setShowVerifyMobileModal] = useState(false);
|
|
21
21
|
const [showVerifyEmailModal, setShowVerifyEmailModal] = useState(false);
|
|
22
22
|
const [sessionToken, setSessionToken] = useState('');
|
|
23
|
-
const { onLogin, appConfig: { appName, privacyPolicyUrl }, LogoComponent } = useAuthPackageContext();
|
|
23
|
+
const { onLogin, appConfig: { appName, privacyPolicyUrl }, LogoComponent, onTokenChange } = useAuthPackageContext();
|
|
24
24
|
const { loading, onAgree } = useConsent();
|
|
25
25
|
const onAgreeHandler = (res) => {
|
|
26
26
|
const { token, member, emailVerificationRequired, mobileVerificationRequired, sessionToken } = res;
|
|
27
27
|
if (token && member) {
|
|
28
|
+
onTokenChange(token);
|
|
28
29
|
return onLogin({ token, member });
|
|
29
30
|
}
|
|
30
31
|
if (emailVerificationRequired) {
|
|
@@ -8,11 +8,12 @@ import { useConsent } from './hooks/internal/useConsent';
|
|
|
8
8
|
const { primary, gray } = Colors;
|
|
9
9
|
const UserConsent = ({ navigation, route }) => {
|
|
10
10
|
const { email, phone } = route.params || {};
|
|
11
|
-
const { onLogin, appConfig: { appName, privacyPolicyUrl } } = useAuthPackageContext();
|
|
11
|
+
const { onLogin, appConfig: { appName, privacyPolicyUrl }, onTokenChange } = useAuthPackageContext();
|
|
12
12
|
const { loading, onAgree } = useConsent();
|
|
13
13
|
const onAgreeHandler = (res) => {
|
|
14
14
|
const { token, member, emailVerificationRequired, mobileVerificationRequired, sessionToken } = res;
|
|
15
15
|
if (token && member) {
|
|
16
|
+
onTokenChange(token);
|
|
16
17
|
return onLogin({ token, member });
|
|
17
18
|
}
|
|
18
19
|
if (emailVerificationRequired) {
|
|
@@ -12,7 +12,7 @@ const initialTimer = 180;
|
|
|
12
12
|
const useVerifyLinkPrimaryAccountMobileOTP = ({ sessionToken }) => {
|
|
13
13
|
const [status, setStatus] = useState('timer');
|
|
14
14
|
const [timer, setTimer] = useState(initialTimer);
|
|
15
|
-
const { onLogin } = useAuthPackageContext();
|
|
15
|
+
const { onLogin, onTokenChange } = useAuthPackageContext();
|
|
16
16
|
const invalidTimerRef = useRef(null);
|
|
17
17
|
const sessionTokenRef = useRef(sessionToken);
|
|
18
18
|
useInterval(() => {
|
|
@@ -47,6 +47,7 @@ const useVerifyLinkPrimaryAccountMobileOTP = ({ sessionToken }) => {
|
|
|
47
47
|
}).then((res) => {
|
|
48
48
|
const { token, member } = res.data;
|
|
49
49
|
setStatus('valid');
|
|
50
|
+
onTokenChange(token);
|
|
50
51
|
onLogin({ token, member });
|
|
51
52
|
}).catch((err) => {
|
|
52
53
|
if (err?.response?.status === 400) {
|
|
@@ -13,7 +13,7 @@ const useVerifyMobile = ({ sessionToken }) => {
|
|
|
13
13
|
const [sessionTokenState, setSessionToken] = useState(sessionToken || '');
|
|
14
14
|
const [timer, setTimer] = useState(initialTimer);
|
|
15
15
|
const [status, setStatus] = useState('timer');
|
|
16
|
-
const { onLogin } = useAuthPackageContext();
|
|
16
|
+
const { onLogin, onTokenChange } = useAuthPackageContext();
|
|
17
17
|
useEffect(() => {
|
|
18
18
|
resendOTP();
|
|
19
19
|
}, []);
|
|
@@ -48,6 +48,7 @@ const useVerifyMobile = ({ sessionToken }) => {
|
|
|
48
48
|
data: { otp, sessionToken: sessionTokenState },
|
|
49
49
|
}).then((res) => {
|
|
50
50
|
const { token, member } = res.data;
|
|
51
|
+
onTokenChange(token);
|
|
51
52
|
onLogin({ token, member });
|
|
52
53
|
setStatus('valid');
|
|
53
54
|
}).catch((err) => {
|
|
@@ -11,7 +11,7 @@ import appleAuth from '@invertase/react-native-apple-authentication';
|
|
|
11
11
|
import { axiosClient } from "../../../../api/axiosClient";
|
|
12
12
|
const useSocialAuth = () => {
|
|
13
13
|
const [loading, setLoading] = useState(false);
|
|
14
|
-
const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
|
|
14
|
+
const { onLogin, socialLoginConfig, onRegistrationMethodChange, onTokenChange } = useAuthPackageContext();
|
|
15
15
|
const navigation = useNavigation();
|
|
16
16
|
const googleAppId = socialLoginConfig?.google?.webClientId;
|
|
17
17
|
const loginWithGoogle = useCallback(async () => {
|
|
@@ -107,10 +107,8 @@ const useSocialAuth = () => {
|
|
|
107
107
|
token: appleAuthResponse.identityToken,
|
|
108
108
|
source: Platform.OS,
|
|
109
109
|
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
member: data.member
|
|
113
|
-
});
|
|
110
|
+
onTokenChange(data.token);
|
|
111
|
+
onLogin({ token: data.token, member: data.member });
|
|
114
112
|
return;
|
|
115
113
|
}
|
|
116
114
|
catch (error) {
|
|
@@ -174,10 +172,8 @@ const useSocialAuth = () => {
|
|
|
174
172
|
type: 'error'
|
|
175
173
|
});
|
|
176
174
|
case SocialAuthStatus.SUCCESS:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
member: result.data.member
|
|
180
|
-
});
|
|
175
|
+
onTokenChange(result.data.token);
|
|
176
|
+
onLogin({ token: result.data.token, member: result.data.member });
|
|
181
177
|
break;
|
|
182
178
|
}
|
|
183
179
|
};
|
|
@@ -6,7 +6,7 @@ import { handleFacebookAuth } from "../../commonSocialAuth";
|
|
|
6
6
|
import { showMessage } from "../../../../../helpers/show-message";
|
|
7
7
|
export const useFacebookAuth = () => {
|
|
8
8
|
const [error, setError] = useState(null);
|
|
9
|
-
const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
|
|
9
|
+
const { onLogin, socialLoginConfig, onRegistrationMethodChange, onTokenChange } = useAuthPackageContext();
|
|
10
10
|
const router = useRouter();
|
|
11
11
|
const facebookAppId = socialLoginConfig?.facebook?.webClientId;
|
|
12
12
|
// Load Facebook SDK once
|
|
@@ -95,10 +95,8 @@ export const useFacebookAuth = () => {
|
|
|
95
95
|
type: "error",
|
|
96
96
|
});
|
|
97
97
|
case "SUCCESS":
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
member: result.data.member
|
|
101
|
-
});
|
|
98
|
+
onTokenChange(result.data.token);
|
|
99
|
+
onLogin({ token: result.data.token, member: result.data.member });
|
|
102
100
|
break;
|
|
103
101
|
}
|
|
104
102
|
});
|
|
@@ -7,7 +7,7 @@ import { useRouter } from "next/router";
|
|
|
7
7
|
import { handleGoogleAuth } from "../../commonSocialAuth";
|
|
8
8
|
export const useGoogleAuth = () => {
|
|
9
9
|
const router = useRouter();
|
|
10
|
-
const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
|
|
10
|
+
const { onLogin, socialLoginConfig, onRegistrationMethodChange, onTokenChange } = useAuthPackageContext();
|
|
11
11
|
const googleAppId = socialLoginConfig?.google?.webClientId;
|
|
12
12
|
const onSuccess = async (response) => {
|
|
13
13
|
const { tokenId, profileObj, googleId } = response;
|
|
@@ -36,10 +36,8 @@ export const useGoogleAuth = () => {
|
|
|
36
36
|
type: "error",
|
|
37
37
|
});
|
|
38
38
|
case "SUCCESS":
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
member: result.data.member
|
|
42
|
-
});
|
|
39
|
+
onTokenChange(result.data.token);
|
|
40
|
+
onLogin({ token: result.data.token, member: result.data.member });
|
|
43
41
|
break;
|
|
44
42
|
}
|
|
45
43
|
};
|
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": "1.2.
|
|
7
|
+
"version": "1.2.12-beta.0",
|
|
8
8
|
"main": "build/src/index.js",
|
|
9
9
|
"types": "build/types/index.d.ts",
|
|
10
10
|
"files": [
|
|
@@ -24,13 +24,11 @@
|
|
|
24
24
|
"@react-native-clipboard/clipboard": "1.16.3",
|
|
25
25
|
"@react-native-community/datetimepicker": "8.1.1",
|
|
26
26
|
"@react-native-google-signin/google-signin": "12.2.1",
|
|
27
|
-
"@react-navigation/native": "
|
|
28
|
-
"@react-navigation/native-stack": "
|
|
29
|
-
"@truworth/twc-rn-common": "1.1.
|
|
27
|
+
"@react-navigation/native": "7.1.17",
|
|
28
|
+
"@react-navigation/native-stack": "7.3.26",
|
|
29
|
+
"@truworth/twc-rn-common": "1.1.3-beta.4",
|
|
30
30
|
"@truworth/twc-web-design": "1.11.0",
|
|
31
31
|
"@twotalltotems/react-native-otp-input": "1.3.11",
|
|
32
|
-
"@types/crypto-js": "^4.2.2",
|
|
33
|
-
"@types/fbemitter": "^2.0.35",
|
|
34
32
|
"@types/lodash": "^4.17.15",
|
|
35
33
|
"@types/react": "^18.2.0",
|
|
36
34
|
"@types/react-google-recaptcha": "^2.1.9",
|
|
@@ -41,28 +39,26 @@
|
|
|
41
39
|
"copyfiles": "^2.4.1",
|
|
42
40
|
"crypto-js": "^4.2.0",
|
|
43
41
|
"del-cli": "^6.0.0",
|
|
44
|
-
"fbemitter": "^3.0.0",
|
|
45
|
-
"js-crypto-rsa": "^1.0.7",
|
|
46
42
|
"lottie-react": "^2.4.1",
|
|
47
|
-
"lottie-react-native": "
|
|
43
|
+
"lottie-react-native": "7.2.4",
|
|
48
44
|
"moment": "^2.30.1",
|
|
49
|
-
"next": "15.5.
|
|
50
|
-
"react": "
|
|
51
|
-
"react-
|
|
45
|
+
"next": "15.5.10",
|
|
46
|
+
"react": "19.1.0",
|
|
47
|
+
"react-native": "0.80.2",
|
|
48
|
+
"react-dom": "^19.1.0",
|
|
52
49
|
"react-google-login": "^5.2.2",
|
|
53
50
|
"react-google-recaptcha": "^3.1.0",
|
|
54
51
|
"react-infinite-scroll-component": "^6.1.0",
|
|
55
52
|
"react-lottie": "^1.2.3",
|
|
56
|
-
"react-native": "0.76.1",
|
|
57
53
|
"react-native-fast-image": "8.6.3",
|
|
58
54
|
"react-native-fbsdk-next": "13.4.1",
|
|
59
55
|
"react-native-linear-gradient": "2.8.3",
|
|
60
56
|
"react-native-modalize": "2.1.1",
|
|
61
57
|
"react-native-parsed-text": "^0.0.22",
|
|
62
|
-
"react-native-reanimated": "
|
|
58
|
+
"react-native-reanimated": "4.1.0",
|
|
63
59
|
"react-native-rsa-native": "2.0.5",
|
|
64
|
-
"react-native-safe-area-context": "
|
|
65
|
-
"react-native-svg": "15.
|
|
60
|
+
"react-native-safe-area-context": "5.6.1",
|
|
61
|
+
"react-native-svg": "15.12.0",
|
|
66
62
|
"react-native-vector-icons": "9.2.0",
|
|
67
63
|
"react-redux": "^9.2.0",
|
|
68
64
|
"sweetalert2": "^11.23.0",
|
|
@@ -93,5 +89,8 @@
|
|
|
93
89
|
"react-native-safe-area-context": ">=5.3.0",
|
|
94
90
|
"react-native-svg": ">=15.8.0",
|
|
95
91
|
"react-native-vector-icons": ">=9.2.0"
|
|
92
|
+
},
|
|
93
|
+
"overrides": {
|
|
94
|
+
"prismjs": "1.30.0"
|
|
96
95
|
}
|
|
97
96
|
}
|