|  | @@ -10,6 +10,7 @@ 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");
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -42,6 +43,15 @@ async function checkUser(action: string, userId: string, check: (user: GuildMemb
 | 
	
		
			
				|  |  |      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}` };
 | 
	
	
		
			
				|  | @@ -53,10 +63,15 @@ const handler: ModuleRpcServer.ServiceHandlerFor<typeof NoctBotService> = {
 | 
	
		
			
				|  |  |          return { authorised: await checkUser("check auth", userId, (user) => isAuthorisedAsync(user)) };
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      async userVerified({ userId }): Promise<{ verified: boolean }> {
 | 
	
		
			
				|  |  | -        return { verified: await checkUser("check verified", userId, async (user, guild) => user.roles.cache.has(guild.verifiedRoleId)) };
 | 
	
		
			
				|  |  | +        // 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);
 |