import { Model } from "indexed_kv"; import { info } from "std/log/mod.ts"; import { Elysia, t } from "elysia"; import { Admin, adminSchema, adminStore } from "../app/adminStore.ts"; import { getUser, withAdmin, withUser } from "./withUser.ts"; export type AdminData = Admin & { id: string }; const adminDataSchema = t.Object({ id: t.String(), tgUserId: t.Number(), promotedBy: t.Nullable(t.String()), }); function getAdminData(adminEntry: Model): AdminData { return { id: adminEntry.id, ...adminEntry.value }; } export const adminsRoute = new Elysia() .get( "", async () => { const adminEntries = await adminStore.getAll(); const admins = adminEntries.map(getAdminData); return admins; }, { response: t.Array(adminDataSchema), }, ) .post( "", async ({ query, body }) => { return withAdmin(query, async (user, adminEntry) => { const newAdminUser = await getUser(body.tgUserId); const newAdminEntry = await adminStore.create({ tgUserId: body.tgUserId, promotedBy: adminEntry.id, }); info(`User ${user.first_name} promoted user ${newAdminUser.first_name} to admin`); return getAdminData(newAdminEntry); }); }, { query: t.Object({ sessionId: t.String() }), body: t.Object({ tgUserId: t.Number(), }), response: adminDataSchema, }, ) .post( "/promote_self", // if there are no admins, allow any user to promote themselves async ({ query }) => { return withUser(query, async (user) => { const adminEntries = await adminStore.getAll(); if (adminEntries.length === 0) { const newAdminEntry = await adminStore.create({ tgUserId: user.id, promotedBy: null, }); info(`User ${user.first_name} promoted themselves to admin`); return getAdminData(newAdminEntry); } throw new Error("You are not allowed to promote yourself"); }); }, { query: t.Object({ sessionId: t.String() }), response: adminDataSchema, }, ) .get( "/:adminId", async ({ params }) => { const adminEntry = await adminStore.getById(params.adminId!); if (!adminEntry) { throw new Error("Admin not found"); } return getAdminData(adminEntry); }, { params: t.Object({ adminId: t.String() }), response: adminDataSchema, }, ) .delete( "/:adminId", async ({ params, query }) => { return withAdmin(query, async (chat) => { const deletedAdminEntry = await adminStore.getById(params.adminId!); if (!deletedAdminEntry) { throw new Error("Admin not found"); } const deletedAdminUser = await getUser(deletedAdminEntry.value.tgUserId); await deletedAdminEntry.delete(); info(`User ${chat.first_name} demoted user ${deletedAdminUser.first_name} from admin`); return null; }); }, { params: t.Object({ adminId: t.String() }), query: t.Object({ sessionId: t.String() }), response: t.Null(), }, );