You've already forked nginx-proxy-manager
							
							
				mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-30 18:05:34 +03:00 
			
		
		
		
	Fix cypress tests following user wizard changes
This commit is contained in:
		| @@ -9,7 +9,7 @@ import internalAuditLog from "./audit-log.js"; | ||||
| import internalToken from "./token.js"; | ||||
|  | ||||
| const omissions = () => { | ||||
| 	return ["is_deleted"]; | ||||
| 	return ["is_deleted", "permissions.id", "permissions.user_id", "permissions.created_on", "permissions.modified_on"]; | ||||
| }; | ||||
|  | ||||
| const DEFAULT_AVATAR = gravatar.url("admin@example.com", { default: "mm" }); | ||||
| @@ -250,6 +250,14 @@ const internalUser = { | ||||
| 			}); | ||||
| 	}, | ||||
|  | ||||
| 	deleteAll: async () => { | ||||
| 		await userModel | ||||
| 			.query() | ||||
| 			.patch({ | ||||
| 				is_deleted: 1, | ||||
| 			}); | ||||
| 	}, | ||||
|  | ||||
| 	/** | ||||
| 	 * This will only count the users | ||||
| 	 * | ||||
|   | ||||
| @@ -199,6 +199,13 @@ const isPostgres = () => { | ||||
|  */ | ||||
| const isDebugMode = () => !!process.env.DEBUG; | ||||
|  | ||||
| /** | ||||
|  * Are we running in CI? | ||||
|  * | ||||
|  * @returns {boolean} | ||||
|  */ | ||||
| const isCI = () => process.env.CI === 'true' && process.env.DEBUG === 'true'; | ||||
|  | ||||
| /** | ||||
|  * Returns a public key | ||||
|  * | ||||
| @@ -234,4 +241,4 @@ const useLetsencryptServer = () => { | ||||
| 	return null; | ||||
| }; | ||||
|  | ||||
| export { configHas, configGet, isSqlite, isMysql, isPostgres, isDebugMode, getPrivateKey, getPublicKey, useLetsencryptStaging, useLetsencryptServer }; | ||||
| export { isCI, configHas, configGet, isSqlite, isMysql, isPostgres, isDebugMode, getPrivateKey, getPublicKey, useLetsencryptStaging, useLetsencryptServer }; | ||||
|   | ||||
| @@ -14,7 +14,10 @@ const errs = { | ||||
| 		Error.captureStackTrace(this, this.constructor); | ||||
| 		this.name = this.constructor.name; | ||||
| 		this.previous = previous; | ||||
| 		this.message = `Item Not Found - ${id}`; | ||||
| 		this.message = "Not Found"; | ||||
| 		if (id) { | ||||
| 			this.message = `Not Found - ${id}`; | ||||
| 		} | ||||
| 		this.public = true; | ||||
| 		this.status = 404; | ||||
| 	}, | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import express from "express"; | ||||
| import internalAuditLog from "../internal/audit-log.js"; | ||||
| import jwtdecode from "../lib/express/jwt-decode.js"; | ||||
| import validator from "../lib/validator/index.js"; | ||||
| import { express as logger } from "../logger.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| @@ -24,31 +25,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all logs | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalAuditLog.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalAuditLog.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalAccessList from "../../internal/access-list.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,31 +27,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all access-lists | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalAccessList.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalAccessList.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -58,15 +59,15 @@ router | ||||
| 	 * | ||||
| 	 * Create a new access-list | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/access-lists", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalAccessList.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/access-lists", "post"), req.body); | ||||
| 			const result = await internalAccessList.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -86,35 +87,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific access-list | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["list_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					list_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["list_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						list_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				list_id: req.params.list_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalAccessList.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.list_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					list_id: req.params.list_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalAccessList.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.list_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,16 +123,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing access-list | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/access-lists/{listID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = Number.parseInt(req.params.list_id, 10); | ||||
| 				return internalAccessList.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/access-lists/{listID}", "put"), req.body); | ||||
| 			payload.id = Number.parseInt(req.params.list_id, 10); | ||||
| 			const result = await internalAccessList.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -139,13 +140,16 @@ router | ||||
| 	 * | ||||
| 	 * Delete and existing access-list | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalAccessList | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.list_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalAccessList.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.list_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import errs from "../../lib/error.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -27,31 +28,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all certificates | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalCertificate.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalCertificate.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -59,16 +60,16 @@ router | ||||
| 	 * | ||||
| 	 * Create a new certificate | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/certificates", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				req.setTimeout(900000); // 15 minutes timeout | ||||
| 				return internalCertificate.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/certificates", "post"), req.body); | ||||
| 			req.setTimeout(900000); // 15 minutes timeout | ||||
| 			const result = await internalCertificate.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -88,18 +89,22 @@ router | ||||
| 	 * | ||||
| 	 * Test HTTP challenge for domains | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 	.get(async (req, res, next) => { | ||||
| 		if (req.query.domains === undefined) { | ||||
| 			next(new errs.ValidationError("Domains are required as query parameters")); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		internalCertificate | ||||
| 			.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains)) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 		try { | ||||
| 			const result = await internalCertificate.testHttpsChallenge( | ||||
| 				res.locals.access, | ||||
| 				JSON.parse(req.query.domains), | ||||
| 			); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -119,35 +124,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific certificate | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["certificate_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					certificate_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["certificate_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						certificate_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				certificate_id: req.params.certificate_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalCertificate.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.certificate_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					certificate_id: req.params.certificate_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalCertificate.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.certificate_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -155,13 +160,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing certificate | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalCertificate | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.certificate_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalCertificate.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.certificate_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -181,19 +189,21 @@ router | ||||
| 	 * | ||||
| 	 * Upload certificates | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 	.post(async (req, res, next) => { | ||||
| 		if (!req.files) { | ||||
| 			res.status(400).send({ error: "No files were uploaded" }); | ||||
| 		} else { | ||||
| 			internalCertificate | ||||
| 				.upload(res.locals.access, { | ||||
| 					id: Number.parseInt(req.params.certificate_id, 10), | ||||
| 					files: req.files, | ||||
| 				}) | ||||
| 				.then((result) => { | ||||
| 					res.status(200).send(result); | ||||
| 				}) | ||||
| 				.catch(next); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		try { | ||||
| 			const result = await internalCertificate.upload(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.certificate_id, 10), | ||||
| 				files: req.files, | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| @@ -214,16 +224,17 @@ router | ||||
| 	 * | ||||
| 	 * Renew certificate | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 	.post(async (req, res, next) => { | ||||
| 		req.setTimeout(900000); // 15 minutes timeout | ||||
| 		internalCertificate | ||||
| 			.renew(res.locals.access, { | ||||
| 		try { | ||||
| 			const result = await internalCertificate.renew(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.certificate_id, 10), | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -243,15 +254,16 @@ router | ||||
| 	 * | ||||
| 	 * Renew certificate | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		internalCertificate | ||||
| 			.download(res.locals.access, { | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalCertificate.download(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.certificate_id, 10), | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).download(result.fileName); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 			}); | ||||
| 			res.status(200).download(result.fileName); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -271,18 +283,20 @@ router | ||||
| 	 * | ||||
| 	 * Validate certificates | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 	.post(async (req, res, next) => { | ||||
| 		if (!req.files) { | ||||
| 			res.status(400).send({ error: "No files were uploaded" }); | ||||
| 		} else { | ||||
| 			internalCertificate | ||||
| 				.validate({ | ||||
| 					files: req.files, | ||||
| 				}) | ||||
| 				.then((result) => { | ||||
| 					res.status(200).send(result); | ||||
| 				}) | ||||
| 				.catch(next); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		try { | ||||
| 			const result = await internalCertificate.validate({ | ||||
| 				files: req.files, | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalDeadHost from "../../internal/dead-host.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,31 +27,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all dead-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalDeadHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalDeadHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -58,15 +59,15 @@ router | ||||
| 	 * | ||||
| 	 * Create a new dead-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/dead-hosts", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalDeadHost.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/dead-hosts", "post"), req.body); | ||||
| 			const result = await internalDeadHost.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -86,35 +87,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific dead-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["host_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					host_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["host_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						host_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				host_id: req.params.host_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalDeadHost.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.host_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					host_id: req.params.host_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalDeadHost.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.host_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,16 +123,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing dead-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/dead-hosts/{hostID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 				return internalDeadHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/dead-hosts/{hostID}", "put"), req.body); | ||||
| 			payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 			const result = await internalDeadHost.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -139,13 +140,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing dead-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalDeadHost | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalDeadHost.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -163,13 +167,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/dead-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalDeadHost | ||||
| 			.enable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalDeadHost.enable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -188,12 +195,13 @@ router | ||||
| 	 * POST /api/nginx/dead-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalDeadHost | ||||
| 			.disable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 		try { | ||||
| 			const result = internalDeadHost.disable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalProxyHost from "../../internal/proxy-host.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,31 +27,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all proxy-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalProxyHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalProxyHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -58,15 +59,15 @@ router | ||||
| 	 * | ||||
| 	 * Create a new proxy-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/proxy-hosts", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalProxyHost.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/proxy-hosts", "post"), req.body); | ||||
| 			const result = await internalProxyHost.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -86,35 +87,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific proxy-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["host_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					host_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["host_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						host_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				host_id: req.params.host_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalProxyHost.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.host_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					host_id: req.params.host_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalProxyHost.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.host_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,16 +123,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing proxy-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/proxy-hosts/{hostID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 				return internalProxyHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/proxy-hosts/{hostID}", "put"), req.body); | ||||
| 			payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 			const result = await internalProxyHost.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -139,13 +140,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing proxy-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalProxyHost | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalProxyHost.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -163,13 +167,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/proxy-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalProxyHost | ||||
| 			.enable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalProxyHost.enable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -187,13 +194,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/proxy-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalProxyHost | ||||
| 			.disable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalProxyHost.disable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalRedirectionHost from "../../internal/redirection-host.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,31 +27,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all redirection-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalRedirectionHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalRedirectionHost.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -58,15 +59,15 @@ router | ||||
| 	 * | ||||
| 	 * Create a new redirection-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/redirection-hosts", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalRedirectionHost.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/redirection-hosts", "post"), req.body); | ||||
| 			const result = await internalRedirectionHost.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -86,35 +87,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific redirection-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["host_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					host_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["host_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						host_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				host_id: req.params.host_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalRedirectionHost.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.host_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					host_id: req.params.host_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalRedirectionHost.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.host_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,16 +123,19 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing redirection-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/redirection-hosts/{hostID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 				return internalRedirectionHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator( | ||||
| 				getValidationSchema("/nginx/redirection-hosts/{hostID}", "put"), | ||||
| 				req.body, | ||||
| 			); | ||||
| 			payload.id = Number.parseInt(req.params.host_id, 10); | ||||
| 			const result = await internalRedirectionHost.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -139,13 +143,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing redirection-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalRedirectionHost | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalRedirectionHost.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -163,13 +170,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/redirection-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalRedirectionHost | ||||
| 			.enable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalRedirectionHost.enable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -187,13 +197,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/redirection-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalRedirectionHost | ||||
| 			.disable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalRedirectionHost.disable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalStream from "../../internal/stream.js"; | ||||
| import jwtdecode from "../../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../../lib/validator/api.js"; | ||||
| import validator from "../../lib/validator/index.js"; | ||||
| import { express as logger } from "../../logger.js"; | ||||
| import { getValidationSchema } from "../../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,31 +27,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all streams | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 					}, | ||||
| 					query: { | ||||
| 						$ref: "common#/properties/query", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 						query: { | ||||
| 							$ref: "common#/properties/query", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalStream.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const rows = await internalStream.getAll(res.locals.access, data.expand, data.query); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -58,15 +59,15 @@ router | ||||
| 	 * | ||||
| 	 * Create a new stream | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/streams", "post"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalStream.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/streams", "post"), req.body); | ||||
| 			const result = await internalStream.create(res.locals.access, payload); | ||||
| 			res.status(201).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -86,35 +87,35 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific stream | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["stream_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					stream_id: { | ||||
| 						$ref: "common#/properties/id", | ||||
| 					}, | ||||
| 					expand: { | ||||
| 						$ref: "common#/properties/expand", | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["stream_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						stream_id: { | ||||
| 							$ref: "common#/properties/id", | ||||
| 						}, | ||||
| 						expand: { | ||||
| 							$ref: "common#/properties/expand", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				stream_id: req.params.stream_id, | ||||
| 				expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalStream.get(res.locals.access, { | ||||
| 					id: Number.parseInt(data.stream_id, 10), | ||||
| 					expand: data.expand, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					stream_id: req.params.stream_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalStream.get(res.locals.access, { | ||||
| 				id: Number.parseInt(data.stream_id, 10), | ||||
| 				expand: data.expand, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,16 +123,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing stream | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/nginx/streams/{streamID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = Number.parseInt(req.params.stream_id, 10); | ||||
| 				return internalStream.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/nginx/streams/{streamID}", "put"), req.body); | ||||
| 			payload.id = Number.parseInt(req.params.stream_id, 10); | ||||
| 			const result = await internalStream.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -139,13 +140,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing stream | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalStream | ||||
| 			.delete(res.locals.access, { id: Number.parseInt(req.params.stream_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalStream.delete(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.stream_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -163,13 +167,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/streams/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalStream | ||||
| 			.enable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalStream.enable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -187,13 +194,16 @@ router | ||||
| 	/** | ||||
| 	 * POST /api/nginx/streams/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalStream | ||||
| 			.disable(res.locals.access, { id: Number.parseInt(req.params.host_id, 10) }) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.post(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalStream.disable(res.locals.access, { | ||||
| 				id: Number.parseInt(req.params.host_id, 10), | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import express from "express"; | ||||
| import internalReport from "../internal/report.js"; | ||||
| import jwtdecode from "../lib/express/jwt-decode.js"; | ||||
| import { express as logger } from "../logger.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| @@ -17,13 +18,14 @@ router | ||||
| 	/** | ||||
| 	 * GET /reports/hosts | ||||
| 	 */ | ||||
| 	.get(jwtdecode(), (_, res, next) => { | ||||
| 		internalReport | ||||
| 			.getHostsReport(res.locals.access) | ||||
| 			.then((data) => { | ||||
| 				res.status(200).send(data); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.get(jwtdecode(), async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await internalReport.getHostsReport(res.locals.access); | ||||
| 			res.status(200).send(data); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import express from "express"; | ||||
| import { express as logger } from "../logger.js"; | ||||
| import PACKAGE from "../package.json" with { type: "json" }; | ||||
| import { getCompiledSchema } from "../schema/index.js"; | ||||
|  | ||||
| @@ -18,21 +19,26 @@ router | ||||
| 	 * GET /schema | ||||
| 	 */ | ||||
| 	.get(async (req, res) => { | ||||
| 		const swaggerJSON = await getCompiledSchema(); | ||||
| 		try { | ||||
| 			const swaggerJSON = await getCompiledSchema(); | ||||
|  | ||||
| 		let proto = req.protocol; | ||||
| 		if (typeof req.headers["x-forwarded-proto"] !== "undefined" && req.headers["x-forwarded-proto"]) { | ||||
| 			proto = req.headers["x-forwarded-proto"]; | ||||
| 			let proto = req.protocol; | ||||
| 			if (typeof req.headers["x-forwarded-proto"] !== "undefined" && req.headers["x-forwarded-proto"]) { | ||||
| 				proto = req.headers["x-forwarded-proto"]; | ||||
| 			} | ||||
|  | ||||
| 			let origin = `${proto}://${req.hostname}`; | ||||
| 			if (typeof req.headers.origin !== "undefined" && req.headers.origin) { | ||||
| 				origin = req.headers.origin; | ||||
| 			} | ||||
|  | ||||
| 			swaggerJSON.info.version = PACKAGE.version; | ||||
| 			swaggerJSON.servers[0].url = `${origin}/api`; | ||||
| 			res.status(200).send(swaggerJSON); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
|  | ||||
| 		let origin = `${proto}://${req.hostname}`; | ||||
| 		if (typeof req.headers.origin !== "undefined" && req.headers.origin) { | ||||
| 			origin = req.headers.origin; | ||||
| 		} | ||||
|  | ||||
| 		swaggerJSON.info.version = PACKAGE.version; | ||||
| 		swaggerJSON.servers[0].url = `${origin}/api`; | ||||
| 		res.status(200).send(swaggerJSON); | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import internalSetting from "../internal/setting.js"; | ||||
| import jwtdecode from "../lib/express/jwt-decode.js"; | ||||
| import apiValidator from "../lib/validator/api.js"; | ||||
| import validator from "../lib/validator/index.js"; | ||||
| import { express as logger } from "../logger.js"; | ||||
| import { getValidationSchema } from "../schema/index.js"; | ||||
|  | ||||
| const router = express.Router({ | ||||
| @@ -26,13 +27,14 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve all settings | ||||
| 	 */ | ||||
| 	.get((_, res, next) => { | ||||
| 		internalSetting | ||||
| 			.getAll(res.locals.access) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200).send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const rows = await internalSetting.getAll(res.locals.access); | ||||
| 			res.status(200).send(rows); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -52,31 +54,31 @@ router | ||||
| 	 * | ||||
| 	 * Retrieve a specific setting | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator( | ||||
| 			{ | ||||
| 				required: ["setting_id"], | ||||
| 				additionalProperties: false, | ||||
| 				properties: { | ||||
| 					setting_id: { | ||||
| 						type: "string", | ||||
| 						minLength: 1, | ||||
| 	.get(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const data = await validator( | ||||
| 				{ | ||||
| 					required: ["setting_id"], | ||||
| 					additionalProperties: false, | ||||
| 					properties: { | ||||
| 						setting_id: { | ||||
| 							type: "string", | ||||
| 							minLength: 1, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| 				setting_id: req.params.setting_id, | ||||
| 			}, | ||||
| 		) | ||||
| 			.then((data) => { | ||||
| 				return internalSetting.get(res.locals.access, { | ||||
| 					id: data.setting_id, | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200).send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 				{ | ||||
| 					setting_id: req.params.setting_id, | ||||
| 				}, | ||||
| 			); | ||||
| 			const row = await internalSetting.get(res.locals.access, { | ||||
| 				id: data.setting_id, | ||||
| 			}); | ||||
| 			res.status(200).send(row); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -84,16 +86,16 @@ router | ||||
| 	 * | ||||
| 	 * Update and existing setting | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(getValidationSchema("/settings/{settingID}", "put"), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = req.params.setting_id; | ||||
| 				return internalSetting.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200).send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/settings/{settingID}", "put"), req.body); | ||||
| 			payload.id = req.params.setting_id; | ||||
| 			const result = await internalSetting.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import express from "express"; | ||||
| import internalUser from "../internal/user.js"; | ||||
| import Access from "../lib/access.js"; | ||||
| import { isCI } from "../lib/config.js"; | ||||
| import errs from "../lib/error.js"; | ||||
| import jwtdecode from "../lib/express/jwt-decode.js"; | ||||
| import userIdFromMe from "../lib/express/user-id-from-me.js"; | ||||
| import apiValidator from "../lib/validator/api.js"; | ||||
| @@ -45,11 +47,18 @@ router | ||||
| 					}, | ||||
| 				}, | ||||
| 				{ | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					expand: | ||||
| 						typeof req.query.expand === "string" | ||||
| 							? req.query.expand.split(",") | ||||
| 							: null, | ||||
| 					query: typeof req.query.query === "string" ? req.query.query : null, | ||||
| 				}, | ||||
| 			); | ||||
| 			const users = await internalUser.getAll(res.locals.access, data.expand, data.query); | ||||
| 			const users = await internalUser.getAll( | ||||
| 				res.locals.access, | ||||
| 				data.expand, | ||||
| 				data.query, | ||||
| 			); | ||||
| 			res.status(200).send(users); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| @@ -85,13 +94,43 @@ router | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			const payload = await apiValidator(getValidationSchema("/users", "post"), body); | ||||
| 			const payload = await apiValidator( | ||||
| 				getValidationSchema("/users", "post"), | ||||
| 				body, | ||||
| 			); | ||||
| 			const user = await internalUser.create(res.locals.access, payload); | ||||
| 			res.status(201).send(user); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 			next(err); | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/users | ||||
| 	 * | ||||
| 	 * Deletes ALL users. This is NOT GENERALLY AVAILABLE! | ||||
| 	 * (!) It is NOT an authenticated endpoint. | ||||
| 	 * (!) Only CI should be able to call this endpoint. As a result, | ||||
| 	 * | ||||
| 	 * it will only work when the env vars DEBUG=true and CI=true | ||||
| 	 * | ||||
| 	 * Do NOT set those env vars in a production environment! | ||||
| 	 */ | ||||
| 	.delete(async (_, res, next) => { | ||||
| 		if (isCI()) { | ||||
| 			try { | ||||
| 				logger.warn("Deleting all users - CI environment detected, allowing this operation"); | ||||
| 				await internalUser.deleteAll(); | ||||
| 				res.status(200).send(true); | ||||
| 			} catch (err) { | ||||
| 				logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| 				next(err); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		next(new errs.ItemNotFoundError()); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
| @@ -129,14 +168,20 @@ router | ||||
| 				}, | ||||
| 				{ | ||||
| 					user_id: req.params.user_id, | ||||
| 					expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, | ||||
| 					expand: | ||||
| 						typeof req.query.expand === "string" | ||||
| 							? req.query.expand.split(",") | ||||
| 							: null, | ||||
| 				}, | ||||
| 			); | ||||
|  | ||||
| 			const user = await internalUser.get(res.locals.access, { | ||||
| 				id: data.user_id, | ||||
| 				expand: data.expand, | ||||
| 				omit: internalUser.getUserOmisionsByAccess(res.locals.access, data.user_id), | ||||
| 				omit: internalUser.getUserOmisionsByAccess( | ||||
| 					res.locals.access, | ||||
| 					data.user_id, | ||||
| 				), | ||||
| 			}); | ||||
| 			res.status(200).send(user); | ||||
| 		} catch (err) { | ||||
| @@ -152,7 +197,10 @@ router | ||||
| 	 */ | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/users/{userID}", "put"), req.body); | ||||
| 			const payload = await apiValidator( | ||||
| 				getValidationSchema("/users/{userID}", "put"), | ||||
| 				req.body, | ||||
| 			); | ||||
| 			payload.id = req.params.user_id; | ||||
| 			const result = await internalUser.update(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| @@ -169,7 +217,9 @@ router | ||||
| 	 */ | ||||
| 	.delete(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const result = await internalUser.delete(res.locals.access, { id: req.params.user_id }); | ||||
| 			const result = await internalUser.delete(res.locals.access, { | ||||
| 				id: req.params.user_id, | ||||
| 			}); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
| @@ -197,7 +247,10 @@ router | ||||
| 	 */ | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/users/{userID}/auth", "put"), req.body); | ||||
| 			const payload = await apiValidator( | ||||
| 				getValidationSchema("/users/{userID}/auth", "put"), | ||||
| 				req.body, | ||||
| 			); | ||||
| 			payload.id = req.params.user_id; | ||||
| 			const result = await internalUser.setPassword(res.locals.access, payload); | ||||
| 			res.status(200).send(result); | ||||
| @@ -227,9 +280,15 @@ router | ||||
| 	 */ | ||||
| 	.put(async (req, res, next) => { | ||||
| 		try { | ||||
| 			const payload = await apiValidator(getValidationSchema("/users/{userID}/permissions", "put"), req.body); | ||||
| 			const payload = await apiValidator( | ||||
| 				getValidationSchema("/users/{userID}/permissions", "put"), | ||||
| 				req.body, | ||||
| 			); | ||||
| 			payload.id = req.params.user_id; | ||||
| 			const result = await internalUser.setPermissions(res.locals.access, payload); | ||||
| 			const result = await internalUser.setPermissions( | ||||
| 				res.locals.access, | ||||
| 				payload, | ||||
| 			); | ||||
| 			res.status(200).send(result); | ||||
| 		} catch (err) { | ||||
| 			logger.debug(`${req.method.toUpperCase()} ${req.path}: ${err}`); | ||||
|   | ||||
| @@ -9,6 +9,11 @@ | ||||
| 			"description": "Healthy", | ||||
| 			"example": "OK" | ||||
| 		}, | ||||
| 		"setup": { | ||||
| 			"type": "boolean", | ||||
| 			"description": "Whether the initial setup has been completed", | ||||
| 			"example": true | ||||
| 		}, | ||||
| 		"version": { | ||||
| 			"type": "object", | ||||
| 			"description": "The version object", | ||||
|   | ||||
| @@ -54,6 +54,63 @@ | ||||
| 			"items": { | ||||
| 				"type": "string" | ||||
| 			} | ||||
| 		}, | ||||
| 		"permissions": { | ||||
| 			"type": "object", | ||||
| 			"description": "Permissions if expanded in request", | ||||
| 			"required": [ | ||||
| 				"visibility", | ||||
| 				"proxy_hosts", | ||||
| 				"redirection_hosts", | ||||
| 				"dead_hosts", | ||||
| 				"streams", | ||||
| 				"access_lists", | ||||
| 				"certificates" | ||||
| 			], | ||||
| 			"properties": { | ||||
| 				"visibility": { | ||||
| 					"type": "string", | ||||
| 					"description": "Visibility level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(all|user)$" | ||||
| 				}, | ||||
| 				"proxy_hosts": { | ||||
| 					"type": "string", | ||||
| 					"description": "Proxy Hosts access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				}, | ||||
| 				"redirection_hosts": { | ||||
| 					"type": "string", | ||||
| 					"description": "Redirection Hosts access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				}, | ||||
| 				"dead_hosts": { | ||||
| 					"type": "string", | ||||
| 					"description": "Dead Hosts access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				}, | ||||
| 				"streams": { | ||||
| 					"type": "string", | ||||
| 					"description": "Streams access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				}, | ||||
| 				"access_lists": { | ||||
| 					"type": "string", | ||||
| 					"description": "Access Lists access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				}, | ||||
| 				"certificates": { | ||||
| 					"type": "string", | ||||
| 					"description": "Certificates access level", | ||||
| 					"example": "all", | ||||
| 					"pattern": "^(manage|view|hidden)$" | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| 						"default": { | ||||
| 							"value": { | ||||
| 								"status": "OK", | ||||
| 								"setup": true, | ||||
| 								"version": { | ||||
| 									"major": 2, | ||||
| 									"minor": 1, | ||||
|   | ||||
| @@ -9,6 +9,7 @@ services: | ||||
|     environment: | ||||
|       TZ: "${TZ:-Australia/Brisbane}" | ||||
|       DEBUG: 'true' | ||||
|       CI: 'true' | ||||
|       FORCE_COLOR: 1 | ||||
|       # Required for DNS Certificate provisioning in CI | ||||
|       LE_SERVER: 'https://ca.internal/acme/acme/directory' | ||||
|   | ||||
| @@ -5,6 +5,7 @@ describe('Certificates endpoints', () => { | ||||
| 	let certID; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Dashboard endpoints', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Full Certificate Provisions', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ describe('LDAP with Authentik', () => { | ||||
| 	if (Cypress.env('skipStackCheck') === 'true' || Cypress.env('stack') === 'postgres') { | ||||
|  | ||||
| 		before(() => { | ||||
| 			cy.resetUsers(); | ||||
| 			cy.getToken().then((tok) => { | ||||
| 				_token = tok; | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Proxy Hosts endpoints', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Settings endpoints', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Streams', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 			// Set default site content | ||||
|   | ||||
| @@ -4,6 +4,7 @@ describe('Users endpoints', () => { | ||||
| 	let token; | ||||
|  | ||||
| 	before(() => { | ||||
| 		cy.resetUsers(); | ||||
| 		cy.getToken().then((tok) => { | ||||
| 			token = tok; | ||||
| 		}); | ||||
|   | ||||
| @@ -12,10 +12,10 @@ | ||||
| import 'cypress-wait-until'; | ||||
|  | ||||
| Cypress.Commands.add('randomString', (length) => { | ||||
| 	var result           = ''; | ||||
| 	var characters       = 'ABCDEFGHIJK LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | ||||
| 	var charactersLength = characters.length; | ||||
| 	for (var i = 0; i < length; i++) { | ||||
| 	let result = ''; | ||||
| 	const characters = 'ABCDEFGHIJK LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | ||||
| 	const charactersLength = characters.length; | ||||
| 	for (let i = 0; i < length; i++) { | ||||
| 		result += characters.charAt(Math.floor(Math.random() * charactersLength)); | ||||
| 	} | ||||
| 	return result; | ||||
| @@ -40,16 +40,81 @@ Cypress.Commands.add('validateSwaggerSchema', (method, code, path, data) => { | ||||
| 	}).should('equal', null); | ||||
| }); | ||||
|  | ||||
| Cypress.Commands.add('getToken', () => { | ||||
| 	// login with existing user | ||||
| 	cy.task('backendApiPost', { | ||||
| 		path: '/api/tokens', | ||||
| 		data: { | ||||
| 			identity: 'admin@example.com', | ||||
| 			secret:   'changeme' | ||||
| Cypress.Commands.add('createInitialUser', (defaultUser) => { | ||||
| 	let user = { | ||||
| 		name:        'Cypress McGee', | ||||
| 		nickname:    'Cypress', | ||||
| 		email:       'cypress@example.com', | ||||
| 		auth:        { | ||||
| 			type:   'password', | ||||
| 			secret: 'changeme' | ||||
| 		}, | ||||
| 	}; | ||||
|  | ||||
| 	if (typeof defaultUser === 'object' && defaultUser) { | ||||
| 		user = Object.assign({}, user, defaultUser); | ||||
| 	} | ||||
|  | ||||
| 	return cy.task('backendApiPost', { | ||||
| 		path: '/api/users', | ||||
| 		data: user, | ||||
| 	}).then((data) => { | ||||
| 		// Check the swagger schema: | ||||
| 		cy.validateSwaggerSchema('post', 201, '/users', data); | ||||
| 		expect(data).to.have.property('id'); | ||||
| 		expect(data.id).to.be.greaterThan(0); | ||||
| 		cy.wrap(data); | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
| Cypress.Commands.add('getToken', (defaultUser, defaultAuth) => { | ||||
| 	if (typeof defaultAuth === 'object' && defaultAuth) { | ||||
| 		if (!defaultUser) { | ||||
| 			defaultUser = {}; | ||||
| 		} | ||||
| 	}).then(res => { | ||||
| 		cy.wrap(res.token); | ||||
| 		defaultUser.auth = defaultAuth; | ||||
| 	} | ||||
|  | ||||
| 	cy.task('backendApiGet', { | ||||
| 		path: '/api/', | ||||
| 	}).then((data) => { | ||||
| 		// Check the swagger schema: | ||||
| 		cy.validateSwaggerSchema('get', 200, '/', data); | ||||
|  | ||||
| 		if (!data.setup) { | ||||
| 			cy.log('Setup = false'); | ||||
| 			// create a new user | ||||
| 			cy.createInitialUser(defaultUser).then(() => { | ||||
| 				return cy.getToken(defaultUser); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			let auth = { | ||||
| 				identity: 'cypress@example.com', | ||||
| 				secret:   'changeme', | ||||
| 			}; | ||||
|  | ||||
| 			if (typeof defaultUser === 'object' && defaultUser && typeof defaultUser.auth === 'object' && defaultUser.auth) { | ||||
| 				auth = Object.assign({}, auth, defaultUser.auth); | ||||
| 			} | ||||
|  | ||||
| 			cy.log('Setup = true'); | ||||
| 			// login with existing user | ||||
| 			cy.task('backendApiPost', { | ||||
| 				path: '/api/tokens', | ||||
| 				data: auth, | ||||
| 			}).then((res) => { | ||||
| 				cy.wrap(res.token); | ||||
| 			}); | ||||
| 		} | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
| Cypress.Commands.add('resetUsers', () => { | ||||
| 	cy.task('backendApiDelete', { | ||||
| 		path: '/api/users' | ||||
| 	}).then((data) => { | ||||
| 		expect(data).to.be.equal(true); | ||||
| 		cy.wrap(data); | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user