2023-10-23 00:39:01 +00:00
|
|
|
import { Model } from "indexed_kv";
|
|
|
|
import { info } from "std/log/mod.ts";
|
2023-11-17 23:52:51 +00:00
|
|
|
import { Elysia, t } from "elysia";
|
2023-10-23 00:39:01 +00:00
|
|
|
import { Admin, adminSchema, adminStore } from "../app/adminStore.ts";
|
|
|
|
import { getUser, withAdmin, withUser } from "./withUser.ts";
|
|
|
|
|
|
|
|
export type AdminData = Admin & { id: string };
|
|
|
|
|
2023-11-17 23:52:51 +00:00
|
|
|
const adminDataSchema = t.Object({
|
|
|
|
id: t.String(),
|
|
|
|
tgUserId: t.Number(),
|
|
|
|
promotedBy: t.Nullable(t.String()),
|
|
|
|
});
|
|
|
|
|
2023-10-23 00:39:01 +00:00
|
|
|
function getAdminData(adminEntry: Model<Admin>): AdminData {
|
|
|
|
return { id: adminEntry.id, ...adminEntry.value };
|
|
|
|
}
|
|
|
|
|
2023-11-17 23:52:51 +00:00
|
|
|
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) => {
|
2023-10-23 00:39:01 +00:00
|
|
|
const adminEntries = await adminStore.getAll();
|
2023-11-17 23:52:51 +00:00
|
|
|
if (adminEntries.length === 0) {
|
2023-10-23 00:39:01 +00:00
|
|
|
const newAdminEntry = await adminStore.create({
|
2023-11-17 23:52:51 +00:00
|
|
|
tgUserId: user.id,
|
|
|
|
promotedBy: null,
|
2023-10-23 00:39:01 +00:00
|
|
|
});
|
2023-11-17 23:52:51 +00:00
|
|
|
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(),
|
|
|
|
},
|
|
|
|
);
|