Improvements: remove dead config, fix ESM, add URL validation, unify types, add missing logging
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m52s

- Remove .prettierrc (dead config, Biome replaces Prettier)
- Rename lighthouserc.json to lighthouserc.cjs with module.exports for ESM compat
- Add logger.warn to empty catch blocks in auth, register, site-settings, prisma-cache, redis, security, rate-limit
- Unify ActionResult type: action-helper.ts uses 'ok' consistent with safe-action-shared.ts
- Add noUnusedLocals + noUnusedParameters to tsconfig + fix 25 pre-existing unused vars
- Replace barrel export src/types/index.ts with direct @/types/common imports
- Make trustHost conditional (development only) in auth.ts
- Add pre-flight URL validation to update-Nitrov3.sh to catch image.library.url misconfigurations
- Improve NITRO_IMAGE_LIBRARY_URL content validation in pre-flight & post-compute checks
This commit is contained in:
openhands committed 2026-07-26 20:28:11 +02:00
1 parent b922f6d49f
commit 17847545dd
292 files changed
+69195 -67915

No files matched your search

+50 -48
View File
@@ -64,63 +64,65 @@ export async function buyBadge(formData: FormData): Promise<void> {
if (!(await rateLimit(`draw-badge-buy:${userId}`, 5, 60_000)).ok) {
outcome = "ratelimit";
} else {
const badge = await prisma.websiteDrawbadges.findUnique({
where: { id: BigInt(rawId) },
select: { id: true, badgePath: true, published: true },
});
const badge = await prisma.websiteDrawbadges.findUnique({
where: { id: BigInt(rawId) },
select: { id: true, badgePath: true, published: true },
});
if (!badge?.published) {
outcome = "invalid";
} else {
const code = badgeCodeFromPath(badge.badgePath);
if (code.length === 0) {
if (!badge?.published) {
outcome = "invalid";
} else {
const price = await resolvePrice();
// Re-read the buyer's live credit balance and verify it covers the cost.
const buyer = await prisma.user.findUnique({
where: { id: userId },
select: { credits: true },
});
if (!buyer || buyer.credits < price) {
outcome = "credits";
const code = badgeCodeFromPath(badge.badgePath);
if (code.length === 0) {
outcome = "invalid";
} else {
// Atomically deduct credits and persist the badge so a failure
// between the two operations cannot orphan the user.
if (price > 0) {
await prisma.$transaction(async (tx: Prisma.TransactionClient) => {
await tx.user.update({
where: { id: userId },
data: { credits: { decrement: price } },
});
const price = await resolvePrice();
const existing = await tx.usersBadges.findFirst({
where: { userId, badgeCode: code },
select: { id: true },
});
if (!existing) {
const max = await tx.usersBadges.aggregate({
where: { userId },
_max: { slotId: true },
});
const slotId = (max._max.slotId ?? 0) + 1;
await tx.usersBadges.create({
data: { userId, slotId, badgeCode: code },
});
}
});
// Re-read the buyer's live credit balance and verify it covers the cost.
const buyer = await prisma.user.findUnique({
where: { id: userId },
select: { credits: true },
});
if (!buyer || buyer.credits < price) {
outcome = "credits";
} else {
// Atomically deduct credits and persist the badge so a failure
// between the two operations cannot orphan the user.
if (price > 0) {
await prisma.$transaction(
async (tx: Prisma.TransactionClient) => {
await tx.user.update({
where: { id: userId },
data: { credits: { decrement: price } },
});
const existing = await tx.usersBadges.findFirst({
where: { userId, badgeCode: code },
select: { id: true },
});
if (!existing) {
const max = await tx.usersBadges.aggregate({
where: { userId },
_max: { slotId: true },
});
const slotId = (max._max.slotId ?? 0) + 1;
await tx.usersBadges.create({
data: { userId, slotId, badgeCode: code },
});
}
},
);
}
// Grant the badge live so it appears immediately for online users.
await rcon.giveBadge(userId, code).catch(() => {});
outcome = "bought";
boughtCode = code;
}
// Grant the badge live so it appears immediately for online users.
await rcon.giveBadge(userId, code).catch(() => {});
outcome = "bought";
boughtCode = code;
}
}
}
}
} catch {
outcome = "fail";
}