import * as argon2 from "argon2"; import { Request, Response } from 'express'; import { getConnectionManager } from 'typeorm'; import { ScanStation } from '../models/entities/ScanStation'; import authchecker from './authchecker'; /** * This middleware handles the authentication of scan station api tokens. * The tokens have to be provided via Bearer authorization header. * You have to manually use this middleware via @UseBefore(ScanAuth) instead of using @Authorized(). * @param req Express request object. * @param res Express response object. * @param next Next function to call on success. */ const ScanAuth = async (req: Request, res: Response, next: () => void) => { let provided_token: string = req.headers["authorization"]; if (provided_token == "" || provided_token === undefined || provided_token === null) { res.status(401).send("No api token provided."); return; } try { provided_token = provided_token.replace("Bearer ", ""); } catch (error) { res.status(401).send("No valid jwt or api token provided."); return; } let prefix = ""; try { prefix = provided_token.split(".")[0]; } finally { if (prefix == "" || prefix == undefined || prefix == null) { res.status(401).send("Api token non-existent or invalid syntax."); return; } } const station = await getConnectionManager().get().getRepository(ScanStation).findOne({ prefix: prefix }); if (!station) { let user_authorized = false; try { let action = { request: req, response: res, context: null, next: next } user_authorized = await authchecker(action, ["SCAN:CREATE"]); } finally { if (user_authorized == false) { res.status(401).send("Api token non-existent or invalid syntax."); return; } else { next(); } } } else { if (station.enabled == false) { res.status(401).send("Station disabled."); } if (!(await argon2.verify(station.key, provided_token))) { res.status(401).send("Api token invalid."); return; } next(); } } export default ScanAuth;