@elogroup-sereduc/ser-front-core-client 1.1.0 → 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.
Files changed (47) hide show
  1. package/OAUTH_MIGRATION.md +86 -0
  2. package/README.md +145 -321
  3. package/dist/{axios.d.ts → api-client.d.ts} +3 -3
  4. package/dist/api-client.d.ts.map +1 -0
  5. package/dist/{axios.js → api-client.js} +11 -11
  6. package/dist/api-client.js.map +1 -0
  7. package/dist/auth/bootstrap.d.ts +5 -0
  8. package/dist/auth/bootstrap.d.ts.map +1 -0
  9. package/dist/auth/bootstrap.js +28 -0
  10. package/dist/auth/bootstrap.js.map +1 -0
  11. package/dist/auth/http-client.d.ts +3 -0
  12. package/dist/auth/http-client.d.ts.map +1 -0
  13. package/dist/auth/http-client.js +31 -0
  14. package/dist/auth/http-client.js.map +1 -0
  15. package/dist/auth/index.d.ts +18 -0
  16. package/dist/auth/index.d.ts.map +1 -0
  17. package/dist/auth/index.js +22 -0
  18. package/dist/auth/index.js.map +1 -0
  19. package/dist/auth/route-guards.d.ts +14 -0
  20. package/dist/auth/route-guards.d.ts.map +1 -0
  21. package/dist/auth/route-guards.js +23 -0
  22. package/dist/auth/route-guards.js.map +1 -0
  23. package/dist/auth/ser-oauth-js.d.ts +54 -0
  24. package/dist/auth/ser-oauth-js.d.ts.map +1 -0
  25. package/dist/auth/ser-oauth-js.js +405 -0
  26. package/dist/auth/ser-oauth-js.js.map +1 -0
  27. package/dist/auth/store.d.ts +14 -0
  28. package/dist/auth/store.d.ts.map +1 -0
  29. package/dist/auth/store.js +20 -0
  30. package/dist/auth/store.js.map +1 -0
  31. package/dist/index.d.ts +3 -6
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +2 -4
  34. package/dist/index.js.map +1 -1
  35. package/dist/keycloak.d.ts +12 -0
  36. package/dist/keycloak.d.ts.map +1 -1
  37. package/dist/keycloak.js +226 -9
  38. package/dist/keycloak.js.map +1 -1
  39. package/dist/utils/auth.d.ts +8 -0
  40. package/dist/utils/auth.d.ts.map +1 -1
  41. package/dist/utils/auth.js +13 -2
  42. package/dist/utils/auth.js.map +1 -1
  43. package/package.json +8 -6
  44. package/public/silent-callback.html +19 -0
  45. package/public/silent-check-sso.html +30 -0
  46. package/dist/axios.d.ts.map +0 -1
  47. package/dist/axios.js.map +0 -1
@@ -0,0 +1,86 @@
1
+ # Migração para Ser OAuth System
2
+
3
+ Esta biblioteca agora inclui um sistema completo de autenticação OAuth/OIDC (`ser-oauth-js`) além do sistema Keycloak original.
4
+
5
+ ## Nova Implementação: Ser OAuth
6
+
7
+ ### Características
8
+
9
+ - ✅ **Silent SSO**: Autenticação invisível via iframe
10
+ - ✅ **PKCE S256**: Segurança avançada para SPAs
11
+ - ✅ **Token Refresh**: Renovação automática de tokens
12
+ - ✅ **API Client**: Cliente HTTP com interceptadores automáticos
13
+ - ✅ **Route Guards**: Proteção de rotas para TanStack Router
14
+ - ✅ **Zustand Store**: Gerenciamento de estado reativo
15
+ - ✅ **IDP Hint**: Redirecionamento automático para provedores específicos
16
+
17
+ ### Setup Básico
18
+
19
+ ```typescript
20
+ import {
21
+ createKeycloakAuthFromUrl,
22
+ initAuth,
23
+ useAuthStore,
24
+ } from "@elogroup-sereduc/ser-front-core-client";
25
+
26
+ const kc = createKeycloakAuthFromUrl(
27
+ "https://sso.sereduc.com/realms/colaboradores/protocol/openid-connect/auth",
28
+ "seu-client-id",
29
+ "ser-oidc", // IDP hint opcional
30
+ );
31
+
32
+ const authenticated = await initAuth(kc, "/seu-base-path");
33
+ ```
34
+
35
+ ### Migração de Projetos
36
+
37
+ 1. **Instalar nova versão** da biblioteca
38
+ 2. **Copiar `silent-check-sso.html`** para pasta public
39
+ 3. **Substituir inicialização** do auth
40
+ 4. **Atualizar imports** dos hooks/stores
41
+ 5. **Testar Silent SSO** e fluxo completo
42
+
43
+ ### Exemplo de Context
44
+
45
+ ```typescript
46
+ import { useAuthStore } from "@elogroup-sereduc/ser-front-core-client";
47
+
48
+ export function useAuth() {
49
+ const authState = useAuthStore();
50
+
51
+ return {
52
+ authenticated: authState.authenticated,
53
+ token: authState.accessToken,
54
+ login: () => kc.login(),
55
+ logout: () => kc.logout(),
56
+ };
57
+ }
58
+ ```
59
+
60
+ ### API Client
61
+
62
+ ```typescript
63
+ import { createApiClient } from "@elogroup-sereduc/ser-front-core-client";
64
+
65
+ const api = createApiClient(kc, "https://api.sereduc.com");
66
+
67
+ // O cliente automaticamente:
68
+ // - Adiciona Bearer token
69
+ // - Renova em caso de 401
70
+ // - Retenta requisição
71
+ ```
72
+
73
+ ### Route Guards
74
+
75
+ ```typescript
76
+ import { createAuthGuard } from "@elogroup-sereduc/ser-front-core-client";
77
+
78
+ const requireAuth = createAuthGuard(kc);
79
+
80
+ export const Route = createFileRoute("/protected")({
81
+ beforeLoad: requireAuth,
82
+ component: ProtectedComponent,
83
+ });
84
+ ```
85
+
86
+ Ver documentação completa em `src/auth/README.md`.
package/README.md CHANGED
@@ -1,405 +1,229 @@
1
- # @elogroup-sereduc/ser-front-core-client
1
+ # Ser Auth Library
2
2
 
3
- Keycloak-based authentication and API client for Portal do Aluno and Backoffices.
3
+ Sistema de autenticação OAuth/OIDC compatível com Keycloak, desenvolvido como substituto para keycloak-js com suporte a Silent SSO, PKCE S256, e gerenciamento automático de tokens.
4
4
 
5
- ## Features
5
+ ## Características
6
6
 
7
- - ✅ Keycloak authentication integration
8
- - ✅ Memory-only JWT token storage (secure)
9
- - ✅ Proactive token refresh (30-second threshold)
10
- - ✅ Axios-based API client with automatic Bearer token injection
11
- - ✅ TypeScript support with full type definitions
12
- - ✅ Configurable error handling
13
- - ✅ Authentication utilities and helpers
7
+ - ✅ **Silent SSO**: Autenticação invisível via iframe
8
+ - ✅ **PKCE S256**: Segurança para SPAs (Single Page Applications)
9
+ - ✅ **Token Refresh**: Renovação automática de tokens
10
+ - ✅ **API Client**: Cliente HTTP com interceptadores automáticos
11
+ - ✅ **Route Guards**: Proteção de rotas para frameworks como TanStack Router
12
+ - ✅ **Zustand Store**: Gerenciamento de estado em memória
13
+ - ✅ **IDP Hint**: Suporte a redirecionamento automático para provedores específicos
14
14
 
