@tgtone/auth-sdk 1.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 +140 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/react-hook.d.ts +13 -0
- package/dist/react-hook.d.ts.map +1 -0
- package/dist/react-hook.js +38 -0
- package/dist/react-hook.js.map +1 -0
- package/dist/tgtone-auth-client.d.ts +70 -0
- package/dist/tgtone-auth-client.d.ts.map +1 -0
- package/dist/tgtone-auth-client.js +305 -0
- package/dist/tgtone-auth-client.js.map +1 -0
- package/docs/INTEGRATION_EXAMPLES.md +536 -0
- package/docs/LOVABLE_QUICK_START.md +478 -0
- package/docs/NPM_PUBLISH.md +131 -0
- package/docs/README.md +83 -0
- package/docs/SDK_FINAL_STATUS.md +88 -0
- package/docs/SDK_INTEGRATION_RULES.md +433 -0
- package/docs/tgtone-identity-auth.code-workspace +11 -0
- package/package.json +51 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# 🔐 TGT One Auth Client SDK
|
|
2
|
+
|
|
3
|
+
SDK para integrar autenticación JWT + MFA en aplicaciones del ecosistema TGT One.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📦 Instalación
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install tgtone-auth-client@latest # v1.2.0
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🚀 TGT Auth SDK v1.2.0 - Quick Start para Lovable
|
|
16
|
+
|
|
17
|
+
## 📦 Instalación
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install tgtone-auth-client@latest
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## ⚡ Uso Básico
|
|
26
|
+
|
|
27
|
+
### **1. Inicializar el SDK**
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { TGTAuthClient } from 'tgtone-auth-client';
|
|
31
|
+
|
|
32
|
+
const auth = new TGTAuthClient({
|
|
33
|
+
identityUrl: 'https://identity.tgtone.cl',
|
|
34
|
+
appDomain: window.location.hostname, // ej: 'app.lovable.dev'
|
|
35
|
+
debug: true // opcional: ver logs en consola
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### **2. Verificar Sesión (en App.tsx)**
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { useEffect, useState } from 'react';
|
|
45
|
+
import { TGTAuthClient, type TGTSession } from 'tgtone-auth-client';
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const [session, setSession] = useState<TGTSession | null>(null);
|
|
49
|
+
const [loading, setLoading] = useState(true);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const auth = new TGTAuthClient({
|
|
53
|
+
identityUrl: 'https://identity.tgtone.cl',
|
|
54
|
+
appDomain: window.location.hostname
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
auth.checkSession().then((session) => {
|
|
58
|
+
setSession(session);
|
|
59
|
+
setLoading(false);
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
if (loading) return <div>Cargando...</div>;
|
|
64
|
+
if (!session) return null; // Ya redirigió a login
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div>
|
|
68
|
+
<h1>Bienvenido {session.user.name}</h1>
|
|
69
|
+
<p>Tenant: {session.tenantName}</p>
|
|
70
|
+
<p>Roles: {JSON.stringify(session.roles)}</p>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🔑 Nuevas Propiedades de Sesión (v1.1)
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const session = await auth.checkSession();
|
|
82
|
+
|
|
83
|
+
// ✅ Información del Tenant
|
|
84
|
+
session.tenantId // "uuid-tenant-123"
|
|
85
|
+
session.tenantName // "TGT Technology"
|
|
86
|
+
|
|
87
|
+
// ✅ Roles por Aplicación
|
|
88
|
+
session.roles // { "console": ["owner"], "crm": ["admin"] }
|
|
89
|
+
|
|
90
|
+
// ✅ Usuario
|
|
91
|
+
session.user.email // "user@tgtone.cl"
|
|
92
|
+
session.user.name // "Juan Pérez"
|
|
93
|
+
|
|
94
|
+
// ✅ Expiración
|
|
95
|
+
session.expiresAt // Date object
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 🎯 Métodos Útiles
|
|
101
|
+
|
|
102
|
+
### **Obtener Tenant ID**
|
|
103
|
+
```typescript
|
|
104
|
+
const tenantId = auth.getTenantId();
|
|
105
|
+
// Usar en requests al backend:
|
|
106
|
+
fetch(`/api/v1/tenants/${tenantId}/data`)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### **Verificar Roles**
|
|
110
|
+
```typescript
|
|
111
|
+
// ¿Es admin de Console?
|
|
112
|
+
if (auth.hasRole('console', 'admin')) {
|
|
113
|
+
// Mostrar panel de administración
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ¿Tiene acceso a CRM?
|
|
117
|
+
if (auth.hasAccessToApp('crm')) {
|
|
118
|
+
// Mostrar enlace a CRM
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Obtener todos los roles de una app
|
|
122
|
+
const roles = auth.getRoles('console'); // ["owner", "admin"]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### **Cerrar Sesión**
|
|
126
|
+
```typescript
|
|
127
|
+
<button onClick={() => auth.logout()}>
|
|
128
|
+
Cerrar Sesión
|
|
129
|
+
</button>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 📡 Requests al Backend con Tenant
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
const session = await auth.checkSession();
|
|
138
|
+
|
|
139
|
+
// ✅ Incluir tenantId en headers
|
|
140
|
+
fetch('https://api.tgtone.cl/v1/data', {
|
|
141
|
+
headers: {
|
|
142
|
+
'Authorization': `Bearer ${localStorage.getItem('tgtone_auth_token')}`,
|
|
143
|
+
'X-Tenant-ID': session.tenantId, // ✅ Tenant context
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🛡️ Validación Local de JWT
|
|
151
|
+
|
|
152
|
+
El SDK ahora **decodifica el JWT localmente** antes de validar con el backend:
|
|
153
|
+
|
|
154
|
+
✅ Verifica `tenant_id` obligatorio
|
|
155
|
+
✅ Valida expiración del token
|
|
156
|
+
✅ Extrae roles sin hacer request
|
|
157
|
+
|
|
158
|
+
**Ventaja:** Menos latencia, mejor UX.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 🔐 Soporte MFA (v1.2.0)
|
|
163
|
+
|
|
164
|
+
El SDK ahora soporta **Multi-Factor Authentication** con Google Authenticator/TOTP.
|
|
165
|
+
|
|
166
|
+
### Flujo de Login con MFA
|
|
167
|
+
|
|
168
|
+
Si el usuario tiene MFA habilitado, el backend NO hace redirect automático. En su lugar, el frontend de Identity maneja el flujo MFA completo:
|
|
169
|
+
|
|
170
|
+
**1. Login con MFA habilitado:**
|
|
171
|
+
```typescript
|
|
172
|
+
// El usuario hace login en Identity (https://identity.tgtone.cl)
|
|
173
|
+
// Si tiene MFA habilitado:
|
|
174
|
+
// → Identity muestra pantalla de código de 6 dígitos
|
|
175
|
+
// → Usuario ingresa código de Google Authenticator
|
|
176
|
+
// → Identity valida y redirige con token final
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**2. Tu app en Lovable recibe el token:**
|
|
180
|
+
```typescript
|
|
181
|
+
// Cuando Identity redirige de vuelta a tu app:
|
|
182
|
+
const session = await auth.checkSession();
|
|
183
|
+
// ✅ El token ya viene validado (con MFA completado)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Métodos MFA del SDK
|
|
187
|
+
|
|
188
|
+
Aunque Identity maneja el flujo MFA visualmente, el SDK expone métodos para casos avanzados:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Verificar código MFA programáticamente (uso avanzado)
|
|
192
|
+
const session = await auth.verifyMfa(tempToken, '123456');
|
|
193
|
+
|
|
194
|
+
// Guardar tempToken en localStorage
|
|
195
|
+
auth.storeTempToken(tempToken);
|
|
196
|
+
|
|
197
|
+
// Obtener tempToken guardado
|
|
198
|
+
const tempToken = auth.getTempToken();
|
|
199
|
+
|
|
200
|
+
// Limpiar tempToken
|
|
201
|
+
auth.clearTempToken();
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
> **💡 Nota para Lovable**: En la mayoría de casos NO necesitas llamar `verifyMfa()` directamente. Identity maneja el flujo MFA completo y tu app solo recibe el token final validado.
|
|
205
|
+
|
|
206
|
+
### ¿Cuándo usar los métodos MFA?
|
|
207
|
+
|
|
208
|
+
**✅ Caso común (recomendado):**
|
|
209
|
+
```typescript
|
|
210
|
+
// Identity maneja todo el flujo MFA
|
|
211
|
+
const session = await auth.checkSession();
|
|
212
|
+
// Ya viene con MFA validado si el usuario lo tiene habilitado
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**🔧 Caso avanzado (si implementas login custom):**
|
|
216
|
+
```typescript
|
|
217
|
+
// Solo si NO usas el frontend de Identity
|
|
218
|
+
const loginResponse = await fetch('/api/auth/login', {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
body: JSON.stringify({ email, password })
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const data = await loginResponse.json();
|
|
224
|
+
|
|
225
|
+
if (data.requiresMfa && data.tempToken) {
|
|
226
|
+
auth.storeTempToken(data.tempToken);
|
|
227
|
+
// Mostrar input para código
|
|
228
|
+
const code = getUserInputCode();
|
|
229
|
+
const session = await auth.verifyMfa(data.tempToken, code);
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 🆕 Cambios por Versión
|
|
236
|
+
|
|
237
|
+
### v1.2.0 (Octubre 2025)
|
|
238
|
+
- ✅ **Soporte MFA** con TOTP (Google Authenticator)
|
|
239
|
+
- ✅ Métodos `verifyMfa()`, `storeTempToken()`, `getTempToken()`, `clearTempToken()`
|
|
240
|
+
- ✅ Detección automática de flujo MFA en `checkSession()`
|
|
241
|
+
- ✅ Identity maneja UI de MFA (no requiere código custom en apps)
|
|
242
|
+
|
|
243
|
+
### v1.1.0 (Octubre 2025)
|
|
244
|
+
- ✅ Validación de `tenant_id` obligatorio
|
|
245
|
+
- ✅ Decodificación local de JWT
|
|
246
|
+
- ✅ Nuevo retorno `TGTSession` en lugar de `TGTUser`
|
|
247
|
+
- ✅ Métodos `hasRole()`, `getRoles()`, `hasAccessToApp()`
|
|
248
|
+
|
|
249
|
+
### v1.0.0
|
|
250
|
+
- ✅ Versión inicial con SSO básico
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 🔧 TypeScript Types
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import type {
|
|
258
|
+
TGTSession,
|
|
259
|
+
TGTUser,
|
|
260
|
+
JWTPayload
|
|
261
|
+
} from 'tgtone-auth-client';
|
|
262
|
+
|
|
263
|
+
interface TGTSession {
|
|
264
|
+
user: TGTUser;
|
|
265
|
+
tenantId: string;
|
|
266
|
+
tenantName: string;
|
|
267
|
+
roles: Record<string, string[]>; // { "console": ["admin"] }
|
|
268
|
+
expiresAt: Date;
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## ⚠️ Breaking Changes
|
|
275
|
+
|
|
276
|
+
Si usabas v1.0, actualizar código:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
// ❌ Antes (v1.0)
|
|
280
|
+
const user = await auth.checkSession();
|
|
281
|
+
console.log(user.email);
|
|
282
|
+
|
|
283
|
+
// ✅ Ahora (v1.1)
|
|
284
|
+
const session = await auth.checkSession();
|
|
285
|
+
console.log(session.user.email);
|
|
286
|
+
console.log(session.tenantId); // ← NUEVO
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🚨 Troubleshooting
|
|
292
|
+
|
|
293
|
+
### Error: "Invalid token: missing tenant_id"
|
|
294
|
+
→ Tu backend no está incluyendo `tenant_id` en el JWT. Verificar `auth.service.ts`.
|
|
295
|
+
|
|
296
|
+
### Error: "Token expired"
|
|
297
|
+
→ El token tiene > 90 días (dev) o > 1h (prod). Re-login automático.
|
|
298
|
+
|
|
299
|
+
### No redirige a login
|
|
300
|
+
→ Verificar que `identityUrl` y `appDomain` sean correctos.
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 📚 Docs Completas
|
|
305
|
+
|
|
306
|
+
Ver: `sdk/README.md` o https://github.com/tgt-technology/tgtone-identity-auth
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 📋 API
|
|
311
|
+
|
|
312
|
+
### `checkSession(): Promise<TGTUser | null>`
|
|
313
|
+
Verifica sesión. Lee token de URL (si viene del redirect), lo guarda en localStorage y valida con backend.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
const user = await auth.checkSession();
|
|
317
|
+
if (user) {
|
|
318
|
+
console.log('Usuario logueado:', user.email);
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### `getUser(): TGTUser | null`
|
|
323
|
+
Obtiene usuario en memoria (sin request). Requiere llamar `checkSession()` primero.
|
|
324
|
+
|
|
325
|
+
### `logout(): Promise<void>`
|
|
326
|
+
Cierra sesión, limpia localStorage y redirige al login.
|
|
327
|
+
|
|
328
|
+
### `hasRole(app: string, role: string): boolean`
|
|
329
|
+
Verifica si tiene un rol específico.
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
if (auth.hasRole('console', 'admin')) {
|
|
333
|
+
// Mostrar panel admin
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### `getRoles(app: string): string[]`
|
|
338
|
+
Obtiene roles del usuario en una app.
|
|
339
|
+
|
|
340
|
+
### `redirectToLogin(): void`
|
|
341
|
+
Redirige manualmente al login.
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 🔄 Flujo Completo (con MFA)
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
1. Usuario visita tu app en Lovable
|
|
349
|
+
↓
|
|
350
|
+
2. App ejecuta auth.checkSession()
|
|
351
|
+
↓
|
|
352
|
+
3. ❌ No hay token → Redirect a Identity con ?redirect=tu-dominio
|
|
353
|
+
↓
|
|
354
|
+
4. Usuario ingresa email + password en Identity
|
|
355
|
+
↓
|
|
356
|
+
5a. ✅ Sin MFA habilitado:
|
|
357
|
+
→ Identity redirige a tu-dominio?token=eyJ...
|
|
358
|
+
→ SDK guarda token y retorna sesión
|
|
359
|
+
|
|
360
|
+
5b. 🔐 Con MFA habilitado:
|
|
361
|
+
→ Identity muestra pantalla de código de 6 dígitos
|
|
362
|
+
→ Usuario ingresa código de Google Authenticator
|
|
363
|
+
→ Identity valida código con backend
|
|
364
|
+
→ ✅ Código válido → Identity redirige a tu-dominio?token=eyJ...
|
|
365
|
+
→ SDK guarda token y retorna sesión
|
|
366
|
+
↓
|
|
367
|
+
6. SDK lee token de URL y lo guarda en localStorage
|
|
368
|
+
↓
|
|
369
|
+
7. SDK valida token con backend (Authorization: Bearer ...)
|
|
370
|
+
↓
|
|
371
|
+
8. ✅ Retorna sesión completa
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**💡 Clave:** Tu app en Lovable NO necesita manejar MFA. Identity lo hace todo y te devuelve el token final ya validado.
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 🧪 Testing Rápido (Sin Login)
|
|
379
|
+
|
|
380
|
+
Para desarrollo rápido sin pasar por login:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
// 1. Hacer login con curl y copiar el token
|
|
385
|
+
// 2. Guardarlo manualmente:
|
|
386
|
+
const testToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
|
|
387
|
+
localStorage.setItem('tgtone_auth_token', testToken);
|
|
388
|
+
|
|
389
|
+
// 3. Ahora checkSession funcionará
|
|
390
|
+
auth.checkSession().then(setUser);
|
|
391
|
+
}, []);
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Obtener token:**
|
|
395
|
+
```bash
|
|
396
|
+
curl -X POST https://identity.tgtone.cl/api/v1/auth/login \
|
|
397
|
+
-H "Content-Type: application/json" \
|
|
398
|
+
-d '{"email": "superadmin@tgtone.cl", "password": "Tgt123."}'
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 👤 Estructura del Usuario
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
interface TGTUser {
|
|
407
|
+
sub: string; // ID usuario
|
|
408
|
+
email: string;
|
|
409
|
+
name: string;
|
|
410
|
+
tenant_id: string;
|
|
411
|
+
tenant_name: string;
|
|
412
|
+
roles: Record<string, string[]>; // { console: ['owner'], zenith: ['admin'] }
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## ⚙️ Configuración
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
interface TGTAuthConfig {
|
|
422
|
+
identityUrl: string; // URL del backend Identity
|
|
423
|
+
appDomain: string; // Dominio de tu app (sin protocolo)
|
|
424
|
+
onAuthSuccess?: (user: TGTUser) => void; // Callback cuando se autentica
|
|
425
|
+
onAuthFailure?: () => void; // Callback cuando falla
|
|
426
|
+
debug?: boolean; // Logs en consola
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 🔐 Cómo Funciona
|
|
433
|
+
|
|
434
|
+
1. **Token en URL**: Después del login, Identity redirige con `?token=...`
|
|
435
|
+
2. **localStorage**: SDK guarda token en `tgtone_auth_token`
|
|
436
|
+
3. **Bearer Token**: Todas las requests usan `Authorization: Bearer <token>`
|
|
437
|
+
4. **Validación**: Backend valida JWT y retorna datos del usuario
|
|
438
|
+
5. **No cookies**: Todo se maneja con Bearer tokens en localStorage
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## 🛠️ Para Producción
|
|
443
|
+
|
|
444
|
+
Cambiar `identityUrl` según ambiente:
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
const auth = new TGTAuthClient({
|
|
448
|
+
identityUrl: import.meta.env.PROD
|
|
449
|
+
? 'https://identity.tgtone.cl'
|
|
450
|
+
: 'https://identity.tgtone.cl', // Mismo dominio en dev y prod
|
|
451
|
+
appDomain: window.location.hostname
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## 🔐 Seguridad MFA
|
|
458
|
+
|
|
459
|
+
El sistema MFA de TGT One usa **TOTP (Time-based One-Time Password)** basado en RFC 6238:
|
|
460
|
+
|
|
461
|
+
- 🔑 **Secret compartido**: Generado al activar MFA, guardado encriptado en BD
|
|
462
|
+
- ⏱️ **Códigos temporales**: Válidos por 30 segundos
|
|
463
|
+
- 🔄 **Ventana de tolerancia**: ±30 segundos para compensar desfase de reloj
|
|
464
|
+
- 📱 **Compatible con**: Google Authenticator, Microsoft Authenticator, Authy, 1Password, etc.
|
|
465
|
+
|
|
466
|
+
### Cómo funciona:
|
|
467
|
+
```
|
|
468
|
+
Usuario habilita MFA → Backend genera secret único
|
|
469
|
+
→ Muestra QR code
|
|
470
|
+
→ Usuario escanea con Google Authenticator
|
|
471
|
+
→ App genera códigos cada 30s: HMAC-SHA1(secret, tiempo)
|
|
472
|
+
→ Al login: Backend valida con mismo algoritmo
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
**Última actualización:** 2025-10-29
|
|
478
|
+
**Versión SDK:** v1.2.0
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# 📦 Publicar SDK a NPM
|
|
2
|
+
|
|
3
|
+
## ✅ Pre-requisitos
|
|
4
|
+
|
|
5
|
+
1. **Cuenta en NPM**: https://www.npmjs.com/signup
|
|
6
|
+
2. **Login en terminal**:
|
|
7
|
+
```bash
|
|
8
|
+
npm login
|
|
9
|
+
# Ingresar: username, password, email, OTP (si tienes 2FA)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🚀 Comandos para Publicar
|
|
15
|
+
|
|
16
|
+
### 1. Ir a la carpeta del SDK
|
|
17
|
+
```bash
|
|
18
|
+
cd /home/jam/develop/tgtone/tgtone-identity-auth/sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Limpiar build anterior
|
|
22
|
+
```bash
|
|
23
|
+
npm run clean
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 3. Compilar TypeScript
|
|
27
|
+
```bash
|
|
28
|
+
npm run build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 4. Verificar qué archivos se publicarán
|
|
32
|
+
```bash
|
|
33
|
+
npm pack --dry-run
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Debería mostrar:
|
|
37
|
+
```
|
|
38
|
+
- README.md
|
|
39
|
+
- package.json
|
|
40
|
+
- dist/
|
|
41
|
+
- docs/
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 5. Publicar
|
|
45
|
+
```bash
|
|
46
|
+
npm publish
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🔄 Para Actualizar Versión
|
|
52
|
+
|
|
53
|
+
### Patch (1.0.2 → 1.0.3) - Bug fixes
|
|
54
|
+
```bash
|
|
55
|
+
npm version patch
|
|
56
|
+
npm publish
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Minor (1.0.3 → 1.1.0) - Nuevas features
|
|
60
|
+
```bash
|
|
61
|
+
npm version minor
|
|
62
|
+
npm publish
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Major (1.1.0 → 2.0.0) - Breaking changes
|
|
66
|
+
```bash
|
|
67
|
+
npm version major
|
|
68
|
+
npm publish
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ✅ Verificar Publicación
|
|
74
|
+
|
|
75
|
+
Una vez publicado:
|
|
76
|
+
```bash
|
|
77
|
+
# Ver en NPM
|
|
78
|
+
https://www.npmjs.com/package/tgtone-auth-client
|
|
79
|
+
|
|
80
|
+
# Instalar en otro proyecto
|
|
81
|
+
npm install tgtone-auth-client
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 🔐 Configuración de Token NPM (CI/CD)
|
|
87
|
+
|
|
88
|
+
Para publicar desde GitHub Actions o CI/CD:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 1. Crear token en NPM
|
|
92
|
+
https://www.npmjs.com/settings/YOUR_USER/tokens
|
|
93
|
+
|
|
94
|
+
# 2. Configurar en GitHub Secrets
|
|
95
|
+
Repo Settings > Secrets > New secret
|
|
96
|
+
Name: NPM_TOKEN
|
|
97
|
+
Value: npm_xxx...
|
|
98
|
+
|
|
99
|
+
# 3. Usar en GitHub Actions
|
|
100
|
+
- run: npm publish
|
|
101
|
+
env:
|
|
102
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 📋 Checklist Pre-publicación
|
|
108
|
+
|
|
109
|
+
- [x] ✅ Version actualizada en package.json (1.0.2)
|
|
110
|
+
- [x] ✅ Build exitoso (`npm run build`)
|
|
111
|
+
- [x] ✅ Tests pasando (si los hay)
|
|
112
|
+
- [x] ✅ README.md actualizado
|
|
113
|
+
- [x] ✅ CHANGELOG.md actualizado
|
|
114
|
+
- [x] ✅ Documentación organizada en docs/
|
|
115
|
+
- [ ] ⬜ Login en NPM (`npm login`)
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 🎯 Comandos Rápidos
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Todo en uno (desde carpeta sdk/)
|
|
123
|
+
cd /home/jam/develop/tgtone/tgtone-identity-auth/sdk
|
|
124
|
+
npm run clean
|
|
125
|
+
npm run build
|
|
126
|
+
npm publish
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
**Última actualización:** 2025-10-16
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# 📚 TGT Auth SDK - Documentación
|
|
2
|
+
|
|
3
|
+
> SDK de autenticación JWT + Bearer Token para el ecosistema TGT One
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Quick Start
|
|
8
|
+
|
|
9
|
+
**[⬆️ README principal](../README.md)** - Instalación y uso básico
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 📖 Guías de Integración
|
|
14
|
+
|
|
15
|
+
### **[LOVABLE_QUICK_START.md](./LOVABLE_QUICK_START.md)** ⭐
|
|
16
|
+
Guía para Lovable/React:
|
|
17
|
+
- Setup en 5 minutos
|
|
18
|
+
- Código completo listo para copiar
|
|
19
|
+
- Testing sin pasar por login
|
|
20
|
+
- Configuración recomendada
|
|
21
|
+
|
|
22
|
+
### **[INTEGRATION_EXAMPLES.md](./INTEGRATION_EXAMPLES.md)**
|
|
23
|
+
Ejemplos para otros frameworks:
|
|
24
|
+
- Vue.js / Nuxt
|
|
25
|
+
- Next.js (App Router)
|
|
26
|
+
- Vanilla JavaScript
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 🛠️ Configuración
|
|
31
|
+
|
|
32
|
+
### **[NPM_PUBLISH.md](./NPM_PUBLISH.md)**
|
|
33
|
+
Guía para publicar actualizaciones en NPM
|
|
34
|
+
|
|
35
|
+
### **[SDK_FINAL_STATUS.md](./SDK_FINAL_STATUS.md)**
|
|
36
|
+
Estado actual del SDK y estructura de archivos
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 🔧 Estructura del SDK
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
sdk/
|
|
44
|
+
├── tgtone-auth-client.ts # SDK principal (Bearer Token)
|
|
45
|
+
├── react-hook.tsx # Hook de React (opcional)
|
|
46
|
+
├── index.ts # Exports
|
|
47
|
+
├── package.json # v1.0.2
|
|
48
|
+
├── README.md # Guía principal
|
|
49
|
+
└── docs/ # Documentación completa
|
|
50
|
+
├── README.md # Este archivo
|
|
51
|
+
├── LOVABLE_QUICK_START.md
|
|
52
|
+
├── INTEGRATION_EXAMPLES.md
|
|
53
|
+
├── NPM_PUBLISH.md
|
|
54
|
+
└── SDK_FINAL_STATUS.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 🎯 Por Dónde Empezar
|
|
60
|
+
|
|
61
|
+
| Quiero... | Ver |
|
|
62
|
+
|-----------|-----|
|
|
63
|
+
| Usarlo en Lovable ahora | [LOVABLE_QUICK_START.md](./LOVABLE_QUICK_START.md) |
|
|
64
|
+
| Ver API completa | [README.md](../README.md) |
|
|
65
|
+
| Ejemplos Vue/Next | [INTEGRATION_EXAMPLES.md](./INTEGRATION_EXAMPLES.md) |
|
|
66
|
+
| Publicar actualización | [NPM_PUBLISH.md](./NPM_PUBLISH.md) |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 🔐 Información Clave
|
|
71
|
+
|
|
72
|
+
**Autenticación:** JWT + Bearer Token en Authorization header
|
|
73
|
+
**Storage:** localStorage (`tgtone_auth_token`)
|
|
74
|
+
**Redirect:** Automático con parámetro `?token=` en URL
|
|
75
|
+
**CORS:** Backend tiene CORS abierto en staging
|
|
76
|
+
|
|
77
|
+
**Versión Actual:** 1.0.2
|
|
78
|
+
**Backend Staging:** https://tgtone-identity-backend-1086175589490.us-central1.run.app
|
|
79
|
+
**Backend Producción:** (Pendiente configurar identity.tgtone.cl)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
**Última actualización:** 2025-10-16
|