first commit
This commit is contained in:
176
lib/auth-api.ts
Normal file
176
lib/auth-api.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Auth API client for login, register, me, refresh.
|
||||
* Uses NEXT_PUBLIC_BASE_API_URL on client (defaults to same as BASE_API_URL for server).
|
||||
*/
|
||||
|
||||
const getBaseUrl = () =>
|
||||
typeof window !== "undefined"
|
||||
? process.env.NEXT_PUBLIC_BASE_API_URL ?? "http://127.0.0.1:8080"
|
||||
: process.env.BASE_API_URL ?? process.env.NEXT_PUBLIC_BASE_API_URL ?? "http://127.0.0.1:8080";
|
||||
|
||||
const API_PREFIX = "/api/v1/auth";
|
||||
|
||||
export interface AuthUser {
|
||||
id: number;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
username?: string;
|
||||
is_admin: boolean;
|
||||
email_verified?: boolean;
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
user: AuthUser;
|
||||
}
|
||||
|
||||
export interface RegisterResponse {
|
||||
message: string;
|
||||
user: AuthUser;
|
||||
}
|
||||
|
||||
export interface RefreshResponse {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
/** POST /api/v1/auth/login – doğrudan backend (token client’ta; cookie için loginViaCookie kullanın) */
|
||||
export async function login(
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<LoginResponse> {
|
||||
const base = getBaseUrl();
|
||||
const res = await fetch(`${base}${API_PREFIX}/login`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", accept: "application/json" },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
throw new Error((err as { detail?: string }).detail ?? "Giriş başarısız");
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** Cookie tabanlı giriş – token’lar HTTP-only secure cookie’de saklanır */
|
||||
export async function loginViaCookie(
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ user: AuthUser }> {
|
||||
const res = await fetch("/api/auth/cookie-login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ email: email.trim(), password }),
|
||||
credentials: "include",
|
||||
});
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok) {
|
||||
throw new Error((data as { error?: string }).error ?? "Giriş başarısız");
|
||||
}
|
||||
return data as { user: AuthUser };
|
||||
}
|
||||
|
||||
/** Cookie tabanlı çıkış */
|
||||
export async function logoutViaCookie(): Promise<void> {
|
||||
await fetch("/api/auth/cookie-logout", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
});
|
||||
}
|
||||
|
||||
/** Cookie oturumunu kontrol et (client tarafında oturum bilgisi için) */
|
||||
export async function getCookieSession(): Promise<{
|
||||
loggedIn: boolean;
|
||||
user?: AuthUser;
|
||||
}> {
|
||||
const res = await fetch("/api/auth/cookie-session", { credentials: "include" });
|
||||
const data = await res.json().catch(() => ({ loggedIn: false }));
|
||||
return data as { loggedIn: boolean; user?: AuthUser };
|
||||
}
|
||||
|
||||
/** POST /api/v1/auth/register */
|
||||
export async function register(body: {
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
password: string;
|
||||
username: string;
|
||||
}): Promise<RegisterResponse> {
|
||||
const base = getBaseUrl();
|
||||
const res = await fetch(`${base}${API_PREFIX}/register`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", accept: "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
const detail = (err as { detail?: string | string[] }).detail;
|
||||
const message = Array.isArray(detail) ? detail.join(" ") : detail ?? "Kayıt başarısız";
|
||||
throw new Error(message);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** GET /api/v1/auth/me */
|
||||
export async function me(accessToken: string): Promise<{ user: AuthUser }> {
|
||||
const base = getBaseUrl();
|
||||
const res = await fetch(`${base}${API_PREFIX}/me`, {
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
if (!res.ok) throw new Error("Oturum bilgisi alınamadı");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** POST /api/v1/auth/refresh */
|
||||
export async function refresh(refreshToken: string): Promise<RefreshResponse> {
|
||||
const base = getBaseUrl();
|
||||
const res = await fetch(`${base}${API_PREFIX}/refresh`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", accept: "application/json" },
|
||||
body: JSON.stringify({ refresh_token: refreshToken }),
|
||||
});
|
||||
if (!res.ok) throw new Error("Token yenilenemedi");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
const ACCESS_KEY = "auth_access_token";
|
||||
const REFRESH_KEY = "auth_refresh_token";
|
||||
|
||||
const AUTH_CHANGE_EVENT = "auth-change";
|
||||
|
||||
/** Header vb. bileşenlerin oturum değişikliğini algılaması için tetiklenir. */
|
||||
export function notifyAuthChange(): void {
|
||||
if (typeof window === "undefined") return;
|
||||
window.dispatchEvent(new Event(AUTH_CHANGE_EVENT));
|
||||
}
|
||||
|
||||
export function setTokens(access: string, refreshToken: string): void {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.setItem(ACCESS_KEY, access);
|
||||
localStorage.setItem(REFRESH_KEY, refreshToken);
|
||||
notifyAuthChange();
|
||||
}
|
||||
|
||||
export function getAccessToken(): string | null {
|
||||
if (typeof window === "undefined") return null;
|
||||
return localStorage.getItem(ACCESS_KEY);
|
||||
}
|
||||
|
||||
export function getRefreshToken(): string | null {
|
||||
if (typeof window === "undefined") return null;
|
||||
return localStorage.getItem(REFRESH_KEY);
|
||||
}
|
||||
|
||||
export function clearTokens(): void {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.removeItem(ACCESS_KEY);
|
||||
localStorage.removeItem(REFRESH_KEY);
|
||||
notifyAuthChange();
|
||||
}
|
||||
|
||||
export { AUTH_CHANGE_EVENT };
|
||||
Reference in New Issue
Block a user