token-permissions: update middleware

This commit is contained in:
split / May 2023-10-02 18:22:18 -07:00
parent b3efd8ca29
commit a04cc9a376
2 changed files with 62 additions and 6 deletions

View file

@ -37,7 +37,7 @@ export function create(
expire:Date.now()+expire,
type,
tokenPermissions
tokenPermissions: type == "App" ? tokenPermissions || ["user"] : undefined
}
AuthTokens.push(token)
@ -52,6 +52,14 @@ export function validate(token:string) {
return AuthTokens.find(e => e.token == token && Date.now() < e.expire)?.account
}
export function getType(token:string): TokenType | undefined {
return AuthTokens.find(e => e.token == token && Date.now() < e.expire)?.type
}
export function getPermissions(token:string): TokenPermission[] | undefined {
return AuthTokens.find(e => e.token == token && Date.now() < e.expire)?.tokenPermissions
}
export function tokenTimer(token:AuthToken) {
if (Date.now() >= token.expire) {
invalidate(token.token)

View file

@ -1,17 +1,22 @@
import * as Accounts from "./accounts";
import express, { type RequestHandler } from "express"
import ServeError from "../lib/errors";
import * as auth from "./auth";
export let getAccount: RequestHandler = function(req, res, next) {
res.locals.acc = Accounts.getFromToken(req.cookies.auth || (
function tokenFor(req: express.Request) {
return req.cookies.auth || (
req.header("authorization")?.startsWith("Bearer ")
? req.header("authorization")?.split(" ")[1]
: undefined
))
)
}
export const getAccount: RequestHandler = function(req, res, next) {
res.locals.acc = Accounts.getFromToken(tokenFor(req))
next()
}
export let requiresAccount: RequestHandler = function(_req, res, next) {
export const requiresAccount: RequestHandler = function(_req, res, next) {
if (!res.locals.acc) {
ServeError(res, 401, "not logged in")
return
@ -19,10 +24,53 @@ export let requiresAccount: RequestHandler = function(_req, res, next) {
next()
}
export let requiresAdmin: RequestHandler = function(_req, res, next) {
export const requiresAdmin: RequestHandler = function(_req, res, next) {
if (!res.locals.acc.admin) {
ServeError(res, 403, "you are not an administrator")
return
}
next()
}
export namespace apiBlockers {
/**
* @description Blocks requests based on the permissions which a token has. Does not apply to routes being accessed with a token of type `User`
* @param tokenPermissions Permissions which your route requires.
* @returns Express middleware
*/
export const requiresPermissions = function(...tokenPermissions: auth.TokenPermission[]): RequestHandler {
return function(req, res, next) {
let token = tokenFor(req)
let type = auth.getType(token)
if (type == "App") {
let permissions = auth.getPermissions(token)
if (!permissions) ServeError(res, 403, "insufficient permissions")
else {
for (let v in tokenPermissions)
if (!permissions.includes(v as auth.TokenPermission)) {
ServeError(res,403,"insufficient permissions")
return
}
next()
}
} else next()
}
}
/**
* @description Blocks requests based on whether or not the token being used to access the route is of type `User`.
*/
export const noAPIAccess: RequestHandler = function(req, res, next) {
if (auth.getType(tokenFor(req)) == "App") ServeError(res, 403, "apps are not allowed to access this endpoint")
else next()
}
}