@quadcore-lib/auth-server
v0.2.0
Published
Módulo NestJS que resuelve autenticación via Auth0 JWT y autorización por roles almacenados en DB propia.
Downloads
78
Readme
@quadcore-lib/auth-server
Módulo NestJS que resuelve autenticación via Auth0 JWT y autorización por roles almacenados en DB propia.
Instalación
npm install @quadcore-lib/auth-serverRequisitos
Peer dependencies que la app consumidora debe tener instaladas:
npm install @nestjs/common @nestjs/core @nestjs/typeorm typeorm reflect-metadataTu app también necesita TypeOrmModule.forRoot() configurado con una DB que incluya la tabla users.
Uso
1. Registrar el módulo
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { QuadcoreAuthModule } from '@quadcore-lib/auth-server';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
url: process.env.DATABASE_URL,
autoLoadEntities: true,
}),
QuadcoreAuthModule.forRoot({
domain: 'mi-tenant.auth0.com',
audience: 'https://api.miapp.com',
}),
],
})
export class AppModule {}2. Proteger rutas con JWT
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard, CurrentUser } from '@quadcore-lib/auth-server';
@Controller('perfil')
export class PerfilController {
@UseGuards(JwtAuthGuard)
@Get()
getPerfil(@CurrentUser() user: Record<string, unknown>) {
return user; // payload del JWT de Auth0
}
}3. Restringir por rol
import { Controller, Delete, Param, UseGuards } from '@nestjs/common';
import { JwtAuthGuard, RolesGuard, Roles } from '@quadcore-lib/auth-server';
@Controller('usuarios')
export class UsuariosController {
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Delete(':id')
eliminar(@Param('id') id: string) {
return { eliminado: id };
}
}RolesGuard lee el rol desde la tabla users en tu DB, no desde el token.
4. Crear o sincronizar usuarios desde Auth0
import { Injectable } from '@nestjs/common';
import { AuthService } from '@quadcore-lib/auth-server';
@Injectable()
export class OnboardingService {
constructor(private readonly authService: AuthService) {}
async sincronizar(auth0Id: string, email: string) {
return this.authService.findOrCreate(auth0Id, email);
}
}API
QuadcoreAuthModule
| Método | Descripción |
|---|---|
| forRoot(options) | Registra el módulo globalmente con la configuración de Auth0 |
AuthModuleOptions
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| domain | string | sí | Dominio Auth0, ej: mi-tenant.auth0.com |
| audience | string | sí | Audience del API en Auth0 |
| emailClaim | string | no | Namespace del claim donde viaja el email si no está en la raíz del token. Ej: https://quadcoreai.com/email. Requiere una Action de Auth0 que lo inyecte. Sin email válido, GET /auth/me responde 400. |
RolesGuard siempre lee la columna role de UserEntity (fija, no configurable): @Entity/@Column son estáticos en TypeORM, así que no hay forma de parametrizar el nombre de columna en runtime sin una entidad distinta. Si tu esquema usa otro nombre para el rol, extendé/reemplazá UserEntity en tu proyecto en vez de esperar una opción roleField.
Guards
| Export | Tipo | Descripción |
|---|---|---|
| JwtAuthGuard | Guard | Valida el JWT de Auth0 via JWKS. Rechaza con 401 si el token es inválido o expiró |
| RolesGuard | Guard | Verifica el rol del usuario contra la DB. Usar siempre junto a JwtAuthGuard |
Decoradores
| Export | Uso | Descripción |
|---|---|---|
| @CurrentUser() | Param decorator | Inyecta el payload del JWT en el parámetro del handler |
| @Roles(...roles) | Method/Class decorator | Define los roles requeridos para acceder al endpoint |
Servicios
| Export | Método | Descripción |
|---|---|---|
| AuthService | findOrCreate(auth0Id, email) | Busca o crea el usuario en DB de forma idempotente (insert ON CONFLICT DO NOTHING + re-lectura; tolera requests concurrentes). Lanza 409 si el email ya pertenece a otra cuenta. |
| AuthService | findByAuth0Id(auth0Id) | Devuelve el usuario por su ID de Auth0 o null |
Entidades
| Export | Tabla | Columnas |
|---|---|---|
| UserEntity | users | id (uuid), email, role (default: "user"), auth0Id, createdAt, updatedAt |
Enforcement de estado de cuenta (opcional)
El JwtAuthGuard puede rechazar (403) cuentas desactivadas o borradas. No lo resuelve auth-server (su UserEntity es minimal): define el puerto AccountStatusProvider (token ACCOUNT_STATUS_PROVIDER) que el guard inyecta de forma opcional. @quadcore-lib/users-server provee la implementación que cruza users con user_accounts; registrándolo, el enforcement se activa solo. Sin provider, el guard no hace el chequeo (retrocompatible).
Flujo de autenticación
Request → JwtAuthGuard
↓ GET https://{domain}/.well-known/jwks.json
↓ valida firma RS256 + audience + issuer
↓ setea request.user = payload del JWT
RolesGuard (si se usa)
↓ lee user.sub del payload
↓ consulta SELECT * FROM users WHERE auth0Id = sub
↓ compara user.role con @Roles(...)
HandlerMigraciones
Este paquete trae sus migraciones de TypeORM en dist/src/migrations/*.js (se compilan junto al resto). Ver la guía completa (setup del DataSource, cómo combinarlas con las de otros paquetes, synchronize en dev vs. prod) en el README de @quadcore-lib/core-server, sección "Migraciones de DB".
