mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	v2.1.0 (#293)
* Fix wrapping when too many hosts are shown (#207) * Update npm packages, fixes CVE-2019-10757 * Revert some breaking packages * Major overhaul - Docker buildx support in CI - Cypress API Testing in CI - Restructured folder layout (insert clean face meme) - Added Swagger documentation and validate API against that (to be completed) - Use common base image for all supported archs, which includes updated nginx with ipv6 support - Updated certbot and changes required for it - Large amount of Hosts names will wrap in UI - Updated packages for frontend - Version bump 2.1.0 * Updated documentation * Fix JWT expire time going crazy. Now set to 1day * Backend JS formatting rules * Remove v1 importer, I doubt anyone is using v1 anymore * Added backend formatting rules and enforce them in Jenkins builds * Fix CI, doesn't need a tty * Thanks bcrypt. Why can't you just be normal. * Cleanup after syntax check Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										52
									
								
								backend/routes/api/audit-log.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								backend/routes/api/audit-log.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| const express          = require('express'); | ||||
| const validator        = require('../../lib/validator'); | ||||
| const jwtdecode        = require('../../lib/express/jwt-decode'); | ||||
| const internalAuditLog = require('../../internal/audit-log'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/audit-log | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/audit-log | ||||
| 	 * | ||||
| 	 * Retrieve all logs | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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 internalAuditLog.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200) | ||||
| 					.send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										51
									
								
								backend/routes/api/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								backend/routes/api/main.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| const express = require('express'); | ||||
| const pjson   = require('../../package.json'); | ||||
| const error   = require('../../lib/error'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * Health Check | ||||
|  * GET /api | ||||
|  */ | ||||
| router.get('/', (req, res/*, next*/) => { | ||||
| 	let version = pjson.version.split('-').shift().split('.'); | ||||
|  | ||||
| 	res.status(200).send({ | ||||
| 		status:  'OK', | ||||
| 		version: { | ||||
| 			major:    parseInt(version.shift(), 10), | ||||
| 			minor:    parseInt(version.shift(), 10), | ||||
| 			revision: parseInt(version.shift(), 10) | ||||
| 		} | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
| router.use('/schema', require('./schema')); | ||||
| router.use('/tokens', require('./tokens')); | ||||
| router.use('/users', require('./users')); | ||||
| router.use('/audit-log', require('./audit-log')); | ||||
| router.use('/reports', require('./reports')); | ||||
| router.use('/settings', require('./settings')); | ||||
| router.use('/nginx/proxy-hosts', require('./nginx/proxy_hosts')); | ||||
| router.use('/nginx/redirection-hosts', require('./nginx/redirection_hosts')); | ||||
| router.use('/nginx/dead-hosts', require('./nginx/dead_hosts')); | ||||
| router.use('/nginx/streams', require('./nginx/streams')); | ||||
| router.use('/nginx/access-lists', require('./nginx/access_lists')); | ||||
| router.use('/nginx/certificates', require('./nginx/certificates')); | ||||
|  | ||||
| /** | ||||
|  * API 404 for all other routes | ||||
|  * | ||||
|  * ALL /api/* | ||||
|  */ | ||||
| router.all(/(.+)/, function (req, res, next) { | ||||
| 	req.params.page = req.params['0']; | ||||
| 	next(new error.ItemNotFoundError(req.params.page)); | ||||
| }); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										148
									
								
								backend/routes/api/nginx/access_lists.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								backend/routes/api/nginx/access_lists.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| const express            = require('express'); | ||||
| const validator          = require('../../../lib/validator'); | ||||
| const jwtdecode          = require('../../../lib/express/jwt-decode'); | ||||
| const internalAccessList = require('../../../internal/access-list'); | ||||
| const apiValidator       = require('../../../lib/validator/api'); | ||||
|  | ||||
| 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: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/access-lists#/links/1/schema'}, 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((req, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/access-lists#/links/2/schema'}, 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; | ||||
							
								
								
									
										243
									
								
								backend/routes/api/nginx/certificates.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								backend/routes/api/nginx/certificates.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,243 @@ | ||||
| const express             = require('express'); | ||||
| const validator           = require('../../../lib/validator'); | ||||
| const jwtdecode           = require('../../../lib/express/jwt-decode'); | ||||
| const internalCertificate = require('../../../internal/certificate'); | ||||
| const apiValidator        = require('../../../lib/validator/api'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/certificates | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/nginx/certificates | ||||
| 	 * | ||||
| 	 * Retrieve all certificates | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/certificates#/links/1/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalCertificate.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific certificate | ||||
|  * | ||||
|  * /api/nginx/certificates/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:certificate_id') | ||||
| 	.options((req, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/nginx/certificates/123 | ||||
| 	 * | ||||
| 	 * Update and existing certificate | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/certificates#/links/2/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = parseInt(req.params.certificate_id, 10); | ||||
| 				return internalCertificate.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.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((req, 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((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/nginx/certificates/123/renew | ||||
| 	 * | ||||
| 	 * Renew certificate | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalCertificate.renew(res.locals.access, { | ||||
| 			id: parseInt(req.params.certificate_id, 10) | ||||
| 		}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Validate Certs before saving | ||||
|  * | ||||
|  * /api/nginx/certificates/validate | ||||
|  */ | ||||
| router | ||||
| 	.route('/validate') | ||||
| 	.options((req, 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; | ||||
							
								
								
									
										196
									
								
								backend/routes/api/nginx/dead_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								backend/routes/api/nginx/dead_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| const express          = require('express'); | ||||
| const validator        = require('../../../lib/validator'); | ||||
| const jwtdecode        = require('../../../lib/express/jwt-decode'); | ||||
| const internalDeadHost = require('../../../internal/dead-host'); | ||||
| const apiValidator     = require('../../../lib/validator/api'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/nginx/dead-hosts | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, 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: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/dead-hosts#/links/1/schema'}, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/dead-hosts#/links/2/schema'}, 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((req, 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((req, 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; | ||||
							
								
								
									
										196
									
								
								backend/routes/api/nginx/proxy_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								backend/routes/api/nginx/proxy_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| const express           = require('express'); | ||||
| const validator         = require('../../../lib/validator'); | ||||
| const jwtdecode         = require('../../../lib/express/jwt-decode'); | ||||
| const internalProxyHost = require('../../../internal/proxy-host'); | ||||
| const apiValidator      = require('../../../lib/validator/api'); | ||||
|  | ||||
| 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: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/proxy-hosts#/links/1/schema'}, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/proxy-hosts#/links/2/schema'}, 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((req, 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((req, 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; | ||||
							
								
								
									
										196
									
								
								backend/routes/api/nginx/redirection_hosts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								backend/routes/api/nginx/redirection_hosts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| const express                 = require('express'); | ||||
| const validator               = require('../../../lib/validator'); | ||||
| const jwtdecode               = require('../../../lib/express/jwt-decode'); | ||||
| const internalRedirectionHost = require('../../../internal/redirection-host'); | ||||
| const apiValidator            = require('../../../lib/validator/api'); | ||||
|  | ||||
| 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: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/redirection-hosts#/links/1/schema'}, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/redirection-hosts#/links/2/schema'}, 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; | ||||
							
								
								
									
										196
									
								
								backend/routes/api/nginx/streams.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								backend/routes/api/nginx/streams.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| const express        = require('express'); | ||||
| const validator      = require('../../../lib/validator'); | ||||
| const jwtdecode      = require('../../../lib/express/jwt-decode'); | ||||
| const internalStream = require('../../../internal/stream'); | ||||
| const apiValidator   = require('../../../lib/validator/api'); | ||||
|  | ||||
| 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: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/streams#/links/1/schema'}, 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: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/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({$ref: 'endpoints/streams#/links/2/schema'}, 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((req, 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((req, 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; | ||||
							
								
								
									
										29
									
								
								backend/routes/api/reports.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								backend/routes/api/reports.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| const express        = require('express'); | ||||
| const jwtdecode      = require('../../lib/express/jwt-decode'); | ||||
| const internalReport = require('../../internal/report'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| router | ||||
| 	.route('/hosts') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /reports/hosts | ||||
| 	 */ | ||||
| 	.get(jwtdecode(), (req, res, next) => { | ||||
| 		internalReport.getHostsReport(res.locals.access) | ||||
| 			.then((data) => { | ||||
| 				res.status(200) | ||||
| 					.send(data); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										36
									
								
								backend/routes/api/schema.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								backend/routes/api/schema.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| const express     = require('express'); | ||||
| const swaggerJSON = require('../../doc/api.swagger.json'); | ||||
| const PACKAGE     = require('../../package.json'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /schema | ||||
| 	 */ | ||||
| 	.get((req, res/*, next*/) => { | ||||
| 		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); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										96
									
								
								backend/routes/api/settings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								backend/routes/api/settings.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| const express         = require('express'); | ||||
| const validator       = require('../../lib/validator'); | ||||
| const jwtdecode       = require('../../lib/express/jwt-decode'); | ||||
| const internalSetting = require('../../internal/setting'); | ||||
| const apiValidator    = require('../../lib/validator/api'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/settings | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/settings | ||||
| 	 * | ||||
| 	 * Retrieve all settings | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		internalSetting.getAll(res.locals.access) | ||||
| 			.then((rows) => { | ||||
| 				res.status(200) | ||||
| 					.send(rows); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific setting | ||||
|  * | ||||
|  * /api/settings/something | ||||
|  */ | ||||
| router | ||||
| 	.route('/:setting_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /settings/something | ||||
| 	 * | ||||
| 	 * Retrieve a specific setting | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['setting_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				setting_id: { | ||||
| 					$ref: 'definitions#/definitions/setting_id' | ||||
| 				} | ||||
| 			} | ||||
| 		}, { | ||||
| 			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); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/settings/something | ||||
| 	 * | ||||
| 	 * Update and existing setting | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/settings#/links/1/schema'}, 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); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										54
									
								
								backend/routes/api/tokens.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								backend/routes/api/tokens.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| const express       = require('express'); | ||||
| const jwtdecode     = require('../../lib/express/jwt-decode'); | ||||
| const internalToken = require('../../internal/token'); | ||||
| const apiValidator  = require('../../lib/validator/api'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /tokens | ||||
| 	 * | ||||
| 	 * Get a new Token, given they already have a token they want to refresh | ||||
| 	 * We also piggy back on to this method, allowing admins to get tokens | ||||
| 	 * for services like Job board and Worker. | ||||
| 	 */ | ||||
| 	.get(jwtdecode(), (req, res, next) => { | ||||
| 		internalToken.getFreshToken(res.locals.access, { | ||||
| 			expiry: (typeof req.query.expiry !== 'undefined' ? req.query.expiry : null), | ||||
| 			scope:  (typeof req.query.scope !== 'undefined' ? req.query.scope : null) | ||||
| 		}) | ||||
| 			.then((data) => { | ||||
| 				res.status(200) | ||||
| 					.send(data); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /tokens | ||||
| 	 * | ||||
| 	 * Create a new Token | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/tokens#/links/0/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalToken.getTokenFromEmail(payload); | ||||
| 			}) | ||||
| 			.then((data) => { | ||||
| 				res.status(200) | ||||
| 					.send(data); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
							
								
								
									
										239
									
								
								backend/routes/api/users.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								backend/routes/api/users.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| const express      = require('express'); | ||||
| const validator    = require('../../lib/validator'); | ||||
| const jwtdecode    = require('../../lib/express/jwt-decode'); | ||||
| const userIdFromMe = require('../../lib/express/user-id-from-me'); | ||||
| const internalUser = require('../../internal/user'); | ||||
| const apiValidator = require('../../lib/validator/api'); | ||||
|  | ||||
| let router = express.Router({ | ||||
| 	caseSensitive: true, | ||||
| 	strict:        true, | ||||
| 	mergeParams:   true | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * /api/users | ||||
|  */ | ||||
| router | ||||
| 	.route('/') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /api/users | ||||
| 	 * | ||||
| 	 * Retrieve all users | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/definitions/expand' | ||||
| 				}, | ||||
| 				query: { | ||||
| 					$ref: 'definitions#/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 internalUser.getAll(res.locals.access, data.expand, data.query); | ||||
| 			}) | ||||
| 			.then((users) => { | ||||
| 				res.status(200) | ||||
| 					.send(users); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/users | ||||
| 	 * | ||||
| 	 * Create a new User | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/users#/links/1/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				return internalUser.create(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific user | ||||
|  * | ||||
|  * /api/users/123 | ||||
|  */ | ||||
| router | ||||
| 	.route('/:user_id') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
| 	.all(userIdFromMe) | ||||
|  | ||||
| 	/** | ||||
| 	 * GET /users/123 or /users/me | ||||
| 	 * | ||||
| 	 * Retrieve a specific user | ||||
| 	 */ | ||||
| 	.get((req, res, next) => { | ||||
| 		validator({ | ||||
| 			required:             ['user_id'], | ||||
| 			additionalProperties: false, | ||||
| 			properties:           { | ||||
| 				user_id: { | ||||
| 					$ref: 'definitions#/definitions/id' | ||||
| 				}, | ||||
| 				expand: { | ||||
| 					$ref: 'definitions#/definitions/expand' | ||||
| 				} | ||||
| 			} | ||||
| 		}, { | ||||
| 			user_id: req.params.user_id, | ||||
| 			expand:  (typeof req.query.expand === 'string' ? req.query.expand.split(',') : null) | ||||
| 		}) | ||||
| 			.then((data) => { | ||||
| 				return internalUser.get(res.locals.access, { | ||||
| 					id:     data.user_id, | ||||
| 					expand: data.expand, | ||||
| 					omit:   internalUser.getUserOmisionsByAccess(res.locals.access, data.user_id) | ||||
| 				}); | ||||
| 			}) | ||||
| 			.then((user) => { | ||||
| 				res.status(200) | ||||
| 					.send(user); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/users/123 | ||||
| 	 * | ||||
| 	 * Update and existing user | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/users#/links/2/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = req.params.user_id; | ||||
| 				return internalUser.update(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| 	 * DELETE /api/users/123 | ||||
| 	 * | ||||
| 	 * Update and existing user | ||||
| 	 */ | ||||
| 	.delete((req, res, next) => { | ||||
| 		internalUser.delete(res.locals.access, {id: req.params.user_id}) | ||||
| 			.then((result) => { | ||||
| 				res.status(200) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific user auth | ||||
|  * | ||||
|  * /api/users/123/auth | ||||
|  */ | ||||
| router | ||||
| 	.route('/:user_id/auth') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
| 	.all(userIdFromMe) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/users/123/auth | ||||
| 	 * | ||||
| 	 * Update password for a user | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/users#/links/4/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = req.params.user_id; | ||||
| 				return internalUser.setPassword(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific user permissions | ||||
|  * | ||||
|  * /api/users/123/permissions | ||||
|  */ | ||||
| router | ||||
| 	.route('/:user_id/permissions') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
| 	.all(userIdFromMe) | ||||
|  | ||||
| 	/** | ||||
| 	 * PUT /api/users/123/permissions | ||||
| 	 * | ||||
| 	 * Set some or all permissions for a user | ||||
| 	 */ | ||||
| 	.put((req, res, next) => { | ||||
| 		apiValidator({$ref: 'endpoints/users#/links/5/schema'}, req.body) | ||||
| 			.then((payload) => { | ||||
| 				payload.id = req.params.user_id; | ||||
| 				return internalUser.setPermissions(res.locals.access, payload); | ||||
| 			}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| /** | ||||
|  * Specific user login as | ||||
|  * | ||||
|  * /api/users/123/login | ||||
|  */ | ||||
| router | ||||
| 	.route('/:user_id/login') | ||||
| 	.options((req, res) => { | ||||
| 		res.sendStatus(204); | ||||
| 	}) | ||||
| 	.all(jwtdecode()) | ||||
|  | ||||
| 	/** | ||||
| 	 * POST /api/users/123/login | ||||
| 	 * | ||||
| 	 * Log in as a user | ||||
| 	 */ | ||||
| 	.post((req, res, next) => { | ||||
| 		internalUser.loginAs(res.locals.access, {id: parseInt(req.params.user_id, 10)}) | ||||
| 			.then((result) => { | ||||
| 				res.status(201) | ||||
| 					.send(result); | ||||
| 			}) | ||||
| 			.catch(next); | ||||
| 	}); | ||||
|  | ||||
| module.exports = router; | ||||
		Reference in New Issue
	
	Block a user