15
- ## Installation
15
+ ## Instalação
16
16
 
17
17
  ```bash
18
18
  npm install @elogroup-sereduc/ser-front-core-client
19
19
  ```
20
20
 
21
- ## Quick Start
21
+ ## Setup Básico
22
22
 
23
- ### Basic API Client
23
+ ### 1. Configuração Inicial
24
24
 
25
25
  ```typescript
26
- import { createApiClient } from "@elogroup-sereduc/ser-front-core-client";
27
-
28
- // Create an API client with Keycloak authentication
29
- const apiClient = createApiClient({
30
- keycloak: {
31
- url: "https://your-keycloak-server",
32
- realm: "your-realm",
33
- clientId: "your-client-id",
34
- },
35
- api: {
36
- baseURL: "https://your-api-server",
37
- },
38
- });
39
-
40
- // Use like a normal axios instance
41
- const users = await apiClient.get("/users");
42
- const newUser = await apiClient.post("/users", userData);
43
- ```
26
+ import {
27
+ createKeycloakAuthFromUrl,
28
+ initAuth,
29
+ } from "@elogroup-sereduc/ser-front-core-client";
44
30
 
45
- ### Simple Client Factory
31
+ // Criar instância do SerOAuth
32
+ const kc = createKeycloakAuthFromUrl(
33
+ "https://seu-keycloak.com/realms/seu-realm/protocol/openid-connect/auth",
34
+ "seu-client-id",
35
+ "seu-idp-hint", // opcional
36
+ );
46
37
 
47
- ```typescript
48
- import { createSimpleApiClient } from "@elogroup-sereduc/ser-front-core-client";
49
-
50
- const apiClient = createSimpleApiClient("https://your-api-server", {
51
- url: "https://your-keycloak-server",
52
- realm: "your-realm",
53
- clientId: "your-client-id",
54
- });
38
+ // Inicializar autenticação
39
+ const authenticated = await initAuth(kc, "/seu-base-path");
55
40
  ```
56
41
 
57
- ## Configuration
42
+ ### 2. Arquivo Silent-Check-SSO
58
43
 
59
- ### Application Base Path Support
44
+ Copie o arquivo `public/silent-check-sso.html` para a pasta `public` da sua aplicação.
60
45
 
61
- For applications that don't run at the domain root (e.g., `/portal-aluno`, `/backoffice`), configure the `basePath`:
46
+ ### 3. Context de Autenticação (React)
62
47
 
63
48
  ```typescript
64
- const config = {
65
- keycloak: {
66
- url: "https://your-keycloak-server",
67
- realm: "your-realm",
68
- clientId: "your-client-id",
69
- basePath: "/portal-aluno", // Application base path
70
- },
71
- api: {
72
- baseURL: "https://your-api-server",
73
- },
74
- };
75
-
76
- const apiClient = createApiClient(config);
77
- ```
78
-
79
- The `basePath` is used to construct correct redirect URIs for:
80
-
81
- - Silent SSO check redirects
82
- - Login/logout redirects
83
- - Error handling redirects
49
+ import { useAuthStore } from '@elogroup-sereduc/ser-front-core-client'
84
50
 
