449 lines
15 KiB
Markdown

# Internet Banking - Aplicación Web Segura
Aplicación web de Internet Banking construida con **Next.js 14 (App Router)**, **TypeScript**, **TailwindCSS + daisyUI**, y **Zustand** para gestión de estado. El backend está desarrollado en **Java 25 Spring Boot** y protegido por **Kong Gateway**.
## 🚀 Características
-**Autenticación segura** con tokens JWT en cookies HTTP-only
-**Server Components** de Next.js para máximo rendimiento
-**Middleware de autenticación** server-side
-**Sistema de logs** centralizado (escribe en archivo .txt)
-**Encriptación Kong** para datos sensibles
-**UI moderna** con TailwindCSS y daisyUI
-**TypeScript** para type-safety completo
-**Zustand** para estado cliente (no Redux)
-**Sin useEffect/useContext** innecesarios (server-first)
# Internet Banking (Next.js)
This repository contains a Next.js application scaffolded with `create-next-app`.
## Getting started
1. Install dependencies:
```bash
npm install
```
2. Run the development server:
```bash
npm run dev
# then open http://localhost:3000
```
## Requisitos
- Node.js 18 LTS o superior
## Instalación y ejecución
1. Instala las dependencias:
```bash
npm install
```
2. Ejecuta el servidor de desarrollo:
```bash
npm run dev
# luego abre http://localhost:3000
```
## Dependencias
Las dependencias actuales (según `package.json`):
### Runtime
- `next` 15.5.6
- `react` 19.1.0
- `react-dom` 19.1.0
- `daisyui` 5.4.5
- `react-icons` 5.5.0
- `zustand` 5.0.8
### Desarrollo
- `typescript` 5
- `@types/node` 20
- `@types/react` 19
- `@types/react-dom` 19
- `eslint` 9
- `@eslint/eslintrc` 3
- `eslint-config-next` 15.5.6
- `tailwindcss` 4.1.17
- `@tailwindcss/postcss` 4.1.17
## Notas
- Para ejecutar el linter localmente:
```bash
npm run lint
```
## 🤖 Infraestructura de Ingeniería AI-Native (Agentes y Esquema MCP)
Esta aplicación está diseñada desde sus cimientos para el desarrollo asistido por **Agentes de Inteligencia Artificial Autónomos** mediante el protocolo **MCP (Model Context Protocol)**, asegurando consistencia arquitectónica, memoria persistente entre sesiones y navegación contextual ultra-rápida.
### 1. El Esquema de Servidores MCP (mcp_config.json)
Para iniciar el entorno de desarrollo con soporte de IA y permitir que los agentes se auto-direccionen, debes registrar los siguientes servidores en el archivo de configuración global de tu entorno de ejecución (ej. `~/.gemini/antigravity/mcp_config.json`):
```json
{
"mcpServers": {
"engram": {
"command": "engram",
"args": [
"mcp",
"--tools=agent"
]
},
"graphify": {
"command": "d:\\Jess\\agent\\graphify\\.venv\\Scripts\\python.exe",
"args": [
"-m",
"graphify.serve",
"d:/Jess/agent/frontend-ai/graphify-out/graph.json"
]
}
}
}
```
* **Engram (Memoria Persistente)**: Servidor escrito en Go que expone herramientas para almacenar decisiones, resúmenes de sesión (`mem_save`) y recuperar contexto de sesiones previas (`mem_search`, `mem_context`), evitando la pérdida de contexto sobre las reglas de negocio críticas o decisiones pasadas.
* **Graphify (Grafo del Repositorio)**: Servidor que mapea todo el código, layouts de Next.js, API routes y documentación en un grafo semántico. Permite al agente responder preguntas de arquitectura mediante consultas directas en lugar de hacer lecturas completas de archivos, optimizando drásticamente la ventana de contexto.
---
### 2. Reglas de Comportamiento para Agentes de IA (AGENTS.md / CLAUDE.md)
Cualquier agente que trabaje en esta base de código está **estrictamente obligado** a seguir las siguientes directrices y reglas operativas integradas en el proyecto:
#### 🔐 Seguridad y Autenticación Primero
1. **Nunca escribirás claves o credenciales en texto plano**: El agente tiene estrictamente prohibido commitear archivos `.env` o variables con valores reales. Siempre utilizará variables de entorno.
2. **Respeto absoluto por el Middleware Server-Side**: Para proteger cualquier ruta o recurso, el agente DEBE usar el middleware centralizado `serverRequireAuth` desde `lib/auth/middleware.ts` en los Server Components. Bajo ninguna circunstancia omitirá este paso o creará validaciones ad-hoc.
3. **Cookies HTTP-Only y Secure**: Los tokens JWT nunca deben tocar el `localStorage` o `sessionStorage` del cliente. Si el agente diseña flujos de autenticación en el cliente, debe delegar el almacenamiento y la gestión de la cookie al navegador y al backend.
4. **Encriptación de Datos Sensibles**: Cualquier dato altamente confidencial (ej. números de cuenta, saldos, datos personales) que viaje por el cliente debe encriptarse usando el módulo placeholder de Kong Gateway (`lib/cypher/encrypt.ts`).
#### 📝 Sistema de Logs Centralizado
* El agente **debe loguear activamente** todas las acciones críticas (inicios de sesión, accesos denegados, errores de comunicación con el backend, llamadas a la API) usando los módulos `server-logger` y `client-logger`.
* Todos los logs generados en componentes del cliente **deben enrutarse** hacia la API local `POST /api/logs` para asegurar que queden guardados en el archivo centralizado `logs/app.log`.
#### 🏗️ Desarrollo Incremental y Verificabilidad
* El agente debe mantener el archivo `STATE.md` y `ENGRAM.md` actualizados en cada punto de control (Checkpoint) para evitar la degradación de la memoria y la ventana de contexto del modelo.
* Después de realizar cualquier cambio estructural en el código, el agente ejecutará localmente `graphify update .` para asegurar que el grafo de conocimiento del proyecto refleje los nuevos módulos inmediatamente.
## 🏗️ Estructura del Proyecto
```
internet-banking/
├── app/ # Next.js App Router
│ ├── page.tsx # Página principal
│ ├── layout.tsx # Layout principal
│ ├── ClientAuthProvider.tsx # Provider para hidratación de auth
│ ├── globals.css # Estilos globales
│ ├── about/ # Sección "Acerca de"
│ │ ├── page.tsx
│ │ ├── layout.tsx
│ │ ├── components/
│ │ │ ├── aboutHeader.tsx
│ │ │ └── aboutContent.tsx
│ │ ├── service/
│ │ │ └── fetchAbout.ts
│ │ └── hooks/
│ │ └── useAboutData.ts
│ ├── login/ # Página de login
│ │ ├── page.tsx
│ │ └── LoginForm.tsx
│ ├── dashboard/ # Dashboard protegido
│ │ └── page.tsx
│ ├── model/ # Modelos TypeScript
│ │ └── cuenta.ts
│ └── api/ # API Routes
│ ├── logs/
│ │ └── route.ts # POST /api/logs
│ └── auth/
│ ├── me/
│ │ └── route.ts # GET /api/auth/me
│ └── logout/
│ └── route.ts # POST /api/auth/logout
├── components/
│ └── ui/ # Componentes UI reutilizables
│ ├── button.tsx
│ ├── input.tsx
│ ├── header.tsx
│ └── table.tsx
├── lib/
│ ├── auth/ # Autenticación
│ │ ├── middleware.ts # Middleware server-side
│ │ └── client/
│ │ └── useAuthStore.ts # Zustand store
│ ├── logger/ # Sistema de logs
│ │ ├── server-logger.ts # Logger server-side
│ │ └── client-logger.ts # Logger client-side
│ └── cypher/ # Encriptación Kong
│ ├── encrypt.ts
│ └── decrypt.ts
├── logs/
│ └── app.log # Archivo de logs (no en git)
├── middleware.ts # Next.js Edge Middleware
├── package.json
├── tsconfig.json
├── tailwind.config.ts
├── next.config.js
└── README.md
```
## 🔐 Autenticación
### Flujo de Autenticación
1. **Login**: Usuario envía credenciales a `POST /api/auth/login`
2. **Backend**: Spring Boot valida y devuelve tokens en cookies HTTP-only:
- `access_token`: Token de acceso (corta duración)
- `refresh_token`: Token de refresco (larga duración)
3. **Frontend**: Cookies se establecen automáticamente (HTTP-only, Secure, SameSite=strict)
4. **Validación**: Cada petición a rutas protegidas valida el token server-side
5. **Logout**: `POST /api/auth/logout` limpia cookies
### Middleware de Autenticación
#### Server-Side (lib/auth/middleware.ts)
```typescript
// Proteger una página (Server Component)
import { serverRequireAuth } from '@/lib/auth/middleware';
export default async function ProtectedPage() {
const user = await serverRequireAuth(); // Redirige si no autenticado
return <div>Hola {user.name}</div>;
}
// Check opcional (no redirige)
import { checkAuth } from '@/lib/auth/middleware';
const authResult = await checkAuth();
if (authResult.isAuthenticated) {
// Usuario logueado
}
```
#### Edge Middleware (middleware.ts)
Automáticamente redirige rutas protegidas (`/dashboard`, `/profile`, etc.) si no hay token.
### Zustand Store (Client-Side)
```typescript
'use client';
import { useAuthStore } from '@/lib/auth/client/useAuthStore';
function MyComponent() {
const { user, isAuthenticated, logout } = useAuthStore();
return (
<div>
{isAuthenticated && <p>Hola {user?.name}</p>}
<button onClick={logout}>Logout</button>
</div>
);
}
```
**IMPORTANTE**: El store Zustand NO guarda tokens, solo datos del usuario y flags UI.
## 📝 Sistema de Logs
Todos los logs se escriben server-side en `logs/app.log`.
### Desde Server Components / API Routes
```typescript
import { logInfo, logWarn, logError } from '@/lib/logger/server-logger';
logInfo('User logged in', { userId: '123' });
logWarn('Failed login attempt', { email: 'user@example.com' });
logError('Database connection failed', { error: err.message });
```
### Desde Client Components
```typescript
'use client';
import { logInfo, logWarn, logError } from '@/lib/logger/client-logger';
// Estos envían logs a /api/logs que los escribe server-side
logInfo('Button clicked', { action: 'submit' });
logError('Form validation failed', { field: 'email' });
```
### Formato de Logs
```
[2024-11-07T10:30:00.000Z] [INFO] Login success | {"userId":"123","email":"user@example.com"}
[2024-11-07T10:31:00.000Z] [WARN] Unauthorized access attempt | {"path":"/dashboard"}
[2024-11-07T10:32:00.000Z] [ERROR] Backend connection failed | {"error":"ECONNREFUSED"}
```
## 🔒 Seguridad
### Tokens HTTP-Only
- Los tokens JWT **nunca** se almacenan en `localStorage` o `sessionStorage`
- Se usan cookies **HTTP-only**, **Secure** (en producción), **SameSite=strict**
- No accesibles desde JavaScript del cliente
### Encriptación Kong
Para datos sensibles que necesitan encriptación:
```typescript
import { kongEncrypt, kongDecrypt } from '@/lib/cypher/decrypt';
// Encriptar
const encrypted = kongEncrypt('sensitive-data');
// Desencriptar
const decrypted = kongDecrypt(encrypted);
// TODO: Reemplazar con la librería Kong real una vez proporcionada
```
### CORS y CSRF
Asegúrate de configurar en tu backend Spring Boot:
```java
// Permitir solo orígenes aprobados
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
// SameSite=strict para cookies
cookie.setSameSite("strict");
```
## 🧪 Pruebas Manuales
### 1. Login Exitoso
1. Ir a `/login`
2. Ingresar credenciales válidas
3. **Esperado**: Redirige a `/dashboard`
4. **Log**: `[INFO] Login success | {"userId":"123"}`
### 2. Login Fallido
1. Ir a `/login`
2. Ingresar credenciales inválidas
3. **Esperado**: Muestra mensaje de error
4. **Log**: `[WARN] Login failed | {"email":"us***@example.com"}`
### 3. Acceso No Autorizado
1. Sin estar logueado, intentar acceder a `/dashboard`
2. **Esperado**: Redirige a `/login?redirect=/dashboard`
3. **Log**: `[WARN] Unauthorized access attempt | {"redirectTo":"/login"}`
### 4. Logout
1. Estando logueado, hacer click en "Cerrar Sesión"
2. **Esperado**: Cookies eliminadas, redirige a `/login`
3. **Log**: `[INFO] Logout user: 123`
## 📦 Build para Producción
```bash
# Build
npm run build
# Start production server
npm run start
```
### Variables de Entorno en Producción
Asegúrate de configurar:
```env
NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api.tudominio.com/api
API_URL_SERVER=https://api-internal.tudominio.com/api
KONG_SECRET_KEY=<tu-clave-secreta-real>
```
## 🚨 Solución de Problemas
### Error: "Failed to fetch"
- Verifica que el backend esté corriendo
- Verifica las URLs en `.env.local`
- Revisa los logs en `logs/app.log`
### Error: "Unauthorized"
- Verifica que las cookies se estén estableciendo correctamente
- Revisa la configuración CORS del backend
- Asegúrate que `withCredentials: true` esté en las peticiones fetch
### Error: Cookies no se establecen
- En desarrollo: Asegúrate que frontend y backend estén en el mismo dominio (localhost)
- Verifica configuración `SameSite` en backend
- Revisa que `httpOnly: true` esté configurado correctamente
### Logs no se escriben
- Verifica que `ENABLE_SERVER_LOGS=true`
- Asegúrate que la carpeta `logs/` tenga permisos de escritura
- Revisa los logs de consola para errores
## 📚 Documentación Adicional
- [Next.js 14 Documentation](https://nextjs.org/docs)
- [TailwindCSS](https://tailwindcss.com/docs)
- [daisyUI Components](https://daisyui.com/components/)
- [Zustand](https://docs.pmnd.rs/zustand/getting-started/introduction)
- [Kong Gateway](https://docs.konghq.com/)
## 🔧 Scripts Disponibles
```bash
npm run dev # Desarrollo
npm run build # Build producción
npm run start # Servidor producción
npm run lint # ESLint
npm run type-check # TypeScript type checking
```
## 📝 TODOs Pendientes
Los siguientes TODOs están marcados en el código con `/* TODO */`:
1. **lib/cypher/encrypt.ts y decrypt.ts**: Reemplazar implementación placeholder con librería Kong real
2. **lib/auth/middleware.ts**: Ajustar headers según requerimientos del backend
3. **app/api/auth/me/route.ts**: Ajustar headers según backend
4. **app/login/LoginForm.tsx**: Ajustar payload y endpoint de login según backend
5. **Variables de entorno**: Reemplazar valores de ejemplo con valores reales
6. **Endpoints backend**: Verificar que coincidan con los del backend Spring Boot
## 🤝 Contribución
1. Crear una rama: `git checkout -b feature/nueva-funcionalidad`
2. Commit cambios: `git commit -am 'Agrega nueva funcionalidad'`
3. Push a la rama: `git push origin feature/nueva-funcionalidad`
4. Crear Pull Request
## 📄 Licencia
Este proyecto es privado y confidencial.
## 👥 Equipo
Desarrollado para el sistema de Internet Banking.
---
**Nota de Seguridad**: Nunca commitear archivos con claves reales, tokens, o credenciales. Usar siempre variables de entorno y mantener `.env.local` fuera del control de versiones.