Untitled
unknown
javascript
8 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