first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:06:07 +03:00
commit 5ad37467cf
475 changed files with 33476 additions and 0 deletions

199
server/api/auth/[...].ts Normal file
View File

@@ -0,0 +1,199 @@
// file: ~/server/api/auth/[...].ts
/* eslint-disable @typescript-eslint/ban-ts-comment */
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';
export default NuxtAuthHandler({
// @ts-ignore
secret: useRuntimeConfig().authSecret,
providers: [
// @ts-expect-error
GithubProvider.default({
clientId: useRuntimeConfig().githubClientId,
clientSecret: useRuntimeConfig().githubClientSecret
}),
// @ts-expect-error
GoogleProvider.default({
clientId: useRuntimeConfig().googleClientId,
clientSecret: useRuntimeConfig().googleClientSecret
}),
// @ts-expect-error
CredentialsProvider.default({
name: 'credentials',
credentials: {
email: { label: 'email', type: 'email' },
password: { type: 'password', label: 'password' }
},
async authorize(credentials: { email: string; password: string } | undefined) {
if (!credentials) return null;
const config = useRuntimeConfig();
const apiUrl = config.public.BASE_API_URL || 'http://127.0.0.1:8000';
try {
const tokenResponse = await fetch(`${apiUrl}/api/v1/auth/jwt/create/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: credentials.email,
password: credentials.password
})
});
if (!tokenResponse.ok) {
return null;
}
const tokenData = await tokenResponse.json();
const { access, refresh } = tokenData;
const userResponse = await fetch(`${apiUrl}/api/v1/auth/users/me/`, {
headers: {
'Authorization': `Bearer ${access}`
}
});
if (!userResponse.ok) {
return null;
}
const userData = await userResponse.json();
// Return a user object with tokens and user data
return {
...userData,
accessToken: access,
refreshToken: refresh
};
} catch (error) {
console.error('Authorize error:', error);
return null;
}
}
})
],
callbacks: {
// @ts-ignore
jwt: async ({ token, user, account }) => {
// The `user` object is from the `authorize` callback.
if (user) {
// @ts-ignore
token.id = user.id;
// @ts-ignore
token.email = user.email;
// @ts-ignore
token.name = user.name;
// @ts-ignore
token.role = user.role;
// @ts-ignore
token.image = user.image;
// @ts-ignore
token.is_active = user.is_active;
// Persist the tokens in the JWT
// @ts-ignore
token.accessToken = user.accessToken;
// @ts-ignore
token.refreshToken = user.refreshToken;
}
// Social login: exchange provider access_token for backend JWT tokens
// This runs only on initial sign-in where `account` is present.
if (
account &&
(account.provider === 'google' || account.provider === 'github') &&
// @ts-ignore
account.access_token
) {
try {
const config = useRuntimeConfig();
const apiUrl = config.public.BASE_API_URL || 'http://127.0.0.1:8000';
const endpoint =
account.provider === 'google'
? `${apiUrl}/api/v1/auth/social/google-oauth2/`
: `${apiUrl}/api/v1/auth/social/github/`;
// @ts-ignore
const accessToken = account.access_token;
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ access_token: accessToken }),
});
if (response.ok) {
const data = await response.json();
// Expected shape (per docs): { access, refresh, user }
// Persist backend JWTs on token so client can call protected APIs.
// @ts-ignore
token.accessToken = data.access;
// @ts-ignore
token.refreshToken = data.refresh;
if (data.user) {
// @ts-ignore
token.id = data.user.id ?? token.id;
// @ts-ignore
token.email = data.user.email ?? token.email;
// @ts-ignore
token.name =
(data.user.name ??
[data.user.first_name, data.user.last_name].filter(Boolean).join(' ')) ||
token.name;
// @ts-ignore
token.image = data.user.image ?? token.image;
// @ts-ignore
token.role = data.user.role ?? token.role;
// @ts-ignore
token.is_active = data.user.is_active ?? token.is_active;
}
} else {
const text = await response.text().catch(() => '');
console.error('Social token exchange failed:', response.status, text);
}
} catch (e) {
console.error('Social token exchange error:', e);
}
}
return token;
},
// @ts-ignore
session: async ({ session, token }) => {
if (token && session.user) {
// @ts-ignore
session.user.id = token.id;
// @ts-ignore
session.user.name = token.name;
// @ts-ignore
session.user.role = token.role;
// @ts-ignore
session.user.email = token.email;
// @ts-ignore
session.user.image = token.image;
// @ts-ignore
session.user.is_active = token.is_active;
}
// Expose backend JWTs to the client session (optional but useful)
// @ts-ignore
session.accessToken = token.accessToken;
// @ts-ignore
session.refreshToken = token.refreshToken;
return session;
},
},
// Disable verbose NextAuth logs to avoid DEBUG_ENABLED warning
// @ts-ignore
debug: false,
pages: {
signIn: '/auth/login'
},
session: {
strategy: 'jwt'
}
})