import ApiRequest from '../models/ApiRequest'; import Config from '../config/Config'; import { StatusCodes } from 'http-status-codes'; import { CustomValidator, ErrorMessage, FieldMessageFactory, Meta } from 'express-validator/src/base'; import { BailOptions, ValidationChain } from 'express-validator/src/chain'; import GitlabManager from '../managers/GitlabManager'; declare type DojoMeta = Meta & { req: ApiRequest }; declare type DojoCustomValidator = (input: any, meta: DojoMeta) => any; class DojoValidators { private static _instance: DojoValidators; private constructor() { } public static get instance(): DojoValidators { if ( !DojoValidators._instance ) { DojoValidators._instance = new DojoValidators(); } return DojoValidators._instance; } private toValidatorSchemaOptions(arg: { errorMessage?: FieldMessageFactory | ErrorMessage, negated?: boolean, bail?: boolean | BailOptions, if?: DojoCustomValidator | ValidationChain, options?: DojoCustomValidator }) { // This is a hack to make the types work with req arg as ApiRequest instead of Request return arg as unknown as { errorMessage?: FieldMessageFactory | ErrorMessage, negated?: boolean, bail?: boolean | BailOptions, if?: CustomValidator | ValidationChain, options?: CustomValidator }; } private getParamValue(req: ApiRequest, path: string): any { return 'body' in req && path in req.body ? req.body[path] : req.query[path]; } readonly nullSanitizer = this.toValidatorSchemaOptions({ options: (value, { req, location, path }) => { try { return value == 'null' || value == 'undefined' || value == '' ? null : value; } catch ( e ) { return value; } } }); readonly arraySanitizer = this.toValidatorSchemaOptions({ options: (value, { req, location, path }) => { try { return JSON.parse(value); } catch ( e ) { return value; } } }); readonly templateUrlValidator = this.toValidatorSchemaOptions({ bail : true, errorMessage: 'Template doesn\'t exist or you don\'t have access to it', options : (value, { req, location, path }) => { return new Promise((resolve, reject) => { const template = this.getParamValue(req, path); if ( template ) { GitlabManager.checkTemplateAccess(template, req).then((templateAccess) => { templateAccess !== StatusCodes.OK ? reject() : resolve(true); }); } resolve(true); }); } }); readonly templateUrlSanitizer = this.toValidatorSchemaOptions({ options: (value, { req, location, path }) => { try { const template = this.getParamValue(req, path); if ( template ) { return `${ Config.gitlab.urls[0].replace(/^([a-z]{3,5}:\/{2})?(.*)/, `$1${ Config.gitlab.account.username }:${ Config.gitlab.account.token }@$2`) }${ template }.git`; } else { return Config.enonce.default.template; } } catch ( e ) { } return value; } }); } export default DojoValidators.instance;