backend/src/middlewares/ScanAuth.ts

69 lines
2.3 KiB
TypeScript

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;