feat: shop buy, forum replies, tickets, messages, sessions, and UX hardening
Complete remaining product gaps: credit-based shop purchases, guild thread replies, help ticket detail/reply/close, offline message compose, sign-out-everywhere via JWT version, ads delete confirm, soft-fail feedback, rate limits, loading states, and single auth() in site layout. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
ed7db6e048
commit
803e8f36c1
47 files changed
+2793
-358
No files matched your search
@@ -3,6 +3,7 @@
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { clientIp, rateLimit } from "@/lib/rate-limit";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
import { sendCurrency } from "@/lib/services/send-currency";
|
||||
|
||||
@@ -40,6 +41,14 @@ export async function redeem(
|
||||
};
|
||||
}
|
||||
|
||||
await clientIp();
|
||||
if (!(await rateLimit(`voucher-redeem:${userId}`, 5, 60_000)).ok) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "You're redeeming too fast. Please wait a moment and try again.",
|
||||
};
|
||||
}
|
||||
|
||||
const code = String(formData.get("code") ?? "")
|
||||
.normalize("NFC")
|
||||
.trim();
|
||||
|
||||
Reference in new issue
Block a user