feat: shared login with session cookie
This commit is contained in:
1 parent
159b549bf7
commit
73295653ee
8 files changed
+215
-9
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { verifyPassword, createSession, SESSION_COOKIE } from "../../../../lib/auth";
|
||||
|
||||
const WINDOW_MS = 60_000;
|
||||
const MAX_ATTEMPTS = 10;
|
||||
const attempts = new Map<string, { count: number; reset: number }>();
|
||||
|
||||
function rateLimited(key: string): boolean {
|
||||
const now = Date.now();
|
||||
const entry = attempts.get(key);
|
||||
if (!entry || now > entry.reset) {
|
||||
attempts.set(key, { count: 1, reset: now + WINDOW_MS });
|
||||
return false;
|
||||
}
|
||||
entry.count += 1;
|
||||
return entry.count > MAX_ATTEMPTS;
|
||||
}
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const ip = req.headers.get("x-forwarded-for") ?? "local";
|
||||
if (rateLimited(ip)) {
|
||||
return NextResponse.json({ error: "Zu viele Versuche" }, { status: 429 });
|
||||
}
|
||||
let body: { user?: string; password?: string };
|
||||
try {
|
||||
body = await req.json();
|
||||
} catch {
|
||||
return NextResponse.json({ error: "Zugangsdaten ungültig" }, { status: 401 });
|
||||
}
|
||||
const appUser = process.env.APP_USER ?? "";
|
||||
const appHash = process.env.APP_PASSWORD_HASH ?? "";
|
||||
const ok =
|
||||
typeof body.user === "string" &&
|
||||
typeof body.password === "string" &&
|
||||
body.user === appUser &&
|
||||
(await verifyPassword(body.password, appHash));
|
||||
if (!ok) {
|
||||
return NextResponse.json({ error: "Zugangsdaten ungültig" }, { status: 401 });
|
||||
}
|
||||
const token = await createSession(appUser);
|
||||
const res = NextResponse.json({ ok: true });
|
||||
res.cookies.set(SESSION_COOKIE, token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: "lax",
|
||||
path: "/",
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { SESSION_COOKIE } from "../../../../lib/auth";
|
||||
|
||||
export async function POST() {
|
||||
const res = NextResponse.json({ ok: true });
|
||||
res.cookies.set(SESSION_COOKIE, "", { path: "/", maxAge: 0 });
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function GET(req: Request) {
|
||||
const res = NextResponse.redirect(new URL("/login", req.url));
|
||||
res.cookies.set(SESSION_COOKIE, "", { path: "/", maxAge: 0 });
|
||||
return res;
|
||||
}
|
||||
Reference in new issue
Block a user