import { NextFunction, Request, Response } from "express"; import RequestError, { HttpStatusCode } from "../../helper/request_error"; import Client from "../../models/client"; import { validateJWT } from "../../keys"; import User from "../../models/user"; import Mail from "../../models/mail"; import { OAuthJWT } from "../../helper/jwt"; export function GetClientAuthMiddleware( checksecret = true, internal = false, checksecret_if_available = false ) { return async (req: Request, res: Response, next: NextFunction) => { try { let client_id = req.query.client_id || req.body.client_id; let client_secret = req.query.client_secret || req.body.client_secret; if (!client_id && !client_secret && req.headers.authorization) { let header = req.headers.authorization; let [type, val] = header.split(" "); if (val) { let str = Buffer.from(val, "base64").toString("utf-8"); let [id, secret] = str.split(":"); client_id = id; client_secret = secret; } } if (!client_id || (!client_secret && checksecret)) { throw new RequestError( "No client credentials", HttpStatusCode.BAD_REQUEST ); } let w = { client_id: client_id, client_secret: client_secret }; if (!checksecret && !(checksecret_if_available && client_secret)) delete w.client_secret; let client = await Client.findOne(w); if (!client) { throw new RequestError( "Invalid client_id" + (checksecret ? "or client_secret" : ""), HttpStatusCode.BAD_REQUEST ); } if (internal && !client.internal) { throw new RequestError( req.__("Client has no permission for access"), HttpStatusCode.FORBIDDEN ); } req.client = client; next(); } catch (e) { if (next) next(e); else throw e; } }; } export const ClientAuthMiddleware = GetClientAuthMiddleware(); export function GetClientApiAuthMiddleware(permissions?: string[]) { return async (req: Request, res: Response, next: NextFunction) => { try { const invalid_err = new RequestError( req.__("You are not logged in or your login is expired"), HttpStatusCode.UNAUTHORIZED ); let token: string = req.query.access_token || req.headers.authorization; if (!token) throw invalid_err; if (token.toLowerCase().startsWith("bearer ")) token = token.substring(7); let data: OAuthJWT; try { data = await validateJWT(token); } catch (err) { throw invalid_err; } let user = await User.findOne({ uid: data.user }); if (!user) throw invalid_err; let client = await Client.findOne({ client_id: data.application }); if (!client) throw invalid_err; if ( permissions && (!data.permissions || !permissions.every((e) => data.permissions.indexOf(e) >= 0)) ) throw invalid_err; req.user = user; req.client = client; next(); } catch (e) { if (next) next(e); else throw e; } }; }