add `right` option to route()

This commit is contained in:
Flam3rboy 2021-10-03 01:55:57 +02:00
parent 62f727783d
commit 7268779dc3
6 changed files with 31 additions and 5 deletions

View File

@ -1,6 +1,6 @@
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response } from "express";
import { HTTPError } from "lambert-server"; import { HTTPError } from "lambert-server";
import { checkToken, Config } from "@fosscord/util"; import { checkToken, Config, Rights } from "@fosscord/util";
export const NO_AUTHORIZATION_ROUTES = [ export const NO_AUTHORIZATION_ROUTES = [
"/auth/login", "/auth/login",
@ -21,6 +21,7 @@ declare global {
user_id: string; user_id: string;
user_bot: boolean; user_bot: boolean;
token: string; token: string;
rights: Rights;
} }
} }
} }
@ -46,6 +47,7 @@ export async function Authentication(req: Request, res: Response, next: NextFunc
req.token = decoded; req.token = decoded;
req.user_id = decoded.id; req.user_id = decoded.id;
req.user_bot = user.bot; req.user_bot = user.bot;
req.rights = new Rights(user.rights);
return next(); return next();
} catch (error: any) { } catch (error: any) {
return next(new HTTPError(error?.toString(), 400)); return next(new HTTPError(error?.toString(), 400));

View File

@ -1,4 +1,15 @@
import { DiscordApiErrors, EVENT, Event, EventData, getPermission, PermissionResolvable, Permissions } from "@fosscord/util"; import {
DiscordApiErrors,
EVENT,
Event,
EventData,
FosscordApiErrors,
getPermission,
PermissionResolvable,
Permissions,
RightResolvable,
Rights
} from "@fosscord/util";
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response } from "express";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
@ -33,6 +44,7 @@ export type RouteResponse = { status?: number; body?: `${string}Response`; heade
export interface RouteOptions { export interface RouteOptions {
permission?: PermissionResolvable; permission?: PermissionResolvable;
right?: RightResolvable;
body?: `${string}Schema`; // typescript interface name body?: `${string}Schema`; // typescript interface name
test?: { test?: {
response?: RouteResponse; response?: RouteResponse;
@ -89,6 +101,13 @@ export function route(opts: RouteOptions) {
} }
} }
if (opts.right) {
const required = new Rights(opts.right);
if (!req.rights || !req.rights.has(required)) {
throw FosscordApiErrors.MISSING_RIGHTS.withParams(opts.right as string);
}
}
if (validate) { if (validate) {
const valid = validate(normalizeBody(req.body)); const valid = validate(normalizeBody(req.body));
if (!valid) { if (!valid) {

View File

@ -143,6 +143,5 @@ export class BitField {
} }
export function BitFlag(x: bigint | number) { export function BitFlag(x: bigint | number) {
if (!x) throw new Error("You need to pass a bitflag");
return BigInt(1) << BigInt(x); return BigInt(1) << BigInt(x);
} }

View File

@ -726,7 +726,9 @@ export const DiscordApiErrors = {
/** /**
* An error encountered while performing an API request (Fosscord only). Here are the potential errors: * An error encountered while performing an API request (Fosscord only). Here are the potential errors:
*/ */
export const FosscordApiErrors = {}; export const FosscordApiErrors = {
MISSING_RIGHTS: new ApiError("You lack rights to perform that action ({})", 50013, undefined, [""]),
};
/** /**
* The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types: * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types:

View File

@ -10,7 +10,10 @@ export function checkToken(token: string, jwtSecret: string): Promise<any> {
jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => { jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
if (err || !decoded) return rej("Invalid Token"); if (err || !decoded) return rej("Invalid Token");
const user = await User.findOne({ id: decoded.id }, { select: ["data", "bot", "disabled", "deleted"] }); const user = await User.findOne(
{ id: decoded.id },
{ select: ["data", "bot", "disabled", "deleted", "rights"] }
);
if (!user) return rej("Invalid Token"); if (!user) return rej("Invalid Token");
// we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds
if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0))

View File

@ -12,6 +12,7 @@ export * from "./MessageFlags";
export * from "./Permissions"; export * from "./Permissions";
export * from "./RabbitMQ"; export * from "./RabbitMQ";
export * from "./Regex"; export * from "./Regex";
export * from "./Rights";
export * from "./Snowflake"; export * from "./Snowflake";
export * from "./String"; export * from "./String";
export * from "./Array"; export * from "./Array";