@tgtone/auth-sdk 1.4.2 → 1.4.4

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.
@@ -1,316 +0,0 @@
1
- # 🔐 TGT Auth SDK - Guía para Lovable/React
2
-
3
- > Integración rápida de autenticación en proyectos React/Lovable
4
-
5
- ---
6
-
7
- ## 📦 Instalación
8
-
9
- ```bash
10
- npm install @tgtone/auth-sdk
11
- ```
12
-
13
- **Versión actual:** 1.2.3
14
-
15
- ---
16
-
17
- ## ⚡ Setup en 3 Pasos
18
-
19
- ### **1. Crear AuthContext**
20
-
21
- ```typescript
22
- // src/contexts/AuthContext.tsx
23
- import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
24
- import { TGTAuthClient, TGTUser } from '@tgtone/auth-sdk';
25
-
26
- // Extender TGTSession para incluir roles (están en user.roles)
27
- interface TGTSession {
28
- user: TGTUser;
29
- tenantId: string;
30
- tenantName: string;
31
- expiresAt: Date;
32
- }
33
-
34
- interface AuthContextType {
35
- session: TGTSession | null;
36
- user: TGTUser | null; // Acceso directo al usuario
37
- tenantId: string | null; // Acceso directo
38
- loading: boolean;
39
- logout: () => Promise<void>;
40
- hasRole: (app: string, role: string) => boolean;
41
- hasAccessToApp: (appName: string) => boolean;
42
- getRoles: (appName: string) => string[];
43
- getToken: () => string | null; // Para API calls
44
- isAuthenticated: boolean; // Shorthand
45
- }
46
-
47
- const AuthContext = createContext<AuthContextType | null>(null);
48
-
49
- // ✅ Singleton FUERA del componente (evita re-crear en cada render)
50
- let authClient: TGTAuthClient | null = null;
51
-
52
- const getAuthClient = (): TGTAuthClient => {
53
- if (!authClient) {
54
- authClient = new TGTAuthClient({
55
- identityUrl: import.meta.env.VITE_IDENTITY_URL || 'https://identity.tgtone.cl',
56
- appDomain: window.location.host, // Usa .host (incluye puerto) para dev
57
- debug: import.meta.env.DEV
58
- });
59
- }
60
- return authClient;
61
- };
62
-
63
- export function AuthProvider({ children }: { children: ReactNode }) {
64
- const [session, setSession] = useState<TGTSession | null>(null);
65
- const [loading, setLoading] = useState(true);
66
-
67
- useEffect(() => {
68
- const initAuth = async () => {
69
- try {
70
- const auth = getAuthClient();
71
- const currentSession = await auth.checkSession();
72
- setSession(currentSession as TGTSession);
73
- } catch (error) {
74
- console.error('Error checking session:', error);
75
- setSession(null);
76
- } finally {
77
- setLoading(false);
78
- }
79
- };
80
- initAuth();
81
- }, []);
82
-
83
- const logout = async () => {
84
- const auth = getAuthClient();
85
- await auth.logout();
86
- setSession(null);
87
- };
88
-
89
- const hasRole = (app: string, role: string) => {
90
- return getAuthClient().hasRole(app, role);
91
- };
92
-
93
- const hasAccessToApp = (appName: string) => {
94
- return getAuthClient().hasAccessToApp(appName);
95
- };
96
-
97
- const getRoles = (appName: string) => {
98
- return getAuthClient().getRoles(appName);
99
- };
100
-
101
- const getToken = () => {
102
- return getAuthClient().getToken();
103
- };
104
-
105
- return (
106
- <AuthContext.Provider value={{
107
- session,
108
- user: session?.user || null,
109
- tenantId: session?.tenantId || null,
110
- loading,
111
- logout,
112
- hasRole,
113
- hasAccessToApp,
114
- getRoles,
115
- getToken,
116
- isAuthenticated: !!session
117
- }}>
118
- {/* ⚠️ CRÍTICO: No renderizar hijos mientras carga para evitar que el Router
119
- limpie los parámetros de la URL (?token=...) antes de que el SDK los procese */}
120
- {loading ? (
121
- <div className="flex items-center justify-center min-h-screen">
122
- <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
123
- </div>
124
- ) : (
125
- children
126
- )}
127
- </AuthContext.Provider>
128
- );
129
- }
130
-
131
- export const useAuth = () => {
132
- const context = useContext(AuthContext);
133
- if (!context) throw new Error('useAuth must be used within AuthProvider');
134
- return context;
135
- };
136
- ```
137
-
138
- ### **2. Envolver App**
139
-
140
- ```tsx
141
- // src/App.tsx
142
- import { AuthProvider } from './contexts/AuthContext';
143
-
144
- function App() {
145
- return (
146
- <AuthProvider>
147
- {/* Tu app */}
148
- </AuthProvider>
149
- );
150
- }
151
- ```
152
-
153
- ### **3. Usar en Componentes**
154
-
155
- ```tsx
156
- import { useAuth } from './contexts/AuthContext';
157
-
158
- function Dashboard() {
159
- const { user, tenantId, loading, logout, hasRole, isAuthenticated } = useAuth();
160
-
161
- if (loading) return <div>Cargando...</div>;
162
-
163
- if (!isAuthenticated) return null; // Ya está redirigiendo a login
164
-
165
- return (
166
- <div>
167
- <h1>Bienvenido {user?.name}</h1>
168
- <p>Tenant: {tenantId}</p>
169
-
170
- {hasRole('console', 'admin') && (
171
- <button>Panel Admin</button>
172
- )}
173
-
174
- <button onClick={logout}>Cerrar Sesión</button>
175
- </div>
176
- );
177
- }
178
- ```
179
-
180
- ---
181
-
182
- ## 🎯 Propiedades de Sesión
183
-
184
- ```typescript
185
- // Datos del usuario
186
- session.user.email // "user@empresa.cl"
187
- session.user.name // "Juan Pérez"
188
- session.user.sub // "uuid-user-123" (ID del usuario)
189
-
190
- // Datos del tenant
191
- session.tenantId // "uuid-tenant-123"
192
- session.tenantName // "Mi Empresa"
193
-
194
- // ⚠️ IMPORTANTE: Los roles están en USER, no en session
195
- session.user.roles // { console: ['owner'], crm: ['admin'] }
196
-
197
- // Expiración
198
- session.expiresAt // Date object
199
- ```
200
-
201
- > **Nota:** Los roles se acceden via `session.user.roles`, NO `session.roles`
202
-
203
- ---
204
-
205
- ## 🔐 Verificar Roles
206
-
207
- ```typescript
208
- // Usando el hook useAuth (recomendado)
209
- const { hasRole, hasAccessToApp, getRoles } = useAuth();
210
-
211
- // ¿Es admin de Console?
212
- if (hasRole('console', 'admin')) {
213
- // Mostrar funciones de admin
214
- }
215
-
216
- // ¿Tiene acceso a CRM?
217
- if (hasAccessToApp('crm')) {
218
- // Mostrar enlace a CRM
219
- }
220
-
221
- // Obtener todos los roles en una app
222
- const roles = getRoles('console'); // ['owner', 'admin']
223
-
224
- // Verificar múltiples roles
225
- const isAdmin = hasRole('myapp', 'admin') || hasRole('myapp', 'owner');
226
- ```
227
-
228
- ---
229
-
230
- ## 🆕 Verificación Silenciosa (v1.2.0)
231
-
232
- Para páginas que no requieren autenticación obligatoria:
233
-
234
- ```typescript
235
- // Landing page o página pública
236
- useEffect(() => {
237
- const checkAuth = async () => {
238
- const session = await authClient.checkSessionSilent();
239
-
240
- if (session) {
241
- // Usuario logeado - mostrar contenido personalizado
242
- showButton('Ir al Dashboard', '/dashboard');
243
- } else {
244
- // Usuario no logeado - mostrar botón de login
245
- showButton('Iniciar Sesión', () => authClient.redirectToLogin());
246
- }
247
- };
248
-
249
- checkAuth();
250
- }, []);
251
- ```
252
-
253
- ---
254
-
255
- ## 🔄 Flujo de Autenticación
256
-
257
- ```
258
- 1. Usuario entra a tu app
259
-
260
- 2. checkSession() no encuentra token
261
-
262
- 3. SDK redirige a identity.tgtone.cl/login
263
-
264
- 4. Usuario hace login (+ MFA si está habilitado)
265
-
266
- 5. Identity redirige: tu-app?token=eyJhbGci...
267
-
268
- 6. SDK guarda token y valida con backend
269
-
270
- 7. ✅ Usuario autenticado
271
- ```
272
-
273
- ---
274
-
275
- ## 🧪 Testing sin Login
276
-
277
- ```typescript
278
- // Guardar token manualmente en localStorage
279
- localStorage.setItem('tgtone_auth_token', 'eyJhbGci...');
280
- window.location.reload();
281
-
282
- // Obtener token de prueba con curl:
283
- // curl -X POST https://tgtone-console-backend.run.app/api/v1/auth/login \
284
- // -d '{"email": "user@test.cl", "password": "Test123!"}'
285
- ```
286
-
287
- ---
288
-
289
- ## 📚 API Completa
290
-
291
- Ver documentación completa: **[README.md](../README.md)**
292
-
293
- Métodos disponibles:
294
- - `checkSession()` - Verifica sesión (redirige si no hay)
295
- - `checkSessionSilent()` - Verifica sin redirigir
296
- - `signup()` - Crear cuenta
297
- - `login()` - Iniciar sesión
298
- - `logout()` - Cerrar sesión
299
- - `verifyMfa()` - Validar código MFA
300
- - `hasRole()` - Verificar roles
301
- - `redirectToLogin()` - Redirigir a login
302
-
303
- ---
304
-
305
- ## 🔧 Variables de Entorno
306
-
307
- ```env
308
- # .env.local
309
- VITE_IDENTITY_URL=https://identity.tgtone.cl
310
- ```
311
-
312
- > En desarrollo local, si no defines `VITE_IDENTITY_URL`, usará `https://identity.tgtone.cl` por defecto.
313
-
314
- ---
315
-
316
- **Última actualización:** 2025-12-19