dauth-context-react 2.2.0 → 2.3.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.
@@ -6,21 +6,31 @@ import {
6
6
  sendEmailVerificationAPI,
7
7
  updateUserAPI,
8
8
  } from '../api/dauth.api';
9
- import { TOKEN_LS, REFRESH_TOKEN_LS } from '../constants';
10
- import { IDauthDomainState, IDauthUser } from '../interfaces';
9
+ import {
10
+ IDauthDomainState,
11
+ IDauthStorageKeys,
12
+ IDauthUser,
13
+ } from '../interfaces';
11
14
  import * as DauthTypes from './dauth.types';
12
15
 
13
- type TSetDauthStateAction = {
16
+ export interface ActionContext {
14
17
  dispatch: React.Dispatch<any>;
18
+ domainName: string;
19
+ storageKeys: IDauthStorageKeys;
20
+ onError: (error: Error) => void;
21
+ }
22
+
23
+ type TSetDauthStateAction = ActionContext & {
15
24
  token: string;
16
25
  refreshToken: string;
17
- domainName: string;
18
26
  };
19
27
  export async function setDauthStateAction({
20
28
  dispatch,
21
29
  token,
22
30
  refreshToken,
23
31
  domainName,
32
+ storageKeys,
33
+ onError,
24
34
  }: TSetDauthStateAction) {
25
35
  dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
26
36
  try {
@@ -35,15 +45,15 @@ export async function setDauthStateAction({
35
45
  },
36
46
  });
37
47
  window.history.replaceState({}, document.title, window.location.pathname);
38
- localStorage.setItem(TOKEN_LS, token);
39
- localStorage.setItem(REFRESH_TOKEN_LS, refreshToken);
48
+ localStorage.setItem(storageKeys.accessToken, token);
49
+ localStorage.setItem(storageKeys.refreshToken, refreshToken);
40
50
  return;
41
51
  } else {
42
- return resetUser(dispatch);
52
+ return resetUser(dispatch, storageKeys);
43
53
  }
44
54
  } catch (error) {
45
- console.error(error);
46
- return resetUser(dispatch);
55
+ onError(error instanceof Error ? error : new Error(String(error)));
56
+ return resetUser(dispatch, storageKeys);
47
57
  } finally {
48
58
  dispatch({
49
59
  type: DauthTypes.SET_IS_LOADING,
@@ -52,30 +62,28 @@ export async function setDauthStateAction({
52
62
  }
53
63
  }
54
64
 
55
- type TSetAutoLoginAction = {
56
- dispatch: React.Dispatch<any>;
57
- domainName: string;
58
- };
59
65
  export async function setAutoLoginAction({
60
66
  dispatch,
61
67
  domainName,
62
- }: TSetAutoLoginAction) {
68
+ storageKeys,
69
+ onError,
70
+ }: ActionContext) {
63
71
  dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
64
- const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
72
+ const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);
65
73
  if (!storedRefreshToken) {
66
74
  dispatch({
67
75
  type: DauthTypes.SET_IS_LOADING,
68
76
  payload: { isLoading: false },
69
77
  });
70
- return resetUser(dispatch);
78
+ return resetUser(dispatch, storageKeys);
71
79
  }
72
80
  try {
73
81
  const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);
74
82
  if (refreshResult.response.status === 200) {
75
83
  const newAccessToken = refreshResult.data.accessToken;
76
84
  const newRefreshToken = refreshResult.data.refreshToken;
77
- localStorage.setItem(TOKEN_LS, newAccessToken);
78
- localStorage.setItem(REFRESH_TOKEN_LS, newRefreshToken);
85
+ localStorage.setItem(storageKeys.accessToken, newAccessToken);
86
+ localStorage.setItem(storageKeys.refreshToken, newRefreshToken);
79
87
  const getUserFetch = await getUserAPI(domainName, newAccessToken);
80
88
  if (getUserFetch.response.status === 200) {
81
89
  dispatch({
@@ -90,10 +98,10 @@ export async function setAutoLoginAction({
90
98
  }
91
99
  }
92
100
  // Refresh failed — session expired
93
- resetUser(dispatch);
101
+ resetUser(dispatch, storageKeys);
94
102
  } catch (error) {
95
- console.error(error);
96
- resetUser(dispatch);
103
+ onError(error instanceof Error ? error : new Error(String(error)));
104
+ resetUser(dispatch, storageKeys);
97
105
  } finally {
98
106
  dispatch({
99
107
  type: DauthTypes.SET_IS_LOADING,
@@ -105,11 +113,9 @@ export async function setAutoLoginAction({
105
113
  export async function setLogoutAction({
106
114
  dispatch,
107
115
  domainName,
108
- }: {
109
- dispatch: React.Dispatch<any>;
110
- domainName: string;
111
- }) {
112
- const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
116
+ storageKeys,
117
+ }: Omit<ActionContext, 'onError'>) {
118
+ const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);
113
119
  if (storedRefreshToken && domainName) {
114
120
  try {
115
121
  await logoutAPI(domainName, storedRefreshToken);
@@ -128,8 +134,8 @@ export async function setLogoutAction({
128
134
  isAuthenticated: false,
129
135
  },
130
136
  });
131
- localStorage.removeItem(TOKEN_LS);
132
- localStorage.removeItem(REFRESH_TOKEN_LS);
137
+ localStorage.removeItem(storageKeys.accessToken);
138
+ localStorage.removeItem(storageKeys.refreshToken);
133
139
  return dispatch({
134
140
  type: DauthTypes.SET_IS_LOADING,
135
141
  payload: { isLoading: false },
@@ -139,32 +145,35 @@ export async function setLogoutAction({
139
145
  export async function refreshSessionAction({
140
146
  dispatch,
141
147
  domainName,
142
- }: {
143
- dispatch: React.Dispatch<any>;
144
- domainName: string;
145
- }) {
146
- const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
148
+ storageKeys,
149
+ onError,
150
+ }: ActionContext) {
151
+ const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);
147
152
  if (!storedRefreshToken) {
148
- return resetUser(dispatch);
153
+ return resetUser(dispatch, storageKeys);
149
154
  }
150
155
  try {
151
156
  const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);
152
157
  if (refreshResult.response.status === 200) {
153
- localStorage.setItem(TOKEN_LS, refreshResult.data.accessToken);
154
- localStorage.setItem(REFRESH_TOKEN_LS, refreshResult.data.refreshToken);
158
+ localStorage.setItem(
159
+ storageKeys.accessToken,
160
+ refreshResult.data.accessToken
161
+ );
162
+ localStorage.setItem(
163
+ storageKeys.refreshToken,
164
+ refreshResult.data.refreshToken
165
+ );
155
166
  return;
156
167
  }
157
168
  // Refresh failed — revoked or expired
158
- resetUser(dispatch);
169
+ resetUser(dispatch, storageKeys);
159
170
  } catch (error) {
160
- console.error(error);
161
- resetUser(dispatch);
171
+ onError(error instanceof Error ? error : new Error(String(error)));
172
+ resetUser(dispatch, storageKeys);
162
173
  }
163
174
  }
164
175
 
165
- type TSetUpdateAction = {
166
- dispatch: React.Dispatch<any>;
167
- domainName: string;
176
+ type TSetUpdateAction = ActionContext & {
168
177
  user: Partial<IDauthUser>;
169
178
  token: string | null;
170
179
  };
@@ -173,6 +182,7 @@ export async function setUpdateUserAction({
173
182
  domainName,
174
183
  user,
175
184
  token,
185
+ onError,
176
186
  }: TSetUpdateAction) {
177
187
  if (user.language) {
178
188
  window.document.documentElement.setAttribute('lang', user.language);
@@ -193,18 +203,18 @@ export async function setUpdateUserAction({
193
203
  });
194
204
  return true;
195
205
  } else {
196
- console.error('Update user error', getUserFetch.data.message);
206
+ onError(new Error('Update user error: ' + getUserFetch.data.message));
197
207
  return false;
198
208
  }
199
209
  } catch (error) {
200
- console.error('Update user error', error);
210
+ onError(
211
+ error instanceof Error ? error : new Error('Update user error')
212
+ );
201
213
  return false;
202
214
  }
203
215
  }
204
216
 
205
- type TSetSendEmailVerificationAction = {
206
- dispatch: React.Dispatch<any>;
207
- domainName: string;
217
+ type TSetSendEmailVerificationAction = ActionContext & {
208
218
  token: string;
209
219
  };
210
220
  export async function sendEmailVerificationAction({
@@ -243,7 +253,7 @@ export async function sendEmailVerificationAction({
243
253
  });
244
254
  return false;
245
255
  }
246
- } catch (error) {
256
+ } catch (_) {
247
257
  dispatch({
248
258
  type: DauthTypes.SET_SEND_EMAIL_VERIFICATION_STATUS,
249
259
  payload: {
@@ -262,11 +272,10 @@ export async function sendEmailVerificationAction({
262
272
  export async function getAccessTokenAction({
263
273
  dispatch,
264
274
  domainName,
265
- }: {
266
- dispatch: React.Dispatch<any>;
267
- domainName: string;
268
- }) {
269
- const token_ls = localStorage.getItem(TOKEN_LS);
275
+ storageKeys,
276
+ onError,
277
+ }: ActionContext) {
278
+ const token_ls = localStorage.getItem(storageKeys.accessToken);
270
279
  if (!token_ls) return 'token-not-found';
271
280
  // Decode JWT to check expiry (without verification — that's the server's job)
272
281
  try {
@@ -276,8 +285,13 @@ export async function getAccessTokenAction({
276
285
  const expiresIn = (payload.exp || 0) * 1000 - Date.now();
277
286
  // If token expires in less than 5 minutes, refresh proactively
278
287
  if (expiresIn < 5 * 60 * 1000) {
279
- await refreshSessionAction({ dispatch, domainName });
280
- const refreshedToken = localStorage.getItem(TOKEN_LS);
288
+ await refreshSessionAction({
289
+ dispatch,
290
+ domainName,
291
+ storageKeys,
292
+ onError,
293
+ });
294
+ const refreshedToken = localStorage.getItem(storageKeys.accessToken);
281
295
  return refreshedToken || 'token-not-found';
282
296
  }
283
297
  }
@@ -290,30 +304,33 @@ export async function getAccessTokenAction({
290
304
  export async function deleteAccountAction({
291
305
  dispatch,
292
306
  domainName,
307
+ storageKeys,
308
+ onError,
293
309
  token,
294
- }: {
295
- dispatch: React.Dispatch<any>;
296
- domainName: string;
297
- token: string;
298
- }) {
310
+ }: ActionContext & { token: string }) {
299
311
  try {
300
312
  const result = await deleteAccountAPI(domainName, token);
301
313
  if (result.response.status === 200) {
302
- resetUser(dispatch);
314
+ resetUser(dispatch, storageKeys);
303
315
  return true;
304
316
  }
305
317
  return false;
306
318
  } catch (error) {
307
- console.error('Delete account error', error);
319
+ onError(
320
+ error instanceof Error ? error : new Error('Delete account error')
321
+ );
308
322
  return false;
309
323
  }
310
324
  }
311
325
 
312
326
  ///////////////////////////////////////////
313
327
  //////////////////////////////////////////
314
- export const resetUser = (dispatch: React.Dispatch<any>) => {
315
- localStorage.removeItem(TOKEN_LS);
316
- localStorage.removeItem(REFRESH_TOKEN_LS);
328
+ export const resetUser = (
329
+ dispatch: React.Dispatch<any>,
330
+ storageKeys: IDauthStorageKeys
331
+ ) => {
332
+ localStorage.removeItem(storageKeys.accessToken);
333
+ localStorage.removeItem(storageKeys.refreshToken);
317
334
  return dispatch({
318
335
  type: DauthTypes.LOGIN,
319
336
  payload: {
@@ -1,11 +0,0 @@
1
- import { IDauthUser } from '../interfaces';
2
- import { IdeleteAccountAPIResponse, IgetUserAPIResponse, IrefreshAccessTokenAPIResponse, IrefreshTokenAPIResponse, IsendEmailVerificationAPIResponse, IupdateUserAPIResponse } from './interfaces/dauth.api.responses';
3
- export declare const getUserAPI: (domainName: string, token: string) => Promise<IgetUserAPIResponse>;
4
- export declare const updateUserAPI: (domainName: string, user: Partial<IDauthUser>, token: string) => Promise<IupdateUserAPIResponse>;
5
- export declare const sendEmailVerificationAPI: (domainName: string, token: string) => Promise<IsendEmailVerificationAPIResponse>;
6
- export declare const refreshAccessTokenAPI: (domainName: string, token: string) => Promise<IrefreshAccessTokenAPIResponse>;
7
- export declare const refreshTokenAPI: (domainName: string, refreshToken: string) => Promise<IrefreshTokenAPIResponse>;
8
- export declare const deleteAccountAPI: (domainName: string, token: string) => Promise<IdeleteAccountAPIResponse>;
9
- export declare const logoutAPI: (domainName: string, refreshToken: string) => Promise<{
10
- response: Response;
11
- }>;
@@ -1,45 +0,0 @@
1
- import { IDauthDomainState, IDauthUser } from '../../interfaces';
2
- export interface IdeleteAccountAPIResponse {
3
- response: Response;
4
- data: {
5
- status: string;
6
- message: string;
7
- };
8
- }
9
- export interface IgetUserAPIResponse {
10
- response: Response;
11
- data: {
12
- status: string;
13
- user: IDauthUser;
14
- domain: IDauthDomainState;
15
- };
16
- }
17
- export interface IupdateUserAPIResponse {
18
- response: Response;
19
- data: {
20
- status: string;
21
- user: IDauthUser;
22
- message: string;
23
- };
24
- }
25
- export interface IsendEmailVerificationAPIResponse {
26
- response: Response;
27
- data: {
28
- status: string;
29
- message: string;
30
- emailStatus: string;
31
- };
32
- }
33
- export interface IrefreshAccessTokenAPIResponse {
34
- response: Response;
35
- data: {
36
- accessToken: string;
37
- };
38
- }
39
- export interface IrefreshTokenAPIResponse {
40
- response: Response;
41
- data: {
42
- accessToken: string;
43
- refreshToken: string;
44
- };
45
- }
@@ -1,4 +0,0 @@
1
- export declare const apiVersion = "v1";
2
- export declare const serverDomain = "dauth.ovh";
3
- export declare function getServerBasePath(): string;
4
- export declare function getClientBasePath(): string;
@@ -1,4 +0,0 @@
1
- export declare const routes: {
2
- signin: string;
3
- updateUser: string;
4
- };
@@ -1,2 +0,0 @@
1
- export declare const TOKEN_LS = "dauth_state";
2
- export declare const REFRESH_TOKEN_LS = "dauth_refresh_token";