dauth-context-react 4.0.4 → 6.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/README.md +101 -228
- package/dist/index.d.mts +15 -8
- package/dist/index.d.ts +15 -8
- package/dist/index.js +914 -393
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +920 -395
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -1
- package/src/DauthProfileModal.tsx +875 -0
- package/src/api/dauth.api.ts +66 -97
- package/src/api/interfaces/dauth.api.responses.ts +9 -18
- package/src/api/utils/config.ts +9 -14
- package/src/api/utils/routes.ts +0 -1
- package/src/constants.ts +0 -2
- package/src/index.tsx +37 -134
- package/src/initialDauthState.ts +0 -2
- package/src/interfaces.ts +14 -12
- package/src/reducer/dauth.actions.ts +60 -187
|
@@ -1,33 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
deleteAccountAPI,
|
|
3
2
|
exchangeCodeAPI,
|
|
4
|
-
|
|
3
|
+
getSessionAPI,
|
|
5
4
|
logoutAPI,
|
|
6
|
-
refreshTokenAPI,
|
|
7
5
|
updateUserAPI,
|
|
6
|
+
deleteAccountAPI,
|
|
8
7
|
} from '../api/dauth.api';
|
|
9
|
-
import {
|
|
10
|
-
IDauthDomainState,
|
|
11
|
-
IDauthStorageKeys,
|
|
12
|
-
IDauthUser,
|
|
13
|
-
} from '../interfaces';
|
|
8
|
+
import { IDauthDomainState, IDauthUser } from '../interfaces';
|
|
14
9
|
import * as DauthTypes from './dauth.types';
|
|
15
10
|
|
|
16
11
|
export interface ActionContext {
|
|
17
12
|
dispatch: React.Dispatch<any>;
|
|
18
|
-
|
|
19
|
-
storageKeys: IDauthStorageKeys;
|
|
13
|
+
authProxyPath: string;
|
|
20
14
|
onError: (error: Error) => void;
|
|
21
15
|
}
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
dispatch,
|
|
26
|
-
code,
|
|
27
|
-
domainName,
|
|
28
|
-
storageKeys,
|
|
29
|
-
onError,
|
|
30
|
-
}: TExchangeCodeAction) {
|
|
17
|
+
export async function exchangeCodeAction(ctx: ActionContext, code: string) {
|
|
18
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
31
19
|
dispatch({
|
|
32
20
|
type: DauthTypes.SET_IS_LOADING,
|
|
33
21
|
payload: { isLoading: true },
|
|
@@ -35,29 +23,22 @@ export async function exchangeCodeAction({
|
|
|
35
23
|
try {
|
|
36
24
|
// Clean URL immediately (before any fetch)
|
|
37
25
|
window.history.replaceState({}, document.title, window.location.pathname);
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
return resetUser(dispatch, storageKeys);
|
|
41
|
-
}
|
|
42
|
-
const { accessToken, refreshToken } = exchangeResult.data;
|
|
43
|
-
localStorage.setItem(storageKeys.accessToken, accessToken);
|
|
44
|
-
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
45
|
-
const getUserFetch = await getUserAPI(domainName, accessToken);
|
|
46
|
-
if (getUserFetch.response.status === 200) {
|
|
26
|
+
const result = await exchangeCodeAPI(authProxyPath, code);
|
|
27
|
+
if (result.response.status === 200) {
|
|
47
28
|
dispatch({
|
|
48
29
|
type: DauthTypes.LOGIN,
|
|
49
30
|
payload: {
|
|
50
|
-
user:
|
|
51
|
-
domain:
|
|
31
|
+
user: result.data.user,
|
|
32
|
+
domain: result.data.domain,
|
|
52
33
|
isAuthenticated: true,
|
|
53
34
|
},
|
|
54
35
|
});
|
|
55
36
|
return;
|
|
56
37
|
}
|
|
57
|
-
|
|
38
|
+
resetUser(dispatch);
|
|
58
39
|
} catch (error) {
|
|
59
40
|
onError(error instanceof Error ? error : new Error(String(error)));
|
|
60
|
-
|
|
41
|
+
resetUser(dispatch);
|
|
61
42
|
} finally {
|
|
62
43
|
dispatch({
|
|
63
44
|
type: DauthTypes.SET_IS_LOADING,
|
|
@@ -66,46 +47,30 @@ export async function exchangeCodeAction({
|
|
|
66
47
|
}
|
|
67
48
|
}
|
|
68
49
|
|
|
69
|
-
export async function
|
|
70
|
-
dispatch,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });
|
|
76
|
-
const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);
|
|
77
|
-
if (!storedRefreshToken) {
|
|
78
|
-
dispatch({
|
|
79
|
-
type: DauthTypes.SET_IS_LOADING,
|
|
80
|
-
payload: { isLoading: false },
|
|
81
|
-
});
|
|
82
|
-
return resetUser(dispatch, storageKeys);
|
|
83
|
-
}
|
|
50
|
+
export async function autoLoginAction(ctx: ActionContext) {
|
|
51
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
52
|
+
dispatch({
|
|
53
|
+
type: DauthTypes.SET_IS_LOADING,
|
|
54
|
+
payload: { isLoading: true },
|
|
55
|
+
});
|
|
84
56
|
try {
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
user: getUserFetch.data.user,
|
|
97
|
-
domain: getUserFetch.data.domain,
|
|
98
|
-
isAuthenticated: true,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
57
|
+
const result = await getSessionAPI(authProxyPath);
|
|
58
|
+
if (result.response.status === 200) {
|
|
59
|
+
dispatch({
|
|
60
|
+
type: DauthTypes.LOGIN,
|
|
61
|
+
payload: {
|
|
62
|
+
user: result.data.user,
|
|
63
|
+
domain: result.data.domain,
|
|
64
|
+
isAuthenticated: true,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
103
68
|
}
|
|
104
|
-
//
|
|
105
|
-
resetUser(dispatch
|
|
69
|
+
// No session — not authenticated (not an error)
|
|
70
|
+
resetUser(dispatch);
|
|
106
71
|
} catch (error) {
|
|
107
72
|
onError(error instanceof Error ? error : new Error(String(error)));
|
|
108
|
-
resetUser(dispatch
|
|
73
|
+
resetUser(dispatch);
|
|
109
74
|
} finally {
|
|
110
75
|
dispatch({
|
|
111
76
|
type: DauthTypes.SET_IS_LOADING,
|
|
@@ -114,20 +79,17 @@ export async function setAutoLoginAction({
|
|
|
114
79
|
}
|
|
115
80
|
}
|
|
116
81
|
|
|
117
|
-
export async function
|
|
118
|
-
dispatch,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (storedRefreshToken && domainName) {
|
|
124
|
-
try {
|
|
125
|
-
await logoutAPI(domainName, storedRefreshToken);
|
|
126
|
-
} catch (_) {
|
|
127
|
-
// Best-effort server-side logout
|
|
128
|
-
}
|
|
82
|
+
export async function logoutAction(ctx: ActionContext) {
|
|
83
|
+
const { dispatch, authProxyPath } = ctx;
|
|
84
|
+
try {
|
|
85
|
+
await logoutAPI(authProxyPath);
|
|
86
|
+
} catch {
|
|
87
|
+
// Best-effort server-side logout
|
|
129
88
|
}
|
|
130
|
-
dispatch({
|
|
89
|
+
dispatch({
|
|
90
|
+
type: DauthTypes.SET_IS_LOADING,
|
|
91
|
+
payload: { isLoading: true },
|
|
92
|
+
});
|
|
131
93
|
dispatch({
|
|
132
94
|
type: DauthTypes.LOGIN,
|
|
133
95
|
payload: {
|
|
@@ -138,127 +100,45 @@ export async function setLogoutAction({
|
|
|
138
100
|
isAuthenticated: false,
|
|
139
101
|
},
|
|
140
102
|
});
|
|
141
|
-
|
|
142
|
-
localStorage.removeItem(storageKeys.refreshToken);
|
|
143
|
-
return dispatch({
|
|
103
|
+
dispatch({
|
|
144
104
|
type: DauthTypes.SET_IS_LOADING,
|
|
145
105
|
payload: { isLoading: false },
|
|
146
106
|
});
|
|
147
107
|
}
|
|
148
108
|
|
|
149
|
-
export async function
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
onError
|
|
154
|
-
}: ActionContext) {
|
|
155
|
-
const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);
|
|
156
|
-
if (!storedRefreshToken) {
|
|
157
|
-
return resetUser(dispatch, storageKeys);
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);
|
|
161
|
-
if (refreshResult.response.status === 200) {
|
|
162
|
-
localStorage.setItem(
|
|
163
|
-
storageKeys.accessToken,
|
|
164
|
-
refreshResult.data.accessToken
|
|
165
|
-
);
|
|
166
|
-
localStorage.setItem(
|
|
167
|
-
storageKeys.refreshToken,
|
|
168
|
-
refreshResult.data.refreshToken
|
|
169
|
-
);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
// Refresh failed — revoked or expired
|
|
173
|
-
resetUser(dispatch, storageKeys);
|
|
174
|
-
} catch (error) {
|
|
175
|
-
onError(error instanceof Error ? error : new Error(String(error)));
|
|
176
|
-
resetUser(dispatch, storageKeys);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
type TSetUpdateAction = ActionContext & {
|
|
181
|
-
user: Partial<IDauthUser>;
|
|
182
|
-
token: string | null;
|
|
183
|
-
};
|
|
184
|
-
export async function setUpdateUserAction({
|
|
185
|
-
dispatch,
|
|
186
|
-
domainName,
|
|
187
|
-
user,
|
|
188
|
-
token,
|
|
189
|
-
onError,
|
|
190
|
-
}: TSetUpdateAction) {
|
|
109
|
+
export async function updateUserAction(
|
|
110
|
+
ctx: ActionContext,
|
|
111
|
+
user: Partial<IDauthUser>
|
|
112
|
+
): Promise<boolean> {
|
|
113
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
191
114
|
if (user.language) {
|
|
192
115
|
window.document.documentElement.setAttribute('lang', user.language);
|
|
193
116
|
}
|
|
194
|
-
if (!token) {
|
|
195
|
-
dispatch({
|
|
196
|
-
type: DauthTypes.UPDATE_USER,
|
|
197
|
-
payload: user,
|
|
198
|
-
});
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
117
|
try {
|
|
202
|
-
const
|
|
203
|
-
if (
|
|
118
|
+
const result = await updateUserAPI(authProxyPath, user);
|
|
119
|
+
if (result.response.status === 200) {
|
|
204
120
|
dispatch({
|
|
205
121
|
type: DauthTypes.UPDATE_USER,
|
|
206
|
-
payload:
|
|
122
|
+
payload: result.data.user,
|
|
207
123
|
});
|
|
208
124
|
return true;
|
|
209
|
-
} else {
|
|
210
|
-
onError(new Error('Update user error: ' + getUserFetch.data.message));
|
|
211
|
-
return false;
|
|
212
125
|
}
|
|
126
|
+
onError(new Error('Update user error: ' + result.data.message));
|
|
127
|
+
return false;
|
|
213
128
|
} catch (error) {
|
|
214
129
|
onError(error instanceof Error ? error : new Error('Update user error'));
|
|
215
130
|
return false;
|
|
216
131
|
}
|
|
217
132
|
}
|
|
218
133
|
|
|
219
|
-
export async function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
onError,
|
|
224
|
-
}: ActionContext) {
|
|
225
|
-
const token_ls = localStorage.getItem(storageKeys.accessToken);
|
|
226
|
-
if (!token_ls) return 'token-not-found';
|
|
227
|
-
// Decode JWT to check expiry (without verification — that's the server's job)
|
|
228
|
-
try {
|
|
229
|
-
const payloadB64 = token_ls.split('.')[1];
|
|
230
|
-
if (payloadB64) {
|
|
231
|
-
const payload = JSON.parse(atob(payloadB64));
|
|
232
|
-
const expiresIn = (payload.exp || 0) * 1000 - Date.now();
|
|
233
|
-
// If token expires in less than 5 minutes, refresh proactively
|
|
234
|
-
if (expiresIn < 5 * 60 * 1000) {
|
|
235
|
-
await refreshSessionAction({
|
|
236
|
-
dispatch,
|
|
237
|
-
domainName,
|
|
238
|
-
storageKeys,
|
|
239
|
-
onError,
|
|
240
|
-
});
|
|
241
|
-
const refreshedToken = localStorage.getItem(storageKeys.accessToken);
|
|
242
|
-
return refreshedToken || 'token-not-found';
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
} catch (_) {
|
|
246
|
-
// If decode fails, return stored token and let server validate
|
|
247
|
-
}
|
|
248
|
-
return token_ls;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export async function deleteAccountAction({
|
|
252
|
-
dispatch,
|
|
253
|
-
domainName,
|
|
254
|
-
storageKeys,
|
|
255
|
-
onError,
|
|
256
|
-
token,
|
|
257
|
-
}: ActionContext & { token: string }) {
|
|
134
|
+
export async function deleteAccountAction(
|
|
135
|
+
ctx: ActionContext
|
|
136
|
+
): Promise<boolean> {
|
|
137
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
258
138
|
try {
|
|
259
|
-
const result = await deleteAccountAPI(
|
|
139
|
+
const result = await deleteAccountAPI(authProxyPath);
|
|
260
140
|
if (result.response.status === 200) {
|
|
261
|
-
resetUser(dispatch
|
|
141
|
+
resetUser(dispatch);
|
|
262
142
|
return true;
|
|
263
143
|
}
|
|
264
144
|
return false;
|
|
@@ -268,14 +148,7 @@ export async function deleteAccountAction({
|
|
|
268
148
|
}
|
|
269
149
|
}
|
|
270
150
|
|
|
271
|
-
|
|
272
|
-
//////////////////////////////////////////
|
|
273
|
-
export const resetUser = (
|
|
274
|
-
dispatch: React.Dispatch<any>,
|
|
275
|
-
storageKeys: IDauthStorageKeys
|
|
276
|
-
) => {
|
|
277
|
-
localStorage.removeItem(storageKeys.accessToken);
|
|
278
|
-
localStorage.removeItem(storageKeys.refreshToken);
|
|
151
|
+
export const resetUser = (dispatch: React.Dispatch<any>) => {
|
|
279
152
|
return dispatch({
|
|
280
153
|
type: DauthTypes.LOGIN,
|
|
281
154
|
payload: {
|