@spidy092/auth-client 1.0.8 → 1.0.10

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.
Files changed (4) hide show
  1. package/config.js +15 -4
  2. package/core.js +136 -104
  3. package/index.js +8 -5
  4. package/package.json +1 -1
package/config.js CHANGED
@@ -1,8 +1,11 @@
1
+ // auth-client/config.js
1
2
  let config = {
2
3
  clientKey: null,
3
4
  authBaseUrl: null,
4
5
  redirectUri: null,
5
- usePkce: false, // optional future
6
+ accountUiUrl: null,
7
+ isRouter: false, // ✅ Add router flag
8
+ usePkce: false,
6
9
  };
7
10
 
8
11
  export function setConfig(customConfig = {}) {
@@ -14,13 +17,21 @@ export function setConfig(customConfig = {}) {
14
17
  ...config,
15
18
  ...customConfig,
16
19
  redirectUri: customConfig.redirectUri || window.location.origin + '/callback',
20
+ // ✅ Auto-detect router mode
21
+ isRouter: customConfig.isRouter || customConfig.clientKey === 'account-ui'
17
22
  };
23
+
24
+ console.log(`🔧 Auth Client Mode: ${config.isRouter ? 'ROUTER' : 'CLIENT'}`, {
25
+ clientKey: config.clientKey,
26
+ isRouter: config.isRouter
27
+ });
18
28
  }
19
29
 
20
30
  export function getConfig() {
21
31
  return { ...config };
22
32
  }
23
33
 
24
-
25
-
26
- // pass client key and authbaseurl and redirectUri
34
+ // ✅ Helper function
35
+ export function isRouterMode() {
36
+ return config.isRouter;
37
+ }
package/core.js CHANGED
@@ -1,146 +1,178 @@
1
+ // auth-client/core.js
1
2
  import { setToken, clearToken, getToken } from './token';
2
- import { getConfig } from './config';
3
+ import { getConfig, isRouterMode } from './config';
3
4
 
