Untitled

 avatar
unknown
javascript
2 months ago
4.7 kB
5
Indexable
/* eslint-disable @typescript-eslint/no-explicit-any */
// src/pages/api/auth/[...nextauth].ts
import { AuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'
import NextAuth from 'next-auth'
import { ApiUrl, TOKEN_HEADER } from '../../../../config/Config'
import { convertUtcToLocalMillis } from '@/utils/date-formater.utils'

const options: AuthOptions = {
  session: {
    strategy: 'jwt',
    maxAge: 60 * 60, // 1 jam
  },
  providers: [
    CredentialsProvider({
      name: 'LP3U Authentication',
      credentials: {
        userNameOrEmail: { label: 'Username/Email', type: 'text' },
        password: { label: 'Password', type: 'password' },
        role: { label: 'Role', type: 'text' },
      },
      async authorize(credentials) {
        try {
          const response = await fetch(`${ApiUrl}/auth/login`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              tokken_lpppu_usu: TOKEN_HEADER!,
            },
            body: JSON.stringify({
              userNameOrEmail: credentials?.userNameOrEmail,
              password: credentials?.password,
              role: credentials?.role,
            }),
          })

          // Handle non-JSON responses
          if (
            !response.headers.get('content-type')?.includes('application/json')
          ) {
            const text = await response.text()
            throw new Error(`Invalid response: ${text}`)
          }

          const data = await response.json()

          if (!response.ok) {
            throw new Error(data.message || 'Authentication failed')
          }

          return {
            id: data.data.id,
            accessToken: data.data.accessToken,
            role: data.data.role,
            accessTokenExpiry: data.data.accessTokenExpiry,
          }
        } catch (error) {
          console.error('Authorization error:', error)
          return null
        }
      },
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
    maxAge: 60 * 60, // 1 jam
  },
  callbacks: {
    async jwt({ token, user }: any) {
      if (user) {
        token.id = user.id
        token.accessToken = user.accessToken
        token.role = user.role

        // Menyimpan expiry token dalam milidetik UNIX
        token.accessTokenExpiry = convertUtcToLocalMillis(
          user.accessTokenExpiry,
        )
      }
      console.log('token.exp * 1000 - 60000', token.exp * 1000 - 60000)
      // Auto logout 1 menit sebelum expired
      if (token.accessTokenExpiry && Date.now() > token.accessTokenExpiry) {
        token = null
        return {}
      }

      return token
    },

    async session({ session, token }: any) {
      // Data dasar dari token
      session.user = {
        id: token.id as string,
        role: token.role as string,
      }
      session.accessToken = token.accessToken as string
      const localTime = convertUtcToLocalMillis(token.accessTokenExpiry)
      session.expires = localTime
      console.log('token', token.accessToken)
      // Ambil data profil jika token valid
      if (token.accessToken) {
        try {
          const profileResponse = await fetch(ApiUrl + '/auth/profile', {
            method: 'GET',
            headers: {
              Authorization: `Bearer ${token.accessToken}`,
              Accept: 'application/json',
              'Content-Type': 'application/json',
              tokken_lpppu_usu: 'project_LP3U_USU_jaya_token#$%6',
            },
          })
          // Handle error response
          if (!profileResponse.ok) {
            session = null
            throw new Error(
              `Gagal mengambil profil: ${profileResponse.statusText}`,
            )
          }

          // Validasi format response
          const contentType = profileResponse.headers.get('content-type')
          if (!contentType?.includes('application/json')) {
            throw new Error('Format response profil tidak valid')
          }

          const profileData = await profileResponse.json()

          // Gabungkan data profil
          session.user = {
            ...session.user,
            ...profileData.data,
          }
        } catch (error) {
          console.error('Error fetching profile:', error)
        }
      } else {
        session = null
      }

      return session
    },
  },
  pages: {
    signIn: '/login',
    error: '/login',
  },
}

export default NextAuth(options)
Editor is loading...
Leave a Comment