auth.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { NextAuthOptions } from "next-auth";
  2. import CredentialsProvider from "next-auth/providers/credentials";
  3. import { prisma } from "@/lib/prisma";
  4. import { config } from "@/lib/config";
  5. import { authenticateUser, UTBApiError, UTB_ROLE_MAP } from "@/lib/utb-api";
  6. import type { Role } from "@prisma/client";
  7. export const authOptions: NextAuthOptions = {
  8. secret: config.nextAuth.secret,
  9. providers: [
  10. CredentialsProvider({
  11. name: "credentials",
  12. credentials: {
  13. username: { label: "Usuario", type: "text" },
  14. password: { label: "Contraseña", type: "password" }
  15. },
  16. async authorize(credentials) {
  17. if (!credentials?.username || !credentials?.password) {
  18. return null;
  19. }
  20. try {
  21. // Autenticar con API UTB
  22. const utbResponse = await authenticateUser(
  23. credentials.username,
  24. credentials.password
  25. );
  26. // Mapear rol UTB a rol interno
  27. const role = UTB_ROLE_MAP[utbResponse.user.tipo] || 'PATIENT';
  28. // Buscar usuario existente por identificación
  29. let user = await prisma.user.findFirst({
  30. where: {
  31. OR: [
  32. { identificacion: utbResponse.user.identificacion },
  33. { username: credentials.username }
  34. ]
  35. }
  36. });
  37. if (user) {
  38. // Actualizar datos del usuario existente
  39. user = await prisma.user.update({
  40. where: { id: user.id },
  41. data: {
  42. name: utbResponse.user.nombres,
  43. lastname: utbResponse.user.apellidos,
  44. dateOfBirth: new Date(utbResponse.user.fecha_nacimiento),
  45. role,
  46. identificacion: utbResponse.user.identificacion,
  47. isExternalAuth: true,
  48. }
  49. });
  50. } else {
  51. // Crear nuevo usuario
  52. user = await prisma.user.create({
  53. data: {
  54. username: credentials.username,
  55. identificacion: utbResponse.user.identificacion,
  56. name: utbResponse.user.nombres,
  57. lastname: utbResponse.user.apellidos,
  58. dateOfBirth: new Date(utbResponse.user.fecha_nacimiento),
  59. role,
  60. isExternalAuth: true,
  61. }
  62. });
  63. }
  64. return {
  65. id: user.id,
  66. email: user.email || '',
  67. name: user.name,
  68. lastname: user.lastname,
  69. role: user.role,
  70. profileImage: user.profileImage || undefined,
  71. isExternalAuth: user.isExternalAuth,
  72. identificacion: user.identificacion || undefined,
  73. phone: user.phone || undefined,
  74. dateOfBirth: user.dateOfBirth || undefined,
  75. gender: user.gender || undefined,
  76. address: user.address || undefined,
  77. emergencyContact: user.emergencyContact || undefined,
  78. medicalHistory: user.medicalHistory || undefined,
  79. allergies: user.allergies || undefined,
  80. currentMedications: user.currentMedications || undefined,
  81. };
  82. } catch (error) {
  83. if (error instanceof UTBApiError) {
  84. console.error("Error UTB API:", error.message);
  85. } else {
  86. console.error("Error en authorize:", error);
  87. }
  88. return null;
  89. }
  90. }
  91. })
  92. ],
  93. session: {
  94. strategy: "jwt",
  95. maxAge: config.session.maxAge, // Configurado desde variables de entorno
  96. },
  97. jwt: {
  98. maxAge: config.session.jwtMaxAge, // Configurado desde variables de entorno
  99. },
  100. callbacks: {
  101. async jwt({ token, user, trigger, session }) {
  102. // Durante login inicial - copiar todos los datos del usuario
  103. if (user) {
  104. return { ...token, ...user };
  105. }
  106. // Durante actualización con update() - solo actualizar campos que fueron enviados
  107. if (trigger === "update" && session) {
  108. return { ...token, ...session };
  109. }
  110. return token;
  111. },
  112. async session({ session, token }) {
  113. // Copiar todos los campos del token a session.user (excepto los internos de JWT)
  114. if (token && session.user) {
  115. // Mantener la estructura de session.user y actualizar con datos del token
  116. session.user = {
  117. ...session.user,
  118. id: token.id as string,
  119. role: token.role as "PATIENT" | "ADMIN",
  120. name: token.name as string,
  121. lastname: token.lastname as string,
  122. email: token.email as string,
  123. profileImage: token.profileImage as string | undefined,
  124. isExternalAuth: token.isExternalAuth as boolean | undefined,
  125. identificacion: token.identificacion as string | undefined,
  126. dateOfBirth: token.dateOfBirth as Date | undefined,
  127. phone: token.phone as string | undefined,
  128. gender: token.gender as string | undefined,
  129. address: token.address as string | undefined,
  130. emergencyContact: token.emergencyContact as string | undefined,
  131. medicalHistory: token.medicalHistory as string | undefined,
  132. allergies: token.allergies as string | undefined,
  133. currentMedications: token.currentMedications as string | undefined,
  134. };
  135. }
  136. return session;
  137. }
  138. },
  139. pages: {
  140. signIn: "/auth/login"
  141. },
  142. debug: process.env.NODE_ENV === "development",
  143. };