## 🔐 Unified Authentication Architecture - CarnTrack

### **SOLUCIÓN UNIFICADA: TODO usa Better Auth + Argon2**

---

## **1. Herramientas Utilizadas**

### **Better Auth (Principal)**
- **Librería**: `better-auth`
- **Algoritmo**: Argon2 (Por defecto)
- **Responsabilidad**: 
  - ✅ Autenticación (sign-up, sign-in, sessions)
  - ✅ Verificación de contraseñas
  - ✅ Manejo de tokens y sesiones

### **Argon2 (Secundario - Consistencia)**
- **Librería**: `argon2`
- **Versión**: Última estable
- **Responsabilidad**:
  - ✅ Hashing manual de contraseñas (password reset)
  - ✅ Usa EXACTAMENTE los mismos parámetros que Better Auth
  - ✅ Garantiza compatibilidad total

### **❌ ELIMINADO: bcrypt**
- Ya no se utiliza
- Reemplazado por Argon2 para consistencia total

---

## **2. Flujos de Password en la App**

### **Flujo 1: Usuario se Registra (Sign-up)**
```
Cliente/Admin → Llena formulario + password
  ↓
POST /api/auth/sign-up/email
  ↓
Better Auth:
  1. Lee password: "123456"
  2. Genera hash Argon2: "$argon2id$v=19$m=19456$..."
  3. Guarda en account.password
  4. Crea user record
  5. Inicia sesión automáticamente
  ↓
✅ Usuario logueado, cookie de sesión creada
```

**Código:**
```typescript
// En src/app/api/clients/route.ts y en formulario de registro
await fetch("/api/auth/sign-up/email", {
  body: JSON.stringify({
    email: "nuevo@email.com",
    password: "123456",
    name: "Nombre",
    role: "trader"
  })
});
// Better Auth maneja todo internamente
```

---

### **Flujo 2: Admin Resetea Contraseña de Cliente**
```
Admin → Selecciona cliente + click "Resetear"
  ↓
PATCH /api/clients/[id] { resetPassword: true }
  ↓
Endpoint llama:
  1. hashPassword("123456") ← Nueva función centralizada
  2. Usa Argon2 con los MISMOS parámetros que Better Auth
  3. Resultado: "$argon2id$v=19$m=19456$..."
  4. UPDATE account SET password = hash
  ↓
Base de Datos:
  account.password = "$argon2id$v=19$m=19456$..."
  ↓
✅ Cliente puede loguear con nueva contraseña
```

**Código:**
```typescript
// En src/app/api/clients/[id]/route.ts
import { hashPassword } from "@/lib/auth";

if (resetPassword) {
  const hashedPassword = await hashPassword("123456");
  
  await pool.query(
    `UPDATE account SET password = $1 WHERE "userId" = $2`,
    [hashedPassword, clientId]
  );
}
```

---

### **Flujo 3: Usuario Intenta Loguear**
```
Usuario → Ingresa email + "123456"
  ↓
POST /api/auth/sign-in/email
  ↓
Better Auth:
  1. Lee password plain: "123456"
  2. Obtiene hash de BD: "$argon2id$v=19$m=19456$..."
  3. Usa Argon2.verify("123456", hash)
  4. ¿Coincide? → ✅ YES
  5. Crea sesión y token
  ↓
✅ Usuario logueado
```

---

## **3. Donde Viven los Hashes**

```
📦 Database (PostgreSQL)
├─ user table
│  ├─ id (PK)
│  ├─ email
│  ├─ name
│  ├─ role
│  └─ [NO contraseñas aquí - por seguridad]
│
└─ account table
   ├─ id (PK)
   ├─ userId (FK → user.id)
   ├─ password ← 🔐 HASH ARGON2 AQUÍ
   ├─ providerId ("credential" para email/pass)
   └─ accessToken, refreshToken
```

---

## **4. Parámetros de Argon2 (Unificados)**

**Todos los hashes usan estos parámetros idénticos:**

