mirror of
				https://github.com/janderedev/automod.git
				synced 2025-11-04 10:34:50 +00:00 
			
		
		
		
	little authentication overhaul
This commit is contained in:
		
							parent
							
								
									8b877f4740
								
							
						
					
					
						commit
						7cf3553026
					
				| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import { app, db } from '../..';
 | 
					import { app, db } from '../..';
 | 
				
			||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import { badRequest, isAuthenticated, unauthorized } from '../../utils';
 | 
					import { badRequest, isAuthenticated, requireAuth, unauthorized } from '../../utils';
 | 
				
			||||||
import { botReq } from '../internal/ws';
 | 
					import { botReq } from '../internal/ws';
 | 
				
			||||||
import { FindOneResult } from 'monk';
 | 
					import { FindOneResult } from 'monk';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ type AntispamRule = {
 | 
				
			||||||
    message: string | null;
 | 
					    message: string | null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.get('/dash/server/:server/automod', async (req: Request, res: Response) => {
 | 
					app.get('/dash/server/:server/automod',requireAuth({ permission: 2 }) , async (req: Request, res: Response) => {
 | 
				
			||||||
    const user = await isAuthenticated(req, res, true);
 | 
					    const user = await isAuthenticated(req, res, true);
 | 
				
			||||||
    if (!user) return;
 | 
					    if (!user) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ app.get('/dash/server/:server/automod', async (req: Request, res: Response) => {
 | 
				
			||||||
    res.send(result);
 | 
					    res.send(result);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.patch('/dash/server/:server/automod/:ruleid', async (req: Request, res: Response) => {
 | 
					app.patch('/dash/server/:server/automod/:ruleid', requireAuth({ permission: 2 }), async (req: Request, res: Response) => {
 | 
				
			||||||
    const user = await isAuthenticated(req, res, true);
 | 
					    const user = await isAuthenticated(req, res, true);
 | 
				
			||||||
    if (!user) return;
 | 
					    if (!user) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,16 +56,6 @@ app.patch('/dash/server/:server/automod/:ruleid', async (req: Request, res: Resp
 | 
				
			||||||
    const body = req.body;
 | 
					    const body = req.body;
 | 
				
			||||||
    if (!server || !ruleid) return badRequest(res);
 | 
					    if (!server || !ruleid) return badRequest(res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const response = await botReq('getUserServerDetails', { user, server });
 | 
					 | 
				
			||||||
    if (!response.success) {
 | 
					 | 
				
			||||||
        return res.status(response.statusCode ?? 500).send({ error: response.error });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!response.server) return res.status(404).send({ error: 'Server not found' });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const permissionLevel: 0|1|2|3 = response.perms;
 | 
					 | 
				
			||||||
    if (permissionLevel < 2) return unauthorized(res, `Only bot managers can manage moderation rules.`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const serverConfig: FindOneResult<any> = await db.get('servers').findOne({ id: server });
 | 
					    const serverConfig: FindOneResult<any> = await db.get('servers').findOne({ id: server });
 | 
				
			||||||
    const antiSpamRules: AntispamRule[] = serverConfig.automodSettings?.spam ?? [];
 | 
					    const antiSpamRules: AntispamRule[] = serverConfig.automodSettings?.spam ?? [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import { app, db } from '../..';
 | 
					import { app, db } from '../..';
 | 
				
			||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import { badRequest, getPermissionLevel, isAuthenticated, unauthorized } from '../../utils';
 | 
					import { badRequest, getPermissionLevel, isAuthenticated, requireAuth, unauthorized } from '../../utils';
 | 
				
			||||||
import { botReq } from '../internal/ws';
 | 
					import { botReq } from '../internal/ws';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User = { id: string, username?: string, avatarURL?: string }
 | 
					type User = { id: string, username?: string, avatarURL?: string }
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ type ServerDetails = {
 | 
				
			||||||
    channels: Channel[],
 | 
					    channels: Channel[],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.get('/dash/server/:server', async (req: Request, res: Response) => {
 | 
					app.get('/dash/server/:server', requireAuth({ permission: 0 }), async (req: Request, res: Response) => {
 | 
				
			||||||
    const user = await isAuthenticated(req, res, true);
 | 
					    const user = await isAuthenticated(req, res, true);
 | 
				
			||||||
    if (!user) return;
 | 
					    if (!user) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,13 @@
 | 
				
			||||||
import { app } from '../..';
 | 
					import { app } from '../..';
 | 
				
			||||||
import { Request, Response } from 'express';
 | 
					import { Request, Response } from 'express';
 | 
				
			||||||
import { isAuthenticated, unauthorized } from '../../utils';
 | 
					import { isAuthenticated, requireAuth, unauthorized } from '../../utils';
 | 
				
			||||||
import { botReq } from '../internal/ws';
 | 
					import { botReq } from '../internal/ws';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Server = { id: string, perms: 0|1|2|3, name: string, iconURL?: string, bannerURL?: string }
 | 
					type Server = { id: string, perms: 0|1|2|3, name: string, iconURL?: string, bannerURL?: string }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.get('/dash/servers', async (req: Request, res: Response) => {
 | 
					app.get('/dash/servers', requireAuth({ requireLogin: true }), async (req: Request, res: Response) => {
 | 
				
			||||||
    const user = await isAuthenticated(req);
 | 
					    const user = await isAuthenticated(req, res, true);
 | 
				
			||||||
    if (!user) return unauthorized(res);
 | 
					    if (!user) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const response = await botReq('getUserServers', { user });
 | 
					    const response = await botReq('getUserServers', { user });
 | 
				
			||||||
    if (!response.success) {
 | 
					    if (!response.success) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import { Request, Response } from 'express';
 | 
				
			||||||
import { botReq } from './internal/ws';
 | 
					import { botReq } from './internal/ws';
 | 
				
			||||||
import { db } from '..';
 | 
					import { db } from '..';
 | 
				
			||||||
import { FindOneResult } from 'monk';
 | 
					import { FindOneResult } from 'monk';
 | 
				
			||||||
import { badRequest } from '../utils';
 | 
					import { badRequest, isAuthenticated, requireAuth } from '../utils';
 | 
				
			||||||
import { RateLimiter } from '../middlewares/ratelimit';
 | 
					import { RateLimiter } from '../middlewares/ratelimit';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BeginReqBody {
 | 
					class BeginReqBody {
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,12 @@ class CompleteReqBody {
 | 
				
			||||||
const beginRatelimiter = new RateLimiter('/login/begin', { limit: 10, timeframe: 300 });
 | 
					const beginRatelimiter = new RateLimiter('/login/begin', { limit: 10, timeframe: 300 });
 | 
				
			||||||
const completeRatelimiter = new RateLimiter('/login/complete', { limit: 5, timeframe: 30 });
 | 
					const completeRatelimiter = new RateLimiter('/login/complete', { limit: 5, timeframe: 30 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.post('/login/begin', (...args) => beginRatelimiter.execute(...args), async (req: Request, res: Response) => {
 | 
					app.post('/login/begin',
 | 
				
			||||||
 | 
					        (...args) => beginRatelimiter.execute(...args),
 | 
				
			||||||
 | 
					        requireAuth({ noAuthOnly: true }),
 | 
				
			||||||
 | 
					        async (req: Request, res: Response) => {
 | 
				
			||||||
 | 
					    if (typeof await isAuthenticated(req) == 'string') return res.status(403).send({ error: 'You are already authenticated' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const body = req.body as BeginReqBody;
 | 
					    const body = req.body as BeginReqBody;
 | 
				
			||||||
    if (!body.user || typeof body.user != 'string') return badRequest(res);
 | 
					    if (!body.user || typeof body.user != 'string') return badRequest(res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +35,10 @@ app.post('/login/begin', (...args) => beginRatelimiter.execute(...args), async (
 | 
				
			||||||
    res.status(200).send({ success: true, nonce: r.nonce, code: r.code, uid: r.uid });
 | 
					    res.status(200).send({ success: true, nonce: r.nonce, code: r.code, uid: r.uid });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.post('/login/complete', (...args) => completeRatelimiter.execute(...args), async (req: Request, res: Response) => {
 | 
					app.post('/login/complete',
 | 
				
			||||||
 | 
					        (...args) => completeRatelimiter.execute(...args),
 | 
				
			||||||
 | 
					        requireAuth({ noAuthOnly: true }),
 | 
				
			||||||
 | 
					        async (req: Request, res: Response) => {
 | 
				
			||||||
    const body = req.body as CompleteReqBody;
 | 
					    const body = req.body as CompleteReqBody;
 | 
				
			||||||
    if ((!body.user || typeof body.user != 'string') ||
 | 
					    if ((!body.user || typeof body.user != 'string') ||
 | 
				
			||||||
        (!body.nonce || typeof body.nonce != 'string') ||
 | 
					        (!body.nonce || typeof body.nonce != 'string') ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,4 +49,24 @@ async function getPermissionLevel(user: string, server: string) {
 | 
				
			||||||
    return await botReq('getPermissionLevel', { user, server });
 | 
					    return await botReq('getPermissionLevel', { user, server });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { isAuthenticated, getSessionInfo, badRequest, unauthorized, getPermissionLevel }
 | 
					type RequireAuthConfig = { permission?: 0|1|2|3, requireLogin?: boolean, noAuthOnly?: boolean }
 | 
				
			||||||
 | 
					function requireAuth(config: RequireAuthConfig): (req: Request, res: Response, next: () => void) => void {
 | 
				
			||||||
 | 
					    return async (req: Request, res: Response, next: () => void) => {
 | 
				
			||||||
 | 
					        const auth = await isAuthenticated(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (config.noAuthOnly && typeof auth == 'string') return res.status(403).send({ error: 'Cannot access this route with authentication' });
 | 
				
			||||||
 | 
					        if (config.requireLogin && !auth) return unauthorized(res, 'Authentication required for this route');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (config.permission != undefined) {
 | 
				
			||||||
 | 
					            if (!auth) return unauthorized(res, 'Authentication required for this route');
 | 
				
			||||||
 | 
					            const server_id = req.params.serverid || req.params.server;
 | 
				
			||||||
 | 
					            const levelRes = await getPermissionLevel(auth, server_id);
 | 
				
			||||||
 | 
					            if (!levelRes.success) return res.status(500).send({ error: 'Unknown server or other error' });
 | 
				
			||||||
 | 
					            if (levelRes.level < config.permission) return unauthorized(res, 'Your permission level is too low');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        next();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { isAuthenticated, getSessionInfo, badRequest, unauthorized, getPermissionLevel, requireAuth }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ async function checkSudoPermission(message: Message): Promise<boolean> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
async function getPermissionLevel(user: User|Member, server: Server): Promise<0|1|2|3> {
 | 
					async function getPermissionLevel(user: User|Member, server: Server): Promise<0|1|2|3> {
 | 
				
			||||||
    if (isSudo(user instanceof User ? user : (user.user || await client.users.fetch(user._id.user)))) return 2;
 | 
					    if (isSudo(user instanceof User ? user : (user.user || await client.users.fetch(user._id.user)))) return 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const member = user instanceof User ? await server.fetchMember(user) : user;
 | 
					    const member = user instanceof User ? await server.fetchMember(user) : user;
 | 
				
			||||||
    if (user instanceof Member) user = user.user!;
 | 
					    if (user instanceof Member) user = user.user!;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue