mirror of
https://github.com/AderKonstantin/aderktech-chronark.com-.git
synced 2025-06-08 13:48:42 +03:00
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import Redis from "ioredis";
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
// Настройка подключения к локальному Redis
|
|
const redis = new Redis({
|
|
host: process.env.REDIS_HOST || "localhost",
|
|
port: parseInt(process.env.REDIS_PORT || "6379"),
|
|
password: process.env.REDIS_PASSWORD,
|
|
});
|
|
|
|
export const config = {
|
|
runtime: "nodejs", // Возможно потребуется изменить на "nodejs" если возникнут проблемы
|
|
};
|
|
|
|
export default async function incr(req: NextRequest): Promise<NextResponse> {
|
|
if (req.method !== "POST") {
|
|
return new NextResponse("use POST", { status: 405 });
|
|
}
|
|
if (req.headers.get("Content-Type") !== "application/json") {
|
|
return new NextResponse("must be json", { status: 400 });
|
|
}
|
|
|
|
const body = await req.json();
|
|
const slug = body.slug;
|
|
|
|
if (!slug) {
|
|
return new NextResponse("Slug not found", { status: 400 });
|
|
}
|
|
|
|
const ip = req.ip;
|
|
if (ip) {
|
|
// Хеширование IP-адреса
|
|
const buf = await crypto.subtle.digest(
|
|
"SHA-256",
|
|
new TextEncoder().encode(ip)
|
|
);
|
|
const hash = Array.from(new Uint8Array(buf))
|
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
.join("");
|
|
|
|
// Проверка уникальности посещения
|
|
const key = `deduplicate:${hash}:${slug}`;
|
|
const isNew = await redis.set(key, "1", "EX", 86400, "NX");
|
|
|
|
if (!isNew) {
|
|
return new NextResponse(null, { status: 202 });
|
|
}
|
|
}
|
|
|
|
// Увеличиваем счетчик просмотров
|
|
await redis.incr(`projects:${slug}:views`);
|
|
return new NextResponse(null, { status: 202 });
|
|
} |