corregido refreshtoken y mejorado ver informacion ui por roles

This commit is contained in:
2026-02-10 21:45:34 -04:00
parent 63c39e399e
commit 42e802f8a7
22 changed files with 2438 additions and 324 deletions

View File

@@ -1,11 +1,10 @@
// lib/auth.config.ts
import { SignInAction } from '@/feactures/auth/actions/login-action';
import { resfreshTokenAction } from '@/feactures/auth/actions/refresh-token-action';
import { logoutAction } from '@/feactures/auth/actions/logout-action';
import { CredentialsSignin, NextAuthConfig, Session, User } from 'next-auth';
import { DefaultJWT } from 'next-auth/jwt';
import { DefaultJWT, JWT } from 'next-auth/jwt';
import CredentialProvider from 'next-auth/providers/credentials';
// Define los tipos para tus respuestas de SignInAction
interface SignInSuccessResponse {
message: string;
@@ -58,8 +57,10 @@ const authConfig: NextAuthConfig = {
// **NUEVO: Manejar el caso `null` primero**
if (response === null) {
console.error("SignInAction returned null, indicating a potential issue before API call or generic error.");
throw new CredentialsSignin("Error de inicio de sesión inesperado.");
console.error(
'SignInAction returned null, indicating a potential issue before API call or generic error.',
);
throw new CredentialsSignin('Error de inicio de sesión inesperado.');
}
// Tipo Guarda: Verificar la respuesta de error
@@ -70,15 +71,19 @@ const authConfig: NextAuthConfig = {
response.type === 'UNKNOWN_ERROR') // Incluye todos los tipos de error posibles
) {
// Si es un error, lánzalo. Este camino termina aquí.
throw new CredentialsSignin("Error en la API:" + response.message);
throw new CredentialsSignin('Error en la API:' + response.message);
}
if (!('user' in response)) {
// Esto solo ocurriría si SignInAction devolvió un objeto que no es null,
// no es un error conocido por 'type', PERO tampoco tiene la propiedad 'user'.
// Es un caso de respuesta inesperada del API.
console.error("Respuesta de SignInAction con formato inesperado: falta la propiedad 'user'.");
throw new CredentialsSignin("Error en el formato de la respuesta del servidor.");
console.error(
"Respuesta de SignInAction con formato inesperado: falta la propiedad 'user'.",
);
throw new CredentialsSignin(
'Error en el formato de la respuesta del servidor.',
);
}
return {
@@ -89,11 +94,7 @@ const authConfig: NextAuthConfig = {
role: response?.user.rol ?? [], // Add role array
access_token: response?.tokens.access_token ?? '',
access_expire_in: response?.tokens.access_expire_in ?? 0,
refresh_token: response?.tokens.refresh_token ?? '',
refresh_expire_in: response?.tokens.refresh_expire_in ?? 0,
};
},
}),
],
@@ -101,11 +102,7 @@ const authConfig: NextAuthConfig = {
signIn: '/', //sigin page
},
callbacks: {
async jwt({ token, user }:{
user: User
token: any
}) {
async jwt({ token, user }: { user: User; token: any }) {
// 1. Manejar el inicio de sesión inicial
// El `user` solo se proporciona en el primer inicio de sesión.
if (user) {
@@ -117,64 +114,14 @@ const authConfig: NextAuthConfig = {
role: user.role,
access_token: user.access_token,
access_expire_in: user.access_expire_in,
refresh_token: user.refresh_token,
refresh_expire_in: user.refresh_expire_in
}
// return token;
};
}
// 2. Si no es un nuevo login, verificar la expiración del token
const now = Math.floor(Date.now() / 1000); // Usar Math.floor para un número entero
// Verificar si el token de acceso aún es válido
if (now < (token.access_expire_in as number)) {
return token; // Si no ha expirado, no hacer nada y devolver el token actual
}
// console.log("Now Access Expire:",token.access_expire_in);
// 3. Si el token de acceso ha expirado, verificar el refresh token
// console.log("Access token ha expirado. Verificando refresh token...");
if (now > (token.refresh_expire_in as number)) {
// console.log("Refresh token ha expirado. Forzando logout.");
return null; // Forzar el logout al devolver null
}
// console.log("token:", token.refresh_token);
// 4. Si el token de acceso ha expirado pero el refresh token es válido, renovar
console.log("Renovando token de acceso...");
try {
const refresh_token = { token: token.refresh_token as string, user_id: Number(token.id) as number}
const res = await resfreshTokenAction(refresh_token);
// console.log('res', res);
if (!res || !res.tokens) {
throw new Error('Fallo en la respuesta de la API de refresco.');
}
// Actualizar el token directamente con los nuevos valores
token.access_token = res.tokens.access_token;
token.access_expire_in = res.tokens.access_expire_in;
token.refresh_token = res.tokens.refresh_token;
token.refresh_expire_in = res.tokens.refresh_expire_in;
return token;
} catch (error) {
console.error("Error al renovar el token: ", error);
return null; // Fallo al renovar, forzar logout
}
return token;
},
async session({ session, token }: { session: Session; token: any }) {
async session({ session, token }: { session: Session; token: DefaultJWT }) {
session.access_token = token.access_token as string;
session.access_expire_in = token.access_expire_in as number;
session.refresh_token = token.refresh_token as string;
session.refresh_expire_in = token.refresh_expire_in as number;
session.user = {
id: token.id as number,
username: token.username as string,
@@ -185,7 +132,18 @@ const authConfig: NextAuthConfig = {
return session;
},
},
events: {
async signOut(message) {
// 1. verificamos que venga token (puede no venir con algunos providers)
const token = (message as { token?: JWT }).token;
if (!token?.access_token) return;
try {
await logoutAction(String(token?.id));
} catch {
/* silencioso para que next-auth siempre cierre */
}
},
},
} satisfies NextAuthConfig;
export default authConfig;