webs-sdk 0.19.62 → 0.19.65
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/AGENTS.md +44 -0
- package/CLAUDE.md +80 -0
- package/README.md +63 -1
- package/dist/components/SpinningWheel/index.d.ts +1 -1
- package/dist/components/SpinningWheel/index.d.ts.map +1 -1
- package/dist/components/SpinningWheel/index.js +2 -1
- package/dist/components/SpinningWheel/index.js.map +1 -1
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts +49 -0
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts.map +1 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js +111 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js.map +1 -0
- package/dist/components/ui/badge.d.ts +1 -0
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/compose-refs.d.ts +6 -0
- package/dist/components/ui/compose-refs.d.ts.map +1 -0
- package/dist/components/ui/compose-refs.js +57 -0
- package/dist/components/ui/compose-refs.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +3 -1
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +2 -2
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/index.d.ts +2 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +2 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/components/ui/media-player.d.ts +127 -0
- package/dist/components/ui/media-player.d.ts.map +1 -0
- package/dist/components/ui/media-player.js +1633 -0
- package/dist/components/ui/media-player.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +3 -1
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +2 -2
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/ui/use-lazy-ref.d.ts +4 -0
- package/dist/components/ui/use-lazy-ref.d.ts.map +1 -0
- package/dist/components/ui/use-lazy-ref.js +45 -0
- package/dist/components/ui/use-lazy-ref.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/libraries/auth.d.ts.map +1 -1
- package/dist/libraries/auth.js +2 -2
- package/dist/libraries/auth.js.map +1 -1
- package/dist/libraries/clarity.d.ts +23 -0
- package/dist/libraries/clarity.d.ts.map +1 -0
- package/dist/libraries/clarity.js +110 -0
- package/dist/libraries/clarity.js.map +1 -0
- package/dist/libraries/index.d.ts +1 -0
- package/dist/libraries/index.d.ts.map +1 -1
- package/dist/libraries/index.js +3 -1
- package/dist/libraries/index.js.map +1 -1
- package/dist/libraries/networking.d.ts +4 -0
- package/dist/libraries/networking.d.ts.map +1 -1
- package/dist/libraries/networking.js +42 -6
- package/dist/libraries/networking.js.map +1 -1
- package/dist/libraries/session.d.ts.map +1 -1
- package/dist/libraries/session.js +2 -0
- package/dist/libraries/session.js.map +1 -1
- package/dist/network.d.ts +12 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +15 -0
- package/dist/network.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/types/media-chrome-store-types.d.ts +107 -0
- package/dist/types/media-chrome-store-types.d.ts.map +1 -0
- package/dist/types/media-chrome-store-types.js +3 -0
- package/dist/types/media-chrome-store-types.js.map +1 -0
- package/dist/utils/QRCode.d.ts +1 -0
- package/dist/utils/QRCode.d.ts.map +1 -0
- package/dist/utils/QRCode.js +2 -0
- package/dist/utils/QRCode.js.map +1 -0
- package/dist/utils/imageValidation.d.ts +6 -0
- package/dist/utils/imageValidation.d.ts.map +1 -0
- package/dist/utils/imageValidation.js +64 -0
- package/dist/utils/imageValidation.js.map +1 -0
- package/docs/CONFIGURED_MEDIA_PLAYER.md +40 -0
- package/docs/CORP_AUTH_USAGE.md +687 -0
- package/docs/EXAMPLES_WALLPAPERSNAME_IMPLEMENTATION.md +1445 -0
- package/docs/EXAMPLE_ENDPOINTS_COMUNICATION.md +55 -0
- package/docs/EXTERNAL_SDK_GUIDE.md +1340 -0
- package/docs/FOR_YOU_360_FACESWAP_FIX.md +400 -0
- package/docs/FOR_YOU_IMPLEMENTATION_GUIDE.md +1413 -0
- package/docs/FOR_YOU_QUIZ_ARCHITECTURE.md +753 -0
- package/docs/FOR_YOU_SDK_WALLPAPERSNAME_BUG.md +106 -0
- package/docs/FOR_YOU_WALLPAPERSNAME_ENHANCEMENT_PLAN.md +210 -0
- package/docs/LEGAL_USAGE.md +190 -0
- package/docs/STREAK_IMPLEMENTATION_GUIDE.md +430 -0
- package/package.json +29 -6
- package/scripts/install-agent-skill.cjs +34 -0
- package/skills/webs-sdk-package/SKILL.md +11 -0
- package/skills/webs-sdk-package/references/components.md +30 -0
- package/skills/webs-sdk-package/references/integration.md +32 -0
- package/dist/libraries/globals.d.ts +0 -17
- package/dist/libraries/globals.d.ts.map +0 -1
- package/dist/libraries/globals.js +0 -38
- package/dist/libraries/globals.js.map +0 -1
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
# Corporate Authentication - Guía de Uso
|
|
2
|
+
|
|
3
|
+
## 📋 Descripción
|
|
4
|
+
|
|
5
|
+
La librería `CorporateAuthManager` proporciona autenticación corporativa centralizada basada en JWT para las aplicaciones web de Telecoming.
|
|
6
|
+
|
|
7
|
+
## 🚀 Instalación
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install webs-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## ⚡ Inicio Rápido
|
|
14
|
+
|
|
15
|
+
### 🖥️ Para Next.js Middleware (Server-Side)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// middleware.ts
|
|
19
|
+
import { NextResponse } from 'next/server'
|
|
20
|
+
import type { NextRequest } from 'next/server'
|
|
21
|
+
import WebsSDK from 'webs-sdk'
|
|
22
|
+
|
|
23
|
+
export async function middleware(request: NextRequest) {
|
|
24
|
+
// ✨ Validación server-side simplificada
|
|
25
|
+
const result = await WebsSDK.CorporateAuthManager.validateCorporateAuthServerSide(request)
|
|
26
|
+
|
|
27
|
+
if (!result.authenticated) {
|
|
28
|
+
return result.redirectResponse // Redirección automática al login
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`✅ Usuario autenticado: ${result.user.name}`)
|
|
32
|
+
return NextResponse.next()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const config = {
|
|
36
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)']
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 🌐 Para Aplicaciones Client-Side
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import WebsSDK from 'webs-sdk';
|
|
44
|
+
|
|
45
|
+
// ✨ Método simplificado - Maneja TODO automáticamente
|
|
46
|
+
const user = await WebsSDK.CorporateAuthManager.checkCorporateLogin();
|
|
47
|
+
|
|
48
|
+
if (user) {
|
|
49
|
+
console.log(`Bienvenido, ${user.name}!`);
|
|
50
|
+
// Usuario autenticado - tu código aquí
|
|
51
|
+
}
|
|
52
|
+
// Si no hay usuario, ya habría redirigido automáticamente al login
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### ¿Qué hace `checkCorporateLogin()`?
|
|
56
|
+
|
|
57
|
+
Este método maneja **TODO** el flujo de autenticación automáticamente:
|
|
58
|
+
|
|
59
|
+
1. ✅ **Detecta callbacks**: Si vienes del login con `?auth_token=...`, lo procesa
|
|
60
|
+
2. ✅ **Verifica sesión**: Comprueba si ya estás autenticado (usa caché inteligente)
|
|
61
|
+
3. ✅ **Valida token**: Verifica con el servidor (o localmente si no hay conexión)
|
|
62
|
+
4. ✅ **Redirige al login**: Si no estás autenticado, te lleva al login automáticamente
|
|
63
|
+
5. ✅ **Retorna usuario**: Si todo está OK, te devuelve los datos del usuario
|
|
64
|
+
|
|
65
|
+
**Sin configuración adicional** - Todo funciona con valores por defecto de Telecoming.
|
|
66
|
+
|
|
67
|
+
## 📖 Uso Básico
|
|
68
|
+
|
|
69
|
+
### 1. Importar el SDK
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import WebsSDK from 'webs-sdk';
|
|
73
|
+
|
|
74
|
+
// Acceder al gestor de autenticación corporativa
|
|
75
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 2. Configuración (Opcional)
|
|
79
|
+
|
|
80
|
+
**Nota:** La configuración es completamente opcional. Por defecto usa los endpoints de Telecoming.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Solo si necesitas personalizar endpoints
|
|
84
|
+
CorporateAuthManager.configure({
|
|
85
|
+
authDomain: 'https://auth.telecoming.com',
|
|
86
|
+
authValidateUrl: 'https://auth.telecoming.com/auth/api/validate',
|
|
87
|
+
authLogoutUrl: 'https://auth.telecoming.com/auth/logout',
|
|
88
|
+
authLoginUrl: 'https://auth.telecoming.com',
|
|
89
|
+
appDomain: 'https://apps.telecoming.com',
|
|
90
|
+
authCookieDuration: 86400, // 24 horas
|
|
91
|
+
authRevalidationInterval: 300, // 5 minutos
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 🔐 Métodos Principales
|
|
96
|
+
|
|
97
|
+
### Validar Usuario
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// Validar usuario sin redirección automática
|
|
101
|
+
const userData = await CorporateAuthManager.validateUser(false);
|
|
102
|
+
|
|
103
|
+
if (userData) {
|
|
104
|
+
console.log('Usuario autenticado:', userData.email);
|
|
105
|
+
console.log('Rol:', userData.role);
|
|
106
|
+
} else {
|
|
107
|
+
console.log('Usuario no autenticado');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Validar con redirección automática al login si no está autenticado
|
|
111
|
+
const user = await CorporateAuthManager.validateUser(true);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Login
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Redirigir al login (guarda la URL actual para volver)
|
|
118
|
+
CorporateAuthManager.login();
|
|
119
|
+
|
|
120
|
+
// Redirigir al login con URL de retorno personalizada
|
|
121
|
+
CorporateAuthManager.login('https://apps.telecoming.com/dashboard');
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Logout
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// Cerrar sesión
|
|
128
|
+
await CorporateAuthManager.logout();
|
|
129
|
+
|
|
130
|
+
// Cerrar sesión con redirección personalizada
|
|
131
|
+
await CorporateAuthManager.logout('https://apps.telecoming.com/');
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Verificar Estado de Autenticación
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Verificar sin consultar al servidor (usa caché)
|
|
138
|
+
const status = await CorporateAuthManager.checkAuthStatus();
|
|
139
|
+
|
|
140
|
+
if (status.authenticated) {
|
|
141
|
+
console.log('Usuario:', status.user?.email);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Obtener Usuario Actual
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const currentUser = await CorporateAuthManager.getCurrentUser();
|
|
149
|
+
|
|
150
|
+
if (currentUser) {
|
|
151
|
+
console.log('ID:', currentUser.id);
|
|
152
|
+
console.log('Email:', currentUser.email);
|
|
153
|
+
console.log('Nombre:', currentUser.name);
|
|
154
|
+
console.log('Rol:', currentUser.role);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Verificar Permisos de Administrador
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const isUserAdmin = await CorporateAuthManager.isAdmin();
|
|
162
|
+
|
|
163
|
+
if (isUserAdmin) {
|
|
164
|
+
console.log('El usuario tiene privilegios de administrador');
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Verificar Sesión Activa
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const hasSession = await CorporateAuthManager.hasActiveSession();
|
|
172
|
+
|
|
173
|
+
if (hasSession) {
|
|
174
|
+
console.log('Hay una sesión activa');
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Manejar Callback de Autenticación
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Llamar después de redirigir desde el login
|
|
182
|
+
const success = await CorporateAuthManager.handleAuthCallback();
|
|
183
|
+
|
|
184
|
+
if (success) {
|
|
185
|
+
console.log('Autenticación completada exitosamente');
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Forzar Revalidación
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Forzar una nueva validación del token
|
|
193
|
+
const userData = await CorporateAuthManager.forceRevalidation();
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 📝 Ejemplos Completos con `checkCorporateLogin()`
|
|
197
|
+
|
|
198
|
+
### Ejemplo 1: Aplicación Simple (Recomendado)
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import WebsSDK from 'webs-sdk';
|
|
202
|
+
|
|
203
|
+
// En tu archivo principal o componente raíz
|
|
204
|
+
async function init() {
|
|
205
|
+
// ✨ Una sola línea - maneja todo el flujo
|
|
206
|
+
const user = await WebsSDK.CorporateAuthManager.checkCorporateLogin();
|
|
207
|
+
|
|
208
|
+
if (user) {
|
|
209
|
+
// Usuario autenticado - inicializar app
|
|
210
|
+
console.log(`Bienvenido, ${user.name}!`);
|
|
211
|
+
document.getElementById('username').textContent = user.name;
|
|
212
|
+
document.getElementById('app').style.display = 'block';
|
|
213
|
+
}
|
|
214
|
+
// Si no hay usuario, ya habría redirigido al login
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Ejecutar al cargar la página
|
|
218
|
+
init();
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Ejemplo 2: App con Verificación de Admin
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import WebsSDK from 'webs-sdk';
|
|
225
|
+
|
|
226
|
+
async function initApp() {
|
|
227
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
228
|
+
|
|
229
|
+
// Verificar autenticación automáticamente
|
|
230
|
+
const user = await CorporateAuthManager.checkCorporateLogin();
|
|
231
|
+
|
|
232
|
+
if (user) {
|
|
233
|
+
// Mostrar nombre de usuario
|
|
234
|
+
document.getElementById('user-name').textContent = user.name;
|
|
235
|
+
|
|
236
|
+
// Verificar si es admin para mostrar opciones adicionales
|
|
237
|
+
const isAdmin = await CorporateAuthManager.isAdmin(user);
|
|
238
|
+
if (isAdmin) {
|
|
239
|
+
document.getElementById('admin-panel').style.display = 'block';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Configurar botón de logout
|
|
243
|
+
document.getElementById('logout-btn').onclick = async () => {
|
|
244
|
+
await CorporateAuthManager.logout();
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
initApp();
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Ejemplo 3: React Component
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { useEffect, useState } from 'react';
|
|
256
|
+
import WebsSDK from 'webs-sdk';
|
|
257
|
+
|
|
258
|
+
function App() {
|
|
259
|
+
const [user, setUser] = useState(null);
|
|
260
|
+
const [loading, setLoading] = useState(true);
|
|
261
|
+
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
async function checkAuth() {
|
|
264
|
+
// ✨ Método simplificado
|
|
265
|
+
const userData = await WebsSDK.CorporateAuthManager.checkCorporateLogin();
|
|
266
|
+
setUser(userData);
|
|
267
|
+
setLoading(false);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
checkAuth();
|
|
271
|
+
}, []);
|
|
272
|
+
|
|
273
|
+
if (loading) {
|
|
274
|
+
return <div>Verificando autenticación...</div>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!user) {
|
|
278
|
+
return <div>Redirigiendo al login...</div>;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div>
|
|
283
|
+
<h1>Bienvenido, {user.name}!</h1>
|
|
284
|
+
<button onClick={() => WebsSDK.CorporateAuthManager.logout()}>
|
|
285
|
+
Cerrar Sesión
|
|
286
|
+
</button>
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export default App;
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Ejemplo 4: Next.js Page
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// pages/dashboard.tsx
|
|
298
|
+
import { useEffect, useState } from 'react';
|
|
299
|
+
import WebsSDK from 'webs-sdk';
|
|
300
|
+
|
|
301
|
+
export default function Dashboard() {
|
|
302
|
+
const [user, setUser] = useState(null);
|
|
303
|
+
|
|
304
|
+
useEffect(() => {
|
|
305
|
+
async function init() {
|
|
306
|
+
const userData = await WebsSDK.CorporateAuthManager.checkCorporateLogin();
|
|
307
|
+
if (userData) {
|
|
308
|
+
setUser(userData);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
init();
|
|
312
|
+
}, []);
|
|
313
|
+
|
|
314
|
+
if (!user) return <div>Cargando...</div>;
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<div>
|
|
318
|
+
<h1>Dashboard</h1>
|
|
319
|
+
<p>Usuario: {user.email}</p>
|
|
320
|
+
<p>Rol: {user.role}</p>
|
|
321
|
+
</div>
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## 📝 Ejemplos con Métodos Individuales
|
|
327
|
+
|
|
328
|
+
### Ejemplo 1: Proteger una Página
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import WebsSDK from 'webs-sdk';
|
|
332
|
+
|
|
333
|
+
async function initProtectedPage() {
|
|
334
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
335
|
+
|
|
336
|
+
// Validar usuario (redirige automáticamente si no está autenticado)
|
|
337
|
+
const user = await CorporateAuthManager.validateUser(true);
|
|
338
|
+
|
|
339
|
+
if (user) {
|
|
340
|
+
console.log(`Bienvenido, ${user.name}!`);
|
|
341
|
+
|
|
342
|
+
// Mostrar contenido protegido
|
|
343
|
+
showDashboard(user);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
initProtectedPage();
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Ejemplo 2: Página de Admin
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import WebsSDK from 'webs-sdk';
|
|
354
|
+
|
|
355
|
+
async function initAdminPage() {
|
|
356
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
357
|
+
|
|
358
|
+
// Validar usuario
|
|
359
|
+
const user = await CorporateAuthManager.validateUser(true);
|
|
360
|
+
|
|
361
|
+
if (user) {
|
|
362
|
+
// Verificar permisos de admin
|
|
363
|
+
const isAdmin = await CorporateAuthManager.isAdmin(user);
|
|
364
|
+
|
|
365
|
+
if (isAdmin) {
|
|
366
|
+
console.log('Acceso concedido al panel de administración');
|
|
367
|
+
showAdminPanel();
|
|
368
|
+
} else {
|
|
369
|
+
console.log('Acceso denegado: Se requieren privilegios de administrador');
|
|
370
|
+
window.location.href = '/';
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
initAdminPage();
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Ejemplo 3: Página de Login/Callback
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import WebsSDK from 'webs-sdk';
|
|
382
|
+
|
|
383
|
+
async function handleAuthPage() {
|
|
384
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
385
|
+
|
|
386
|
+
// Intentar manejar el callback de autenticación
|
|
387
|
+
const success = await CorporateAuthManager.handleAuthCallback();
|
|
388
|
+
|
|
389
|
+
if (success) {
|
|
390
|
+
console.log('Login exitoso, redirigiendo...');
|
|
391
|
+
// El callback ya manejó la redirección
|
|
392
|
+
} else {
|
|
393
|
+
// No hay callback, mostrar botón de login
|
|
394
|
+
showLoginButton();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function showLoginButton() {
|
|
399
|
+
const loginBtn = document.getElementById('login-btn');
|
|
400
|
+
loginBtn?.addEventListener('click', () => {
|
|
401
|
+
WebsSDK.CorporateAuthManager.login();
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
handleAuthPage();
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Ejemplo 4: Botón de Logout
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
import WebsSDK from 'webs-sdk';
|
|
412
|
+
|
|
413
|
+
function setupLogoutButton() {
|
|
414
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
415
|
+
|
|
416
|
+
const logoutBtn = document.getElementById('logout-btn');
|
|
417
|
+
logoutBtn?.addEventListener('click', async () => {
|
|
418
|
+
await CorporateAuthManager.logout();
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
setupLogoutButton();
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Ejemplo 5: Verificación Periódica de Sesión
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
import WebsSDK from 'webs-sdk';
|
|
429
|
+
|
|
430
|
+
async function setupSessionMonitor() {
|
|
431
|
+
const { CorporateAuthManager } = WebsSDK;
|
|
432
|
+
|
|
433
|
+
// Verificar sesión cada 5 minutos
|
|
434
|
+
setInterval(async () => {
|
|
435
|
+
const userData = await CorporateAuthManager.validateUser(false);
|
|
436
|
+
|
|
437
|
+
if (!userData) {
|
|
438
|
+
console.log('Sesión expirada, redirigiendo al login...');
|
|
439
|
+
CorporateAuthManager.login();
|
|
440
|
+
}
|
|
441
|
+
}, 5 * 60 * 1000); // 5 minutos
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
setupSessionMonitor();
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## 🔧 Ejemplos Avanzados con Next.js
|
|
448
|
+
|
|
449
|
+
### Middleware con Headers Personalizados
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
// middleware.ts - Añadir info del usuario a los headers
|
|
453
|
+
import { NextResponse } from 'next/server'
|
|
454
|
+
import type { NextRequest } from 'next/server'
|
|
455
|
+
import WebsSDK from 'webs-sdk'
|
|
456
|
+
|
|
457
|
+
export async function middleware(request: NextRequest) {
|
|
458
|
+
const result = await WebsSDK.CorporateAuthManager.validateCorporateAuthServerSide(request)
|
|
459
|
+
|
|
460
|
+
if (!result.authenticated) {
|
|
461
|
+
return result.redirectResponse
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Añadir información del usuario a los headers del request
|
|
465
|
+
const requestHeaders = new Headers(request.headers)
|
|
466
|
+
requestHeaders.set('x-user-id', result.user.id)
|
|
467
|
+
requestHeaders.set('x-user-email', result.user.email)
|
|
468
|
+
requestHeaders.set('x-user-name', result.user.name)
|
|
469
|
+
requestHeaders.set('x-user-role', result.user.role)
|
|
470
|
+
|
|
471
|
+
return NextResponse.next({
|
|
472
|
+
request: {
|
|
473
|
+
headers: requestHeaders,
|
|
474
|
+
},
|
|
475
|
+
})
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### API Route Protegida
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
// app/api/protected/route.ts
|
|
483
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
484
|
+
import WebsSDK from 'webs-sdk'
|
|
485
|
+
|
|
486
|
+
export async function GET(request: NextRequest) {
|
|
487
|
+
const result = await WebsSDK.CorporateAuthManager.validateCorporateAuthServerSide(request)
|
|
488
|
+
|
|
489
|
+
if (!result.authenticated) {
|
|
490
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Lógica de la API con usuario autenticado
|
|
494
|
+
return NextResponse.json({
|
|
495
|
+
message: 'Success',
|
|
496
|
+
user: result.user
|
|
497
|
+
})
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Middleware con Rutas Específicas
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
// middleware.ts - Proteger solo ciertas rutas
|
|
505
|
+
import { NextResponse } from 'next/server'
|
|
506
|
+
import type { NextRequest } from 'next/server'
|
|
507
|
+
import WebsSDK from 'webs-sdk'
|
|
508
|
+
|
|
509
|
+
export async function middleware(request: NextRequest) {
|
|
510
|
+
// Solo validar en rutas protegidas
|
|
511
|
+
const protectedPaths = ['/dashboard', '/admin', '/profile']
|
|
512
|
+
const isProtectedPath = protectedPaths.some(path =>
|
|
513
|
+
request.nextUrl.pathname.startsWith(path)
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
if (!isProtectedPath) {
|
|
517
|
+
return NextResponse.next()
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const result = await WebsSDK.CorporateAuthManager.validateCorporateAuthServerSide(request)
|
|
521
|
+
|
|
522
|
+
if (!result.authenticated) {
|
|
523
|
+
return result.redirectResponse
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Verificar permisos de admin para rutas /admin
|
|
527
|
+
if (request.nextUrl.pathname.startsWith('/admin')) {
|
|
528
|
+
if (result.user.role !== 'admin') {
|
|
529
|
+
return NextResponse.redirect(new URL('/unauthorized', request.url))
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return NextResponse.next()
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export const config = {
|
|
537
|
+
matcher: ['/dashboard/:path*', '/admin/:path*', '/profile/:path*']
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Client Component con Callback Handler
|
|
542
|
+
|
|
543
|
+
```typescript
|
|
544
|
+
// app/components/AuthHandler.tsx
|
|
545
|
+
'use client'
|
|
546
|
+
|
|
547
|
+
import { useEffect } from 'react'
|
|
548
|
+
import WebsSDK from 'webs-sdk'
|
|
549
|
+
|
|
550
|
+
export function AuthHandler() {
|
|
551
|
+
useEffect(() => {
|
|
552
|
+
async function handleCallback() {
|
|
553
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
554
|
+
if (urlParams.has('auth_token')) {
|
|
555
|
+
await WebsSDK.CorporateAuthManager.handleAuthCallback()
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
handleCallback()
|
|
559
|
+
}, [])
|
|
560
|
+
|
|
561
|
+
return null
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
// app/layout.tsx
|
|
567
|
+
import { AuthHandler } from './components/AuthHandler'
|
|
568
|
+
|
|
569
|
+
export default function RootLayout({ children }) {
|
|
570
|
+
return (
|
|
571
|
+
<html>
|
|
572
|
+
<body>
|
|
573
|
+
<AuthHandler />
|
|
574
|
+
{children}
|
|
575
|
+
</body>
|
|
576
|
+
</html>
|
|
577
|
+
)
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Server Component con User Info
|
|
582
|
+
|
|
583
|
+
```typescript
|
|
584
|
+
// app/dashboard/page.tsx
|
|
585
|
+
import { headers } from 'next/headers'
|
|
586
|
+
|
|
587
|
+
export default function DashboardPage() {
|
|
588
|
+
const headersList = headers()
|
|
589
|
+
|
|
590
|
+
// Los headers fueron añadidos por el middleware
|
|
591
|
+
const userId = headersList.get('x-user-id')
|
|
592
|
+
const userEmail = headersList.get('x-user-email')
|
|
593
|
+
const userName = headersList.get('x-user-name')
|
|
594
|
+
|
|
595
|
+
return (
|
|
596
|
+
<div>
|
|
597
|
+
<h1>Dashboard</h1>
|
|
598
|
+
<p>Usuario: {userName}</p>
|
|
599
|
+
<p>Email: {userEmail}</p>
|
|
600
|
+
</div>
|
|
601
|
+
)
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## 🔧 Características Avanzadas
|
|
606
|
+
|
|
607
|
+
### Validación Local como Fallback
|
|
608
|
+
|
|
609
|
+
Si el servicio central de autenticación no está disponible, la librería automáticamente:
|
|
610
|
+
1. Intenta validar el token localmente usando JWT
|
|
611
|
+
2. Verifica la firma del token
|
|
612
|
+
3. Comprueba la expiración
|
|
613
|
+
4. Retorna los datos del usuario con una marca `local_validation: true`
|
|
614
|
+
|
|
615
|
+
### Caché de Validaciones
|
|
616
|
+
|
|
617
|
+
- Las validaciones se cachean durante 5 minutos por defecto
|
|
618
|
+
- Reduce llamadas innecesarias al servidor
|
|
619
|
+
- Se puede forzar una revalidación con `forceRevalidation()`
|
|
620
|
+
|
|
621
|
+
### Gestión de Cookies
|
|
622
|
+
|
|
623
|
+
- Las cookies se establecen automáticamente con flags de seguridad
|
|
624
|
+
- HttpOnly para prevenir XSS (cuando sea posible)
|
|
625
|
+
- Secure en HTTPS
|
|
626
|
+
- SameSite=Lax para prevenir CSRF
|
|
627
|
+
|
|
628
|
+
## 📊 Tipos de Datos
|
|
629
|
+
|
|
630
|
+
### UserData
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
interface UserData {
|
|
634
|
+
id: string;
|
|
635
|
+
email: string;
|
|
636
|
+
name: string;
|
|
637
|
+
role: string;
|
|
638
|
+
local_validation?: boolean; // true si se validó localmente
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### CorporateAuthConfig
|
|
643
|
+
|
|
644
|
+
```typescript
|
|
645
|
+
interface CorporateAuthConfig {
|
|
646
|
+
authDomain: string;
|
|
647
|
+
authValidateUrl: string;
|
|
648
|
+
authLogoutUrl: string;
|
|
649
|
+
authLoginUrl: string;
|
|
650
|
+
appDomain: string;
|
|
651
|
+
authCookieDuration: number;
|
|
652
|
+
authRevalidationInterval: number;
|
|
653
|
+
jwtSecret: string;
|
|
654
|
+
authJwtIssuer: string;
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
## ⚠️ Notas Importantes
|
|
659
|
+
|
|
660
|
+
1. **Seguridad**: No almacenes el `jwtSecret` en el código del cliente. Debe configurarse en el servidor.
|
|
661
|
+
|
|
662
|
+
2. **HTTPS**: En producción, siempre usa HTTPS para proteger los tokens.
|
|
663
|
+
|
|
664
|
+
3. **Cookies**: Las cookies HttpOnly solo funcionan si se establecen desde el servidor.
|
|
665
|
+
|
|
666
|
+
4. **Redirecciones**: Las redirecciones automáticas solo funcionan en entornos de navegador.
|
|
667
|
+
|
|
668
|
+
5. **Fallback Local**: El fallback local no verifica la validez del token con el servidor, solo verifica su estructura y firma.
|
|
669
|
+
|
|
670
|
+
## 🐛 Depuración
|
|
671
|
+
|
|
672
|
+
Todos los métodos emiten logs en consola que puedes usar para depurar:
|
|
673
|
+
|
|
674
|
+
```typescript
|
|
675
|
+
// En desarrollo, abre la consola del navegador para ver:
|
|
676
|
+
// - "CorporateAuthManager init"
|
|
677
|
+
// - "Validating token with central auth service"
|
|
678
|
+
// - "Token validated successfully: user@example.com"
|
|
679
|
+
// - "Using cached user data"
|
|
680
|
+
// - etc.
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
## 📞 Soporte
|
|
684
|
+
|
|
685
|
+
Para problemas o preguntas sobre la autenticación corporativa:
|
|
686
|
+
- Email: dev-team@telecoming.com
|
|
687
|
+
- Documentación completa: Ver `src/libraries/corporate_auth.md`
|