dauth-context-react 2.5.0 → 4.0.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/src/index.tsx CHANGED
@@ -11,7 +11,7 @@ import initialDauthState from './initialDauthState';
11
11
  import userReducer from './reducer/dauth.reducer';
12
12
  import * as action from './reducer/dauth.actions';
13
13
  import { getClientBasePath, setDauthUrl } from './api/utils/config';
14
- import { TOKEN_LS, REFRESH_TOKEN_LS } from './constants';
14
+ import { TOKEN_LS, REFRESH_TOKEN_LS, AUTH_CODE_PARAM } from './constants';
15
15
  import { routes } from './api/utils/routes';
16
16
  import type {
17
17
  IDauthProviderProps,
@@ -28,8 +28,7 @@ const defaultOnError = (error: Error) => console.error(error);
28
28
  export const DauthProvider: React.FC<IDauthProviderProps> = (
29
29
  props: IDauthProviderProps
30
30
  ) => {
31
- const { domainName, children, storageKey, onError, env, dauthUrl } =
32
- props;
31
+ const { domainName, children, storageKey, onError, env, dauthUrl } = props;
33
32
  const [dauthState, dispatch] = useReducer(userReducer, initialDauthState);
34
33
  const refreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
35
34
 
@@ -75,27 +74,25 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
75
74
  }, refreshIn);
76
75
  } catch (_) {
77
76
  // If decode fails, retry in 5 minutes
78
- refreshTimerRef.current = setTimeout(async () => {
79
- await action.refreshSessionAction(ctx);
80
- scheduleRefresh();
81
- }, 5 * 60 * 1000);
77
+ refreshTimerRef.current = setTimeout(
78
+ async () => {
79
+ await action.refreshSessionAction(ctx);
80
+ scheduleRefresh();
81
+ },
82
+ 5 * 60 * 1000
83
+ );
82
84
  }
83
85
  }, [ctx, storageKeys.accessToken]);
84
86
 
85
- // Catch login redirect
87
+ // Catch login redirect — exchange authorization code for tokens
86
88
  useEffect(() => {
87
89
  (async () => {
88
90
  const queryString = window.location.search;
89
91
  if (!queryString) return;
90
92
  const urlParams = new URLSearchParams(queryString);
91
- const token_url = urlParams.get(storageKeys.accessToken);
92
- const refresh_url = urlParams.get(storageKeys.refreshToken);
93
- if (token_url && refresh_url && !dauthState.isAuthenticated) {
94
- return action.setDauthStateAction({
95
- ...ctx,
96
- token: token_url,
97
- refreshToken: refresh_url,
98
- });
93
+ const code = urlParams.get(AUTH_CODE_PARAM);
94
+ if (code && !dauthState.isAuthenticated) {
95
+ return action.exchangeCodeAction({ ...ctx, code });
99
96
  }
100
97
  })();
101
98
  }, []);
@@ -127,9 +124,7 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
127
124
 
128
125
  const loginWithRedirect = useCallback(() => {
129
126
  const base = `${getClientBasePath()}/${domainName}/${routes.signin}`;
130
- const url = env
131
- ? `${base}?env=${encodeURIComponent(env)}`
132
- : base;
127
+ const url = env ? `${base}?env=${encodeURIComponent(env)}` : base;
133
128
  return window.location.replace(url);
134
129
  }, [domainName, env]);
135
130
 
@@ -191,15 +186,6 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
191
186
  );
192
187
  }, [domainName, storageKeys.accessToken]);
193
188
 
194
- const sendEmailVerification = useCallback(async () => {
195
- const token_ls = localStorage.getItem(storageKeys.accessToken);
196
- if (!token_ls) return false;
197
- return (await action.sendEmailVerificationAction({
198
- ...ctx,
199
- token: token_ls,
200
- })) as boolean;
201
- }, [ctx, storageKeys.accessToken]);
202
-
203
189
  const deleteAccount = useCallback(async () => {
204
190
  const token_ls = localStorage.getItem(storageKeys.accessToken);
205
191
  if (!token_ls) return false;
@@ -218,7 +204,6 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
218
204
  getAccessToken,
219
205
  updateUser,
220
206
  updateUserWithRedirect,
221
- sendEmailVerification,
222
207
  deleteAccount,
223
208
  }),
