first commit
This commit is contained in:
153
server/api/auth/[...].ts
Normal file
153
server/api/auth/[...].ts
Normal file
@@ -0,0 +1,153 @@
|
||||
// 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',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user