certificates.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. const express = require('express');
  2. const error = require('../../lib/error');
  3. const validator = require('../../lib/validator');
  4. const jwtdecode = require('../../lib/express/jwt-decode');
  5. const apiValidator = require('../../lib/validator/api');
  6. const internalCertificate = require('../../internal/certificate');
  7. const schema = require('../../schema');
  8. let router = express.Router({
  9. caseSensitive: true,
  10. strict: true,
  11. mergeParams: true
  12. });
  13. /**
  14. * /api/nginx/certificates
  15. */
  16. router
  17. .route('/')
  18. .options((_, res) => {
  19. res.sendStatus(204);
  20. })
  21. .all(jwtdecode())
  22. /**
  23. * GET /api/nginx/certificates
  24. *
  25. * Retrieve all certificates
  26. */
  27. .get((req, res, next) => {
  28. validator({
  29. additionalProperties: false,
  30. properties: {
  31. expand: {
  32. $ref: 'common#/properties/expand'
  33. },
  34. query: {
  35. $ref: 'common#/properties/query'
  36. }
  37. }
  38. }, {
  39. expand: (typeof req.query.expand === 'string' ? req.query.expand.split(',') : null),
  40. query: (typeof req.query.query === 'string' ? req.query.query : null)
  41. })
  42. .then((data) => {
  43. return internalCertificate.getAll(res.locals.access, data.expand, data.query);
  44. })
  45. .then((rows) => {
  46. res.status(200)
  47. .send(rows);
  48. })
  49. .catch(next);
  50. })
  51. /**
  52. * POST /api/nginx/certificates
  53. *
  54. * Create a new certificate
  55. */
  56. .post((req, res, next) => {
  57. apiValidator(schema.getValidationSchema('/nginx/certificates', 'post'), req.body)
  58. .then((payload) => {
  59. req.setTimeout(900000); // 15 minutes timeout
  60. return internalCertificate.create(res.locals.access, payload);
  61. })
  62. .then((result) => {
  63. res.status(201)
  64. .send(result);
  65. })
  66. .catch(next);
  67. });
  68. /**
  69. * Test HTTP challenge for domains
  70. *
  71. * /api/nginx/certificates/test-http
  72. */
  73. router
  74. .route('/test-http')
  75. .options((_, res) => {
  76. res.sendStatus(204);
  77. })
  78. .all(jwtdecode())
  79. /**
  80. * GET /api/nginx/certificates/test-http
  81. *
  82. * Test HTTP challenge for domains
  83. */
  84. .get((req, res, next) => {
  85. if (req.query.domains === undefined) {
  86. next(new error.ValidationError('Domains are required as query parameters'));
  87. return;
  88. }
  89. internalCertificate.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains))
  90. .then((result) => {
  91. res.status(200)
  92. .send(result);
  93. })
  94. .catch(next);
  95. });
  96. /**
  97. * Specific certificate
  98. *
  99. * /api/nginx/certificates/123
  100. */
  101. router
  102. .route('/:certificate_id')
  103. .options((_, res) => {
  104. res.sendStatus(204);
  105. })
  106. .all(jwtdecode())
  107. /**
  108. * GET /api/nginx/certificates/123
  109. *
  110. * Retrieve a specific certificate
  111. */
  112. .get((req, res, next) => {
  113. validator({
  114. required: ['certificate_id'],
  115. additionalProperties: false,
  116. properties: {
  117. certificate_id: {
  118. $ref: 'common#/properties/id'
  119. },
  120. expand: {
  121. $ref: 'common#/properties/expand'
  122. }
  123. }
  124. }, {
  125. certificate_id: req.params.certificate_id,
  126. expand: (typeof req.query.expand === 'string' ? req.query.expand.split(',') : null)
  127. })
  128. .then((data) => {
  129. return internalCertificate.get(res.locals.access, {
  130. id: parseInt(data.certificate_id, 10),
  131. expand: data.expand
  132. });
  133. })
  134. .then((row) => {
  135. res.status(200)
  136. .send(row);
  137. })
  138. .catch(next);
  139. })
  140. /**
  141. * DELETE /api/nginx/certificates/123
  142. *
  143. * Update and existing certificate
  144. */
  145. .delete((req, res, next) => {
  146. internalCertificate.delete(res.locals.access, {id: parseInt(req.params.certificate_id, 10)})
  147. .then((result) => {
  148. res.status(200)
  149. .send(result);
  150. })
  151. .catch(next);
  152. });
  153. /**
  154. * Upload Certs
  155. *
  156. * /api/nginx/certificates/123/upload
  157. */
  158. router
  159. .route('/:certificate_id/upload')
  160. .options((_, res) => {
  161. res.sendStatus(204);
  162. })
  163. .all(jwtdecode())
  164. /**
  165. * POST /api/nginx/certificates/123/upload
  166. *
  167. * Upload certificates
  168. */
  169. .post((req, res, next) => {
  170. if (!req.files) {
  171. res.status(400)
  172. .send({error: 'No files were uploaded'});
  173. } else {
  174. internalCertificate.upload(res.locals.access, {
  175. id: parseInt(req.params.certificate_id, 10),
  176. files: req.files
  177. })
  178. .then((result) => {
  179. res.status(200)
  180. .send(result);
  181. })
  182. .catch(next);
  183. }
  184. });
  185. /**
  186. * Renew LE Certs
  187. *
  188. * /api/nginx/certificates/123/renew
  189. */
  190. router
  191. .route('/:certificate_id/renew')
  192. .options((_, res) => {
  193. res.sendStatus(204);
  194. })
  195. .all(jwtdecode())
  196. /**
  197. * POST /api/nginx/certificates/123/renew
  198. *
  199. * Renew certificate
  200. */
  201. .post((req, res, next) => {
  202. req.setTimeout(900000); // 15 minutes timeout
  203. internalCertificate.renew(res.locals.access, {
  204. id: parseInt(req.params.certificate_id, 10)
  205. })
  206. .then((result) => {
  207. res.status(200)
  208. .send(result);
  209. })
  210. .catch(next);
  211. });
  212. /**
  213. * Download LE Certs
  214. *
  215. * /api/nginx/certificates/123/download
  216. */
  217. router
  218. .route('/:certificate_id/download')
  219. .options((req, res) => {
  220. res.sendStatus(204);
  221. })
  222. .all(jwtdecode())
  223. /**
  224. * GET /api/nginx/certificates/123/download
  225. *
  226. * Renew certificate
  227. */
  228. .get((req, res, next) => {
  229. internalCertificate.download(res.locals.access, {
  230. id: parseInt(req.params.certificate_id, 10)
  231. })
  232. .then((result) => {
  233. res.status(200)
  234. .download(result.fileName);
  235. })
  236. .catch(next);
  237. });
  238. /**
  239. * Validate Certs before saving
  240. *
  241. * /api/nginx/certificates/validate
  242. */
  243. router
  244. .route('/validate')
  245. .options((_, res) => {
  246. res.sendStatus(204);
  247. })
  248. .all(jwtdecode())
  249. /**
  250. * POST /api/nginx/certificates/validate
  251. *
  252. * Validate certificates
  253. */
  254. .post((req, res, next) => {
  255. if (!req.files) {
  256. res.status(400)
  257. .send({error: 'No files were uploaded'});
  258. } else {
  259. internalCertificate.validate({
  260. files: req.files
  261. })
  262. .then((result) => {
  263. res.status(200)
  264. .send(result);
  265. })
  266. .catch(next);
  267. }
  268. });
  269. module.exports = router;