224
209
  [
@@ -228,7 +213,6 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
228
213
  getAccessToken,
229
214
  updateUser,
230
215
  updateUserWithRedirect,
231
- sendEmailVerification,
232
216
  deleteAccount,
233
217
  ]
234
218
  );
@@ -1,9 +1,4 @@
1
- import {
2
- IActionStatus,
3
- IDauthDomainState,
4
- IDauthState,
5
- IDauthUser,
6
- } from './interfaces';
1
+ import { IDauthDomainState, IDauthState, IDauthUser } from './interfaces';
7
2
 
8
3
  const initialDauthState: IDauthState = {
9
4
  user: {
@@ -20,15 +15,6 @@ const initialDauthState: IDauthState = {
20
15
  getAccessToken: () => Promise.resolve(''),
21
16
  updateUser: () => Promise.resolve(false),
22
17
  updateUserWithRedirect: () => {},
23
- // Send email verification
24
- sendEmailVerificationStatus: {
25
- status: {
26
- type: 'info',
27
- message: 'Sending email verification...',
28
- } as IActionStatus,
29
- isLoading: false,
30
- },
31
- sendEmailVerification: () => Promise.resolve(false),
32
18
  deleteAccount: () => Promise.resolve(false),
33
19
  };
34
20
 
package/src/interfaces.ts CHANGED
@@ -27,7 +27,6 @@ export interface IDauthDomainEnvironment {
27
27
  }
28
28
 
29
29
  export interface IDauthAuthMethods {
30
- password: boolean;
31
30
  magicLink: boolean;
32
31
  passkey: boolean;
33
32
  }
@@ -50,12 +49,6 @@ export interface IDauthState {
50
49
  getAccessToken: () => Promise<string>;
51
50
  updateUser: (fields: Partial<IDauthUser>) => Promise<boolean>;
52
51
  updateUserWithRedirect: () => void;
53
- // Send email verification
54
- sendEmailVerificationStatus: {
55
- status: IActionStatus;
56
- isLoading: boolean;
57
- };
58
- sendEmailVerification: () => Promise<boolean>;
59
52
  deleteAccount: () => Promise<boolean>;
60
53
  }
61
54
 
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deleteAccountAPI,
3
+ exchangeCodeAPI,
3
4
  getUserAPI,
4
5
  logoutAPI,
5
6
  refreshTokenAPI,
6
- sendEmailVerificationAPI,
7
7
  updateUserAPI,
8
8
  } from '../api/dauth.api';
9
9
  import {
@@ -62,6 +62,58 @@ export async function setDauthStateAction({
62
62
  }
63
63
  }
64
64
 
65
+ type TExchangeCodeAction = ActionContext & { code: string };
66
+ export async function exchangeCodeAction({
67
+ dispatch,
68
+ code,
69
+ domainName,
70
+ storageKeys,
71
+ onError,
72
+ }: TExchangeCodeAction) {
73
+ dispatch({
74
+ type: DauthTypes.SET_IS_LOADING,
75
+ payload: { isLoading: true },
76
+ });
77
+ try {
78
+ // Clean URL immediately (before any fetch)
79
+ window.history.replaceState(
80
+ {},
81
+ document.title,
82
+ window.location.pathname
83
+ );
84
+ const exchangeResult = await exchangeCodeAPI(domainName, code);
85
+ if (exchangeResult.response.status !== 200) {
86
+ return resetUser(dispatch, storageKeys);
87
+ }
88
+ const { accessToken, refreshToken } = exchangeResult.data;
89
+ localStorage.setItem(storageKeys.accessToken, accessToken);
90
+ localStorage.setItem(storageKeys.refreshToken, refreshToken);
91
+ const getUserFetch = await getUserAPI(domainName, accessToken);
92
+ if (getUserFetch.response.status === 200) {
93
+ dispatch({
94
+ type: DauthTypes.LOGIN,
95
+ payload: {
96
+ user: getUserFetch.data.user,
97
+ domain: getUserFetch.data.domain,
98
+ isAuthenticated: true,
99
+ },
100
+ });
101
+ return;
102
+ }
103
+ return resetUser(dispatch, storageKeys);
104
+ } catch (error) {
105
+ onError(
106
+ error instanceof Error ? error : new Error(String(error))
107
+ );
108
+ return resetUser(dispatch, storageKeys);
109
+ } finally {
110
+ dispatch({
111
+ type: DauthTypes.SET_IS_LOADING,
112
+ payload: { isLoading: false },
113
+ });
114
+ }
115
+ }
116
+
65
117
  export async function setAutoLoginAction({
66
118
  dispatch,
67
119
  domainName,
@@ -207,64 +259,7 @@ export async function setUpdateUserAction({
207
259
  return false;
208
260
  }
209
261
  } catch (error) {
210
- onError(
211
- error instanceof Error ? error : new Error('Update user error')
212
- );
213
- return false;
214
- }
215
- }
216
-
217
- type TSetSendEmailVerificationAction = ActionContext & {
218
- token: string;
219
- };
220
- export async function sendEmailVerificationAction({
221
- dispatch,
222
- domainName,
223
- token,
224
- }: TSetSendEmailVerificationAction) {
225
- dispatch({
226
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_IS_LOADING,
227
- payload: true,
228
- });
229
- dispatch({
230
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS,
231
- payload: { type: 'info', message: 'Sending email verification...' },
232
- });
233
- try {
234
- const sendEmailFetch = await sendEmailVerificationAPI(domainName, token);
235
- if (sendEmailFetch.response.status === 200) {
236
- dispatch({
237
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS,
238
- payload: { type: 'success', message: sendEmailFetch.data.message },
239
- });
240
- dispatch({
241
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_IS_LOADING,
242
- payload: false,
243
- });
244
- return true;
245
- } else {
246
- dispatch({
247
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS,
248
- payload: { type: 'error', message: sendEmailFetch.data.message },
249
- });
250
- dispatch({
251
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_IS_LOADING,
252
- payload: false,
253
- });
254
- return false;
255
- }
256
- } catch (_) {
257
- dispatch({
258
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS,
259
- payload: {
260
- type: 'error',
261
- message: 'Send email verification fetch error',
262
- },
263
- });
264
- dispatch({
265
- type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_IS_LOADING,
266
- payload: false,
267
- });
262
+ onError(error instanceof Error ? error : new Error('Update user error'));
268
263
  return false;
269
264
  }
270
265
  }
@@ -316,9 +311,7 @@ export async function deleteAccountAction({
316
311
  }
317
312
  return false;
318
313
  } catch (error) {
319
- onError(
320
- error instanceof Error ? error : new Error('Delete account error')
321
- );
314
+ onError(error instanceof Error ? error : new Error('Delete account error'));
322
315
  return false;
323
316
  }
324
317
  }
@@ -34,31 +34,6 @@ export default function userReducer(state: IDauthState, action: any) {
34
34
  return updateUser;
35
35
  }
36
36
 
37
- case DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS: {
38
- const setSendEmailVerificationStatus: IDauthState = {
39
- ...state,
40
- sendEmailVerificationStatus: {
41
- ...state.sendEmailVerificationStatus,
42
- status: {
43
- type: payload.type,
44
- message: payload.message,
45
- },
46
- },
47
- };
48
- return setSendEmailVerificationStatus;
49
- }
50
-
51
- case DauthTypes.SET_SEND_EMAIL_VERIFICATION_IS_LOADING: {
52
- const setSendEmailVerificationIsLoading: IDauthState = {
53
- ...state,
54
- sendEmailVerificationStatus: {
55
- ...state.sendEmailVerificationStatus,
56
- isLoading: payload,
57
- },
58
- };
59
- return setSendEmailVerificationIsLoading;
60
- }
61
-
62
37
  default:
63
38
  return state;
64
39
  }
@@ -1,7 +1,3 @@
1
1
  export const LOGIN = 'LOGIN';
2
2
  export const SET_IS_LOADING = 'SET_IS_LOADING';
3
3
  export const UPDATE_USER = 'UPDATE_USER';
4
- export const SET_SEND_EMAIL_VERIFICATION_IS_LOADING =
5
- 'SET_SEND_EMAIL_VERIFICATION_IS_LOADING';
6
- export const SET_SEND_EMAIL_VERIFICATION_STATUS =
7
- 'SET_SEND_EMAIL_VERIFICATION_STATUS';