Update code

This commit is contained in:
UltraLionFr
2025-08-20 14:14:33 +02:00
parent 174cf5ef60
commit 0c1a0d74d7
53 changed files with 3830 additions and 373 deletions
+25
View File
@@ -0,0 +1,25 @@
import NextAuth, { NextAuthOptions } from 'next-auth';
import DiscordProvider from 'next-auth/providers/discord';
export const authOptions: NextAuthOptions = {
providers: [
DiscordProvider({
clientId: process.env.DISCORD_CLIENT_ID!,
clientSecret: process.env.DISCORD_CLIENT_SECRET!,
}),
],
callbacks: {
async session({ session, token }) {
if (session.user && token.sub) {
session.user.id = token.sub;
} else {
session.user.id = '';
}
return session;
},
}
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
+30
View File
@@ -0,0 +1,30 @@
import { prisma } from '@/lib/prisma';
interface Props {
params: { id: string };
}
export default async function PastePage({ params }: Props) {
const paste = await prisma.paste.findUnique({
where: { id: params.id },
select: { title: true, content: true, createdAt: true, views: true },
});
if (!paste) return <div>Paste not found</div>;
return (
<div className="min-h-screen bg-[#0e0f13] text-white p-6">
<h1 className="text-3xl font-bold text-blue-400 mb-4">
{paste.title || 'Untitled'}
</h1>
<pre className="bg-[#11131c] p-6 rounded-xl whitespace-pre-wrap overflow-auto text-sm border border-white/10 shadow-lg">
{paste.content}
</pre>
<p className="mt-4 text-xs text-neutral-400">
Views: {paste.views} · Created at: {new Date(paste.createdAt).toLocaleString()}
</p>
</div>
);
}
+68
View File
@@ -0,0 +1,68 @@
import { prisma } from '@/lib/prisma';
import bcrypt from 'bcryptjs';
import { NextRequest, NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
export const revalidate = 0;
export async function POST(
request: NextRequest,
context: { params: { id: string } }
) {
const { params } = context;
const pasteId = params.id;
const { password = '' } = await request.json();
if (!pasteId) {
return NextResponse.json({ error: 'Invalid ID' }, { status: 400 });
}
const paste = await prisma.paste.findUnique({ where: { id: pasteId } });
if (!paste) {
return NextResponse.json({ error: 'Not found' }, { status: 404 });
}
if (paste.maxViews !== null && paste.views >= paste.maxViews) {
await prisma.paste.delete({ where: { id: paste.id } });
return NextResponse.json({ error: 'Max views exceeded' }, { status: 404 });
}
if (paste.password) {
const valid = await bcrypt.compare(password, paste.password);
if (!valid) {
return NextResponse.json({ error: 'Invalid password' }, { status: 403 });
}
}
const updated = await prisma.paste.update({
where: { id: paste.id },
data: { views: { increment: 1 } },
select: {
id: true,
title: true,
content: true,
createdAt: true,
views: true,
maxViews: true,
password: true,
},
});
const payload = {
id: updated.id,
title: updated.title,
content: updated.content,
createdAt: updated.createdAt,
views: updated.views,
protected: !!updated.password,
};
if (updated.maxViews !== null && updated.views >= updated.maxViews) {
prisma.paste.delete({ where: { id: updated.id } }).catch(() => {});
}
return NextResponse.json(payload, {
headers: { 'Cache-Control': 'no-store' },
});
}
+61
View File
@@ -0,0 +1,61 @@
import { prisma } from '@/lib/prisma';
import bcrypt from 'bcryptjs';
import { getServerSession } from 'next-auth';
import { NextResponse } from 'next/server';
import { authOptions } from '../auth/[...nextauth]/route';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 7);
export async function POST(req: Request) {
const body = await req.json();
const session = await getServerSession(authOptions);
let hashedPassword = null;
if (body.password) {
hashedPassword = await bcrypt.hash(body.password, 10);
}
const paste = await prisma.paste.create({
data: {
id: nanoid(),
title: body.title || null,
content: body.content,
password: hashedPassword,
maxViews: body.maxViews ? parseInt(body.maxViews, 10) : null,
createdBy: session?.user?.id ?? null,
size: Buffer.byteLength(body.content, 'utf8'),
},
});
return NextResponse.json(paste);
}
export async function DELETE(req: Request) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const { searchParams } = new URL(req.url);
const id = searchParams.get("id");
if (!id) {
return NextResponse.json({ error: "Missing id" }, { status: 400 });
}
try {
const paste = await prisma.paste.findUnique({ where: { id } });
if (!paste || paste.createdBy !== session.user.id) {
return NextResponse.json({ error: "Not found" }, { status: 404 });
}
await prisma.paste.delete({ where: { id } });
return NextResponse.json({ success: true });
} catch (error) {
console.error(error);
return NextResponse.json({ error: "Server error" }, { status: 500 });
}
}
+10
View File
@@ -0,0 +1,10 @@
import { getDashboardStats } from '@/lib/stats';
import { getServerSession } from 'next-auth';
import { NextResponse } from 'next/server';
import { authOptions } from '../auth/[...nextauth]/route';
export async function GET() {
const session = await getServerSession(authOptions);
const stats = await getDashboardStats(session?.user?.id);
return NextResponse.json(stats);
}
+45
View File
@@ -0,0 +1,45 @@
import { authOptions } from '@/app/api/auth/[...nextauth]/route';
import { prisma } from '@/lib/prisma';
import { getServerSession } from 'next-auth';
import { NextResponse } from 'next/server';
export async function GET(req: Request) {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return NextResponse.json([], { status: 401 });
}
const { searchParams } = new URL(req.url);
const page = parseInt(searchParams.get('page') || '1', 10);
const perPage = parseInt(searchParams.get('perPage') || '10', 10);
const skip = (page - 1) * perPage;
const search = searchParams.get('q') || '';
const filter = {
createdBy: session.user.id,
...(search
? {
title: {
contains: search,
mode: 'insensitive',
},
}
: {}),
};
const [pastes, total] = await Promise.all([
prisma.paste.findMany({
where: filter,
orderBy: { createdAt: 'desc' },
skip,
take: perPage,
}),
prisma.paste.count({
where: filter,
}),
]);
return NextResponse.json({ pastes, total });
}