4
- export function login(clientKeyArg, redirectUriArg) { // Removed stateArg
5
+ // Track if callback was already processed
6
+ let callbackProcessed = false;
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
+ export function login(clientKeyArg, redirectUriArg) {
56
+ // ✅ Reset callback state when starting new login
57
+ resetCallbackState();
58
+
5
59
  const {
6
- clientKey: defaultClientKey,
7
- authBaseUrl,
8
- redirectUri: defaultRedirectUri,
9
- accountUiUrl
60
+ clientKey: defaultClientKey,
61
+ authBaseUrl,
62
+ redirectUri: defaultRedirectUri,
63
+ accountUiUrl
10
64
  } = getConfig();
11
65
 
12
66
  const clientKey = clientKeyArg || defaultClientKey;
13
67
  const redirectUri = redirectUriArg || defaultRedirectUri;
14
- // Removed state generation
15
68
 
16
- console.log('Initiating login with parameters:', {
69
+ console.log('🔄 Smart Login initiated:', {
70
+ mode: isRouterMode() ? 'ROUTER' : 'CLIENT',
17
71
  clientKey,
18
72
  redirectUri
19
- // Removed state from logging
20
73
  });
21
-
74
+
22
75
  if (!clientKey || !redirectUri) {
23
76
  throw new Error('Missing clientKey or redirectUri');
24
77
  }
25
78
 
26
- // Store only app info, no state
79
+ // Store app info
27
80
  sessionStorage.setItem('originalApp', clientKey);
28
81
  sessionStorage.setItem('returnUrl', redirectUri);
29
82
 
30
- // --- ENTERPRISE LOGIC ---
31
- // If we are already in Account-UI, go straight to the backend
32
- if (window.location.origin === accountUiUrl && clientKey === 'account-ui') {
33
- // Direct SSO kick-off for Account-UI (no state parameter)
34
- const backendLoginUrl = `${authBaseUrl}/login/${clientKey}?redirect_uri=${encodeURIComponent(redirectUri)}`;
35
- console.log('Redirecting directly to auth backend:', backendLoginUrl);
36
- window.location.href = backendLoginUrl;
37
- return;
83
+ // Smart Router Logic (from my previous response)
84
+ if (isRouterMode()) {
85
+ return routerLogin(clientKey, redirectUri);
86
+ } else {
87
+ return clientLogin(clientKey, redirectUri);
38
88
  }
89
+ }
90
+
91
+ // ✅ Router mode: Direct backend call
92
+ function routerLogin(clientKey, redirectUri) {
93
+ const { authBaseUrl } = getConfig();
94
+ const backendLoginUrl = `${authBaseUrl}/login/${clientKey}?redirect_uri=${encodeURIComponent(redirectUri)}`;
95
+
96
+ console.log('🏭 Router Login: Direct backend authentication', {
97
+ clientKey,
98
+ redirectUri,
99
+ backendUrl: backendLoginUrl
100
+ });
101
+
102
+ window.location.href = backendLoginUrl;
103
+ }
39
104
 
40
- // Otherwise, centralized login flow (for other apps, no state)
41
- const accountLoginUrl = `${accountUiUrl}/login?` + new URLSearchParams({
42
- client: clientKey,
43
- redirect_uri: redirectUri
44
- // Removed state
105
+ // Client mode: Centralized login
106
+ function clientLogin(clientKey, redirectUri) {
107
+ const { accountUiUrl } = getConfig();
108
+ const centralizedLoginUrl = `${accountUiUrl}/login?client=${clientKey}&redirect_uri=${encodeURIComponent(redirectUri)}`;
109
+
110
+ console.log('🔄 Client Login: Redirecting to centralized login', {
111
+ clientKey,
112
+ redirectUri,
113
+ centralizedUrl: centralizedLoginUrl
45
114
  });
46
- console.log('Redirecting to centralized Account UI:', accountLoginUrl);
47
- window.location.href = accountLoginUrl;
115
+
116
+ window.location.href = centralizedLoginUrl;
48
117
  }
49
118
 
50
119
  export function logout() {
120
+ // ✅ Reset callback state on logout
121
+ resetCallbackState();
122
+
51
123
  const { clientKey, authBaseUrl, accountUiUrl } = getConfig();
52
124
  const token = getToken();
53
-
54
- console.log('Initiating logout for client:', clientKey);
125
+
126
+ console.log('🚪 Smart Logout initiated:', {
127
+ mode: isRouterMode() ? 'ROUTER' : 'CLIENT',
128
+ clientKey,
129
+ hasToken: !!token
130
+ });
55
131
 
56
132
  // Clear local storage immediately
57
133
  clearToken();
58
134
  sessionStorage.clear();
59
- // Don't clear localStorage completely - might break other stuff
60
- // localStorage.clear(); // Remove this line
61
135
 
62
- // Call backend logout if we have a token
63
- if (token) {
64
- fetch(`${authBaseUrl}/logout/${clientKey}`, {
65
- method: 'POST',
66
- credentials: 'include', // ✅ CRITICAL: This sends cookies
67
- headers: {
68
- 'Authorization': `Bearer ${token}`,
69
- 'Content-Type': 'application/json'
70
- }
71
- })
72
- .then(response => response.json())
73
- .then(data => {
74
- console.log('Backend logout response:', data);
75
-
76
- // If we get a Keycloak logout URL, redirect there
77
- if (data.keycloakLogoutUrl) {
78
- window.location.href = data.keycloakLogoutUrl;
79
- return;
80
- }
81
-
82
- // Otherwise redirect to login
83
- window.location.href = `${accountUiUrl}/login`;
84
- })
85
- .catch(error => {
86
- console.error('Logout error:', error);
87
- // Always redirect to login even on error
88
- window.location.href = `${accountUiUrl}/login`;
89
- });
136
+ if (isRouterMode()) {
137
+ return routerLogout(clientKey, authBaseUrl, accountUiUrl, token);
90
138
  } else {
91
- // No token, just redirect to login
92
- window.location.href = `${accountUiUrl}/login`;
139
+ return clientLogout(clientKey, accountUiUrl);
93
140
  }
94
141
  }
95
142
 
96
-
97
- export function handleCallback() {
98
- const params = new URLSearchParams(window.location.search);
99
- const accessToken = params.get('access_token');
100
- const error = params.get('error');
101
- // Removed state handling completely
102
-
103
- console.log('Handling authentication callback:', {
104
- accessToken,
105
- error
106
- // Removed state from logging
107
- });
143
+ // Router logout (same as before)
144
+ async function routerLogout(clientKey, authBaseUrl, accountUiUrl, token) {
145
+ console.log('🏭 Router Logout: Backend logout for all sessions');
108
146
 
109
- // Removed all state validation
110
-
111
- sessionStorage.removeItem('originalApp');
112
- sessionStorage.removeItem('returnUrl');
113
-
114
- if (error) {
115
- throw new Error(`Authentication failed: ${error}`);
116
- }
147
+ if (token) {
148
+ try {
149
+ const response = await fetch(`${authBaseUrl}/logout/${clientKey}`, {
150
+ method: 'POST',
151
+ credentials: 'include',
152
+ headers: {
153
+ 'Authorization': `Bearer ${token}`,
154
+ 'Content-Type': 'application/json'
155
+ }
156
+ });
157
+
158
+ const data = await response.json();
159
+ console.log('Backend logout response:', data);
117
160
 
118
- if (accessToken) {
119
- setToken(accessToken);
120
- return accessToken;
161
+ if (data.keycloakLogoutUrl) {
162
+ window.location.href = data.keycloakLogoutUrl;
163
+ return;
164
+ }
165
+ } catch (error) {
166
+ console.warn('Backend logout failed:', error);
167
+ }
121
168
  }
122
169
 
123
- throw new Error('No access token found in callback URL');
170
+ window.location.href = '/login';
124
171
  }
125
172
 
126
- export async function refreshToken() {
127
- const { clientKey, authBaseUrl } = getConfig();
128
-
129
- try {
130
- const response = await fetch(`${authBaseUrl}/refresh/${clientKey}`, {
131
- method: 'POST',
132
- credentials: 'include',
133
- });
134
-
135
- if (!response.ok) {
136
- throw new Error('Refresh failed');
137
- }
138
-
139
- const { access_token } = await response.json();
140
- setToken(access_token);
141
- return access_token;
142
- } catch (err) {
143
- clearToken();
144
- throw err;
145
- }
173
+ // Client logout (same as before)
174
+ function clientLogout(clientKey, accountUiUrl) {
175
+ console.log('🔄 Client Logout: Redirecting to centralized login');
176
+ const logoutUrl = `${accountUiUrl}/login?client=${clientKey}&logout=true`;
177
+ window.location.href = logoutUrl;
146
178
  }
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { setConfig, getConfig } from './config';
1
+ // auth-client/index.js
2
+ import { setConfig, getConfig, isRouterMode } from './config';
2
3
  import { login, logout, handleCallback, refreshToken } from './core';
3
4
  import { getToken, setToken, clearToken } from './token';
4
5
  import api from './api';
@@ -8,6 +9,7 @@ export const auth = {
8
9
  // 🔧 Config
9
10
  setConfig,
10
11
  getConfig,
12
+ isRouterMode, // ✅ Expose router mode check
11
13
 
12
14
  // 🔐 Core flows
13
15
  login,
@@ -26,23 +28,24 @@ export const auth = {
26
28
  // 🧪 Utilities
27
29
  decodeToken,
28
30
  isTokenExpired,
29
-
31
+
30
32
  // 🔄 Auto-refresh setup
31
33
  startTokenRefresh: () => {
32
34
  const interval = setInterval(async () => {
33
35
  const token = getToken();
34
- if (token && isTokenExpired(token, 300)) { // Refresh 5 min before expiry
36
+ if (token && isTokenExpired(token, 300)) {
35
37
  try {
36
38
  await refreshToken();
39
+ console.log('🔄 Auto-refresh successful');
37
40
  } catch (err) {
38
41
  console.error('Auto-refresh failed:', err);
39
42
  clearInterval(interval);
40
43
  }
41
44
  }
42
- }, 60000); // Check every minute
45
+ }, 60000);
43
46
  return interval;
44
47
  }
45
48
  };
46
49
 
47
50
  export { AuthProvider } from './react/AuthProvider';
48
- export { useAuth } from './react/useAuth';
51
+ export { useAuth } from './react/useAuth';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spidy092/auth-client",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Scalable frontend auth SDK for centralized login using Keycloak + Auth Service.",
5
5
  "main": "index.js",
6
6
  "module": "index.js",