server-ts: Convert etapi/etapi_utils

This commit is contained in:
Elian Doran 2024-04-07 14:54:01 +03:00
parent b8eb301f34
commit 569bdf19be
No known key found for this signature in database

View File

@ -1,15 +1,21 @@
const cls = require('../services/cls'); import cls = require('../services/cls');
const sql = require('../services/sql'); import sql = require('../services/sql');
const log = require('../services/log'); import log = require('../services/log');
const becca = require('../becca/becca'); import becca = require('../becca/becca');
const etapiTokenService = require('../services/etapi_tokens'); import etapiTokenService = require('../services/etapi_tokens');
const config = require('../services/config'); import config = require('../services/config');
import { NextFunction, Request, RequestHandler, Response, Router } from 'express';
const GENERIC_CODE = "GENERIC"; const GENERIC_CODE = "GENERIC";
type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
const noAuthentication = config.General && config.General.noAuthentication === true; const noAuthentication = config.General && config.General.noAuthentication === true;
class EtapiError extends Error { class EtapiError extends Error {
constructor(statusCode, code, message) { statusCode: number;
code: string;
constructor(statusCode: number, code: string, message: string) {
super(); super();
this.statusCode = statusCode; this.statusCode = statusCode;
@ -18,7 +24,7 @@ class EtapiError extends Error {
} }
} }
function sendError(res, statusCode, code, message) { function sendError(res: Response, statusCode: number, code: string, message: string) {
return res return res
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.status(statusCode) .status(statusCode)
@ -29,7 +35,7 @@ function sendError(res, statusCode, code, message) {
})); }));
} }
function checkEtapiAuth(req, res, next) { function checkEtapiAuth(req: Request, res: Response, next: NextFunction) {
if (noAuthentication || etapiTokenService.isValidAuthHeader(req.headers.authorization)) { if (noAuthentication || etapiTokenService.isValidAuthHeader(req.headers.authorization)) {
next(); next();
} }
@ -38,7 +44,7 @@ function checkEtapiAuth(req, res, next) {
} }
} }
function processRequest(req, res, routeHandler, next, method, path) { function processRequest(req: Request, res: Response, routeHandler: RequestHandler, next: NextFunction, method: string, path: string) {
try { try {
cls.namespace.bindEmitter(req); cls.namespace.bindEmitter(req);
cls.namespace.bindEmitter(res); cls.namespace.bindEmitter(res);
@ -51,7 +57,7 @@ function processRequest(req, res, routeHandler, next, method, path) {
return sql.transactional(cb); return sql.transactional(cb);
}); });
} catch (e) { } catch (e: any) {
log.error(`${method} ${path} threw exception ${e.message} with stacktrace: ${e.stack}`); log.error(`${method} ${path} threw exception ${e.message} with stacktrace: ${e.stack}`);
if (e instanceof EtapiError) { if (e instanceof EtapiError) {
@ -62,15 +68,15 @@ function processRequest(req, res, routeHandler, next, method, path) {
} }
} }
function route(router, method, path, routeHandler) { function route(router: Router, method: HttpMethod, path: string, routeHandler: RequestHandler) {
router[method](path, checkEtapiAuth, (req, res, next) => processRequest(req, res, routeHandler, next, method, path)); router[method](path, checkEtapiAuth, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
} }
function NOT_AUTHENTICATED_ROUTE(router, method, path, middleware, routeHandler) { function NOT_AUTHENTICATED_ROUTE(router: Router, method: HttpMethod, path: string, middleware: RequestHandler[], routeHandler: RequestHandler) {
router[method](path, ...middleware, (req, res, next) => processRequest(req, res, routeHandler, next, method, path)); router[method](path, ...middleware, (req: Request, res: Response, next: NextFunction) => processRequest(req, res, routeHandler, next, method, path));
} }
function getAndCheckNote(noteId) { function getAndCheckNote(noteId: string) {
const note = becca.getNote(noteId); const note = becca.getNote(noteId);
if (note) { if (note) {
@ -81,7 +87,7 @@ function getAndCheckNote(noteId) {
} }
} }
function getAndCheckAttachment(attachmentId) { function getAndCheckAttachment(attachmentId: string) {
const attachment = becca.getAttachment(attachmentId, {includeContentLength: true}); const attachment = becca.getAttachment(attachmentId, {includeContentLength: true});
if (attachment) { if (attachment) {
@ -92,7 +98,7 @@ function getAndCheckAttachment(attachmentId) {
} }
} }
function getAndCheckBranch(branchId) { function getAndCheckBranch(branchId: string) {
const branch = becca.getBranch(branchId); const branch = becca.getBranch(branchId);
if (branch) { if (branch) {
@ -103,7 +109,7 @@ function getAndCheckBranch(branchId) {
} }
} }
function getAndCheckAttribute(attributeId) { function getAndCheckAttribute(attributeId: string) {
const attribute = becca.getAttribute(attributeId); const attribute = becca.getAttribute(attributeId);
if (attribute) { if (attribute) {
@ -114,7 +120,7 @@ function getAndCheckAttribute(attributeId) {
} }
} }
function validateAndPatch(target, source, allowedProperties) { function validateAndPatch(target: Record<string, string>, source: Record<string, string>, allowedProperties: Record<string, ((value: string) => boolean)[]>) {
for (const key of Object.keys(source)) { for (const key of Object.keys(source)) {
if (!(key in allowedProperties)) { if (!(key in allowedProperties)) {
throw new EtapiError(400, "PROPERTY_NOT_ALLOWED", `Property '${key}' is not allowed for this method.`); throw new EtapiError(400, "PROPERTY_NOT_ALLOWED", `Property '${key}' is not allowed for this method.`);
@ -136,7 +142,7 @@ function validateAndPatch(target, source, allowedProperties) {
} }
} }
module.exports = { export = {
EtapiError, EtapiError,
sendError, sendError,
route, route,