|
Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Core: - Add catalog reference implementations (auth, payments, notifications, websocket, etc.) - New agent profiles: Database Auditor, Integration Validator, LLM Agent, Policy Auditor, Trading Strategist - Update SIMCO directives and add escalation/git guidelines - Add deployment inventory and audit execution reports Projects: - erp-suite: DevOps configs, Dockerfiles, shared libs, vertical enhancements - gamilit: Test structure, admin controllers, service refactoring, husky/commitlint - trading-platform: MT4 gateway, auth controllers, admin frontend, deployment scripts - platform_marketing_content: Full DevOps setup, tests, Docker configs - betting-analytics/inmobiliaria-analytics: Initial app structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| _reference | ||
| IMPLEMENTATION.md | ||
| README.md | ||
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
backend:
framework: NestJS
orm: TypeORM
crypto: Node.js crypto (SHA256)
database:
engine: PostgreSQL
schemas:
- auth_management (sesiones)
Dependencias NPM
{
"typeorm": "^0.3.x",
"@nestjs/typeorm": "^10.x"
}
Nota: crypto es nativo de Node.js, no requiere instalación.
Tabla Requerida
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
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
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
// En UsersController
@Get('sessions')
@UseGuards(JwtAuthGuard)
async getSessions(@Request() req) {
return this.sessionManagementService.getSessions(req.user.id);
}
3. Revocar sesión
// 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
// 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
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
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
// El refresh token se hashea antes de guardar en BD
const hashedToken = crypto.createHash('sha256')
.update(refreshToken)
.digest('hex');
Validación de Propiedad
// 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 = falseyrevoked_at - Limpieza periódica de datos obsoletos
- No se serializa
refresh_tokenen respuestas
Adaptaciones Necesarias
- Límite de sesiones: Ajustar
MAX_SESSIONS_PER_USERsegún necesidades - Tiempo de expiración: Configurar según política de seguridad
- Geo-location: Implementar si se requiere país/ciudad
- Multi-tenant: Omitir
tenant_idsi no aplica - 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