Files
PANEL_BASES_ANEXO24/src/lib/server/auth.ts
ernestohc21 5fa97105c9 feat: improved sidebar UI with larger icons and user info in footer
- Increased all sidebar navigation icons from text-sm to text-xl for better visibility
- Moved user information and logout button from header to sidebar footer
- Added user avatar with name and email in expanded sidebar state
- Collapsed sidebar shows avatar icon and logout icon button stacked vertically
- Simplified header by removing user badge and logout button
- Added version info (v1.0.0) in sidebar footer
- Improved responsive design for both collapsed and expanded states
2026-02-19 12:08:56 -06:00

88 lines
2.3 KiB
TypeScript

import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { env } from '$env/dynamic/private';
const JWT_SECRET = env.JWT_SECRET || 'change-this-secret-in-production-please';
const JWT_EXPIRES_IN = '7d'; // 7 días
export interface Usuario {
id: number;
username: string;
email: string;
nombre_completo: string;
activo: boolean;
es_admin: boolean;
}
export interface SessionPayload {
userId: number;
username: string;
es_admin: boolean;
}
/**
* Hash de contraseña usando bcrypt
*/
export async function hashPassword(password: string): Promise<string> {
const saltRounds = 10;
return bcrypt.hash(password, saltRounds);
}
/**
* Verificar contraseña
*/
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
try {
return await bcrypt.compare(password, hash);
} catch (error) {
console.error('Error verificando contraseña:', error);
return false;
}
}
/**
* Crear token JWT
*/
export function createToken(payload: SessionPayload): string {
return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
}
/**
* Verificar y decodificar token JWT
*/
export function verifyToken(token: string): SessionPayload | null {
try {
return jwt.verify(token, JWT_SECRET) as SessionPayload;
} catch (error) {
console.error('Error verificando token:', error);
return null;
}
}
/**
* Validar fuerza de contraseña
*/
export function validatePassword(password: string): { valid: boolean; message?: string } {
if (password.length < 8) {
return { valid: false, message: 'La contraseña debe tener al menos 8 caracteres' };
}
if (!/[A-Z]/.test(password)) {
return { valid: false, message: 'La contraseña debe contener al menos una mayúscula' };
}
if (!/[a-z]/.test(password)) {
return { valid: false, message: 'La contraseña debe contener al menos una minúscula' };
}
if (!/[0-9]/.test(password)) {
return { valid: false, message: 'La contraseña debe contener al menos un número' };
}
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
return { valid: false, message: 'La contraseña debe contener al menos un carácter especial' };
}
return { valid: true };
}