@spidy092/auth-client 1.0.12 → 1.0.14
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/core.js +87 -53
- package/index.js +5 -2
- package/package.json +1 -1
- package/token.js +70 -0
package/core.js
CHANGED
|
@@ -2,56 +2,9 @@
|
|
|
2
2
|
import { setToken, clearToken, getToken } from './token';
|
|
3
3
|
import { getConfig, isRouterMode } from './config';
|
|
4
4
|
|
|
5
|
-
// ✅ Track
|
|
5
|
+
// ✅ Track callback state with listeners
|
|
6
6
|
let callbackProcessed = false;
|
|
7
7
|
|
|
8
|
-
export function handleCallback() {
|
|
9
|
-
const params = new URLSearchParams(window.location.search);
|
|
10
|
-
const accessToken = params.get('access_token');
|
|
11
|
-
const error = params.get('error');
|
|
12
|
-
|
|
13
|
-
console.log('🔄 Handling authentication callback:', {
|
|
14
|
-
mode: isRouterMode() ? 'ROUTER' : 'CLIENT',
|
|
15
|
-
hasAccessToken: !!accessToken,
|
|
16
|
-
error,
|
|
17
|
-
alreadyProcessed: callbackProcessed // ✅ Log if already processed
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// ✅ If already processed and we have a token, return it
|
|
21
|
-
if (callbackProcessed) {
|
|
22
|
-
const existingToken = getToken();
|
|
23
|
-
if (existingToken) {
|
|
24
|
-
console.log('🔄 Callback already processed, returning existing token');
|
|
25
|
-
return existingToken;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ✅ Mark as processed first
|
|
30
|
-
callbackProcessed = true;
|
|
31
|
-
|
|
32
|
-
// Clean up session storage (only once)
|
|
33
|
-
sessionStorage.removeItem('originalApp');
|
|
34
|
-
sessionStorage.removeItem('returnUrl');
|
|
35
|
-
|
|
36
|
-
if (error) {
|
|
37
|
-
throw new Error(`Authentication failed: ${error}`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (accessToken) {
|
|
41
|
-
setToken(accessToken);
|
|
42
|
-
console.log('✅ Token set successfully');
|
|
43
|
-
return accessToken;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
throw new Error('No access token found in callback URL');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// ✅ Reset callback state when needed
|
|
50
|
-
export function resetCallbackState() {
|
|
51
|
-
callbackProcessed = false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Your other functions remain the same...
|
|
55
8
|
export function login(clientKeyArg, redirectUriArg) {
|
|
56
9
|
// ✅ Reset callback state when starting new login
|
|
57
10
|
resetCallbackState();
|
|
@@ -80,10 +33,12 @@ export function login(clientKeyArg, redirectUriArg) {
|
|
|
80
33
|
sessionStorage.setItem('originalApp', clientKey);
|
|
81
34
|
sessionStorage.setItem('returnUrl', redirectUri);
|
|
82
35
|
|
|
83
|
-
// Smart Router Logic
|
|
36
|
+
// ✅ Smart Router Logic
|
|
84
37
|
if (isRouterMode()) {
|
|
38
|
+
// Router mode: Direct backend authentication
|
|
85
39
|
return routerLogin(clientKey, redirectUri);
|
|
86
40
|
} else {
|
|
41
|
+
// Client mode: Redirect to centralized login
|
|
87
42
|
return clientLogin(clientKey, redirectUri);
|
|
88
43
|
}
|
|
89
44
|
}
|
|
@@ -129,7 +84,7 @@ export function logout() {
|
|
|
129
84
|
hasToken: !!token
|
|
130
85
|
});
|
|
131
86
|
|
|
132
|
-
// Clear local storage immediately
|
|
87
|
+
// Clear local storage immediately (this will trigger listeners)
|
|
133
88
|
clearToken();
|
|
134
89
|
sessionStorage.clear();
|
|
135
90
|
|
|
@@ -140,7 +95,7 @@ export function logout() {
|
|
|
140
95
|
}
|
|
141
96
|
}
|
|
142
97
|
|
|
143
|
-
// Router logout
|
|
98
|
+
// ✅ Router logout
|
|
144
99
|
async function routerLogout(clientKey, authBaseUrl, accountUiUrl, token) {
|
|
145
100
|
console.log('🏭 Router Logout: Backend logout for all sessions');
|
|
146
101
|
|
|
@@ -170,18 +125,68 @@ async function routerLogout(clientKey, authBaseUrl, accountUiUrl, token) {
|
|
|
170
125
|
window.location.href = '/login';
|
|
171
126
|
}
|
|
172
127
|
|
|
173
|
-
// Client logout
|
|
128
|
+
// ✅ Client logout
|
|
174
129
|
function clientLogout(clientKey, accountUiUrl) {
|
|
175
130
|
console.log('🔄 Client Logout: Redirecting to centralized login');
|
|
176
131
|
const logoutUrl = `${accountUiUrl}/login?client=${clientKey}&logout=true`;
|
|
177
132
|
window.location.href = logoutUrl;
|
|
178
133
|
}
|
|
179
134
|
|
|
135
|
+
export function handleCallback() {
|
|
136
|
+
const params = new URLSearchParams(window.location.search);
|
|
137
|
+
const accessToken = params.get('access_token');
|
|
138
|
+
const error = params.get('error');
|
|
139
|
+
|
|
140
|
+
console.log('🔄 Handling authentication callback:', {
|
|
141
|
+
mode: isRouterMode() ? 'ROUTER' : 'CLIENT',
|
|
142
|
+
hasAccessToken: !!accessToken,
|
|
143
|
+
error,
|
|
144
|
+
alreadyProcessed: callbackProcessed
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ✅ If already processed and we have a token, return it
|
|
148
|
+
if (callbackProcessed) {
|
|
149
|
+
const existingToken = getToken();
|
|
150
|
+
if (existingToken) {
|
|
151
|
+
console.log('🔄 Callback already processed, returning existing token');
|
|
152
|
+
return existingToken;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ✅ Mark as processed first
|
|
157
|
+
callbackProcessed = true;
|
|
158
|
+
|
|
159
|
+
// Clean up session storage (only once)
|
|
160
|
+
sessionStorage.removeItem('originalApp');
|
|
161
|
+
sessionStorage.removeItem('returnUrl');
|
|
162
|
+
|
|
163
|
+
if (error) {
|
|
164
|
+
throw new Error(`Authentication failed: ${error}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (accessToken) {
|
|
168
|
+
// ✅ This will trigger token listeners
|
|
169
|
+
setToken(accessToken);
|
|
170
|
+
console.log('✅ Token set successfully, listeners notified');
|
|
171
|
+
return accessToken;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
throw new Error('No access token found in callback URL');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ✅ Reset callback state
|
|
178
|
+
export function resetCallbackState() {
|
|
179
|
+
callbackProcessed = false;
|
|
180
|
+
console.log('🔄 Callback state reset');
|
|
181
|
+
}
|
|
180
182
|
|
|
181
183
|
export async function refreshToken() {
|
|
182
184
|
const { clientKey, authBaseUrl } = getConfig();
|
|
183
185
|
|
|
184
|
-
console.log('🔄 Refreshing token:', {
|
|
186
|
+
console.log('🔄 Refreshing token:', {
|
|
187
|
+
clientKey,
|
|
188
|
+
mode: isRouterMode() ? 'ROUTER' : 'CLIENT'
|
|
189
|
+
});
|
|
185
190
|
|
|
186
191
|
try {
|
|
187
192
|
const response = await fetch(`${authBaseUrl}/refresh/${clientKey}`, {
|
|
@@ -194,10 +199,39 @@ export async function refreshToken() {
|
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
const { access_token } = await response.json();
|
|
202
|
+
// ✅ This will trigger token listeners
|
|
197
203
|
setToken(access_token);
|
|
204
|
+
console.log('✅ Token refresh successful, listeners notified');
|
|
198
205
|
return access_token;
|
|
199
206
|
} catch (err) {
|
|
207
|
+
// ✅ This will trigger token listeners
|
|
200
208
|
clearToken();
|
|
201
209
|
throw err;
|
|
202
210
|
}
|
|
203
211
|
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
// export async function refreshToken() {
|
|
216
|
+
// const { clientKey, authBaseUrl } = getConfig();
|
|
217
|
+
|
|
218
|
+
// console.log('🔄 Refreshing token:', { clientKey, mode: isRouterMode() ? 'ROUTER' : 'CLIENT' });
|
|
219
|
+
|
|
220
|
+
// try {
|
|
221
|
+
// const response = await fetch(`${authBaseUrl}/refresh/${clientKey}`, {
|
|
222
|
+
// method: 'POST',
|
|
223
|
+
// credentials: 'include',
|
|
224
|
+
// });
|
|
225
|
+
|
|
226
|
+
// if (!response.ok) {
|
|
227
|
+
// throw new Error('Refresh failed');
|
|
228
|
+
// }
|
|
229
|
+
|
|
230
|
+
// const { access_token } = await response.json();
|
|
231
|
+
// setToken(access_token);
|
|
232
|
+
// return access_token;
|
|
233
|
+
// } catch (err) {
|
|
234
|
+
// clearToken();
|
|
235
|
+
// throw err;
|
|
236
|
+
// }
|
|
237
|
+
// }
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// auth-client/index.js
|
|
2
2
|
import { setConfig, getConfig, isRouterMode } from './config';
|
|
3
3
|
import { login, logout, handleCallback, refreshToken, resetCallbackState } from './core';
|
|
4
|
-
import { getToken, setToken, clearToken } from './token';
|
|
4
|
+
import { getToken, setToken, clearToken, addTokenListener, removeTokenListener, getListenerCount } from './token';
|
|
5
5
|
import api from './api';
|
|
6
6
|
import { decodeToken, isTokenExpired } from './utils/jwt';
|
|
7
7
|
|
|
@@ -16,12 +16,15 @@ export const auth = {
|
|
|
16
16
|
logout,
|
|
17
17
|
handleCallback,
|
|
18
18
|
refreshToken,
|
|
19
|
-
resetCallbackState,
|
|
19
|
+
resetCallbackState,
|
|
20
20
|
|
|
21
21
|
// 🔑 Token management
|
|
22
22
|
getToken,
|
|
23
23
|
setToken,
|
|
24
24
|
clearToken,
|
|
25
|
+
addTokenListener, // ✅ Export new functions
|
|
26
|
+
removeTokenListener,
|
|
27
|
+
getListenerCount, // ✅ Debug function
|
|
25
28
|
|
|
26
29
|
// 🌐 Authenticated API client
|
|
27
30
|
api,
|
package/package.json
CHANGED
package/token.js
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
// auth-client/token.js
|
|
1
2
|
let memoryToken = null;
|
|
3
|
+
const listeners = new Set(); // ✅ Add listeners
|
|
2
4
|
|
|
3
5
|
export function setToken(token) {
|
|
6
|
+
const previousToken = memoryToken;
|
|
4
7
|
memoryToken = token;
|
|
8
|
+
|
|
5
9
|
try {
|
|
6
10
|
localStorage.setItem('authToken', token);
|
|
7
11
|
} catch (err) {
|
|
8
12
|
console.warn('Could not write token to localStorage:', err);
|
|
9
13
|
}
|
|
14
|
+
|
|
15
|
+
// ✅ Notify listeners when token changes
|
|
16
|
+
if (previousToken !== token) {
|
|
17
|
+
console.log('🔔 Token changed, notifying listeners:', {
|
|
18
|
+
listenerCount: listeners.size,
|
|
19
|
+
hadToken: !!previousToken,
|
|
20
|
+
hasToken: !!token
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
listeners.forEach(listener => {
|
|
24
|
+
try {
|
|
25
|
+
listener(token, previousToken);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.warn('Token listener error:', err);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
10
31
|
}
|
|
11
32
|
|
|
12
33
|
export function getToken() {
|
|
@@ -22,10 +43,59 @@ export function getToken() {
|
|
|
22
43
|
}
|
|
23
44
|
|
|
24
45
|
export function clearToken() {
|
|
46
|
+
const previousToken = memoryToken;
|
|
25
47
|
memoryToken = null;
|
|
48
|
+
|
|
26
49
|
try {
|
|
27
50
|
localStorage.removeItem('authToken');
|
|
28
51
|
} catch (err) {
|
|
29
52
|
console.warn('Could not clear token from localStorage:', err);
|
|
30
53
|
}
|
|
54
|
+
|
|
55
|
+
// ✅ Notify listeners when token is cleared
|
|
56
|
+
if (previousToken) {
|
|
57
|
+
console.log('🔔 Token cleared, notifying listeners:', {
|
|
58
|
+
listenerCount: listeners.size
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
listeners.forEach(listener => {
|
|
62
|
+
try {
|
|
63
|
+
listener(null, previousToken);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.warn('Token listener error:', err);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ✅ Add listener management
|
|
72
|
+
export function addTokenListener(listener) {
|
|
73
|
+
if (typeof listener !== 'function') {
|
|
74
|
+
throw new Error('Token listener must be a function');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
listeners.add(listener);
|
|
78
|
+
console.log('📎 Token listener added, total listeners:', listeners.size);
|
|
79
|
+
|
|
80
|
+
// Return cleanup function
|
|
81
|
+
return () => {
|
|
82
|
+
const removed = listeners.delete(listener);
|
|
83
|
+
if (removed) {
|
|
84
|
+
console.log('📎 Token listener removed, remaining listeners:', listeners.size);
|
|
85
|
+
}
|
|
86
|
+
return removed;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function removeTokenListener(listener) {
|
|
91
|
+
const removed = listeners.delete(listener);
|
|
92
|
+
if (removed) {
|
|
93
|
+
console.log('📎 Token listener removed, remaining listeners:', listeners.size);
|
|
94
|
+
}
|
|
95
|
+
return removed;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ✅ Debug function to see current listeners
|
|
99
|
+
export function getListenerCount() {
|
|
100
|
+
return listeners.size;
|
|
31
101
|
}
|