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 = req.query.access_token || req.headers.authorization; if (!token) throw invalid_err; 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; } } }