feat(auth): login JWT en API y las 4 apps

- Modelo Usuario + seed desde lista de vendedores (18 usuarios, bcrypt cost 12)
- POST /api/auth/login + /api/auth/me; middleware Bearer en todo /api
  excepto health, login y webhook Monday; flag AUTH_ENABLED
- Username = nombre completo normalizado (case/acentos insensible),
  password inicial Frasa2026, admin vía ADMIN_PASSWORD
- Apps: LoginScreen + AuthGate (StudioBlank), token en localStorage,
  header Authorization en todas las llamadas, logout en 401
- Tests: api 136, cotizador 71, alta 65, cobranza 71, agente-ia 13, landing 4
This commit is contained in:
2026-08-27 08:20:25 +00:00
parent b39fe6334f
commit de11af985e
40 changed files with 2085 additions and 38 deletions

View File

@@ -0,0 +1,22 @@
import type { Request, Response } from 'express'
import { z } from 'zod'
import { login, me } from '../services/auth.service.js'
import { BadRequestError } from '../utils/errors.js'
const loginSchema = z.object({
username: z.string().min(1),
password: z.string().min(1),
})
/** POST /api/auth/login → { token, usuario } */
export async function loginEndpoint(req: Request, res: Response): Promise<void> {
const { username, password } = loginSchema.parse(req.body)
const resultado = await login(username, password)
res.json(resultado)
}
/** GET /api/auth/me (Bearer) → usuario público del token */
export async function meEndpoint(req: Request, res: Response): Promise<void> {
if (!req.usuarioToken) throw new BadRequestError('Falta el token verificado')
res.json(await me(req.usuarioToken))
}