154 lines
5.5 KiB
TypeScript
154 lines
5.5 KiB
TypeScript
// file: ~/server/api/auth/[...].ts
|
||
import { NuxtAuthHandler } from '#auth'
|
||
import CredentialsProvider from 'next-auth/providers/credentials';
|
||
import GithubProvider from 'next-auth/providers/github'
|
||
import GoogleProvider from 'next-auth/providers/google';
|
||
import type { JWT } from 'next-auth/jwt';
|
||
|
||
const config = useRuntimeConfig();
|
||
const API_BASE_URL = config.public.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:8080';
|
||
|
||
// Helper to refresh the access token
|
||
async function refreshAccessToken(token: JWT): Promise<JWT> {
|
||
try {
|
||
if (!token.refreshToken) {
|
||
throw new Error("No refresh token available");
|
||
}
|
||
|
||
const response = await fetch(`${API_BASE_URL}/api/v1/auth/refresh`, {
|
||
headers: { 'Content-Type': 'application/json' },
|
||
method: 'POST',
|
||
body: JSON.stringify({ refresh_token: token.refreshToken }),
|
||
});
|
||
|
||
const refreshedProperies = await response.json();
|
||
|
||
if (!response.ok) {
|
||
throw refreshedProperies;
|
||
}
|
||
|
||
return {
|
||
...token,
|
||
accessToken: refreshedProperies.access_token,
|
||
refreshToken: refreshedProperies.refresh_token ?? token.refreshToken, // Fallback to old refresh token
|
||
accessTokenExpires: Date.now() + 15 * 60 * 1000, // Varsayılan 15 dk, backend yanıtına göre ayarlanabilir
|
||
};
|
||
} catch (error) {
|
||
console.error('RefreshAccessTokenError', error);
|
||
return {
|
||
...token,
|
||
error: 'RefreshAccessTokenError',
|
||
};
|
||
}
|
||
}
|
||
|
||
export default NuxtAuthHandler({
|
||
secret: config.authSecret,
|
||
providers: [
|
||
// @ts-expect-error
|
||
GithubProvider.default({
|
||
clientId: config.githubClientId,
|
||
clientSecret: config.githubClientSecret
|
||
}),
|
||
// @ts-expect-error
|
||
GoogleProvider.default({
|
||
clientId: config.googleClientId,
|
||
clientSecret: config.googleClientSecret
|
||
}),
|
||
// @ts-expect-error
|
||
CredentialsProvider.default({
|
||
name: 'Credentials',
|
||
credentials: {
|
||
email: { label: 'Email', type: 'email' },
|
||
password: { label: 'Password', type: 'password' }
|
||
},
|
||
async authorize(credentials) {
|
||
if (!credentials?.email || !credentials?.password) return null;
|
||
|
||
try {
|
||
const res = await fetch(`${API_BASE_URL}/api/v1/auth/login`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
email: credentials.email,
|
||
password: credentials.password
|
||
})
|
||
});
|
||
|
||
const user = await res.json();
|
||
|
||
// Backend dönüş formatı: { access_token, refresh_token, user: { ... } }
|
||
if (res.ok && user.access_token && user.user) {
|
||
return {
|
||
...user.user, // id, email, username, is_admin vb.
|
||
access_token: user.access_token,
|
||
refresh_token: user.refresh_token,
|
||
};
|
||
}
|
||
return null;
|
||
} catch (error) {
|
||
console.error('Login error:', error);
|
||
return null;
|
||
}
|
||
}
|
||
})
|
||
],
|
||
callbacks: {
|
||
async jwt({ token, user, account }) {
|
||
// Initial sign in
|
||
if (account && user) {
|
||
// Social login case handled here if needed, consistent with Credentials
|
||
// Eğer social login backend değişimi yapılacaksa burası da güncellenmeli.
|
||
// Şimdilik Credentials akışına odaklanıyoruz.
|
||
|
||
return {
|
||
...token,
|
||
accessToken: user.access_token,
|
||
refreshToken: user.refresh_token,
|
||
accessTokenExpires: Date.now() + 15 * 60 * 1000, // 15 dakika
|
||
id: user.id as number,
|
||
email: user.email as string,
|
||
username: user.username as string,
|
||
first_name: user.first_name as string,
|
||
last_name: user.last_name as string,
|
||
is_admin: user.is_admin as boolean,
|
||
// Diğer alanlar
|
||
};
|
||
}
|
||
|
||
// Return previous token if the access token has not expired yet
|
||
if (Date.now() < (token.accessTokenExpires as number)) {
|
||
return token;
|
||
}
|
||
|
||
// Access token has expired, try to update it
|
||
return refreshAccessToken(token);
|
||
},
|
||
async session({ session, token }) {
|
||
if (token) {
|
||
session.user.id = token.id;
|
||
session.user.email = token.email;
|
||
session.user.username = token.username;
|
||
session.user.first_name = token.first_name;
|
||
session.user.last_name = token.last_name;
|
||
session.user.is_admin = token.is_admin;
|
||
|
||
session.accessToken = token.accessToken;
|
||
session.refreshToken = token.refreshToken;
|
||
session.error = token.error;
|
||
}
|
||
return session;
|
||
}
|
||
},
|
||
pages: {
|
||
signIn: '/auth/login',
|
||
newUser: '/auth/register' // Opsiyonel
|
||
},
|
||
session: {
|
||
strategy: 'jwt'
|
||
},
|
||
// Debug only in development
|
||
debug: process.env.NODE_ENV === 'development',
|
||
})
|
||
|