upload fix
This commit is contained in:
@@ -181,7 +181,7 @@ function AdminPage({ user }: Props) {
|
||||
});
|
||||
setName(""); setDescription(""); setPicture(""); setIcon(""); setAttachments("");
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}
|
||||
|
||||
async function removeRating(id: string) {
|
||||
@@ -303,7 +303,7 @@ function AdminPage({ user }: Props) {
|
||||
await fetch(ua(`/api/admin/tags/${id}`), { method: "DELETE" });
|
||||
loadTags();
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}
|
||||
|
||||
async function updateTag(id: string) {
|
||||
@@ -316,7 +316,7 @@ function AdminPage({ user }: Props) {
|
||||
setEditingTagId(null);
|
||||
loadTags();
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}
|
||||
|
||||
async function addTagToRating(ratingId: string, tagId: string) {
|
||||
@@ -329,13 +329,13 @@ function AdminPage({ user }: Props) {
|
||||
setAddingTagToRating(null);
|
||||
setSelectedTagForRating("");
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}
|
||||
|
||||
async function removeTagFromRating(ratingId: string, tagId: string) {
|
||||
await fetch(ua(`/api/admin/ratings/${ratingId}/tags/${tagId}`), { method: "DELETE" });
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}
|
||||
|
||||
async function createBet() {
|
||||
@@ -635,7 +635,7 @@ function AdminPage({ user }: Props) {
|
||||
}
|
||||
setSelectedRatingIds(new Set());
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}} style={{ padding: "6px 14px", fontSize: 13, background: "#424e88", color: "#fff", border: "none", cursor: "pointer", whiteSpace: "nowrap" }}>Apply</button>
|
||||
</div>
|
||||
)}
|
||||
@@ -710,7 +710,7 @@ function AdminPage({ user }: Props) {
|
||||
if (!r.ok) { const err = await r.json(); console.error("Upload failed:", err); return; }
|
||||
setMusicUploads([]);
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
} catch (e) { console.error("Upload error:", e); }
|
||||
setUploadingMusic(false);
|
||||
}} disabled={musicUploads.length === 0 || uploadingMusic} style={{ padding: "10px 0", fontSize: 16, fontWeight: 700, background: "#424e88", color: "#fff", border: "none", cursor: musicUploads.length === 0 || uploadingMusic ? "not-allowed" : "pointer", width: "100%", opacity: musicUploads.length === 0 || uploadingMusic ? 0.6 : 1 }}>
|
||||
@@ -1008,7 +1008,7 @@ function AdminPage({ user }: Props) {
|
||||
await fetch(ua(`/api/admin/ratings/${editingRating.id}`), { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(editRatingData) });
|
||||
setEditingRating(null);
|
||||
const res = await fetch("/api/ratings").then((r) => r.json());
|
||||
setRatings(res);
|
||||
setRatings(res.items);
|
||||
}} style={{ padding: "8px 16px", fontSize: 14, background: "#424e88", color: "#fff", border: "none", cursor: "pointer" }}>Save</button>
|
||||
<button onClick={() => setEditingRating(null)} style={{ padding: "8px 16px", fontSize: 14, background: "none", color: textClr, border: `1px solid ${borderClr}`, cursor: "pointer" }}>Cancel</button>
|
||||
</div>
|
||||
|
||||
+7
-1
@@ -15,6 +15,8 @@ type RatingCacheEntry = { id: string; type: string; name: string; picture: strin
|
||||
type PendingVoteOp = { userId?: string; ip?: string; ratingId: string; ratingCategoryId: string; score: number | null };
|
||||
type PendingStarOp = { userId: string; ratingId: string; ratingCategoryId: string; starred: boolean };
|
||||
|
||||
let adminUserId: string | null = null;
|
||||
|
||||
const cache = {
|
||||
ratings: new Map<string, RatingCacheEntry>(),
|
||||
ratingTypes: new Map<string, { id: string; name: string; hasAttachments: boolean; categories: { id: string; name: string }[] }>(),
|
||||
@@ -67,6 +69,8 @@ async function rebuildCache() {
|
||||
prisma.anonymousRatingVote.findMany(),
|
||||
prisma.ratingStar.findMany(),
|
||||
]);
|
||||
const adminUser = await prisma.user.findUnique({ where: { email: "invoictoan@gmail.com" }, select: { id: true } });
|
||||
adminUserId = adminUser?.id ?? null;
|
||||
cache.ratings.clear();
|
||||
for (const r of ratings) cache.ratings.set(r.id, { ...r, tags: r.tags.map(rt => ({ id: rt.tag.id, name: rt.tag.name, color: rt.tag.color })) });
|
||||
cache.ratingTypes.clear();
|
||||
@@ -132,12 +136,14 @@ setInterval(() => {
|
||||
|
||||
app.use((req, res, next) => {
|
||||
const userId = req.body?.userId || (req.query?.userId as string) || undefined;
|
||||
if (userId && userId === adminUserId) { next(); return; }
|
||||
const key = userId || getIp(req);
|
||||
const now = Date.now();
|
||||
const cutoff = now - 60000;
|
||||
let times = rateLimitStore.get(key) || [];
|
||||
times = times.filter(t => t > cutoff);
|
||||
if (times.length >= 60) {
|
||||
const limit = userId ? 120 : 60;
|
||||
if (times.length >= limit) {
|
||||
res.status(429).json({ error: "rate limit exceeded" });
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user