workspace-v1/shared/libs/session-management/README.md
rckrdmrd 66161b1566 feat: Workspace-v1 complete migration with NEXUS v3.4
Sistema NEXUS v3.4 migrado con:

Estructura principal:
- core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles)
- core/catalog: Catalogo de funcionalidades reutilizables
- shared/knowledge-base: Base de conocimiento compartida
- devtools/scripts: Herramientas de desarrollo
- control-plane/registries: Control de servicios y CI/CD
- orchestration/: Configuracion de orquestacion de agentes

Proyectos incluidos (11):
- gamilit (submodule -> GitHub)
- trading-platform (OrbiquanTIA)
- erp-suite con 5 verticales:
  - erp-core, construccion, vidrio-templado
  - mecanicas-diesel, retail, clinicas
- betting-analytics
- inmobiliaria-analytics
- platform_marketing_content
- pos-micro, erp-basico

Configuracion:
- .gitignore completo para Node.js/Python/Docker
- gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git)
- Sistema de puertos estandarizado (3005-3199)

Generated with NEXUS v3.4 Migration System
EPIC-010: Configuracion Git y Repositorios
2026-01-04 03:37:42 -06:00

302 lines
7.2 KiB
Markdown

# Gestión de Sesiones
**Versión:** 1.0.0
**Origen:** projects/gamilit
**Estado:** Producción
**Última actualización:** 2025-12-08
---
## Descripción
Sistema de gestión de sesiones de usuario con:
- Múltiples sesiones concurrentes (máx 5)
- Tracking de dispositivo, IP, ubicación
- Renovación automática con refresh tokens
- Revocación individual y masiva
- Limpieza automática de sesiones expiradas
---
## Características
| Característica | Descripción |
|----------------|-------------|
| Multi-sesión | Hasta 5 sesiones concurrentes por usuario |
| Auto-limpieza | Sesiones más antiguas eliminadas automáticamente |
| Device Tracking | IP, User-Agent, dispositivo, navegador, OS |
| Geo-location | País y ciudad (si disponible) |
| Refresh Tokens | Hasheados con SHA256 |
| Revocación | Individual o masiva |
| Multi-tenant | Soporte para múltiples tenants |
---
## Stack Tecnológico
```yaml
backend:
framework: NestJS
orm: TypeORM
crypto: Node.js crypto (SHA256)
database:
engine: PostgreSQL
schemas:
- auth_management (sesiones)
```
---
## Dependencias NPM
```json
{
"typeorm": "^0.3.x",
"@nestjs/typeorm": "^10.x"
}
```
Nota: crypto es nativo de Node.js, no requiere instalación.
---
## Tabla Requerida
```sql
CREATE TABLE auth_management.user_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
tenant_id UUID,
session_token TEXT NOT NULL UNIQUE,
refresh_token TEXT, -- Hasheado con SHA256
user_agent TEXT,
ip_address INET,
device_type VARCHAR(50), -- desktop, mobile, tablet, unknown
browser VARCHAR(100),
os VARCHAR(100),
country VARCHAR(100),
city VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT NOW(),
last_activity_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
revoked_at TIMESTAMPTZ,
metadata JSONB DEFAULT '{}'
);
-- Índices
CREATE INDEX idx_user_sessions_user_id ON auth_management.user_sessions(user_id);
CREATE INDEX idx_user_sessions_tenant_id ON auth_management.user_sessions(tenant_id);
CREATE INDEX idx_user_sessions_session_token ON auth_management.user_sessions(session_token);
CREATE INDEX idx_user_sessions_expires_at ON auth_management.user_sessions(expires_at);
```
---
## Estructura del Módulo
```
session-management/
├── services/
│ └── session-management.service.ts
├── entities/
│ └── user-session.entity.ts
├── dto/
│ ├── create-user-session.dto.ts
│ ├── update-user-session.dto.ts
│ └── user-session-response.dto.ts
└── __tests__/
└── session-management.service.spec.ts
```
---
## API del Servicio
```typescript
class SessionManagementService {
// Crear nueva sesión
async createSession(dto: CreateUserSessionDto): Promise<UserSession>;
// Validar sesión y actualizar actividad
async validateSession(sessionId: string): Promise<UserSession | null>;
// Renovar sesión
async refreshSession(sessionId: string, newExpiresAt: Date): Promise<UserSession>;
// Revocar sesión específica
async revokeSession(sessionId: string, userId: string): Promise<{ message: string }>;
// Revocar todas excepto la actual
async revokeAllSessions(userId: string, currentSessionId: string): Promise<{ message: string; count: number }>;
// Limpiar sesiones expiradas (cron)
async cleanExpiredSessions(): Promise<number>;
// Obtener sesiones activas del usuario
async getSessions(userId: string): Promise<UserSession[]>;
}
```
---
## Uso Rápido
### 1. Crear sesión al login
```typescript
import { SessionManagementService } from '@/modules/auth/services';
// En AuthService.login()
const session = await this.sessionManagementService.createSession({
user_id: user.id,
tenant_id: profile.tenant_id,
session_token: crypto.randomBytes(32).toString('hex'),
refresh_token: refreshToken, // Será hasheado internamente
ip_address: req.ip,
user_agent: req.headers['user-agent'],
device_type: this.detectDeviceType(userAgent),
browser: this.detectBrowser(userAgent),
os: this.detectOS(userAgent),
expires_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 días
});
```
### 2. Obtener sesiones activas
```typescript
// En UsersController
@Get('sessions')
@UseGuards(JwtAuthGuard)
async getSessions(@Request() req) {
return this.sessionManagementService.getSessions(req.user.id);
}
```
### 3. Revocar sesión
```typescript
// En UsersController
@Delete('sessions/:id')
@UseGuards(JwtAuthGuard)
async revokeSession(@Param('id') sessionId: string, @Request() req) {
return this.sessionManagementService.revokeSession(sessionId, req.user.id);
}
```
### 4. Cerrar todas las sesiones
```typescript
// En UsersController
@Post('sessions/revoke-all')
@UseGuards(JwtAuthGuard)
async revokeAllSessions(@Request() req, @Body() body: { currentSessionId: string }) {
return this.sessionManagementService.revokeAllSessions(
req.user.id,
body.currentSessionId
);
}
```
### 5. Cron job para limpieza
```typescript
import { Cron, CronExpression } from '@nestjs/schedule';
@Cron(CronExpression.EVERY_HOUR)
async cleanExpiredSessions() {
const count = await this.sessionManagementService.cleanExpiredSessions();
this.logger.log(`Limpiadas ${count} sesiones expiradas`);
}
```
---
## Comportamientos Clave
### Límite de Sesiones
```typescript
MAX_SESSIONS_PER_USER = 5;
// Al crear la 6ta sesión:
// 1. Se eliminan sesiones expiradas
// 2. Si aún hay 5+, se elimina la más antigua
// 3. Se crea la nueva sesión
```
### Hasheo de Refresh Tokens
```typescript
// El refresh token se hashea antes de guardar en BD
const hashedToken = crypto.createHash('sha256')
.update(refreshToken)
.digest('hex');
```
### Validación de Propiedad
```typescript
// Solo el dueño puede revocar sus sesiones
await this.sessionRepository.findOne({
where: { id: sessionId, user_id: userId }, // Validación de ownership
});
```
---
## Flujo de Sesiones
```
LOGIN
├─► Crear sesión con tokens
│ ├─► Limpiar expiradas
│ ├─► Si >5, eliminar antigua
│ └─► Guardar nueva sesión
REFRESH
├─► Validar refresh token
├─► Buscar sesión por hash
└─► Actualizar expiración
LOGOUT
└─► Marcar sesión como inactiva
└─► Establecer revoked_at
```
---
## Seguridad
- Refresh tokens nunca se almacenan en texto plano
- Validación de ownership en revocación
- Soft delete con `is_active = false` y `revoked_at`
- Limpieza periódica de datos obsoletos
- No se serializa `refresh_token` en respuestas
---
## Adaptaciones Necesarias
1. **Límite de sesiones**: Ajustar `MAX_SESSIONS_PER_USER` según necesidades
2. **Tiempo de expiración**: Configurar según política de seguridad
3. **Geo-location**: Implementar si se requiere país/ciudad
4. **Multi-tenant**: Omitir `tenant_id` si no aplica
5. **Cron schedule**: Ajustar frecuencia de limpieza
---
## Referencias
- Código completo: `projects/gamilit/apps/backend/src/modules/auth/services/session-management.service.ts`
- Entity: `projects/gamilit/apps/backend/src/modules/auth/entities/user-session.entity.ts`
---
**Mantenido por:** Sistema NEXUS
**Proyecto origen:** Gamilit Platform