```typescript
// En src/lib/auth.ts
await argon2.hash(password, {
  type: argon2.argon2id,     // Tipo: Argon2id (más seguro)
  timeCost: 2,               // 2 iteraciones
  memoryCost: 19456,         // 19 MB de memoria
  parallelism: 1,            // 1 thread
});

// Resultado: $argon2id$v=19$m=19456,t=2,p=1$...
```

📌 **Estos son los MISMOS parámetros que Better Auth usa por defecto.**

---

## **5. Funciones Centralizadas (Nuevo)**

Ahora hay dos funcion es centralizadas en `src/lib/auth.ts`:

```typescript
/**
 * Hash una contraseña usando Argon2 (mismo que Better Auth)
 * Cuando: Admin resetea contraseña de cliente
 */
export async function hashPassword(password: string): Promise<string> {
  const argon2 = await import("argon2");
  return argon2.hash(password, {
    type: argon2.argon2id,
    timeCost: 2,
    memoryCost: 19456,
    parallelism: 1,
  });
}

/**
 * Generar token seguro para reset (futuro)
 */
export function generateResetToken(): string {
  return crypto.randomBytes(32).toString("hex");
}
```

---

## **6. Matriz de Compatibilidad**

| Escenario | Tool | Hash | Verificación | ✅/❌ |
|-----------|------|------|--------------|--------|
| Sign-up | Better Auth | Argon2 | Argon2 | ✅ |
| Login | Better Auth | Argon2 | Argon2 | ✅ |
| Admin Reset | hashPassword() | Argon2 | Better Auth | ✅ |
| Sign-in Username | Better Auth | Argon2 | Argon2 | ✅ |

🎯 **TODOS los hashes son Argon2 - 100% compatible**

---

## **7. Seguridad Mejorada**

✅ **Ventajas de esta arquitectura:**
- Un solo algoritmo (Argon2) - consistencia total
- No hay mezcla de tecnologías (adiós bcrypt)
- Parámetros estándar y probados
- Fácil de auditar y mantener
- Compatible con Better Auth al 100%

⚠️ **Consideraciones:**
- Argon2 requiere compilación nativa en algunos sistemas
- Ya instalado con npm install argon2

---

## **8. Cómo Probar la Solución**

### **Test 1: Crear cliente nuevo**
```bash
1. Login como admin
2. Ir a Clientes → Agregar nuevo
3. Ingresa email + nombre
4. Client se crea con password "123456"
5. Login como cliente con email + "123456" → ✅ Funciona
```

### **Test 2: Resetear contraseña**
```bash
1. Login como admin
2. Ir a Clientes → Seleccionar cliente
3. Click "Resetear contraseña"
4. Logout
5. Login con email + "123456" → ✅ Funciona
```

### **Test 3: Registrarse (Sign-up)**
```bash
1. Goto /register
2. Completa formulario + crea contraseña
3. Se registra automáticamente
4. Verifica DB: account.password = "$argon2id$..." → ✅ Correcto
```

---

## **9. Archivos Modificados**

| Archivo | Cambio |
|---------|--------|
| `src/lib/auth.ts` | ✅ Agregó `hashPassword()` y `generateResetToken()` |
| `src/app/api/clients/[id]/route.ts` | ✅ Eliminó `bcrypt`, usa `hashPassword()` |
| `package.json` | ✅ Agregó `argon2` dependency |

---

## **10. Próximos Pasos (Opcional)**

Si en el futuro quieres agregar:
- **Email password reset**: Usar `generateResetToken()` + email
- **Password change**: Similar al reset actual
- **Auditoría**: Log de cambios de password

Todas estas tendrán la misma base: `hashPassword()` con Argon2.

---

## **Resumen**

```
ANTES                          AHORA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Sign-up   → Argon2             Sign-up   → Argon2 ✅
Reset     → bcrypt ❌          Reset     → Argon2 ✅
Login     → Argon2             Login     → Argon2 ✅
Mezcla    → 2 algoritmos ❌    Mezcla    → 1 algoritmo ✅
```

🎯 **100% UNIFICADO CON BETTER AUTH + ARGON2**
