feat: panele auth sistemi ekle (kullanıcı/şifre + oturum + middleware)
Panel şu ana kadar herkese açıktı — URL'yi bilen herkes kanal ekleyip/silebilir, cookie güncelleyebilir, kayıt indirebilirdi. - users tablosu (bcrypt şifre hash'i) - /login: hiç kullanıcı yoksa "ilk admin hesabı oluştur" formu, varsa normal giriş formu - jose ile imzalanmış, httpOnly çerezde tutulan 30 günlük oturum - middleware.ts: /login hariç tüm rotaları korur (video stream route'u dahil — aynı origin istekleri çerezi otomatik taşır) - layout: oturum yoksa nav hiç gösterilmiyor, varsa kullanıcı adı + çıkış butonu ekleniyor SESSION_SECRET production'da zorunlu (docker-compose derleme zamanında kontrol ediyor); Coolify'a rastgele bir değer eklendi. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { cookies } from "next/headers";
|
||||
import { SignJWT, jwtVerify } from "jose";
|
||||
|
||||
export const SESSION_COOKIE_NAME = "session";
|
||||
|
||||
const secret = new TextEncoder().encode(
|
||||
process.env.SESSION_SECRET ?? "dev-insecure-secret-change-me-in-production",
|
||||
);
|
||||
|
||||
export interface SessionPayload {
|
||||
sub: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
export async function createSessionToken(payload: SessionPayload): Promise<string> {
|
||||
return new SignJWT({ username: payload.username })
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setSubject(payload.sub)
|
||||
.setIssuedAt()
|
||||
.setExpirationTime("30d")
|
||||
.sign(secret);
|
||||
}
|
||||
|
||||
export async function verifySessionToken(token: string): Promise<SessionPayload | null> {
|
||||
try {
|
||||
const { payload } = await jwtVerify(token, secret);
|
||||
if (typeof payload.sub !== "string" || typeof payload.username !== "string") return null;
|
||||
return { sub: payload.sub, username: payload.username };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Server Component helper — reads and verifies the session cookie. */
|
||||
export async function getSession(): Promise<SessionPayload | null> {
|
||||
const jar = await cookies();
|
||||
const token = jar.get(SESSION_COOKIE_NAME)?.value;
|
||||
if (!token) return null;
|
||||
return verifySessionToken(token);
|
||||
}
|
||||
Reference in New Issue
Block a user