mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-05-13 21:27:46 +00:00
Compare commits
4 commits
b8a4808595
...
147d005a14
| Author | SHA1 | Date | |
|---|---|---|---|
| 147d005a14 | |||
| 1dacc3ab4a | |||
| 8608acae31 | |||
| 655af51766 |
8 changed files with 37 additions and 22 deletions
|
|
@ -6,6 +6,9 @@ REDIS_URL="redis://localhost:6379/0"
|
||||||
# Used for metadata, sitemaps, etc.
|
# Used for metadata, sitemaps, etc.
|
||||||
NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
||||||
|
|
||||||
|
CLOUDFLARE_ZONE_ID=XXXXXXXXXXXXXXXX
|
||||||
|
CLOUDFLARE_API_TOKEN=XXXXXXXXXXXXXXXX
|
||||||
|
|
||||||
# Used for error tracking
|
# Used for error tracking
|
||||||
NEXT_PUBLIC_SENTRY_DSN=""
|
NEXT_PUBLIC_SENTRY_DSN=""
|
||||||
SENTRY_URL=""
|
SENTRY_URL=""
|
||||||
|
|
|
||||||
2
prisma/migrations/20260401000000_queue/migration.sql
Normal file
2
prisma/migrations/20260401000000_queue/migration.sql
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "miis" ADD COLUMN "in_queue" BOOLEAN NOT NULL DEFAULT false;
|
||||||
|
|
@ -76,6 +76,7 @@ model Mii {
|
||||||
description String? @db.VarChar(512)
|
description String? @db.VarChar(512)
|
||||||
platform MiiPlatform @default(THREE_DS)
|
platform MiiPlatform @default(THREE_DS)
|
||||||
quarantined Boolean @default(false)
|
quarantined Boolean @default(false)
|
||||||
|
in_queue Boolean @default(false)
|
||||||
|
|
||||||
instructions Json?
|
instructions Json?
|
||||||
gender MiiGender?
|
gender MiiGender?
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent non-admins from quarantining Miis
|
// Prevent non-admins from quarantining Miis
|
||||||
if (quarantined && session.user?.id != process.env.NEXT_PUBLIC_ADMIN_USER_ID) return rateLimit.sendResponse({ error: `You're not an admin!` }, 401);
|
if (quarantined && session.user?.id?.toString() !== process.env.NEXT_PUBLIC_ADMIN_USER_ID)
|
||||||
|
return rateLimit.sendResponse({ error: `You're not an admin!` }, 401);
|
||||||
|
|
||||||
// Edit Mii in database
|
// Edit Mii in database
|
||||||
const updateData: Prisma.MiiUpdateInput = {};
|
const updateData: Prisma.MiiUpdateInput = {};
|
||||||
|
|
@ -136,7 +137,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
||||||
if (instructions !== undefined) updateData.instructions = instructions;
|
if (instructions !== undefined) updateData.instructions = instructions;
|
||||||
if (images.length > 0) updateData.imageCount = images.length;
|
if (images.length > 0) updateData.imageCount = images.length;
|
||||||
|
|
||||||
if (Object.keys(updateData).length == 0) return rateLimit.sendResponse({ error: "Nothing was changed" }, 400);
|
if (Object.keys(updateData).length === 0) return rateLimit.sendResponse({ error: "Nothing was changed" }, 400);
|
||||||
const updatedMii = await prisma.mii.update({
|
const updatedMii = await prisma.mii.update({
|
||||||
where: {
|
where: {
|
||||||
id: miiId,
|
id: miiId,
|
||||||
|
|
@ -230,15 +231,28 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (description === undefined) {
|
|
||||||
// If images or description were not changed, regenerate the metadata image
|
|
||||||
try {
|
try {
|
||||||
await generateMetadataImage(updatedMii, updatedMii.user.name!);
|
await generateMetadataImage(updatedMii, updatedMii.user.name!);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return rateLimit.sendResponse({ error: `Failed to generate 'metadata' type image for mii ${miiId}` }, 500);
|
return rateLimit.sendResponse({ error: `Failed to generate 'metadata' type image for mii ${miiId}` }, 500);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Tell Cloudflare to purge cache for the changed pages
|
||||||
|
fetch(`https://api.cloudflare.com/client/v4/zones/${process.env.CLOUDFLARE_ZONE_ID}/purge_cache`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`, "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
files: [
|
||||||
|
`${process.env.NEXT_PUBLIC_BASE_URL}/mii/${miiId}`,
|
||||||
|
`${process.env.NEXT_PUBLIC_BASE_URL}/mii/${miiId}/image?type=mii`,
|
||||||
|
`${process.env.NEXT_PUBLIC_BASE_URL}/mii/${miiId}/image?type=features`,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error("Cloudflare cache purge failed:", err);
|
||||||
|
Sentry.captureException(err, { extra: { stage: "cloudflare-purge", miiId } });
|
||||||
|
});
|
||||||
|
|
||||||
return rateLimit.sendResponse({ success: true });
|
return rateLimit.sendResponse({ success: true });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,7 @@ export async function POST(request: NextRequest) {
|
||||||
tags,
|
tags,
|
||||||
description,
|
description,
|
||||||
gender: gender ?? "MALE",
|
gender: gender ?? "MALE",
|
||||||
|
in_queue: true,
|
||||||
|
|
||||||
// Automatically detect certain information if on 3DS
|
// Automatically detect certain information if on 3DS
|
||||||
...(platform === "THREE_DS"
|
...(platform === "THREE_DS"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const searchParamsSchema = z.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||||
const rateLimit = new RateLimit(request, 20000, "/mii/image");
|
const rateLimit = new RateLimit(request, 200, "/mii/image");
|
||||||
const check = await rateLimit.handle();
|
const check = await rateLimit.handle();
|
||||||
if (check) return check;
|
if (check) return check;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,8 @@ export default async function SubmitPage() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return <p>An error occurred!</p>;
|
return <p>An error occurred!</p>;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/admin/can-submit`);
|
|
||||||
value = await response.json();
|
|
||||||
} catch (error) {
|
|
||||||
return <p>An error occurred!</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value)
|
if (!value) return (
|
||||||
return (
|
|
||||||
<div className="grow flex items-center justify-center">
|
<div className="grow flex items-center justify-center">
|
||||||
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-8 max-w-xs w-full text-center flex flex-col">
|
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-8 max-w-xs w-full text-center flex flex-col">
|
||||||
<h2 className="text-5xl font-black">Sorry</h2>
|
<h2 className="text-5xl font-black">Sorry</h2>
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
|
||||||
}
|
}
|
||||||
|
|
||||||
const where: Prisma.MiiWhereInput = {
|
const where: Prisma.MiiWhereInput = {
|
||||||
|
in_queue: false,
|
||||||
// Only show liked miis on likes page
|
// Only show liked miis on likes page
|
||||||
...(inLikesPage && miiIdsLiked && { id: { in: miiIdsLiked } }),
|
...(inLikesPage && miiIdsLiked && { id: { in: miiIdsLiked } }),
|
||||||
// Searching
|
// Searching
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue