co-authored by
Gunshin
Unverified
parent
45f6d06cc9
commit
8a96ea8573
+28
-31
@@ -4,8 +4,7 @@ import { and, eq, inArray, not, or, sql } from "drizzle-orm";
|
||||
import type { PgDatabase } from "drizzle-orm/pg-core";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
import { after } from "next/server";
|
||||
import type { TypedFormData } from "@/app/(ui)/endgame/type";
|
||||
import type { TypedFormData } from "@/app/(ui)/rubgram/type";
|
||||
import { adminCheck } from "./auth";
|
||||
import { uidRegex } from "./const";
|
||||
import { db } from "./db";
|
||||
@@ -93,7 +92,7 @@ export async function toggleCheck(submissionId: string) {
|
||||
revalidatePath("/artifact/admin");
|
||||
revalidatePath("/artifact");
|
||||
|
||||
actionLog(`Toggled an artifact submission check mark`);
|
||||
await actionLog(`Toggled an artifact submission check mark`);
|
||||
}
|
||||
|
||||
export async function toggleLock() {
|
||||
@@ -109,7 +108,7 @@ export async function toggleLock() {
|
||||
revalidatePath("/artifact/admin");
|
||||
revalidatePath("/artifact");
|
||||
|
||||
actionLog(
|
||||
await actionLog(
|
||||
`${(existing.length ? existing[0].locked : true) ? "Locked" : "Unlocked"} artifact submission`,
|
||||
);
|
||||
}
|
||||
@@ -131,7 +130,7 @@ export async function setLimit(limit: number) {
|
||||
revalidatePath("/artifact/admin");
|
||||
revalidatePath("/artifact");
|
||||
|
||||
actionLog(`Set artifact submit limit to ${limit < 0 ? "unlimited" : limit}`);
|
||||
await actionLog(`Set artifact submit limit to ${limit < 0 ? "unlimited" : limit}`);
|
||||
}
|
||||
|
||||
export async function wipe() {
|
||||
@@ -143,7 +142,7 @@ export async function wipe() {
|
||||
revalidatePath("/artifact/admin");
|
||||
revalidatePath("/artifact");
|
||||
|
||||
actionLog(`Deleted artifact submissions`);
|
||||
await actionLog(`Deleted artifact submissions`);
|
||||
redirect("/artifact/admin");
|
||||
}
|
||||
|
||||
@@ -192,7 +191,7 @@ export async function tlState(
|
||||
|
||||
revalidatePath(`/api/tl/${list}/states`);
|
||||
|
||||
actionLog(`Updated a state in tierlist ${list}`, data);
|
||||
await actionLog(`Updated a state in tierlist ${list}`, data);
|
||||
sse.publish(states, { topic: `tl-${list}`, event: "update_states" });
|
||||
}
|
||||
|
||||
@@ -214,7 +213,7 @@ export async function tlPlacements(
|
||||
|
||||
revalidatePath(`/api/tl/${list}`);
|
||||
|
||||
actionLog(`Updated a placement in tierlist ${list}`);
|
||||
await actionLog(`Updated a placement in tierlist ${list}`);
|
||||
sse.publish(placements, { topic: `tl-${list}`, event: "update_placements" });
|
||||
}
|
||||
|
||||
@@ -227,7 +226,7 @@ export async function cdnDelete(ids: string[], force = false) {
|
||||
const refs = await checkCdnRefs(id);
|
||||
if (refs.length) {
|
||||
revalidatePath("/cdn/admin");
|
||||
actionLog(
|
||||
await actionLog(
|
||||
`Deleted ${deleted}/${ids.length}(Incomplete) files`,
|
||||
ids.slice(0, deleted),
|
||||
);
|
||||
@@ -238,7 +237,7 @@ export async function cdnDelete(ids: string[], force = false) {
|
||||
}
|
||||
revalidatePath("/cdn/admin");
|
||||
|
||||
actionLog(`Deleted ${deleted} files`, ids);
|
||||
await actionLog(`Deleted ${deleted} files`, ids);
|
||||
}
|
||||
|
||||
export async function checkCdnRefs(
|
||||
@@ -272,7 +271,7 @@ export async function cdnify(
|
||||
})
|
||||
.returning({ id: cdn.id });
|
||||
|
||||
actionLog(`File uploaded: ${name || `[${id}]`} (${b2s(data.size)})`);
|
||||
await actionLog(`File uploaded: ${name || `[${id}]`} (${b2s(data.size)})`);
|
||||
|
||||
try {
|
||||
revalidatePath("/admin/cdn");
|
||||
@@ -281,27 +280,25 @@ export async function cdnify(
|
||||
}
|
||||
|
||||
export async function actionLog(text: string, details?: unknown) {
|
||||
after(async () => {
|
||||
// If not running in Next.js, skip.
|
||||
if (typeof process.versions.bun !== "undefined") return;
|
||||
const session = await adminCheck();
|
||||
// If not running in Next.js, skip.
|
||||
if (typeof process.versions.bun !== "undefined") return;
|
||||
const session = await adminCheck();
|
||||
|
||||
const res = await db
|
||||
.insert(auditLog)
|
||||
.values({
|
||||
author: session?.name,
|
||||
text,
|
||||
details,
|
||||
})
|
||||
.returning()
|
||||
.catch(() =>
|
||||
console.error(
|
||||
`Error logging audit log, printing it here:\n${session?.name || "[Unknown User]"} - ${text}`,
|
||||
),
|
||||
);
|
||||
const res = await db
|
||||
.insert(auditLog)
|
||||
.values({
|
||||
author: session?.name,
|
||||
text,
|
||||
details,
|
||||
})
|
||||
.returning()
|
||||
.catch(() =>
|
||||
console.error(
|
||||
`Error logging audit log, printing it here:\n${session?.name || "[Unknown User]"} - ${text}`,
|
||||
),
|
||||
);
|
||||
|
||||
revalidatePath("/admin/log");
|
||||
revalidatePath("/admin/log");
|
||||
|
||||
if (res) sse.publish(res, { topic: "log" });
|
||||
});
|
||||
if (res) sse.publish(res, { topic: "log" });
|
||||
}
|
||||
|
||||
@@ -10,12 +10,6 @@ export const auth = betterAuth({
|
||||
enabled: true,
|
||||
disableSignUp: true,
|
||||
},
|
||||
socialProviders: {
|
||||
discord: {
|
||||
enabled: true,
|
||||
clientId: "1397024670355554336",
|
||||
},
|
||||
},
|
||||
plugins: [admin()],
|
||||
trustedOrigins: [
|
||||
"http://nyx:3000",
|
||||
|
||||
+9
-1
@@ -14,6 +14,7 @@ type WebsiteComms = Partial<{
|
||||
debug: boolean;
|
||||
connected: boolean;
|
||||
updated: boolean;
|
||||
"rubgram.services": ("abyss" | "theater" | "stygian")[];
|
||||
_raw: Record<string, unknown>;
|
||||
}>;
|
||||
|
||||
@@ -91,7 +92,14 @@ export default function CommsProvider({
|
||||
}
|
||||
|
||||
export const comms = {
|
||||
var(name: keyof WebsiteComms) {
|
||||
var<K extends keyof WebsiteComms>(
|
||||
name: K,
|
||||
): [
|
||||
WebsiteComms[K],
|
||||
(
|
||||
value: WebsiteComms[K] | ((prev: WebsiteComms[K]) => WebsiteComms[K]),
|
||||
) => void,
|
||||
] {
|
||||
const comms = use(CommsContext);
|
||||
if (!comms.active) {
|
||||
console.warn("ICC used outside of provider. Using local state instead.");
|
||||
|
||||
+51
-3
@@ -3,6 +3,7 @@ import {
|
||||
boolean,
|
||||
integer,
|
||||
jsonb,
|
||||
numeric,
|
||||
pgEnum,
|
||||
pgSchema,
|
||||
pgTable,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
timestamp,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { uuidv7 } from "uuidv7";
|
||||
import type { SlipokResponse } from "@/app/(ui)/rubgram/api";
|
||||
import { bytea } from "./custom";
|
||||
|
||||
export const element = pgEnum("character_element", [
|
||||
@@ -102,22 +104,68 @@ export const artifactSettings = artifact.table("settings", {
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Artifact
|
||||
//#region Endgame
|
||||
export const endgame = pgSchema("endgame");
|
||||
|
||||
export const endgameServer = endgame.enum("server", ["as", "eu", "us", "tw"]);
|
||||
export const endgameService = endgame.enum("service", [
|
||||
"abyss",
|
||||
"theater",
|
||||
"stygian",
|
||||
]);
|
||||
|
||||
export const endgameSubmissions = endgame.table("submissions", {
|
||||
id: text().primaryKey().$defaultFn(uuidv7),
|
||||
name: text().notNull(),
|
||||
user: text().notNull(),
|
||||
expires: timestamp().$defaultFn(() => new Date(Date.now() + 15 * 60 * 1000)), // 15 minutes to pay
|
||||
user: text()
|
||||
.notNull()
|
||||
.references(() => endgameDiscord.uid, {
|
||||
onDelete: "cascade",
|
||||
onUpdate: "cascade",
|
||||
}),
|
||||
expires: timestamp().$defaultFn(() => new Date(Date.now() + 20 * 60 * 1000)), // 20 minutes to pay
|
||||
queue: serial(),
|
||||
server: endgameServer().notNull(),
|
||||
service: endgameService().array().notNull(),
|
||||
price: integer().notNull(), // calculated on submission
|
||||
slip: text().references(() => endgameSlips.id), // not paid = null
|
||||
checked: boolean().notNull().default(false),
|
||||
});
|
||||
|
||||
// deleted submissions
|
||||
export const endgameArchive = endgame.table("archive", {
|
||||
id: text().primaryKey().$defaultFn(uuidv7),
|
||||
name: text().notNull(),
|
||||
user: text()
|
||||
.notNull()
|
||||
.references(() => endgameDiscord.uid, {
|
||||
onDelete: "cascade",
|
||||
onUpdate: "cascade",
|
||||
}),
|
||||
server: endgameServer().notNull(),
|
||||
service: endgameService().array().notNull(),
|
||||
});
|
||||
|
||||
export const endgameSlips = endgame.table("slips", {
|
||||
id: text().primaryKey().$defaultFn(uuidv7),
|
||||
slip: bytea().notNull(),
|
||||
ref: text().unique().notNull(),
|
||||
amount: numeric().notNull(),
|
||||
data: jsonb().$type<SlipokResponse>().notNull(),
|
||||
});
|
||||
|
||||
export const endgameSettings = endgame.table("settings", {
|
||||
id: boolean().primaryKey().default(true),
|
||||
locked: boolean().notNull().default(false),
|
||||
limit: integer().notNull().default(-1),
|
||||
free: integer().notNull().default(0),
|
||||
});
|
||||
|
||||
export const endgameDiscord = endgame.table("discord", {
|
||||
uid: text().primaryKey(), // user snowflake
|
||||
display: text().notNull(),
|
||||
username: text().notNull(),
|
||||
token: text().notNull().$defaultFn(uuidv7), // for accessing existing user with cookie.
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
+3
-1
@@ -117,7 +117,9 @@ export class EventSourceManager {
|
||||
if (s.topic !== topic) continue;
|
||||
try {
|
||||
s.send(data, event);
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error(` ERR #${topic}#${s.id}, ${error}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user