123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import express from "express";
- import { createServer } from "http";
- import { ModuleRpcServer } from "rpc_ts/lib/server";
- import { ModuleRpcProtocolServer } from "rpc_ts/lib/protocol/server";
- import { NoctBotService } from "@shared/rpc/backend";
- import { eventLogger, logger } from "./logging";
- import { client } from "./client";
- import { tryDo } from "@shared/common/async_utils";
- import { getRepository } from "typeorm";
- import { GuildVerification } from "@shared/db/entity/GuildVerification";
- import { isAuthorisedAsync } from "./util";
- import { GuildMember } from "discord.js";
- import { GuildViolationSettings } from "@shared/db/entity/GuildViolationSettings";
- const PORT = +(process.env.RPC_PORT ?? "8181");
- const app = express();
- async function checkUser(action: string, userId: string, check: (user: GuildMember, verification: GuildVerification) => Promise<boolean>): Promise<boolean> {
- const verificationGuildRepo = getRepository(GuildVerification);
- const guilds = await verificationGuildRepo.find({
- select: [
- "guildId",
- "verifiedRoleId",
- ]
- });
- for (const guild of guilds) {
- const guildInstance = await tryDo(client.bot.guilds.fetch(guild.guildId));
- if (!guildInstance.ok) {
- logger.error("Failed to fetch guild instance for guild %s: %s", guild.guildId, guildInstance.error);
- continue;
- }
- const user = await tryDo(guildInstance.result.members.fetch(userId));
- if (!user.ok) {
- const userInfo = await tryDo(client.bot.users.fetch(userId));
- const userName = userInfo.ok ? `${userInfo.result.username}#${userInfo.result.discriminator}` : "???";
- logger.warn("Couldn't %s for user %s (%s) on server %s because: %s", action, userId, userName, guild.guildId, user.error);
- }
- if (user.ok && await check(user.result, guild)) {
- return true;
- }
- }
- return false;
- }
- async function userMuted(user: GuildMember, guild: GuildVerification): Promise<boolean> {
- const violationSettingsRepo = await getRepository(GuildViolationSettings);
- const settings = await violationSettingsRepo.findOne(guild.guildId);
- if (!settings?.muteRoleId) {
- return false;
- }
- return user.roles.cache.has(settings.muteRoleId);
- }
- const handler: ModuleRpcServer.ServiceHandlerFor<typeof NoctBotService> = {
- async getPing({ ping }): Promise<{ text: string }> {
- return { text: `pong: ${ping}` };
- },
- async userInServer({ userId }): Promise<{ exists: boolean }> {
- return { exists: await checkUser("check access" ,userId, async () => true) };
- },
- async userAuthorised({ userId }): Promise<{ authorised: boolean }> {
- return { authorised: await checkUser("check auth", userId, (user) => isAuthorisedAsync(user)) };
- },
- async userVerified({ userId }): Promise<{ verified: boolean }> {
- // Prevent muted users from gaining verified role back
- return { verified: await checkUser("check verified", userId, async (user, guild) => user.roles.cache.has(guild.verifiedRoleId) || await userMuted(user, guild)) };
- },
- async verifyUser({ userId }): Promise<{ ok: boolean }> {
- return { ok: !(await checkUser("verify", userId, async (user, guild) => {
- if (await userMuted(user, guild)) {
- logger.info("Muted user %s#%s (%s) tried to re-verify in guild %s", user.user.username, user.user.discriminator, user.user.id, guild.guildId);
- return false;
- }
- const result = await tryDo(user.roles.add(guild.verifiedRoleId));
- if (result.ok) {
- eventLogger.info("Verifying user %s#%s (%s)", user.user.username, user.user.discriminator, user.user.id);
- logger.info("Verifying user %s#%s (%s) on guild %s", user.user.username, user.user.discriminator, user.user.id, guild.guildId);
- } else {
- eventLogger.warn("Failed to verify user %s#%s (%s): %s", user.user.username, user.user.discriminator, user.user.id, result.error);
- logger.warn("Failed to verify user %s#%s (%s) on guild %s: %s", user.user.username, user.user.discriminator, user.user.id, guild.guildId, result.error);
- }
- return !result.ok;
- }))};
- }
- };
- app.use(ModuleRpcProtocolServer.registerRpcRoutes(NoctBotService, handler));
- export function startRpcServer(): void {
- logger.info(`Starting RPC at *:${PORT}`);
- createServer(app).listen(PORT);
- }
|