UDT-001: Login (scaffolding + JWT RS256 end-to-end) #1
134
docs/smoke-test-udt-001.md
Normal file
134
docs/smoke-test-udt-001.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Smoke Test — UDT-001 Login
|
||||
|
||||
Manual checklist para verificar la integración completa del flujo de login.
|
||||
|
||||
## Pre-requisitos
|
||||
|
||||
- SQL Server TECNICA3 con base `SIGCM2` y seed admin ejecutado (`database/seeds/S001__seed_admin.sql`)
|
||||
- Claves RSA generadas: `scripts/generate-keys.ps1` ya corrido
|
||||
- `src/api/SIGCM2.Api/appsettings.Development.json` configurado con connection string y rutas de claves
|
||||
- Node.js 18+ instalado
|
||||
- .NET 10 SDK instalado
|
||||
|
||||
## Pasos
|
||||
|
||||
### 1. Arrancar el backend
|
||||
|
||||
Abrir Terminal 1 en la raíz del repositorio:
|
||||
|
||||
```bash
|
||||
dotnet run --project src/api/SIGCM2.Api
|
||||
```
|
||||
|
||||
Verificar que la consola muestre algo similar a:
|
||||
|
||||
```
|
||||
Now listening on: http://localhost:5000
|
||||
Application started. Press Ctrl+C to shut down.
|
||||
```
|
||||
|
||||
### 2. Arrancar el frontend
|
||||
|
||||
Abrir Terminal 2:
|
||||
|
||||
```bash
|
||||
cd src/web
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Verificar que la consola muestre:
|
||||
|
||||
```
|
||||
VITE v8.x.x ready in Xms
|
||||
|
||||
➜ Local: http://localhost:5173/
|
||||
```
|
||||
|
||||
### 3. Verificar redirect a /login
|
||||
|
||||
- Abrir `http://localhost:5173` en el navegador
|
||||
- Debe redirigir automáticamente a `http://localhost:5173/login`
|
||||
- Debe mostrar el formulario de login con campos **Usuario** y **Contraseña**
|
||||
|
||||
**Esperado**: Formulario visible, sin errores en consola del navegador.
|
||||
|
||||
### 4. Login con credenciales válidas
|
||||
|
||||
- Ingresar `admin` en el campo **Usuario**
|
||||
- Ingresar `@Diego550@` en el campo **Contraseña**
|
||||
- Hacer click en **Ingresar**
|
||||
|
||||
**Esperado**: Botón se deshabilita brevemente mientras carga.
|
||||
|
||||
### 5. Verificar Network tab — POST /api/v1/auth/login
|
||||
|
||||
- Abrir DevTools → pestaña **Network**
|
||||
- Buscar la request `POST /api/v1/auth/login`
|
||||
- Verificar:
|
||||
- Status: `200 OK`
|
||||
- Response body contiene: `accessToken`, `refreshToken`, `expiresIn`, `usuario`
|
||||
- `usuario.username` = `"admin"`, `usuario.rol` = `"admin"`
|
||||
|
||||
**Esperado**: Respuesta 200 con JWT válido.
|
||||
|
||||
### 6. Verificar LocalStorage — auth-storage
|
||||
|
||||
- DevTools → pestaña **Application** → Storage → Local Storage → `http://localhost:5173`
|
||||
- Buscar clave `auth-storage`
|
||||
- Verificar que el JSON contenga:
|
||||
```json
|
||||
{
|
||||
"state": {
|
||||
"user": { "username": "admin", "rol": "admin", ... },
|
||||
"accessToken": "eyJ..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Esperado**: Token y datos de usuario persistidos correctamente.
|
||||
|
||||
### 7. Verificar redirect a Dashboard
|
||||
|
||||
- Luego del login exitoso, la URL debe cambiar a `http://localhost:5173/`
|
||||
- Debe mostrarse: **"SIG-CM2 — Dashboard — Bienvenido al SIG-CM2."**
|
||||
|
||||
**Esperado**: Placeholder de Dashboard visible.
|
||||
|
||||
### 8. Verificar firma JWT en jwt.io
|
||||
|
||||
- Copiar el valor de `accessToken` del LocalStorage
|
||||
- Abrir [https://jwt.io](https://jwt.io)
|
||||
- Pegar el token en el campo "Encoded"
|
||||
- En "VERIFY SIGNATURE" → sección "Public Key or Certificate": pegar el contenido de `src/api/SIGCM2.Api/keys/public.pem`
|
||||
- Verificar:
|
||||
- Header: `"alg": "RS256"`
|
||||
- Payload contiene: `sub`, `name` (= `"admin"`), `rol` (= `"admin"`), `permisos` (= `["*"]`), `iss`, `aud`, `exp`
|
||||
- Footer muestra: **"Signature Verified"** (fondo azul)
|
||||
|
||||
**Esperado**: Firma RS256 válida, claims correctos.
|
||||
|
||||
### 9. Probar login fallido
|
||||
|
||||
- Volver a `http://localhost:5173/login` (o hacer logout si hubiera botón)
|
||||
- Ingresar `admin` / `wrongpass`
|
||||
- Hacer click en **Ingresar**
|
||||
- Verificar en **Network**: `POST /api/v1/auth/login` → Status `401`
|
||||
- Verificar en la UI: mensaje de error visible con texto **"Credenciales inválidas"** (sin stack trace)
|
||||
|
||||
**Esperado**: Error visible en UI, sin exposición de detalles internos.
|
||||
|
||||
---
|
||||
|
||||
## Resultado esperado global
|
||||
|
||||
| Paso | Resultado |
|
||||
|------|-----------|
|
||||
| 1. Backend arranca en :5000 | ✅ / ❌ |
|
||||
| 2. Frontend arranca en :5173 | ✅ / ❌ |
|
||||
| 3. Redirect a /login | ✅ / ❌ |
|
||||
| 4. Login con admin/@Diego550@ | ✅ / ❌ |
|
||||
| 5. Network: POST 200 + JWT | ✅ / ❌ |
|
||||
| 6. LocalStorage: auth-storage con token | ✅ / ❌ |
|
||||
| 7. Redirect a / Dashboard | ✅ / ❌ |
|
||||
| 8. JWT verificado en jwt.io (RS256) | ✅ / ❌ |
|
||||
| 9. Login fallido: error en UI, 401 en Network | ✅ / ❌ |
|
||||
Reference in New Issue
Block a user