@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.
@@ -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