mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-11-04 01:15:14 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			3b89d5f380
			...
			929ac3bd7c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					929ac3bd7c | ||
| 
						 | 
					f48e1b46a8 | ||
| 
						 | 
					351ba8dacd | 
							
								
								
									
										10
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
								
							@@ -127,6 +127,11 @@ pipeline {
 | 
				
			|||||||
					junit 'test/results/junit/*'
 | 
										junit 'test/results/junit/*'
 | 
				
			||||||
					sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
 | 
										sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									unstable {
 | 
				
			||||||
 | 
										dir(path: 'testing/results') {
 | 
				
			||||||
 | 
											archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		stage('Test Mysql') {
 | 
							stage('Test Mysql') {
 | 
				
			||||||
@@ -155,6 +160,11 @@ pipeline {
 | 
				
			|||||||
					junit 'test/results/junit/*'
 | 
										junit 'test/results/junit/*'
 | 
				
			||||||
					sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
 | 
										sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									unstable {
 | 
				
			||||||
 | 
										dir(path: 'testing/results') {
 | 
				
			||||||
 | 
											archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		stage('MultiArch Build') {
 | 
							stage('MultiArch Build') {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,27 +3,29 @@ const fs               = require('fs');
 | 
				
			|||||||
const https            = require('https');
 | 
					const https            = require('https');
 | 
				
			||||||
const tempWrite        = require('temp-write');
 | 
					const tempWrite        = require('temp-write');
 | 
				
			||||||
const moment           = require('moment');
 | 
					const moment           = require('moment');
 | 
				
			||||||
 | 
					const archiver         = require('archiver');
 | 
				
			||||||
 | 
					const path             = require('path');
 | 
				
			||||||
 | 
					const { isArray }      = require('lodash');
 | 
				
			||||||
const logger           = require('../logger').ssl;
 | 
					const logger           = require('../logger').ssl;
 | 
				
			||||||
const config           = require('../lib/config');
 | 
					const config           = require('../lib/config');
 | 
				
			||||||
const error            = require('../lib/error');
 | 
					const error            = require('../lib/error');
 | 
				
			||||||
const utils            = require('../lib/utils');
 | 
					const utils            = require('../lib/utils');
 | 
				
			||||||
 | 
					const certbot          = require('../lib/certbot');
 | 
				
			||||||
const certificateModel = require('../models/certificate');
 | 
					const certificateModel = require('../models/certificate');
 | 
				
			||||||
const tokenModel       = require('../models/token');
 | 
					const tokenModel       = require('../models/token');
 | 
				
			||||||
const dnsPlugins       = require('../global/certbot-dns-plugins.json');
 | 
					const dnsPlugins       = require('../global/certbot-dns-plugins.json');
 | 
				
			||||||
const internalAuditLog = require('./audit-log');
 | 
					const internalAuditLog = require('./audit-log');
 | 
				
			||||||
const internalNginx    = require('./nginx');
 | 
					const internalNginx    = require('./nginx');
 | 
				
			||||||
const internalHost     = require('./host');
 | 
					const internalHost     = require('./host');
 | 
				
			||||||
const certbot          = require('../lib/certbot');
 | 
					
 | 
				
			||||||
const archiver         = require('archiver');
 | 
					 | 
				
			||||||
const path             = require('path');
 | 
					 | 
				
			||||||
const { isArray }      = require('lodash');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const letsencryptStaging = config.useLetsencryptStaging();
 | 
					const letsencryptStaging = config.useLetsencryptStaging();
 | 
				
			||||||
 | 
					const letsencryptServer  = config.useLetsencryptServer();
 | 
				
			||||||
const letsencryptConfig  = '/etc/letsencrypt.ini';
 | 
					const letsencryptConfig  = '/etc/letsencrypt.ini';
 | 
				
			||||||
const certbotCommand     = 'certbot';
 | 
					const certbotCommand     = 'certbot';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function omissions() {
 | 
					function omissions() {
 | 
				
			||||||
	return ['is_deleted'];
 | 
						return ['is_deleted', 'owner.is_deleted'];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const internalCertificate = {
 | 
					const internalCertificate = {
 | 
				
			||||||
@@ -837,7 +839,8 @@ const internalCertificate = {
 | 
				
			|||||||
			'--email "' + certificate.meta.letsencrypt_email + '" ' +
 | 
								'--email "' + certificate.meta.letsencrypt_email + '" ' +
 | 
				
			||||||
			'--preferred-challenges "dns,http" ' +
 | 
								'--preferred-challenges "dns,http" ' +
 | 
				
			||||||
			'--domains "' + certificate.domain_names.join(',') + '" ' +
 | 
								'--domains "' + certificate.domain_names.join(',') + '" ' +
 | 
				
			||||||
			(letsencryptStaging ? '--staging' : '');
 | 
								(letsencryptStaging ? '--staging' : '') +
 | 
				
			||||||
 | 
								(letsencryptServer !== null ? `--server '${letsencryptServer}'` : '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		logger.info('Command:', cmd);
 | 
							logger.info('Command:', cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -180,5 +180,15 @@ module.exports = {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	useLetsencryptStaging: function () {
 | 
						useLetsencryptStaging: function () {
 | 
				
			||||||
		return !!process.env.LE_STAGING;
 | 
							return !!process.env.LE_STAGING;
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @returns {string|null}
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						useLetsencryptServer: function () {
 | 
				
			||||||
 | 
							if (process.env.LE_SERVER) {
 | 
				
			||||||
 | 
								return process.env.LE_SERVER;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,13 +24,23 @@
 | 
				
			|||||||
			"description": "Nice Name for the custom certificate"
 | 
								"description": "Nice Name for the custom certificate"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"domain_names": {
 | 
							"domain_names": {
 | 
				
			||||||
			"$ref": "../common.json#/properties/domain_names"
 | 
								"description": "Domain Names separated by a comma",
 | 
				
			||||||
 | 
								"type": "array",
 | 
				
			||||||
 | 
								"maxItems": 100,
 | 
				
			||||||
 | 
								"uniqueItems": true,
 | 
				
			||||||
 | 
								"items": {
 | 
				
			||||||
 | 
									"type": "string",
 | 
				
			||||||
 | 
									"pattern": "^[^&| @!#%^();:/\\\\}{=+?<>,~`'\"]+$"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"expires_on": {
 | 
							"expires_on": {
 | 
				
			||||||
			"description": "Date and time of expiration",
 | 
								"description": "Date and time of expiration",
 | 
				
			||||||
			"readOnly": true,
 | 
								"readOnly": true,
 | 
				
			||||||
			"type": "string"
 | 
								"type": "string"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							"owner": {
 | 
				
			||||||
 | 
								"$ref": "./user-object.json"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		"meta": {
 | 
							"meta": {
 | 
				
			||||||
			"type": "object",
 | 
								"type": "object",
 | 
				
			||||||
			"additionalProperties": false,
 | 
								"additionalProperties": false,
 | 
				
			||||||
@@ -51,12 +61,16 @@
 | 
				
			|||||||
					"type": "string"
 | 
										"type": "string"
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				"propagation_seconds": {
 | 
									"propagation_seconds": {
 | 
				
			||||||
					"anyOf": [
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
					"type": "integer",
 | 
										"type": "integer",
 | 
				
			||||||
					"minimum": 0
 | 
										"minimum": 0
 | 
				
			||||||
						}
 | 
									},
 | 
				
			||||||
					]
 | 
									"certificate": {
 | 
				
			||||||
 | 
										"type": "string",
 | 
				
			||||||
 | 
										"minLength": 1
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									"certificate_key": {
 | 
				
			||||||
 | 
										"type": "string",
 | 
				
			||||||
 | 
										"minLength": 1
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,6 +55,25 @@
 | 
				
			|||||||
								"certificate_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1n9j9C5Bes1nd\nqACDckERauxXVNKCnUlUM1buGBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2w\nrbmvZvLuPmXePOKbIKS+XXh+2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHge\nYz6Cv/Si2/LJPCh/CoBfM4hUQJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQ\noxRAHiOR9081Xn1WeoKr7kVBIa5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7Z\nEo+nS8Wr/4QWicatIWZXpVaEOPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79X\nzGONeH1PAgMBAAECggEAANb3Wtwl07pCjRrMvc7WbC0xYIn82yu8/g2qtjkYUJcU\nia5lQbYN7RGCS85Oc/tkq48xQEG5JQWNH8b918jDEMTrFab0aUEyYcru1q9L8PL6\nYHaNgZSrMrDcHcS8h0QOXNRJT5jeGkiHJaTR0irvB526tqF3knbK9yW22KTfycUe\na0Z9voKn5xRk1DCbHi/nk2EpT7xnjeQeLFaTIRXbS68omkr4YGhwWm5OizoyEGZu\nW0Zum5BkQyMr6kor3wdxOTG97ske2rcyvvHi+ErnwL0xBv0qY0Dhe8DpuXpDezqw\no72yY8h31Fu84i7sAj24YuE5Df8DozItFXQpkgbQ6QKBgQDPrufhvIFm2S/MzBdW\nH8JxY7CJlJPyxOvc1NIl9RczQGAQR90kx52cgIcuIGEG6/wJ/xnGfMmW40F0DnQ+\nN+oLgB9SFxeLkRb7s9Z/8N3uIN8JJFYcerEOiRQeN2BXEEWJ7bUThNtsVrAcKoUh\nELsDmnHW/3V+GKwhd0vpk842+wKBgQDf4PGLG9PTE5tlAoyHFodJRd2RhTJQkwsU\nMDNjLJ+KecLv+Nl+QiJhoflG1ccqtSFlBSCG067CDQ5LV0xm3mLJ7pfJoMgjcq31\nqjEmX4Ls91GuVOPtbwst3yFKjsHaSoKB5fBvWRcKFpBUezM7Qcw2JP3+dQT+bQIq\ncMTkRWDSvQKBgQDOdCQFDjxg/lR7NQOZ1PaZe61aBz5P3pxNqa7ClvMaOsuEQ7w9\nvMYcdtRq8TsjA2JImbSI0TIg8gb2FQxPcYwTJKl+FICOeIwtaSg5hTtJZpnxX5LO\nutTaC0DZjNkTk5RdOdWA8tihyUdGqKoxJY2TVmwGe2rUEDjFB++J4inkEwKBgB6V\ng0nmtkxanFrzOzFlMXwgEEHF+Xaqb9QFNa/xs6XeNnREAapO7JV75Cr6H2hFMFe1\nmJjyqCgYUoCWX3iaHtLJRnEkBtNY4kzyQB6m46LtsnnnXO/dwKA2oDyoPfFNRoDq\nYatEd3JIXNU9s2T/+x7WdOBjKhh72dTkbPFmTPDdAoGAU6rlPBevqOFdObYxdPq8\nEQWu44xqky3Mf5sBpOwtu6rqCYuziLiN7K4sjN5GD5mb1cEU+oS92ZiNcUQ7MFXk\n8yTYZ7U0VcXyAcpYreWwE8thmb0BohJBr+Mp3wLTx32x0HKdO6vpUa0d35LUTUmM\nRrKmPK/msHKK/sVHiL+NFqo=\n-----END PRIVATE KEY-----\n"
 | 
													"certificate_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1n9j9C5Bes1nd\nqACDckERauxXVNKCnUlUM1buGBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2w\nrbmvZvLuPmXePOKbIKS+XXh+2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHge\nYz6Cv/Si2/LJPCh/CoBfM4hUQJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQ\noxRAHiOR9081Xn1WeoKr7kVBIa5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7Z\nEo+nS8Wr/4QWicatIWZXpVaEOPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79X\nzGONeH1PAgMBAAECggEAANb3Wtwl07pCjRrMvc7WbC0xYIn82yu8/g2qtjkYUJcU\nia5lQbYN7RGCS85Oc/tkq48xQEG5JQWNH8b918jDEMTrFab0aUEyYcru1q9L8PL6\nYHaNgZSrMrDcHcS8h0QOXNRJT5jeGkiHJaTR0irvB526tqF3knbK9yW22KTfycUe\na0Z9voKn5xRk1DCbHi/nk2EpT7xnjeQeLFaTIRXbS68omkr4YGhwWm5OizoyEGZu\nW0Zum5BkQyMr6kor3wdxOTG97ske2rcyvvHi+ErnwL0xBv0qY0Dhe8DpuXpDezqw\no72yY8h31Fu84i7sAj24YuE5Df8DozItFXQpkgbQ6QKBgQDPrufhvIFm2S/MzBdW\nH8JxY7CJlJPyxOvc1NIl9RczQGAQR90kx52cgIcuIGEG6/wJ/xnGfMmW40F0DnQ+\nN+oLgB9SFxeLkRb7s9Z/8N3uIN8JJFYcerEOiRQeN2BXEEWJ7bUThNtsVrAcKoUh\nELsDmnHW/3V+GKwhd0vpk842+wKBgQDf4PGLG9PTE5tlAoyHFodJRd2RhTJQkwsU\nMDNjLJ+KecLv+Nl+QiJhoflG1ccqtSFlBSCG067CDQ5LV0xm3mLJ7pfJoMgjcq31\nqjEmX4Ls91GuVOPtbwst3yFKjsHaSoKB5fBvWRcKFpBUezM7Qcw2JP3+dQT+bQIq\ncMTkRWDSvQKBgQDOdCQFDjxg/lR7NQOZ1PaZe61aBz5P3pxNqa7ClvMaOsuEQ7w9\nvMYcdtRq8TsjA2JImbSI0TIg8gb2FQxPcYwTJKl+FICOeIwtaSg5hTtJZpnxX5LO\nutTaC0DZjNkTk5RdOdWA8tihyUdGqKoxJY2TVmwGe2rUEDjFB++J4inkEwKBgB6V\ng0nmtkxanFrzOzFlMXwgEEHF+Xaqb9QFNa/xs6XeNnREAapO7JV75Cr6H2hFMFe1\nmJjyqCgYUoCWX3iaHtLJRnEkBtNY4kzyQB6m46LtsnnnXO/dwKA2oDyoPfFNRoDq\nYatEd3JIXNU9s2T/+x7WdOBjKhh72dTkbPFmTPDdAoGAU6rlPBevqOFdObYxdPq8\nEQWu44xqky3Mf5sBpOwtu6rqCYuziLiN7K4sjN5GD5mb1cEU+oS92ZiNcUQ7MFXk\n8yTYZ7U0VcXyAcpYreWwE8thmb0BohJBr+Mp3wLTx32x0HKdO6vpUa0d35LUTUmM\nRrKmPK/msHKK/sVHiL+NFqo=\n-----END PRIVATE KEY-----\n"
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										"schema": {
 | 
				
			||||||
 | 
											"type": "object",
 | 
				
			||||||
 | 
											"additionalProperties": false,
 | 
				
			||||||
 | 
											"required": ["certificate", "certificate_key"],
 | 
				
			||||||
 | 
											"properties": {
 | 
				
			||||||
 | 
												"certificate": {
 | 
				
			||||||
 | 
													"type": "string",
 | 
				
			||||||
 | 
													"minLength": 1
 | 
				
			||||||
 | 
												},
 | 
				
			||||||
 | 
												"certificate_key": {
 | 
				
			||||||
 | 
													"type": "string",
 | 
				
			||||||
 | 
													"minLength": 1
 | 
				
			||||||
 | 
												},
 | 
				
			||||||
 | 
												"intermediate_certificate": {
 | 
				
			||||||
 | 
													"type": "string",
 | 
				
			||||||
 | 
													"minLength": 1
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# This file assumes that the frontend has been built using ./scripts/frontend-build
 | 
					# This file assumes that the frontend has been built using ./scripts/frontend-build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM nginxproxymanager/testca AS testca
 | 
				
			||||||
 | 
					FROM letsencrypt/pebble AS pebbleca
 | 
				
			||||||
FROM nginxproxymanager/nginx-full:certbot-node
 | 
					FROM nginxproxymanager/nginx-full:certbot-node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARG TARGETPLATFORM
 | 
					ARG TARGETPLATFORM
 | 
				
			||||||
@@ -45,6 +47,8 @@ RUN yarn install \
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# add late to limit cache-busting by modifications
 | 
					# add late to limit cache-busting by modifications
 | 
				
			||||||
COPY docker/rootfs /
 | 
					COPY docker/rootfs /
 | 
				
			||||||
 | 
					COPY --from=pebbleca /test/certs/pebble.minica.pem /etc/ssl/certs/pebble.minica.pem
 | 
				
			||||||
 | 
					COPY --from=testca /home/step/certs/root_ca.crt /etc/ssl/certs/NginxProxyManager.crt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Remove frontend service not required for prod, dev nginx config as well
 | 
					# Remove frontend service not required for prod, dev nginx config as well
 | 
				
			||||||
RUN rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/frontend /etc/nginx/conf.d/dev.conf \
 | 
					RUN rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/frontend /etc/nginx/conf.d/dev.conf \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
 | 
					FROM nginxproxymanager/testca AS testca
 | 
				
			||||||
 | 
					FROM letsencrypt/pebble AS pebbleca
 | 
				
			||||||
FROM nginxproxymanager/nginx-full:certbot-node
 | 
					FROM nginxproxymanager/nginx-full:certbot-node
 | 
				
			||||||
LABEL maintainer="Jamie Curnow <jc@jc21.com>"
 | 
					LABEL maintainer="Jamie Curnow <jc@jc21.com>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# See: https://github.com/just-containers/s6-overlay/blob/master/README.md
 | 
					SHELL ["/bin/bash", "-o", "pipefail", "-c"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV SUPPRESS_NO_CONFIG_WARNING=1 \
 | 
					ENV SUPPRESS_NO_CONFIG_WARNING=1 \
 | 
				
			||||||
	S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \
 | 
						S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \
 | 
				
			||||||
	S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
 | 
						S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
 | 
				
			||||||
@@ -17,17 +20,20 @@ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
 | 
				
			|||||||
	&& rm -rf /var/lib/apt/lists/*
 | 
						&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Task
 | 
					# Task
 | 
				
			||||||
RUN cd /usr \
 | 
					WORKDIR /usr
 | 
				
			||||||
	&& curl -sL https://taskfile.dev/install.sh | sh \
 | 
					RUN curl -sL https://taskfile.dev/install.sh | sh
 | 
				
			||||||
	&& cd /root
 | 
					WORKDIR /root
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY rootfs /
 | 
					COPY rootfs /
 | 
				
			||||||
RUN rm -f /etc/nginx/conf.d/production.conf
 | 
					 | 
				
			||||||
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# s6 overlay
 | 
					 | 
				
			||||||
COPY scripts/install-s6 /tmp/install-s6
 | 
					COPY scripts/install-s6 /tmp/install-s6
 | 
				
			||||||
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
 | 
					RUN rm -f /etc/nginx/conf.d/production.conf \
 | 
				
			||||||
 | 
						&& chmod 644 /etc/logrotate.d/nginx-proxy-manager \
 | 
				
			||||||
 | 
						&& /tmp/install-s6 "${TARGETPLATFORM}" \
 | 
				
			||||||
 | 
						&& rm -f /tmp/install-s6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Certs for testing purposes
 | 
				
			||||||
 | 
					COPY --from=pebbleca /test/certs/pebble.minica.pem /etc/ssl/certs/pebble.minica.pem
 | 
				
			||||||
 | 
					COPY --from=testca /home/step/certs/root_ca.crt /etc/ssl/certs/NginxProxyManager.crt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 80 81 443
 | 
					EXPOSE 80 81 443
 | 
				
			||||||
ENTRYPOINT [ "/init" ]
 | 
					ENTRYPOINT [ "/init" ]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,9 @@ services:
 | 
				
			|||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
      DEBUG: 'true'
 | 
					      DEBUG: 'true'
 | 
				
			||||||
      FORCE_COLOR: 1
 | 
					      FORCE_COLOR: 1
 | 
				
			||||||
 | 
					      # Required for DNS Certificate provisioning in CI
 | 
				
			||||||
 | 
					      LE_SERVER: 'https://ca.internal/acme/acme/directory'
 | 
				
			||||||
 | 
					      REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt'
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - 'npm_data_ci:/data'
 | 
					      - 'npm_data_ci:/data'
 | 
				
			||||||
      - 'npm_le_ci:/etc/letsencrypt'
 | 
					      - 'npm_le_ci:/etc/letsencrypt'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
 | 
					# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  npm:
 | 
					  fullstack:
 | 
				
			||||||
    image: nginxproxymanager:dev
 | 
					    image: nginxproxymanager:dev
 | 
				
			||||||
    container_name: npm_core
 | 
					    container_name: npm_core
 | 
				
			||||||
    build:
 | 
					    build:
 | 
				
			||||||
@@ -33,12 +33,20 @@ services:
 | 
				
			|||||||
      DB_MYSQL_NAME: 'npm'
 | 
					      DB_MYSQL_NAME: 'npm'
 | 
				
			||||||
      # DB_SQLITE_FILE: "/data/database.sqlite"
 | 
					      # DB_SQLITE_FILE: "/data/database.sqlite"
 | 
				
			||||||
      # DISABLE_IPV6: "true"
 | 
					      # DISABLE_IPV6: "true"
 | 
				
			||||||
 | 
					      # Required for DNS Certificate provisioning testing:
 | 
				
			||||||
 | 
					      LE_SERVER: 'https://ca.internal/acme/acme/directory'
 | 
				
			||||||
 | 
					      REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt'
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - npm_data:/data
 | 
					      - npm_data:/data
 | 
				
			||||||
      - le_data:/etc/letsencrypt
 | 
					      - le_data:/etc/letsencrypt
 | 
				
			||||||
 | 
					      - './dev/resolv.conf:/etc/resolv.conf:ro'
 | 
				
			||||||
      - ../backend:/app
 | 
					      - ../backend:/app
 | 
				
			||||||
      - ../frontend:/app/frontend
 | 
					      - ../frontend:/app/frontend
 | 
				
			||||||
      - ../global:/app/global
 | 
					      - ../global:/app/global
 | 
				
			||||||
 | 
					    healthcheck:
 | 
				
			||||||
 | 
					      test: ["CMD", "/usr/bin/check-health"]
 | 
				
			||||||
 | 
					      interval: 10s
 | 
				
			||||||
 | 
					      timeout: 3s
 | 
				
			||||||
    depends_on:
 | 
					    depends_on:
 | 
				
			||||||
      - db
 | 
					      - db
 | 
				
			||||||
    working_dir: /app
 | 
					    working_dir: /app
 | 
				
			||||||
@@ -58,6 +66,23 @@ services:
 | 
				
			|||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - db_data:/var/lib/mysql
 | 
					      - db_data:/var/lib/mysql
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  stepca:
 | 
				
			||||||
 | 
					    image: jc21/testca
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - './dev/resolv.conf:/etc/resolv.conf:ro'
 | 
				
			||||||
 | 
					      - '/etc/localtime:/etc/localtime:ro'
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      nginx_proxy_manager:
 | 
				
			||||||
 | 
					        aliases:
 | 
				
			||||||
 | 
					          - ca.internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dnsrouter:
 | 
				
			||||||
 | 
					    image: jc21/dnsrouter
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - ./dev/dnsrouter-config.json.tmp:/dnsrouter-config.json:ro
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      - nginx_proxy_manager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  swagger:
 | 
					  swagger:
 | 
				
			||||||
    image: swaggerapi/swagger-ui:latest
 | 
					    image: swaggerapi/swagger-ui:latest
 | 
				
			||||||
    container_name: npm_swagger
 | 
					    container_name: npm_swagger
 | 
				
			||||||
@@ -67,19 +92,78 @@ services:
 | 
				
			|||||||
      URL: "http://npm:81/api/schema"
 | 
					      URL: "http://npm:81/api/schema"
 | 
				
			||||||
      PORT: '80'
 | 
					      PORT: '80'
 | 
				
			||||||
    depends_on:
 | 
					    depends_on:
 | 
				
			||||||
      - npm
 | 
					      - fullstack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  squid:
 | 
					  squid:
 | 
				
			||||||
    image: ubuntu/squid
 | 
					    image: ubuntu/squid
 | 
				
			||||||
    container_name: npm_squid
 | 
					    container_name: npm_squid
 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - './dev/squid.conf:/etc/squid/squid.conf:ro'
 | 
					      - './dev/squid.conf:/etc/squid/squid.conf:ro'
 | 
				
			||||||
 | 
					      - './dev/resolv.conf:/etc/resolv.conf:ro'
 | 
				
			||||||
      - '/etc/localtime:/etc/localtime:ro'
 | 
					      - '/etc/localtime:/etc/localtime:ro'
 | 
				
			||||||
    networks:
 | 
					    networks:
 | 
				
			||||||
      - nginx_proxy_manager
 | 
					      - nginx_proxy_manager
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - 8128:3128
 | 
					      - 8128:3128
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pdns:
 | 
				
			||||||
 | 
					    image: pschiffe/pdns-mysql
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - '/etc/localtime:/etc/localtime:ro'
 | 
				
			||||||
 | 
					    environment:
 | 
				
			||||||
 | 
					      PDNS_master: 'yes'
 | 
				
			||||||
 | 
					      PDNS_api: 'yes'
 | 
				
			||||||
 | 
					      PDNS_api_key: 'npm'
 | 
				
			||||||
 | 
					      PDNS_webserver: 'yes'
 | 
				
			||||||
 | 
					      PDNS_webserver_address: '0.0.0.0'
 | 
				
			||||||
 | 
					      PDNS_webserver_password: 'npm'
 | 
				
			||||||
 | 
					      PDNS_webserver-allow-from: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8'
 | 
				
			||||||
 | 
					      PDNS_version_string: 'anonymous'
 | 
				
			||||||
 | 
					      PDNS_default_ttl: 1500
 | 
				
			||||||
 | 
					      PDNS_allow_axfr_ips: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8'
 | 
				
			||||||
 | 
					      PDNS_gmysql_host: pdns-db
 | 
				
			||||||
 | 
					      PDNS_gmysql_port: 3306
 | 
				
			||||||
 | 
					      PDNS_gmysql_user: pdns
 | 
				
			||||||
 | 
					      PDNS_gmysql_password: pdns
 | 
				
			||||||
 | 
					      PDNS_gmysql_dbname: pdns
 | 
				
			||||||
 | 
					    depends_on:
 | 
				
			||||||
 | 
					      - pdns-db
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      nginx_proxy_manager:
 | 
				
			||||||
 | 
					        aliases:
 | 
				
			||||||
 | 
					          - ns1.pdns
 | 
				
			||||||
 | 
					          - ns2.pdns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pdns-db:
 | 
				
			||||||
 | 
					    image: mariadb
 | 
				
			||||||
 | 
					    environment:
 | 
				
			||||||
 | 
					      MYSQL_ROOT_PASSWORD: 'pdns'
 | 
				
			||||||
 | 
					      MYSQL_DATABASE: 'pdns'
 | 
				
			||||||
 | 
					      MYSQL_USER: 'pdns'
 | 
				
			||||||
 | 
					      MYSQL_PASSWORD: 'pdns'
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - 'pdns_mysql:/var/lib/mysql'
 | 
				
			||||||
 | 
					      - '/etc/localtime:/etc/localtime:ro'
 | 
				
			||||||
 | 
					      - './dev/pdns-db.sql:/docker-entrypoint-initdb.d/01_init.sql:ro'
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      - nginx_proxy_manager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cypress:
 | 
				
			||||||
 | 
					    image: "npm_dev_cypress"
 | 
				
			||||||
 | 
					    build:
 | 
				
			||||||
 | 
					      context: ../
 | 
				
			||||||
 | 
					      dockerfile: test/cypress/Dockerfile
 | 
				
			||||||
 | 
					    environment:
 | 
				
			||||||
 | 
					      HTTP_PROXY: 'squid:3128'
 | 
				
			||||||
 | 
					      HTTPS_PROXY: 'squid:3128'
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - '../test/results:/results'
 | 
				
			||||||
 | 
					      - './dev/resolv.conf:/etc/resolv.conf:ro'
 | 
				
			||||||
 | 
					      - '/etc/localtime:/etc/localtime:ro'
 | 
				
			||||||
 | 
					    command: cypress run --browser chrome --config-file=cypress/config/ci.js
 | 
				
			||||||
 | 
					    networks:
 | 
				
			||||||
 | 
					      - nginx_proxy_manager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
volumes:
 | 
					volumes:
 | 
				
			||||||
  npm_data:
 | 
					  npm_data:
 | 
				
			||||||
    name: npm_core_data
 | 
					    name: npm_core_data
 | 
				
			||||||
@@ -87,6 +171,8 @@ volumes:
 | 
				
			|||||||
    name: npm_le_data
 | 
					    name: npm_le_data
 | 
				
			||||||
  db_data:
 | 
					  db_data:
 | 
				
			||||||
    name: npm_db_data
 | 
					    name: npm_db_data
 | 
				
			||||||
 | 
					  pdns_mysql:
 | 
				
			||||||
 | 
					    name: npm_pdns_mysql
 | 
				
			||||||
 | 
					
 | 
				
			||||||
networks:
 | 
					networks:
 | 
				
			||||||
  nginx_proxy_manager:
 | 
					  nginx_proxy_manager:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,3 +15,13 @@ COMPOSE_PROJECT_NAME="npmdev"
 | 
				
			|||||||
COMPOSE_FILE="docker/docker-compose.dev.yml"
 | 
					COMPOSE_FILE="docker/docker-compose.dev.yml"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export COMPOSE_FILE COMPOSE_PROJECT_NAME
 | 
					export COMPOSE_FILE COMPOSE_PROJECT_NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# $1: container_name
 | 
				
			||||||
 | 
					get_container_ip () {
 | 
				
			||||||
 | 
						local container_name=$1
 | 
				
			||||||
 | 
						local container
 | 
				
			||||||
 | 
						local ip
 | 
				
			||||||
 | 
						container=$(docker-compose ps --all -q "${container_name}" | tail -n1)
 | 
				
			||||||
 | 
						ip=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
 | 
				
			||||||
 | 
						echo "$ip"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								scripts/cypress-dev
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								scripts/cypress-dev
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					#!/bin/bash -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 | 
				
			||||||
 | 
					. "$DIR/.common.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ensure docker-compose exists
 | 
				
			||||||
 | 
					if hash docker-compose 2>/dev/null; then
 | 
				
			||||||
 | 
						cd "${DIR}/.."
 | 
				
			||||||
 | 
						rm -rf "$DIR/../test/results"
 | 
				
			||||||
 | 
						docker-compose up --build cypress
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						echo -e "${RED}❯ docker-compose command is not available${RESET}"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
@@ -7,8 +7,43 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 | 
				
			|||||||
if hash docker-compose 2>/dev/null; then
 | 
					if hash docker-compose 2>/dev/null; then
 | 
				
			||||||
	cd "${DIR}/.."
 | 
						cd "${DIR}/.."
 | 
				
			||||||
	echo -e "${BLUE}❯ ${CYAN}Starting Dev Stack ...${RESET}"
 | 
						echo -e "${BLUE}❯ ${CYAN}Starting Dev Stack ...${RESET}"
 | 
				
			||||||
 | 
						echo -e "${BLUE}❯ $(docker-compose config)${RESET}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	docker-compose up -d --remove-orphans --force-recreate --build
 | 
						# Bring up a stack, in steps so we can inject IPs everywhere
 | 
				
			||||||
 | 
						docker-compose up -d pdns pdns-db
 | 
				
			||||||
 | 
						PDNS_IP=$(get_container_ip "pdns")
 | 
				
			||||||
 | 
						echo -e "${BLUE}❯ ${YELLOW}PDNS IP is ${PDNS_IP}${RESET}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# adjust the dnsrouter config
 | 
				
			||||||
 | 
						LOCAL_DNSROUTER_CONFIG="$DIR/../docker/dev/dnsrouter-config.json"
 | 
				
			||||||
 | 
						rm -rf "$LOCAL_DNSROUTER_CONFIG.tmp"
 | 
				
			||||||
 | 
						# IMPORTANT: changes to dnsrouter-config.json will affect this line:
 | 
				
			||||||
 | 
						jq --arg a "$PDNS_IP" '.servers[0].upstreams[1].upstream = $a' "$LOCAL_DNSROUTER_CONFIG" > "$LOCAL_DNSROUTER_CONFIG.tmp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						docker-compose up -d dnsrouter
 | 
				
			||||||
 | 
						DNSROUTER_IP=$(get_container_ip "dnsrouter")
 | 
				
			||||||
 | 
						echo -e "${BLUE}❯ ${YELLOW}DNS Router IP is ${DNSROUTER_IP}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ "${DNSROUTER_IP:-}" = "" ]; then
 | 
				
			||||||
 | 
							echo -e "${RED}❯ ERROR: DNS Router IP is not set${RESET}"
 | 
				
			||||||
 | 
							exit 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# mount the resolver
 | 
				
			||||||
 | 
						LOCAL_RESOLVE="$DIR/../docker/dev/resolv.conf"
 | 
				
			||||||
 | 
						rm -rf "${LOCAL_RESOLVE}"
 | 
				
			||||||
 | 
						printf "nameserver %s\noptions ndots:0" "${DNSROUTER_IP}" > "${LOCAL_RESOLVE}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# bring up all remaining containers, except cypress!
 | 
				
			||||||
 | 
						docker-compose up -d --remove-orphans stepca squid
 | 
				
			||||||
 | 
						docker-compose pull db
 | 
				
			||||||
 | 
						docker-compose up -d --remove-orphans --pull=never fullstack
 | 
				
			||||||
 | 
						docker-compose up -d --remove-orphans swagger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# docker-compose up -d --remove-orphans --force-recreate --build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# wait for main container to be healthy
 | 
				
			||||||
 | 
						bash "$DIR/wait-healthy" "$(docker-compose ps --all -q fullstack)" 120
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	echo ""
 | 
						echo ""
 | 
				
			||||||
	echo -e "${CYAN}Admin UI:     http://127.0.0.1:3081${RESET}"
 | 
						echo -e "${CYAN}Admin UI:     http://127.0.0.1:3081${RESET}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ module.exports = defineConfig({
 | 
				
			|||||||
			return require("../plugins/index.js")(on, config);
 | 
								return require("../plugins/index.js")(on, config);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		env: {
 | 
							env: {
 | 
				
			||||||
			swaggerBase: 'http://fullstack:81/api/schema',
 | 
								swaggerBase: '{{baseUrl}}/api/schema?ts=' + Date.now(),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		baseUrl: 'http://fullstack:81',
 | 
							baseUrl: 'http://fullstack:81',
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
const { defineConfig } = require('cypress');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = defineConfig({
 | 
					 | 
				
			||||||
	requestTimeout: 30000,
 | 
					 | 
				
			||||||
	defaultCommandTimeout: 20000,
 | 
					 | 
				
			||||||
	reporter: 'cypress-multi-reporters',
 | 
					 | 
				
			||||||
	reporterOptions: {
 | 
					 | 
				
			||||||
		configFile: 'multi-reporter.json'
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	video: false,
 | 
					 | 
				
			||||||
	videosFolder: 'results/videos',
 | 
					 | 
				
			||||||
	screenshotsFolder: 'results/screenshots',
 | 
					 | 
				
			||||||
	e2e: {
 | 
					 | 
				
			||||||
		setupNodeEvents(on, config) {
 | 
					 | 
				
			||||||
			return require("../plugins/index.js")(on, config);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		env: {
 | 
					 | 
				
			||||||
			swaggerBase: 'http://npm:81/api/schema',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		baseUrl: 'http://npm:81',
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
/// <reference types="Cypress" />
 | 
					/// <reference types="cypress" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Certificates endpoints', () => {
 | 
					describe('Certificates endpoints', () => {
 | 
				
			||||||
	let token;
 | 
						let token;
 | 
				
			||||||
 | 
						let certID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	before(() => {
 | 
						before(() => {
 | 
				
			||||||
		cy.getToken().then((tok) => {
 | 
							cy.getToken().then((tok) => {
 | 
				
			||||||
@@ -24,6 +25,54 @@ describe('Certificates endpoints', () => {
 | 
				
			|||||||
		});
 | 
							});
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						it('Custom certificate lifecycle', function() {
 | 
				
			||||||
 | 
							// Create custom cert
 | 
				
			||||||
 | 
							cy.task('backendApiPost', {
 | 
				
			||||||
 | 
								token: token,
 | 
				
			||||||
 | 
								path:  '/api/nginx/certificates',
 | 
				
			||||||
 | 
								data:  {
 | 
				
			||||||
 | 
									provider: "other",
 | 
				
			||||||
 | 
									nice_name: "Test Certificate",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}).then((data) => {
 | 
				
			||||||
 | 
								cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data);
 | 
				
			||||||
 | 
								expect(data).to.have.property('id');
 | 
				
			||||||
 | 
								certID = data.id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Upload files
 | 
				
			||||||
 | 
								cy.task('backendApiPostFiles', {
 | 
				
			||||||
 | 
									token: token,
 | 
				
			||||||
 | 
									path:  `/api/nginx/certificates/${certID}/upload`,
 | 
				
			||||||
 | 
									files:  {
 | 
				
			||||||
 | 
										certificate: 'test.example.com.pem',
 | 
				
			||||||
 | 
										certificate_key: 'test.example.com-key.pem',
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								}).then((data) => {
 | 
				
			||||||
 | 
									cy.validateSwaggerSchema('post', 200, '/nginx/certificates/{certID}/upload', data);
 | 
				
			||||||
 | 
									expect(data).to.have.property('certificate');
 | 
				
			||||||
 | 
									expect(data).to.have.property('certificate_key');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Get all certs
 | 
				
			||||||
 | 
									cy.task('backendApiGet', {
 | 
				
			||||||
 | 
										token: token,
 | 
				
			||||||
 | 
										path:  '/api/nginx/certificates?expand=owner'
 | 
				
			||||||
 | 
									}).then((data) => {
 | 
				
			||||||
 | 
										cy.validateSwaggerSchema('get', 200, '/nginx/certificates', data);
 | 
				
			||||||
 | 
										expect(data.length).to.be.greaterThan(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Delete cert
 | 
				
			||||||
 | 
										cy.task('backendApiDelete', {
 | 
				
			||||||
 | 
											token: token,
 | 
				
			||||||
 | 
											path:  `/api/nginx/certificates/${certID}`
 | 
				
			||||||
 | 
										}).then((data) => {
 | 
				
			||||||
 | 
											cy.validateSwaggerSchema('delete', 200, '/nginx/certificates/{certID}', data);
 | 
				
			||||||
 | 
											expect(data).to.be.equal(true);
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	it('Request Certificate - CVE-2024-46256/CVE-2024-46257', function() {
 | 
						it('Request Certificate - CVE-2024-46256/CVE-2024-46257', function() {
 | 
				
			||||||
		cy.task('backendApiPost', {
 | 
							cy.task('backendApiPost', {
 | 
				
			||||||
			token: token,
 | 
								token: token,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
/// <reference types="Cypress" />
 | 
					/// <reference types="cypress" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Basic API checks', () => {
 | 
					describe('Basic API checks', () => {
 | 
				
			||||||
	it('Should return a valid health payload', function () {
 | 
						it('Should return a valid health payload', function () {
 | 
				
			||||||
@@ -12,7 +12,7 @@ describe('Basic API checks', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	it('Should return a valid schema payload', function () {
 | 
						it('Should return a valid schema payload', function () {
 | 
				
			||||||
		cy.task('backendApiGet', {
 | 
							cy.task('backendApiGet', {
 | 
				
			||||||
			path: '/api/schema',
 | 
								path: '/api/schema?ts=' + Date.now(),
 | 
				
			||||||
		}).then((data) => {
 | 
							}).then((data) => {
 | 
				
			||||||
			expect(data.openapi).to.be.equal('3.1.0');
 | 
								expect(data.openapi).to.be.equal('3.1.0');
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
/// <reference types="Cypress" />
 | 
					/// <reference types="cypress" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Hosts endpoints', () => {
 | 
					describe('Hosts endpoints', () => {
 | 
				
			||||||
	let token;
 | 
						let token;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
/// <reference types="Cypress" />
 | 
					/// <reference types="cypress" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Users endpoints', () => {
 | 
					describe('Users endpoints', () => {
 | 
				
			||||||
	let token;
 | 
						let token;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,7 @@ BackendApi.prototype._handleError = function(err, resolve, reject, returnOnError
 | 
				
			|||||||
 * @returns {Promise<object>}
 | 
					 * @returns {Promise<object>}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
BackendApi.prototype.request = function (method, path, returnOnError, data) {
 | 
					BackendApi.prototype.request = function (method, path, returnOnError, data) {
 | 
				
			||||||
	logger(method.toUpperCase(), this.config.baseUrl + path);
 | 
						logger(method.toUpperCase(), path);
 | 
				
			||||||
	const options = this._prepareOptions(returnOnError);
 | 
						const options = this._prepareOptions(returnOnError);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return new Promise((resolve, reject) => {
 | 
						return new Promise((resolve, reject) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
	"description": "",
 | 
						"description": "",
 | 
				
			||||||
	"main": "index.js",
 | 
						"main": "index.js",
 | 
				
			||||||
	"dependencies": {
 | 
						"dependencies": {
 | 
				
			||||||
		"@jc21/cypress-swagger-validation": "^0.2.7",
 | 
							"@jc21/cypress-swagger-validation": "^0.3.1",
 | 
				
			||||||
		"axios": "^1.7.7",
 | 
							"axios": "^1.7.7",
 | 
				
			||||||
		"cypress": "^13.15.0",
 | 
							"cypress": "^13.15.0",
 | 
				
			||||||
		"cypress-multi-reporters": "^1.6.4",
 | 
							"cypress-multi-reporters": "^1.6.4",
 | 
				
			||||||
@@ -19,8 +19,8 @@
 | 
				
			|||||||
		"mocha-junit-reporter": "^2.2.1"
 | 
							"mocha-junit-reporter": "^2.2.1"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"scripts": {
 | 
						"scripts": {
 | 
				
			||||||
		"cypress": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress open --config-file=cypress/config/dev.js",
 | 
							"cypress": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress open --config-file=cypress/config/ci.js",
 | 
				
			||||||
		"cypress:headless": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress run --config-file=cypress/config/dev.js"
 | 
							"cypress:headless": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress run --config-file=cypress/config/ci.js"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"author": "",
 | 
						"author": "",
 | 
				
			||||||
	"license": "ISC"
 | 
						"license": "ISC"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,14 +11,13 @@
 | 
				
			|||||||
    call-me-maybe "^1.0.1"
 | 
					    call-me-maybe "^1.0.1"
 | 
				
			||||||
    js-yaml "^3.13.1"
 | 
					    js-yaml "^3.13.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@apidevtools/json-schema-ref-parser@9.0.9":
 | 
					"@apidevtools/json-schema-ref-parser@^11.7.2":
 | 
				
			||||||
  version "9.0.9"
 | 
					  version "11.7.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b"
 | 
					  resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz#cdf3e0aded21492364a70e193b45b7cf4177f031"
 | 
				
			||||||
  integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==
 | 
					  integrity sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
    "@jsdevtools/ono" "^7.1.3"
 | 
					    "@jsdevtools/ono" "^7.1.3"
 | 
				
			||||||
    "@types/json-schema" "^7.0.6"
 | 
					    "@types/json-schema" "^7.0.15"
 | 
				
			||||||
    call-me-maybe "^1.0.1"
 | 
					 | 
				
			||||||
    js-yaml "^4.1.0"
 | 
					    js-yaml "^4.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@apidevtools/openapi-schemas@^2.1.0":
 | 
					"@apidevtools/openapi-schemas@^2.1.0":
 | 
				
			||||||
@@ -167,15 +166,16 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
 | 
					  resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
 | 
				
			||||||
  integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
 | 
					  integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@jc21/cypress-swagger-validation@^0.2.7":
 | 
					"@jc21/cypress-swagger-validation@^0.3.1":
 | 
				
			||||||
  version "0.2.7"
 | 
					  version "0.3.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.2.7.tgz#64642b12d98b884df8c30b72852162941285d2af"
 | 
					  resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.3.1.tgz#1cdd49850a20f876ed62149623f99988264751be"
 | 
				
			||||||
  integrity sha512-4EQ0gfigRwVVl3DnVYbR48/EKGnn7oH5YYdMzf6zqypO+bqYvDHu9kgk/WqkGlT/aauGQ7e0YGMo8ZvR7mL0Ng==
 | 
					  integrity sha512-Vdt1gLfj8p0tJhA42Cfn43XBbsKocNfVCEVSwkn7RmZgWUyRKjqhBBRTVa9cKZTozyg8Co/yhBMsNyjmHFVXtQ==
 | 
				
			||||||
  dependencies:
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    "@apidevtools/json-schema-ref-parser" "^11.7.2"
 | 
				
			||||||
    "@apidevtools/swagger-parser" "^10.1.0"
 | 
					    "@apidevtools/swagger-parser" "^10.1.0"
 | 
				
			||||||
    ajv "^8.17.1"
 | 
					    ajv "^8.17.1"
 | 
				
			||||||
 | 
					    axios "^1.7.7"
 | 
				
			||||||
    json-schema "^0.4.0"
 | 
					    json-schema "^0.4.0"
 | 
				
			||||||
    json-schema-ref-parser "^9.0.9"
 | 
					 | 
				
			||||||
    jsonpath "^1.1.1"
 | 
					    jsonpath "^1.1.1"
 | 
				
			||||||
    lodash "^4.17.21"
 | 
					    lodash "^4.17.21"
 | 
				
			||||||
    openapi-types "^12.1.3"
 | 
					    openapi-types "^12.1.3"
 | 
				
			||||||
@@ -196,7 +196,7 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
 | 
					  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
 | 
				
			||||||
  integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
 | 
					  integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@types/json-schema@^7.0.15", "@types/json-schema@^7.0.6":
 | 
					"@types/json-schema@^7.0.15":
 | 
				
			||||||
  version "7.0.15"
 | 
					  version "7.0.15"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
 | 
					  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
 | 
				
			||||||
  integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
 | 
					  integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
 | 
				
			||||||
@@ -1468,13 +1468,6 @@ json-buffer@3.0.1:
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
 | 
					  resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
 | 
				
			||||||
  integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
 | 
					  integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
json-schema-ref-parser@^9.0.9:
 | 
					 | 
				
			||||||
  version "9.0.9"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#66ea538e7450b12af342fa3d5b8458bc1e1e013f"
 | 
					 | 
				
			||||||
  integrity sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    "@apidevtools/json-schema-ref-parser" "9.0.9"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
json-schema-traverse@^0.4.1:
 | 
					json-schema-traverse@^0.4.1:
 | 
				
			||||||
  version "0.4.1"
 | 
					  version "0.4.1"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
 | 
					  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user