85
- ### KeycloakConfig
51
+ export function AuthContext({ children }) {
52
+ const authState = useAuthStore()
86
53
 
87
- ```typescript
88
- interface KeycloakConfig {
89
- url: string; // Keycloak server URL
90
- realm: string; // Keycloak realm
91
- clientId: string; // Client ID
92
- basePath?: string; // Application base path (e.g., '/portal-aluno', '/backoffice')
93
- initOptions?: {
94
- // Optional Keycloak initialization options
95
- onLoad?: "login-required" | "check-sso";
96
- silentCheckSsoRedirectUri?: string;
97
- checkLoginIframe?: boolean;
98
- // ... other KeycloakInitOptions
99
- };
54
+ return (
55
+ <AuthProvider value={{
56
+ authenticated: authState.authenticated,
57
+ user: extractUserFromToken(authState.idToken),
58
+ login: () => kc.login(),
59
+ logout: () => kc.logout(),
60
+ }}>
61
+ {children}
62
+ </AuthProvider>
63
+ )
100
64
  }
101
65
  ```
102
66
 
103
- ### ApiClientConfig
67
+ ### 4. Cliente API
104
68
 
105
69
  ```typescript
106
- interface ApiClientConfig {
107
- baseURL: string; // API base URL
108
- headers?: Record<string, string>; // Default headers
109
- withCredentials?: boolean; // Include cookies (default: true)
110
- onTokenRefreshFailed?: (error: Error) => void; // Custom error handler
111
- loginRedirectUrl?: string; // Custom login redirect URL
112
- }
113
- ```
114
-
115
- ### Login Interfaces
70
+ import { createApiClient } from "@elogroup-sereduc/ser-front-core-client";
116
71
 
117
- ```typescript
118
- interface DirectLoginCredentials {
119
- username: string; // Username for direct login
120
- password: string; // Password for direct login
121
- }
72
+ const api = createApiClient(kc, "https://sua-api.com");
122
73
 
123
- interface LoginOptions {
124
- redirectUri?: string; // Custom redirect URI after login
125
- credentials?: DirectLoginCredentials; // For direct login (internal users)
126
- loginHint?: string; // Login hint for external login
127
- prompt?: "none" | "login" | "consent" | "select_account"; // OIDC prompt parameter
128
- }
74
+ // O cliente automaticamente:
75
+ // - Adiciona Bearer token nos headers
76
+ // - Renova token em caso de 401
77
+ // - Retenta requisição com novo token
129
78
  ```
130
79
 
131
- ## Authentication Management
132
-
133
- ### Login Types
134
-
135
- This package supports two types of login:
136
-
137
- 1. **External Login (Default)**: Redirects to Keycloak login page
138
- 2. **Direct Login (Internal Users)**: Uses username/password without external redirect
139
-
140
- ### External Login (Standard Flow)
80
+ ### 5. Route Guards
141
81
 
142
82
  ```typescript
143
- import { createAuthService } from "@elogroup-sereduc/ser-front-core-client";
83
+ import { createAuthGuard } from "@elogroup-sereduc/ser-front-core-client";
84
+ import { createFileRoute } from "@tanstack/react-router";
144
85
 
145
- const authService = await createAuthService({
146
- url: "https://your-keycloak-server",
147
- realm: "your-realm",
148
- clientId: "your-client-id",
149
- });
86
+ const requireAuth = createAuthGuard(kc);
150
87
 
151
- // Redirects user to Keycloak login page
152
- await authService.login();
88
+ export const Route = createFileRoute("/protected")({
89
+ beforeLoad: requireAuth,
90
+ component: ProtectedComponent,
91
+ });
153
92
  ```
154
93
 
155
- ### Direct Login (Internal Users)
94
+ ## API Reference
156
95
 
157
- For internal users that don't need external redirect, you can use direct login with username/password:
96
+ ### SerOAuth
158
97
 
159
98
  ```typescript
160
- import {
161
- createAuthService,
162
- type DirectLoginCredentials,
163
- DirectLoginError,
164
- } from "@elogroup-sereduc/ser-front-core-client";
165
-
166
- const authService = await createAuthService(keycloakConfig);
167
-
168
- // Direct login without external redirect
169
- try {
170
- await authService.login({
171
- credentials: {
172
- username: "internal.user@company.com",
173
- password: "userPassword123",
174
- },
175
- });
176
- console.log("User logged in successfully!");
177
- } catch (error) {
178
- if (error instanceof DirectLoginError) {
179
- console.error("Direct login failed:", error.message);
180
- // Handle specific direct login errors:
181
- // - Invalid credentials
182
- // - Account locked
183
- // - Client not configured for direct access
184
- }
185
- }
186
- ```
187
-
188
- **📋 Keycloak Configuration Requirements for Direct Login:**
99
+ class SerOAuth {
100
+ constructor(config: SerOAuthConfig);
189
101
 
190
- 1. In Keycloak Admin Console, go to your client settings
191
- 2. Enable "Direct Access Grants Enabled" in the Capability config
192
- 3. Ensure the client has the appropriate roles and scope mappings
193
- 4. For production, consider IP restrictions and additional security measures
102
+ // Métodos principais
103
+ async init(options?: InitOptions): Promise<boolean>;
104
+ async login(options?: LoginOptions): Promise<void>;
105
+ async logout(options?: LogoutOptions): Promise<void>;
106
+ async updateToken(minValidity?: number): Promise<boolean>;
194
107
 
195
- ### Mixed Login Scenarios
108
+ // Propriedades
109
+ get authenticated(): boolean;
110
+ get token(): string | null;
111
+ get refreshToken(): string | null;
112
+ get idToken(): string | null;
196
113
 
197
- You can handle both internal and external users in the same application:
198
-
199
- ```typescript
200
- async function handleLogin(
201
- isInternalUser: boolean,
202
- credentials?: DirectLoginCredentials,
203
- ) {
204
- try {
205
- if (isInternalUser && credentials) {
206
- // Direct login for internal users
207
- await authService.login({ credentials });
208
- } else {
209
- // External redirect for external users
210
- await authService.login();
211
- }
212
- } catch (error) {
213
- console.error("Login failed:", error);
214
- }
114
+ // Callbacks
115
+ onAuthSuccess?: () => void;
116
+ onAuthError?: (err: unknown) => void;
117
+ onAuthLogout?: () => void;
118
+ onTokenExpired?: () => void;
119
+ onTokenRefreshed?: () => void;
215
120
  }
216
121
  ```
217
122
 
218
- ### Manual Authentication
123
+ ### Configuração
219
124
 
220
125
  ```typescript
221
- import {
222
- createAuthService,
223
- getAuthState,
224
- } from "@elogroup-sereduc/ser-front-core-client";
225
-
226
- // Create standalone auth service
227
- const authService = await createAuthService({
228
- url: "https://your-keycloak-server",
229
- realm: "your-realm",
230
- clientId: "your-client-id",
231
- });
232
-
233
- // Check authentication state
234
- const authState = getAuthState(authService);
235
- console.log("Is authenticated:", authState.isAuthenticated);
236
-
237
- // Login (external redirect)
238
- if (!authState.isAuthenticated) {
239
- await authService.login();
240
- }
241
-
242
- // Direct login for internal users (no external redirect)
243
- if (!authState.isAuthenticated) {
244
- await authService.login({
245
- credentials: {
246
- username: "internal.user@company.com",
247
- password: "userPassword123",
248
- },
249
- });
250
- }
126
+ type SerOAuthConfig = {
127
+ url: string; // https://seu-keycloak.com
128
+ realm: string; // nome-do-realm
129
+ clientId: string; // seu-client-id
130
+ idp?: string; // hint para IDP específico
131
+ };
251
132
 
252
- // Logout
253
- await authService.logout();
133
+ type InitOptions = {
134
+ onLoad?: "check-sso" | "login-required";
135
+ silentCheckSsoRedirectUri?: string;
136
+ pkceMethod?: "S256";
137
+ };
254
138
  ```
255
139
 
256
- ### Access Keycloak Service from API Client
140
+ ### Store (Zustand)
257
141
 
258
142
  ```typescript
259
- import { getKeycloakService } from "@elogroup-sereduc/ser-front-core-client";
260
-
261
- const apiClient = createApiClient(config);
262
- const keycloakService = getKeycloakService(apiClient);
263
-
264
- if (keycloakService) {
265
- const authState = keycloakService.getAuthState();
266
- console.log("User info:", authState.userInfo);
267
- }
143
+ const authState = useAuthStore();
144
+ // {
145
+ // accessToken: string | null
146
+ // refreshToken: string | null
147
+ // idToken: string | null
148
+ // accessExpiresAt: number | null
149
+ // authenticated: boolean
150
+ // setTokens: (tokens: TokenSet) => void
151
+ // clear: () => void
152
+ // }
268
153
  ```
269
154
 
270
- ## Authentication Utilities
155
+ ## Migração do keycloak-js
271
156
 
272
- ### Token Management
157
+ ### Antes (keycloak-js)
273
158
 
274
159
  ```typescript
275
- import {
276
- isTokenExpired,
277
- parseTokenUserInfo,
278
- hasRole,
279
- getUserRoles,
280
- } from "@elogroup-sereduc/ser-front-core-client";
160
+ import Keycloak from "keycloak-js";
281
161
 
282
- // Check if token is expired
283
- const expired = isTokenExpired(token, 30); // 30-second buffer
284
-
285
- // Parse user info from token
286
- const userInfo = parseTokenUserInfo(token);
162
+ const keycloak = new Keycloak({
163
+ url: "https://keycloak.com",
164
+ realm: "myrealm",
165
+ clientId: "myclient",
166
+ });
287
167
 
288
- // Check user roles
289
- const isAdmin = hasRole(token, "admin");
290
- const userRoles = getUserRoles(token);
168
+ await keycloak.init({ onLoad: "check-sso" });
291
169
  ```
292
170
 
293
- ### URL Building with Base Path
171
+ ### Depois (ser-auth)
294
172
 
295
173
  ```typescript
296
174
  import {
297
- buildUrl,
298
- logout,
299
- redirectToLogin,
175
+ createSerOAuth,
176
+ initAuth,
300
177
  } from "@elogroup-sereduc/ser-front-core-client";
301
178
 
302
- // Build URLs with base path support
303
- const silentSsoUrl = buildUrl("/silent-check-sso.html", "/portal-aluno");
304
- // Result: 'https://domain.com/portal-aluno/silent-check-sso.html'
305
-
306
- const homeUrl = buildUrl("/", "/backoffice");
307
- // Result: 'https://domain.com/backoffice/'
308
-
309
- // Use with auth functions
310
- const keycloakService = getKeycloakService(apiClient);
311
-
312
- // Logout with base path
313
- await logout(keycloakService, undefined, "/portal-aluno");
179
+ const kc = createSerOAuth({
180
+ url: "https://keycloak.com",
181
+ realm: "myrealm",
182
+ clientId: "myclient",
183
+ });
314
184
 
315
- // Redirect to login with base path
316
- redirectToLogin(undefined, "/portal-aluno");
185
+ await initAuth(kc);
317
186
  ```
318
187
 
319
- ## Error Handling
320
-
321
- ### Default Behavior
322
-
323
- By default, when token refresh fails, the user is redirected to the login page.
188
+ ## Exemplos Avançados
324
189
 
325
190
  ### Custom Error Handling
326
191
 
327
192
  ```typescript
328
- const apiClient = createApiClient({
329
- keycloak: {
330
- /* ... */
331
- },
332
- api: {
333
- baseURL: "https://api.example.com",
334
- onTokenRefreshFailed: (error) => {
335
- console.error("Auth failed:", error);
336
- // Custom handling - show modal, redirect to specific page, etc.
337
- showAuthErrorModal();
338
- },
339
- },
340
- });
341
- ```
342
-
343
- ## Silent SSO Setup
344
-
345
- For silent SSO, create a `silent-check-sso.html` file in your public folder:
346
-
347
- ```html
348
- <!doctype html>
349
- <html>
350
- <body>
351
- <script>
352
- parent.postMessage(location.href, location.origin);
353
- </script>
354
- </body>
355
- </html>
356
- ```
357
-
358
- Then configure your client:
193
+ kc.onAuthError = (error) => {
194
+ console.error("Auth error:", error);
195
+ // Redirecionar para página de erro
196
+ };
359
197
 
360
- ```typescript
361
- const config = {
362
- keycloak: {
363
- url: "https://your-keycloak-server",
364
- realm: "your-realm",
365
- clientId: "your-client-id",
366
- initOptions: {
367
- onLoad: "check-sso",
368
- silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,
369
- },
370
- },
371
- // ...
198
+ kc.onTokenExpired = () => {
199
+ console.log("Token expirado, renovando...");
372
200
  };
373
201
  ```
374
202
 
375
- ## TypeScript Support
376
-
377
- Full TypeScript support with comprehensive type definitions:
203
+ ### Múltiplas Instâncias
378
204
 
379
205
  ```typescript
380
- import type {
381
- CoreClientConfig,
382
- AuthState,
383
- KeycloakConfig,
384
- LoginOptions,
385
- DirectLoginCredentials,
386
- AuthenticationError,
387
- TokenRefreshError,
388
- DirectLoginError,
389
- } from "@elogroup-sereduc/ser-front-core-client";
390
- ```
206
+ const adminKc = createSerOAuth({
207
+ url: "https://admin-sso.com",
208
+ realm: "admin",
209
+ clientId: "admin-client",
210
+ });
391
211
 
392
- ## Differences from portal-aluno-api-client
212
+ const userKc = createSerOAuth({
213
+ url: "https://user-sso.com",
214
+ realm: "users",
215
+ clientId: "user-client",
216
+ });
217
+ ```
393
218
 
394
- - **Memory-only storage**: Tokens stored in memory (more secure)
395
- - ✅ **Proactive refresh**: Uses `updateToken(30)` before requests instead of 401/403 retry
396
- - ✅ **Keycloak integration**: OIDC-based authentication instead of session-based
397
- - ✅ **Per-client config**: Keycloak config provided per API client
398
- - ✅ **No retry logic**: Does not retry requests on auth failure
399
- - ✅ **Direct login support**: Internal users can login with username/password without external redirect
400
- - ✅ **Base path support**: Applications running in subfolders (e.g., /portal-aluno, /backoffice) are fully supported
401
- - ✅ **Mixed authentication**: Supports both internal (direct) and external (redirect) users in the same app
219
+ ### Interceptação Customizada
402
220
 
403
- ## License
221
+ ```typescript
222
+ const api = createApiClient(kc);
404
223
 
405
- MIT
224
+ api.interceptors.request.use((config) => {
225
+ // Adicionar headers customizados
226
+ config.headers["X-Custom-Header"] = "value";
227
+ return config;
228
+ });
229
+ ```
@@ -1,7 +1,7 @@
1
1
  import { type AxiosInstance } from "axios";
2
2
  import { KeycloakService } from "./keycloak.js";
3
- import type { CoreClientConfig, ApiClientConfig } from "./types/index.js";
3
+ import type { CoreClientConfig } from "./types/index.js";
4
4
  export declare function createApiClient(config: CoreClientConfig): AxiosInstance;
5
- export declare function createSimpleApiClient(baseURL: string, keycloakConfig: CoreClientConfig["keycloak"], options?: Partial<ApiClientConfig>): AxiosInstance;
5
+ export declare function createSimpleApiClient(config: CoreClientConfig): AxiosInstance;
6
6
  export declare function getKeycloakService(apiClient: AxiosInstance): KeycloakService | undefined;
7
- //# sourceMappingURL=axios.d.ts.map
7
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAc,EACZ,KAAK,aAAa,EAGnB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AAM1E,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,CA8EvE;AAyBD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,CAE7E;AAKD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,aAAa,GACvB,eAAe,GAAG,SAAS,CAE7B"}