dauth-context-react 1.0.2 → 2.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/dist/api/dauth.api.d.ts +5 -6
- package/dist/api/interfaces/dauth.api.responses.d.ts +3 -3
- package/dist/constants.d.ts +1 -0
- package/dist/dauth-context-react.cjs.development.js +564 -805
- package/dist/dauth-context-react.cjs.development.js.map +1 -1
- package/dist/dauth-context-react.cjs.production.min.js +1 -1
- package/dist/dauth-context-react.cjs.production.min.js.map +1 -1
- package/dist/dauth-context-react.esm.js +565 -806
- package/dist/dauth-context-react.esm.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/reducer/dauth.actions.d.ts +11 -11
- package/package.json +1 -1
- package/src/api/dauth.api.ts +24 -16
- package/src/api/interfaces/dauth.api.responses.ts +3 -3
- package/src/constants.ts +1 -0
- package/src/index.tsx +53 -71
- package/src/reducer/dauth.actions.ts +83 -83
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getUserAPI,
|
|
3
|
-
|
|
3
|
+
logoutAPI,
|
|
4
|
+
refreshTokenAPI,
|
|
4
5
|
sendEmailVerificationAPI,
|
|
5
6
|
updateUserAPI,
|
|
6
7
|
} from '../api/dauth.api';
|
|
7
|
-
import {
|
|
8
|
-
import { TOKEN_LS } from '../constants';
|
|
8
|
+
import { TOKEN_LS, REFRESH_TOKEN_LS } from '../constants';
|
|
9
9
|
import { IDauthDomainState, IDauthUser } from '../interfaces';
|
|
10
|
-
import { routes } from '../api/utils/routes';
|
|
11
10
|
import * as DauthTypes from './dauth.types';
|
|
12
11
|
|
|
13
12
|
type TSetDauthStateAction = {
|
|
14
13
|
dispatch: React.Dispatch<any>;
|
|
15
14
|
token: string;
|
|
15
|
+
refreshToken: string;
|
|
16
16
|
domainName: string;
|
|
17
17
|
};
|
|
18
18
|
export async function setDauthStateAction({
|
|
19
19
|
dispatch,
|
|
20
20
|
token,
|
|
21
|
+
refreshToken,
|
|
21
22
|
domainName,
|
|
22
23
|
}: TSetDauthStateAction) {
|
|
23
24
|
dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
|
|
@@ -32,12 +33,10 @@ export async function setDauthStateAction({
|
|
|
32
33
|
isAuthenticated: true,
|
|
33
34
|
},
|
|
34
35
|
});
|
|
35
|
-
window.history.replaceState(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
);
|
|
40
|
-
return localStorage.setItem(TOKEN_LS, token);
|
|
36
|
+
window.history.replaceState({}, document.title, window.location.pathname);
|
|
37
|
+
localStorage.setItem(TOKEN_LS, token);
|
|
38
|
+
localStorage.setItem(REFRESH_TOKEN_LS, refreshToken);
|
|
39
|
+
return;
|
|
41
40
|
} else {
|
|
42
41
|
return resetUser(dispatch);
|
|
43
42
|
}
|
|
@@ -54,23 +53,29 @@ export async function setDauthStateAction({
|
|
|
54
53
|
|
|
55
54
|
type TSetAutoLoginAction = {
|
|
56
55
|
dispatch: React.Dispatch<any>;
|
|
57
|
-
token_ls: string;
|
|
58
56
|
domainName: string;
|
|
59
57
|
};
|
|
60
58
|
export async function setAutoLoginAction({
|
|
61
59
|
dispatch,
|
|
62
|
-
token_ls,
|
|
63
60
|
domainName,
|
|
64
61
|
}: TSetAutoLoginAction) {
|
|
65
62
|
dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
|
|
63
|
+
const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
|
|
64
|
+
if (!storedRefreshToken) {
|
|
65
|
+
dispatch({
|
|
66
|
+
type: DauthTypes.SET_IS_LOADING,
|
|
67
|
+
payload: { isLoading: false },
|
|
68
|
+
});
|
|
69
|
+
return resetUser(dispatch);
|
|
70
|
+
}
|
|
66
71
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const getUserFetch = await getUserAPI(domainName,
|
|
72
|
+
const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);
|
|
73
|
+
if (refreshResult.response.status === 200) {
|
|
74
|
+
const newAccessToken = refreshResult.data.accessToken;
|
|
75
|
+
const newRefreshToken = refreshResult.data.refreshToken;
|
|
76
|
+
localStorage.setItem(TOKEN_LS, newAccessToken);
|
|
77
|
+
localStorage.setItem(REFRESH_TOKEN_LS, newRefreshToken);
|
|
78
|
+
const getUserFetch = await getUserAPI(domainName, newAccessToken);
|
|
74
79
|
if (getUserFetch.response.status === 200) {
|
|
75
80
|
dispatch({
|
|
76
81
|
type: DauthTypes.LOGIN,
|
|
@@ -80,26 +85,14 @@ export async function setAutoLoginAction({
|
|
|
80
85
|
isAuthenticated: true,
|
|
81
86
|
},
|
|
82
87
|
});
|
|
83
|
-
localStorage.setItem(
|
|
84
|
-
TOKEN_LS,
|
|
85
|
-
refreshAccessTokenFetch.data.accessToken
|
|
86
|
-
);
|
|
87
88
|
return;
|
|
88
|
-
} else {
|
|
89
|
-
window.location.replace(
|
|
90
|
-
`${getClientBasePath()}/${domainName}/${routes.signin}`
|
|
91
|
-
);
|
|
92
|
-
return resetUser(dispatch);
|
|
93
89
|
}
|
|
94
|
-
} else {
|
|
95
|
-
window.location.replace(
|
|
96
|
-
`${getClientBasePath()}/${domainName}/${routes.signin}`
|
|
97
|
-
);
|
|
98
|
-
return resetUser(dispatch);
|
|
99
90
|
}
|
|
91
|
+
// Refresh failed — session expired
|
|
92
|
+
resetUser(dispatch);
|
|
100
93
|
} catch (error) {
|
|
101
94
|
console.error(error);
|
|
102
|
-
|
|
95
|
+
resetUser(dispatch);
|
|
103
96
|
} finally {
|
|
104
97
|
dispatch({
|
|
105
98
|
type: DauthTypes.SET_IS_LOADING,
|
|
@@ -108,29 +101,67 @@ export async function setAutoLoginAction({
|
|
|
108
101
|
}
|
|
109
102
|
}
|
|
110
103
|
|
|
111
|
-
export function setLogoutAction({
|
|
104
|
+
export async function setLogoutAction({
|
|
112
105
|
dispatch,
|
|
106
|
+
domainName,
|
|
113
107
|
}: {
|
|
114
108
|
dispatch: React.Dispatch<any>;
|
|
109
|
+
domainName: string;
|
|
115
110
|
}) {
|
|
111
|
+
const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
|
|
112
|
+
if (storedRefreshToken && domainName) {
|
|
113
|
+
try {
|
|
114
|
+
await logoutAPI(domainName, storedRefreshToken);
|
|
115
|
+
} catch (_) {
|
|
116
|
+
// Best-effort server-side logout
|
|
117
|
+
}
|
|
118
|
+
}
|
|
116
119
|
dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
|
|
117
120
|
dispatch({
|
|
118
121
|
type: DauthTypes.LOGIN,
|
|
119
122
|
payload: {
|
|
120
123
|
user: {
|
|
121
|
-
language:
|
|
124
|
+
language:
|
|
125
|
+
window.document.documentElement.getAttribute('lang') || 'es',
|
|
122
126
|
},
|
|
123
127
|
domain: {},
|
|
124
128
|
isAuthenticated: false,
|
|
125
129
|
},
|
|
126
130
|
});
|
|
127
131
|
localStorage.removeItem(TOKEN_LS);
|
|
132
|
+
localStorage.removeItem(REFRESH_TOKEN_LS);
|
|
128
133
|
return dispatch({
|
|
129
134
|
type: DauthTypes.SET_IS_LOADING,
|
|
130
135
|
payload: { isLoading: false },
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
|
|
139
|
+
export async function refreshSessionAction({
|
|
140
|
+
dispatch,
|
|
141
|
+
domainName,
|
|
142
|
+
}: {
|
|
143
|
+
dispatch: React.Dispatch<any>;
|
|
144
|
+
domainName: string;
|
|
145
|
+
}) {
|
|
146
|
+
const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_LS);
|
|
147
|
+
if (!storedRefreshToken) {
|
|
148
|
+
return resetUser(dispatch);
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);
|
|
152
|
+
if (refreshResult.response.status === 200) {
|
|
153
|
+
localStorage.setItem(TOKEN_LS, refreshResult.data.accessToken);
|
|
154
|
+
localStorage.setItem(REFRESH_TOKEN_LS, refreshResult.data.refreshToken);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Refresh failed — revoked or expired
|
|
158
|
+
resetUser(dispatch);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error(error);
|
|
161
|
+
resetUser(dispatch);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
134
165
|
type TSetUpdateAction = {
|
|
135
166
|
dispatch: React.Dispatch<any>;
|
|
136
167
|
domainName: string;
|
|
@@ -228,40 +259,6 @@ export async function sendEmailVerificationAction({
|
|
|
228
259
|
}
|
|
229
260
|
}
|
|
230
261
|
|
|
231
|
-
export async function checkTokenAction({
|
|
232
|
-
dispatch,
|
|
233
|
-
domainName,
|
|
234
|
-
token,
|
|
235
|
-
}: {
|
|
236
|
-
dispatch: React.Dispatch<any>;
|
|
237
|
-
domainName: string;
|
|
238
|
-
token: string;
|
|
239
|
-
}) {
|
|
240
|
-
try {
|
|
241
|
-
const refreshAccessTokenFetch = await refreshAccessTokenAPI(
|
|
242
|
-
domainName,
|
|
243
|
-
token
|
|
244
|
-
);
|
|
245
|
-
if (refreshAccessTokenFetch.response.status === 200) {
|
|
246
|
-
if (refreshAccessTokenFetch.data.accessToken) {
|
|
247
|
-
localStorage.setItem(
|
|
248
|
-
TOKEN_LS,
|
|
249
|
-
refreshAccessTokenFetch.data.accessToken
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
return;
|
|
253
|
-
} else {
|
|
254
|
-
window.location.replace(
|
|
255
|
-
`${getClientBasePath()}/${domainName}/${routes.signin}`
|
|
256
|
-
);
|
|
257
|
-
return resetUser(dispatch);
|
|
258
|
-
}
|
|
259
|
-
} catch (error) {
|
|
260
|
-
resetUser(dispatch);
|
|
261
|
-
throw error;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
262
|
export async function getAccessTokenAction({
|
|
266
263
|
dispatch,
|
|
267
264
|
domainName,
|
|
@@ -270,28 +267,31 @@ export async function getAccessTokenAction({
|
|
|
270
267
|
domainName: string;
|
|
271
268
|
}) {
|
|
272
269
|
const token_ls = localStorage.getItem(TOKEN_LS);
|
|
273
|
-
if (!token_ls) return;
|
|
270
|
+
if (!token_ls) return 'token-not-found';
|
|
271
|
+
// Decode JWT to check expiry (without verification — that's the server's job)
|
|
274
272
|
try {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
273
|
+
const payloadB64 = token_ls.split('.')[1];
|
|
274
|
+
if (payloadB64) {
|
|
275
|
+
const payload = JSON.parse(atob(payloadB64));
|
|
276
|
+
const expiresIn = (payload.exp || 0) * 1000 - Date.now();
|
|
277
|
+
// If token expires in less than 5 minutes, refresh proactively
|
|
278
|
+
if (expiresIn < 5 * 60 * 1000) {
|
|
279
|
+
await refreshSessionAction({ dispatch, domainName });
|
|
280
|
+
const refreshedToken = localStorage.getItem(TOKEN_LS);
|
|
281
|
+
return refreshedToken || 'token-not-found';
|
|
282
|
+
}
|
|
284
283
|
}
|
|
285
|
-
} catch (
|
|
286
|
-
|
|
287
|
-
throw error;
|
|
284
|
+
} catch (_) {
|
|
285
|
+
// If decode fails, return stored token and let server validate
|
|
288
286
|
}
|
|
287
|
+
return token_ls;
|
|
289
288
|
}
|
|
290
289
|
|
|
291
290
|
///////////////////////////////////////////
|
|
292
291
|
//////////////////////////////////////////
|
|
293
292
|
export const resetUser = (dispatch: React.Dispatch<any>) => {
|
|
294
293
|
localStorage.removeItem(TOKEN_LS);
|
|
294
|
+
localStorage.removeItem(REFRESH_TOKEN_LS);
|
|
295
295
|
return dispatch({
|
|
296
296
|
type: DauthTypes.LOGIN,
|
|
297
297
|
payload: {
|