eris/api/adminsRoute.ts

108 lines
3.1 KiB
TypeScript

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<Admin>): 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(),
},
);