mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Refactor API Schema and validation
- /schema now returns full openapi/swagger schema - That schema is used to validate incoming requests - And used as a contract in future integration tests - Moved route files up one level - Fixed incorrect 404 reponses when getting objects - Fixed saving new objects and passing jsonschemavalidation
This commit is contained in:
		
							
								
								
									
										149
									
								
								backend/routes/nginx/access_lists.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								backend/routes/nginx/access_lists.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| const express            = require('express'); | ||||
| const validator          = require('../../lib/validator'); | ||||
| const jwtdecode          = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator       = require('../../lib/validator/api'); | ||||
| const internalAccessList = require('../../internal/access-list'); | ||||
| const schema             = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/access-lists | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/access-lists | ||||
| 	 * | ||||
| 	 * Retrieve all access-lists | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/access-lists | ||||
| 	 * | ||||
| 	 * Create a new access-list | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific access-list | ||||
|  * | ||||
|  * /api/nginx/access-lists/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:list_id') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/access-lists/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific access-list | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['list_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				list_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.list_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/access-lists/123 | ||||
| 	 * | ||||
| 	 * Update and existing access-list | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/access-lists/{listID}', 'put'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.list_id, 10); | ||||
| 				return internalAccessList.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/access-lists/123 | ||||
| 	 * | ||||
| 	 * Delete and existing access-list | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalAccessList.delete(res.locals.access, {id: parseInt(req.params.list_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										288
									
								
								backend/routes/nginx/certificates.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								backend/routes/nginx/certificates.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,288 @@ | ||||
| const express             = require('express'); | ||||
| const error               = require('../../lib/error'); | ||||
| const validator           = require('../../lib/validator'); | ||||
| const jwtdecode           = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator        = require('../../lib/validator/api'); | ||||
| const internalCertificate = require('../../internal/certificate'); | ||||
| const schema              = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/certificates | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/certificates | ||||
| 	 * | ||||
| 	 * Retrieve all certificates | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/certificates | ||||
| 	 * | ||||
| 	 * Create a new certificate | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Test HTTP challenge for domains | ||||
|  * | ||||
|  * /api/nginx/certificates/test-http | ||||
|  */ | ||||
| router | ||||
| 	.route('/test-http') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/certificates/test-http | ||||
| 	 * | ||||
| 	 * Test HTTP challenge for domains | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		if (req.query.domains === undefined) { | ||||
| 			next(new error.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific certificate | ||||
|  * | ||||
|  * /api/nginx/certificates/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:certificate_id') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/certificates/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific certificate | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['certificate_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				certificate_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.certificate_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/certificates/123 | ||||
| 	 * | ||||
| 	 * Update and existing certificate | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalCertificate.delete(res.locals.access, {id: parseInt(req.params.certificate_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Upload Certs | ||||
|  * | ||||
|  * /api/nginx/certificates/123/upload | ||||
|  */ | ||||
| router | ||||
| 	.route('/:certificate_id/upload') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/certificates/123/upload | ||||
| 	 * | ||||
| 	 * Upload certificates | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		if (!req.files) { | ||||
| 			res.status(400) | ||||
| 				.send({error: 'No files were uploaded'}); | ||||
| 		} else { | ||||
| 			internalCertificate.upload(res.locals.access, { | ||||
| 				id:    parseInt(req.params.certificate_id, 10), | ||||
| 				files: req.files | ||||
| 			}) | ||||
| 				.then((result) => { | ||||
| 					res.status(200) | ||||
| 						.send(result); | ||||
| 				}) | ||||
| 				.catch(next); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Renew LE Certs | ||||
|  * | ||||
|  * /api/nginx/certificates/123/renew | ||||
|  */ | ||||
| router | ||||
| 	.route('/:certificate_id/renew') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/certificates/123/renew | ||||
| 	 * | ||||
| 	 * Renew certificate | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		req.setTimeout(900000); // 15 minutes timeout | ||||
| 		internalCertificate.renew(res.locals.access, { | ||||
| 			id: parseInt(req.params.certificate_id, 10) | ||||
| 		}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Download LE Certs | ||||
|  * | ||||
|  * /api/nginx/certificates/123/download | ||||
|  */ | ||||
| router | ||||
| 	.route('/:certificate_id/download') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/certificates/123/download | ||||
| 	 * | ||||
| 	 * Renew certificate | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		internalCertificate.download(res.locals.access, { | ||||
| 			id: parseInt(req.params.certificate_id, 10) | ||||
| 		}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.download(result.fileName); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Validate Certs before saving | ||||
|  * | ||||
|  * /api/nginx/certificates/validate | ||||
|  */ | ||||
| router | ||||
| 	.route('/validate') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/certificates/validate | ||||
| 	 * | ||||
| 	 * Validate certificates | ||||
| 	 */ | ||||
| 	.post((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); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										197
									
								
								backend/routes/nginx/dead_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								backend/routes/nginx/dead_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| const express          = require('express'); | ||||
| const validator        = require('../../lib/validator'); | ||||
| const jwtdecode        = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator     = require('../../lib/validator/api'); | ||||
| const internalDeadHost = require('../../internal/dead-host'); | ||||
| const schema           = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/dead-hosts | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/dead-hosts | ||||
| 	 * | ||||
| 	 * Retrieve all dead-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/dead-hosts | ||||
| 	 * | ||||
| 	 * Create a new dead-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific dead-host | ||||
|  * | ||||
|  * /api/nginx/dead-hosts/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/dead-hosts/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific dead-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['host_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				host_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.host_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/dead-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing dead-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/dead-hosts/{hostID}', 'put'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.host_id, 10); | ||||
| 				return internalDeadHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/dead-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing dead-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalDeadHost.delete(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Enable dead-host | ||||
|  * | ||||
|  * /api/nginx/dead-hosts/123/enable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/enable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/dead-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalDeadHost.enable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Disable dead-host | ||||
|  * | ||||
|  * /api/nginx/dead-hosts/123/disable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/disable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/dead-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalDeadHost.disable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										197
									
								
								backend/routes/nginx/proxy_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								backend/routes/nginx/proxy_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| const express           = require('express'); | ||||
| const validator         = require('../../lib/validator'); | ||||
| const jwtdecode         = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator      = require('../../lib/validator/api'); | ||||
| const internalProxyHost = require('../../internal/proxy-host'); | ||||
| const schema            = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/proxy-hosts | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/proxy-hosts | ||||
| 	 * | ||||
| 	 * Retrieve all proxy-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/proxy-hosts | ||||
| 	 * | ||||
| 	 * Create a new proxy-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific proxy-host | ||||
|  * | ||||
|  * /api/nginx/proxy-hosts/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/proxy-hosts/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific proxy-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['host_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				host_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.host_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/proxy-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing proxy-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/proxy-hosts/{hostID}', 'put'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.host_id, 10); | ||||
| 				return internalProxyHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/proxy-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing proxy-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalProxyHost.delete(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Enable proxy-host | ||||
|  * | ||||
|  * /api/nginx/proxy-hosts/123/enable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/enable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/proxy-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalProxyHost.enable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Disable proxy-host | ||||
|  * | ||||
|  * /api/nginx/proxy-hosts/123/disable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/disable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/proxy-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalProxyHost.disable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										197
									
								
								backend/routes/nginx/redirection_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								backend/routes/nginx/redirection_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| const express                 = require('express'); | ||||
| const validator               = require('../../lib/validator'); | ||||
| const jwtdecode               = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator            = require('../../lib/validator/api'); | ||||
| const internalRedirectionHost = require('../../internal/redirection-host'); | ||||
| const schema                  = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/redirection-hosts | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/redirection-hosts | ||||
| 	 * | ||||
| 	 * Retrieve all redirection-hosts | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/redirection-hosts | ||||
| 	 * | ||||
| 	 * Create a new redirection-host | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.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); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific redirection-host | ||||
|  * | ||||
|  * /api/nginx/redirection-hosts/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/redirection-hosts/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific redirection-host | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['host_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				host_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.host_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/redirection-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing redirection-host | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/redirection-hosts/{hostID}', 'put'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.host_id, 10); | ||||
| 				return internalRedirectionHost.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/redirection-hosts/123 | ||||
| 	 * | ||||
| 	 * Update and existing redirection-host | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalRedirectionHost.delete(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Enable redirection-host | ||||
|  * | ||||
|  * /api/nginx/redirection-hosts/123/enable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/enable') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/redirection-hosts/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalRedirectionHost.enable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Disable redirection-host | ||||
|  * | ||||
|  * /api/nginx/redirection-hosts/123/disable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/disable') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/redirection-hosts/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalRedirectionHost.disable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										197
									
								
								backend/routes/nginx/streams.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								backend/routes/nginx/streams.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| const express        = require('express'); | ||||
| const validator      = require('../../lib/validator'); | ||||
| const jwtdecode      = require('../../lib/express/jwt-decode'); | ||||
| const apiValidator   = require('../../lib/validator/api'); | ||||
| const internalStream = require('../../internal/stream'); | ||||
| const schema         = require('../../schema'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/streams | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) // preferred so it doesn't apply to nonexistent routes | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/streams | ||||
| 	 * | ||||
| 	 * Retrieve all streams | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'common#/definitions/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/streams | ||||
| 	 * | ||||
| 	 * Create a new stream | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/streams', 'post'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalStream.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific stream | ||||
|  * | ||||
|  * /api/nginx/streams/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:stream_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) // preferred so it doesn't apply to nonexistent routes | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/streams/123 | ||||
| 	 * | ||||
| 	 * Retrieve a specific stream | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['stream_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				stream_id: { | ||||
| 					$ref: 'common#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'common#/definitions/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:     parseInt(data.stream_id, 10), | ||||
| 					expand: data.expand | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((row) => { | ||||
| 				res.status(200) | ||||
| 					.send(row); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/streams/123 | ||||
| 	 * | ||||
| 	 * Update and existing stream | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator(schema.getValidationSchema('/nginx/streams/{streamID}', 'put'), req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.stream_id, 10); | ||||
| 				return internalStream.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/nginx/streams/123 | ||||
| 	 * | ||||
| 	 * Update and existing stream | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalStream.delete(res.locals.access, {id: parseInt(req.params.stream_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Enable stream | ||||
|  * | ||||
|  * /api/nginx/streams/123/enable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/enable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/streams/123/enable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalStream.enable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Disable stream | ||||
|  * | ||||
|  * /api/nginx/streams/123/disable | ||||
|  */ | ||||
| router | ||||
| 	.route('/:host_id/disable') | ||||
| 	.options((_, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/streams/123/disable | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalStream.disable(res.locals.access, {id: parseInt(req.params.host_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
		Reference in New Issue
	
	Block a user