first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:12:36 +03:00
commit e881f38e4e
278 changed files with 24095 additions and 0 deletions

View File

@@ -0,0 +1,219 @@
import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
import { JWT } from "next-auth/jwt";
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000/api/v1";
// Django REST API - Token Refresh
async function refreshAccessToken(token: JWT) {
try {
const response = await fetch(
`${API_BASE_URL}/auth/jwt/refresh/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
refresh: token.refreshToken,
}),
}
);
const data = await response.json();
if (!response.ok) {
throw data;
}
return {
...token,
accessToken: data.access,
refreshToken: data.refresh ?? token.refreshToken,
// Django JWT access token: 60 dakika (3600000 ms)
accessTokenExpiry: Date.now() + 3600000,
};
} catch (error) {
console.error("Error refreshing access token:", error);
return {
...token,
error: "RefreshAccessTokenError",
};
}
}
// Django REST API - Social Auth Handler
async function handleSocialAuth(provider: string, accessToken: string) {
const response = await fetch(
`${API_BASE_URL}/auth/social/${provider}/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
access_token: accessToken,
}),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || "Social authentication failed");
}
return await response.json();
}
export const authOptions: NextAuthOptions = {
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID || "",
clientSecret: process.env.GITHUB_SECRET || "",
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID || "",
clientSecret: process.env.GOOGLE_SECRET || "",
}),
CredentialsProvider({
name: "Django REST API",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
return null;
}
try {
// Django REST API - Login
const response = await fetch(
`${API_BASE_URL}/auth/jwt/create/`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: credentials.email,
password: credentials.password,
}),
}
);
if (!response.ok) {
return null;
}
const data = await response.json();
if (data?.access && data?.refresh) {
// Get user profile
const userResponse = await fetch(
`${API_BASE_URL}/auth/users/me/`,
{
headers: {
Authorization: `Bearer ${data.access}`,
},
}
);
const userData = await userResponse.json();
return {
id: userData.id?.toString() || credentials.email,
email: userData.email,
name: `${userData.first_name || ""} ${userData.last_name || ""}`.trim(),
accessToken: data.access,
refreshToken: data.refresh,
accessTokenExpiry: Date.now() + 3600000, // 60 dakika
};
}
return null;
} catch (error) {
console.error("Authentication error:", error);
return null;
}
},
}),
],
callbacks: {
async jwt({ token, user, account }) {
// İlk login - Email/Password (Credentials Provider)
if (user && account?.provider === "credentials") {
token.accessToken = user.accessToken;
token.refreshToken = user.refreshToken;
token.accessTokenExpiry = user.accessTokenExpiry;
return token;
}
// İlk login - Social Auth (Google/GitHub)
if (account && (account.provider === "google" || account.provider === "github")) {
try {
const providerMap: Record<string, string> = {
google: "google-oauth2",
github: "github",
};
const djangoProvider = providerMap[account.provider];
const socialData = await handleSocialAuth(
djangoProvider,
account.access_token!
);
token.accessToken = socialData.access;
token.refreshToken = socialData.refresh;
token.accessTokenExpiry = Date.now() + 3600000;
token.email = socialData.user.email;
token.name = `${socialData.user.first_name || ""} ${socialData.user.last_name || ""}`.trim();
return token;
} catch (error) {
console.error("Social auth error:", error);
token.error = "SocialAuthError";
return token;
}
}
// Token hala geçerliyse mevcut tokeni döndür
if (token.accessTokenExpiry && Date.now() < (token.accessTokenExpiry as number)) {
return token;
}
// Token süresi dolmuşsa refresh et
return refreshAccessToken(token);
},
async session({ session, token }) {
session.accessToken = token.accessToken as string;
session.refreshToken = token.refreshToken as string;
session.error = token.error as string | undefined;
if (token.email) {
session.user = {
...session.user,
email: token.email as string,
name: token.name as string,
};
}
return session;
},
},
pages: {
signIn: "/auth/login",
error: "/auth/error",
},
session: {
strategy: "jwt",
maxAge: 7 * 24 * 60 * 60, // 7 gün (refresh token süresi)
},
secret: process.env.NEXTAUTH_SECRET,
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };