/
Hiru
/
yaprosebya
Обзор
Документация
Войти
/
Hiru
/
yaprosebya
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/proxy.ts
97 строк
2 KB
Hiruman
yaprosebya 2.0 - admin panel
21 мар 2026, 22:07
21 мар 2026, 22:07
e11d65d
Код
Авторство
О чём код?
import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; const ADMIN_COOKIE_NAME = "corementa_admin_session"; export async function proxy(request: NextRequest) { const { pathname } = request.nextUrl; if (!pathname.startsWith("/admin")) { return NextResponse.next(); } if (pathname === "/admin/login") { return NextResponse.next(); } const token = request.cookies.get(ADMIN_COOKIE_NAME)?.value; const secret = process.env.ADMIN_SESSION_SECRET; if (!token || !secret) { return NextResponse.redirect(new URL("/admin/login", request.url)); } const isValid = await verifyToken(token, secret); if (!isValid) { return NextResponse.redirect(new URL("/admin/login", request.url)); } return NextResponse.next(); } async function verifyToken(token: string, secret: string) { const parts = token.split("."); if (parts.length !== 2) return false; const [encodedPayload, signature] = parts; const expectedSignature = await signValue(encodedPayload, secret); if (signature !== expectedSignature) return false; try { const payloadJson = decodeBase64Url(encodedPayload); const payload = JSON.parse(payloadJson) as { sub: string; exp: number; }; if (payload.sub !== "admin") return false; if (payload.exp < Math.floor(Date.now() / 1000)) return false; return true; } catch { return false; } } async function signValue(value: string, secret: string) { const key = await crypto.subtle.importKey( "raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"], ); const signature = await crypto.subtle.sign( "HMAC", key, new TextEncoder().encode(value), ); return encodeBase64Url(new Uint8Array(signature)); } function encodeBase64Url(bytes: Uint8Array) { let binary = ""; for (const byte of bytes) { binary += String.fromCharCode(byte); } return btoa(binary) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/g, ""); } function decodeBase64Url(value: string) { const normalized = value.replace(/-/g, "+").replace(/_/g, "/"); const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4); return atob(padded); } export const config = { matcher: ["/admin", "/admin/:path*"], };