mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-06-18 02:06:25 +00:00
Compare commits
15 Commits
b0b234ff7d
...
v2.12.1
Author | SHA1 | Date | |
---|---|---|---|
5084cb7296 | |||
2f9e062718 | |||
edbed1af90 | |||
8497022e41 | |||
fa2c814fcb | |||
d96a3987c0 | |||
e677bfa2e8 | |||
fe2d8895d6 | |||
5bdc05878f | |||
929ac3bd7c | |||
f48e1b46a8 | |||
351ba8dacd | |||
3b89d5f380 | |||
e5aa880ec4 | |||
7322d35bd7 |
19
Jenkinsfile
vendored
19
Jenkinsfile
vendored
@ -127,6 +127,11 @@ pipeline {
|
||||
junit 'test/results/junit/*'
|
||||
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
|
||||
}
|
||||
unstable {
|
||||
dir(path: 'testing/results') {
|
||||
archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Test Mysql') {
|
||||
@ -155,6 +160,11 @@ pipeline {
|
||||
junit 'test/results/junit/*'
|
||||
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
|
||||
}
|
||||
unstable {
|
||||
dir(path: 'testing/results') {
|
||||
archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('MultiArch Build') {
|
||||
@ -204,20 +214,13 @@ pipeline {
|
||||
always {
|
||||
sh 'echo Reverting ownership'
|
||||
sh 'docker run --rm -v "$(pwd):/data" jc21/ci-tools chown -R "$(id -u):$(id -g)" /data'
|
||||
}
|
||||
success {
|
||||
juxtapose event: 'success'
|
||||
sh 'figlet "SUCCESS"'
|
||||
printResult(true)
|
||||
}
|
||||
failure {
|
||||
archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true)
|
||||
juxtapose event: 'failure'
|
||||
sh 'figlet "FAILURE"'
|
||||
}
|
||||
unstable {
|
||||
archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true)
|
||||
juxtapose event: 'unstable'
|
||||
sh 'figlet "UNSTABLE"'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<p align="center">
|
||||
<img src="https://nginxproxymanager.com/github.png">
|
||||
<br><br>
|
||||
<img src="https://img.shields.io/badge/version-2.12.0-green.svg?style=for-the-badge">
|
||||
<img src="https://img.shields.io/badge/version-2.12.1-green.svg?style=for-the-badge">
|
||||
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
||||
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
||||
</a>
|
||||
|
@ -9,22 +9,6 @@ function generateDbConfig() {
|
||||
if (cfg.engine === 'knex-native') {
|
||||
return cfg.knex;
|
||||
}
|
||||
if (cfg.engine === 'pg') {
|
||||
|
||||
return {
|
||||
client: cfg.engine,
|
||||
connection: {
|
||||
host: cfg.host,
|
||||
user: cfg.user,
|
||||
password: cfg.password,
|
||||
database: cfg.name,
|
||||
port: cfg.port
|
||||
},
|
||||
migrations: {
|
||||
tableName: 'migrations'
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
client: cfg.engine,
|
||||
connection: {
|
||||
|
@ -3,27 +3,29 @@ const fs = require('fs');
|
||||
const https = require('https');
|
||||
const tempWrite = require('temp-write');
|
||||
const moment = require('moment');
|
||||
const archiver = require('archiver');
|
||||
const path = require('path');
|
||||
const { isArray } = require('lodash');
|
||||
const logger = require('../logger').ssl;
|
||||
const config = require('../lib/config');
|
||||
const error = require('../lib/error');
|
||||
const utils = require('../lib/utils');
|
||||
const certbot = require('../lib/certbot');
|
||||
const certificateModel = require('../models/certificate');
|
||||
const tokenModel = require('../models/token');
|
||||
const dnsPlugins = require('../global/certbot-dns-plugins.json');
|
||||
const internalAuditLog = require('./audit-log');
|
||||
const internalNginx = require('./nginx');
|
||||
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 letsencryptServer = config.useLetsencryptServer();
|
||||
const letsencryptConfig = '/etc/letsencrypt.ini';
|
||||
const certbotCommand = 'certbot';
|
||||
|
||||
function omissions() {
|
||||
return ['is_deleted'];
|
||||
return ['is_deleted', 'owner.is_deleted'];
|
||||
}
|
||||
|
||||
const internalCertificate = {
|
||||
@ -207,6 +209,7 @@ const internalCertificate = {
|
||||
.patchAndFetchById(certificate.id, {
|
||||
expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss')
|
||||
})
|
||||
.then(utils.omitRow(omissions()))
|
||||
.then((saved_row) => {
|
||||
// Add cert data for audit log
|
||||
saved_row.meta = _.assign({}, saved_row.meta, {
|
||||
@ -730,29 +733,29 @@ const internalCertificate = {
|
||||
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
|
||||
.then((result) => {
|
||||
// Examples:
|
||||
// subject=CN = *.jc21.com
|
||||
// subject=CN = something.example.com
|
||||
const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
||||
const match = regex.exec(result);
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine subject from certificate: ' + result);
|
||||
}
|
||||
|
||||
if (match && typeof match[1] !== 'undefined') {
|
||||
certData['cn'] = match[1];
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
|
||||
})
|
||||
|
||||
.then((result) => {
|
||||
// Examples:
|
||||
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
||||
// issuer=C = US, O = Let's Encrypt, CN = E5
|
||||
// issuer=O = NginxProxyManager, CN = NginxProxyManager Intermediate CA","O = NginxProxyManager, CN = NginxProxyManager Intermediate CA
|
||||
const regex = /^(?:issuer=)?(.*)$/gim;
|
||||
const match = regex.exec(result);
|
||||
|
||||
if (typeof match[1] === 'undefined') {
|
||||
throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
|
||||
}
|
||||
|
||||
if (match && typeof match[1] !== 'undefined') {
|
||||
certData['issuer'] = match[1];
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
|
||||
@ -827,17 +830,18 @@ const internalCertificate = {
|
||||
requestLetsEncryptSsl: (certificate) => {
|
||||
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const cmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
const cmd = `${certbotCommand} certonly ` +
|
||||
`--config '${letsencryptConfig}' ` +
|
||||
'--work-dir "/tmp/letsencrypt-lib" ' +
|
||||
'--logs-dir "/tmp/letsencrypt-log" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
`--cert-name "npm-${certificate.id}" ` +
|
||||
'--agree-tos ' +
|
||||
'--authenticator webroot ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
`--email '${certificate.meta.letsencrypt_email}' ` +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
`--domains "${certificate.domain_names.join(',')}" ` +
|
||||
(letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') +
|
||||
(letsencryptStaging && letsencryptServer === null ? '--staging ' : '');
|
||||
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
@ -868,25 +872,26 @@ const internalCertificate = {
|
||||
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
|
||||
|
||||
let mainCmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
`--config '${letsencryptConfig}' ` +
|
||||
'--work-dir "/tmp/letsencrypt-lib" ' +
|
||||
'--logs-dir "/tmp/letsencrypt-log" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
`--cert-name 'npm-${certificate.id}' ` +
|
||||
'--agree-tos ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
'--authenticator ' + dnsPlugin.full_plugin_name + ' ' +
|
||||
`--email '${certificate.meta.letsencrypt_email}' ` +
|
||||
`--domains '${certificate.domain_names.join(',')}' ` +
|
||||
`--authenticator '${dnsPlugin.full_plugin_name}' ` +
|
||||
(
|
||||
hasConfigArg
|
||||
? '--' + dnsPlugin.full_plugin_name + '-credentials "' + credentialsLocation + '"'
|
||||
? `--${dnsPlugin.full_plugin_name}-credentials '${credentialsLocation}' `
|
||||
: ''
|
||||
) +
|
||||
(
|
||||
certificate.meta.propagation_seconds !== undefined
|
||||
? ' --' + dnsPlugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||
? `--${dnsPlugin.full_plugin_name}-propagation-seconds '${certificate.meta.propagation_seconds}' `
|
||||
: ''
|
||||
) +
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
(letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') +
|
||||
(letsencryptStaging && letsencryptServer === null ? '--staging ' : '');
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
@ -963,14 +968,15 @@ const internalCertificate = {
|
||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const cmd = certbotCommand + ' renew --force-renewal ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
`--config '${letsencryptConfig}' ` +
|
||||
'--work-dir "/tmp/letsencrypt-lib" ' +
|
||||
'--logs-dir "/tmp/letsencrypt-log" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
`--cert-name 'npm-${certificate.id}' ` +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
'--disable-hook-validation ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
(letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') +
|
||||
(letsencryptStaging && letsencryptServer === null ? '--staging ' : '');
|
||||
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
@ -995,13 +1001,14 @@ const internalCertificate = {
|
||||
logger.info(`Renewing Let'sEncrypt certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||
|
||||
let mainCmd = certbotCommand + ' renew --force-renewal ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
`--config "${letsencryptConfig}" ` +
|
||||
'--work-dir "/tmp/letsencrypt-lib" ' +
|
||||
'--logs-dir "/tmp/letsencrypt-log" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
`--cert-name 'npm-${certificate.id}' ` +
|
||||
'--disable-hook-validation ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
(letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') +
|
||||
(letsencryptStaging && letsencryptServer === null ? '--staging ' : '');
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
@ -1027,12 +1034,13 @@ const internalCertificate = {
|
||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const mainCmd = certbotCommand + ' revoke ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
`--config '${letsencryptConfig}' ` +
|
||||
'--work-dir "/tmp/letsencrypt-lib" ' +
|
||||
'--logs-dir "/tmp/letsencrypt-log" ' +
|
||||
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||
`--cert-path '/etc/letsencrypt/live/npm-${certificate.id}/fullchain.pem' ` +
|
||||
'--delete-after-revoke ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
(letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') +
|
||||
(letsencryptStaging && letsencryptServer === null ? '--staging ' : '');
|
||||
|
||||
// Don't fail command if file does not exist
|
||||
const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||
|
@ -181,7 +181,9 @@ const internalNginx = {
|
||||
* @param {Object} host
|
||||
* @returns {Promise}
|
||||
*/
|
||||
generateConfig: (host_type, host) => {
|
||||
generateConfig: (host_type, host_row) => {
|
||||
// Prevent modifying the original object:
|
||||
let host = JSON.parse(JSON.stringify(host_row));
|
||||
const nice_host_type = internalNginx.getFileFriendlyHostType(host_type);
|
||||
|
||||
if (config.debug()) {
|
||||
|
@ -45,25 +45,6 @@ const configure = () => {
|
||||
};
|
||||
return;
|
||||
}
|
||||
const envPostgresqlHost = process.env.DB_POSTGRESQL_HOST || null;
|
||||
const envPostgresqlUser = process.env.DB_POSTGRESQL_USER || null;
|
||||
const envPostgresqlName = process.env.DB_POSTGRESQL_NAME || null;
|
||||
if (envPostgresqlHost && envPostgresqlUser && envPostgresqlName) {
|
||||
// we have enough mysql creds to go with mysql
|
||||
logger.info('Using POSTGRESQL configuration');
|
||||
instance = {
|
||||
database: {
|
||||
engine: 'pg',
|
||||
host: envPostgresqlHost,
|
||||
port: process.env.DB_POSTGRESQL_PORT || 3306,
|
||||
user: envPostgresqlUser,
|
||||
password: process.env.DB_POSTGRESQL_PASSWORD,
|
||||
name: envPostgresqlName,
|
||||
},
|
||||
keys: getKeys(),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const envSqliteFile = process.env.DB_SQLITE_FILE || '/data/database.sqlite';
|
||||
logger.info(`Using Sqlite: ${envSqliteFile}`);
|
||||
@ -199,5 +180,15 @@ module.exports = {
|
||||
*/
|
||||
useLetsencryptStaging: function () {
|
||||
return !!process.env.LE_STAGING;
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {string|null}
|
||||
*/
|
||||
useLetsencryptServer: function () {
|
||||
if (process.env.LE_SERVER) {
|
||||
return process.env.LE_SERVER;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,6 @@
|
||||
"node-rsa": "^1.0.8",
|
||||
"objection": "3.0.1",
|
||||
"path": "^0.12.7",
|
||||
"pg": "^8.13.0",
|
||||
"signale": "1.4.0",
|
||||
"sqlite3": "5.1.6",
|
||||
"temp-write": "^4.0.0"
|
||||
|
@ -24,22 +24,34 @@
|
||||
"description": "Nice Name for the custom certificate"
|
||||
},
|
||||
"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": {
|
||||
"description": "Date and time of expiration",
|
||||
"readOnly": true,
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"$ref": "./user-object.json"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"letsencrypt_email": {
|
||||
"type": "string"
|
||||
"certificate": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"letsencrypt_agree": {
|
||||
"type": "boolean"
|
||||
"certificate_key": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"dns_challenge": {
|
||||
"type": "boolean"
|
||||
@ -50,14 +62,19 @@
|
||||
"dns_provider_credentials": {
|
||||
"type": "string"
|
||||
},
|
||||
"letsencrypt_agree": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"letsencrypt_certificate": {
|
||||
"type": "object"
|
||||
},
|
||||
"letsencrypt_email": {
|
||||
"type": "string"
|
||||
},
|
||||
"propagation_seconds": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,7 @@
|
||||
"locations",
|
||||
"hsts_enabled",
|
||||
"hsts_subdomains",
|
||||
"certificate",
|
||||
"use_default_location",
|
||||
"ipv6"
|
||||
"certificate"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@ -151,12 +149,6 @@
|
||||
"$ref": "./access-list-object.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"use_default_location": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ipv6": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
},
|
||||
"forward_scheme": {
|
||||
"type": "string",
|
||||
"enum": ["http", "https"]
|
||||
"enum": ["auto", "http", "https"]
|
||||
},
|
||||
"forward_domain_name": {
|
||||
"description": "Domain Name",
|
||||
|
@ -25,7 +25,7 @@
|
||||
"value": {
|
||||
"description": "Value in almost any form",
|
||||
"example": "congratulations",
|
||||
"oneOf": [
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
@ -46,7 +46,10 @@
|
||||
},
|
||||
"meta": {
|
||||
"description": "Extra metadata",
|
||||
"example": {},
|
||||
"example": {
|
||||
"redirect": "http://example.com",
|
||||
"html": "<h1>404</h1>"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +94,7 @@
|
||||
"avatar": "",
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"certificate": null,
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
"certificate": null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -79,9 +79,7 @@
|
||||
"nickname": "Admin",
|
||||
"avatar": "",
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -129,9 +129,7 @@
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"certificate": null,
|
||||
"access_list": null,
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
"access_list": null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -114,9 +114,7 @@
|
||||
"avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm",
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"access_list": null,
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
"access_list": null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -114,9 +114,7 @@
|
||||
"avatar": "",
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"certificate": null,
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
"certificate": null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -99,9 +99,7 @@
|
||||
"nickname": "Admin",
|
||||
"avatar": "",
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -129,9 +129,7 @@
|
||||
"roles": ["admin"]
|
||||
},
|
||||
"certificate": null,
|
||||
"access_list": null,
|
||||
"use_default_location": true,
|
||||
"ipv6": true
|
||||
"access_list": null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -13,7 +13,8 @@
|
||||
"name": "settingID",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
"minLength": 1,
|
||||
"enum": ["default-site"]
|
||||
},
|
||||
"required": true,
|
||||
"description": "Setting ID",
|
||||
@ -31,10 +32,21 @@
|
||||
"minProperties": 1,
|
||||
"properties": {
|
||||
"value": {
|
||||
"$ref": "../../../components/setting-object.json#/properties/value"
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"enum": ["congratulations", "404", "444", "redirect", "html"]
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "../../../components/setting-object.json#/properties/meta"
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"redirect": {
|
||||
"type": "string"
|
||||
},
|
||||
"html": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ const certbot = require('./lib/certbot');
|
||||
const setupDefaultUser = () => {
|
||||
return userModel
|
||||
.query()
|
||||
.select('id')
|
||||
.select(userModel.raw('COUNT(`id`) as `count`'))
|
||||
.where('is_deleted', 0)
|
||||
.first()
|
||||
.then((row) => {
|
||||
if (!row.length || !row[0].id) {
|
||||
if (!row.count) {
|
||||
// Create a new user and set password
|
||||
let email = process.env.INITIAL_ADMIN_EMAIL || 'admin@example.com';
|
||||
let password = process.env.INITIAL_ADMIN_PASSWORD || 'changeme';
|
||||
@ -76,10 +77,11 @@ const setupDefaultUser = () => {
|
||||
const setupDefaultSettings = () => {
|
||||
return settingModel
|
||||
.query()
|
||||
.select('id')
|
||||
.select(settingModel.raw('COUNT(`id`) as `count`'))
|
||||
.where({id: 'default-site'})
|
||||
.first()
|
||||
.then((row) => {
|
||||
if (!row.length || !row[0].id) {
|
||||
if (!row.count) {
|
||||
settingModel
|
||||
.query()
|
||||
.insert({
|
||||
|
@ -2735,67 +2735,11 @@ path@^0.12.7:
|
||||
process "^0.11.1"
|
||||
util "^0.10.3"
|
||||
|
||||
pg-cloudflare@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98"
|
||||
integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==
|
||||
|
||||
pg-connection-string@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34"
|
||||
integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==
|
||||
|
||||
pg-connection-string@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.7.0.tgz#f1d3489e427c62ece022dba98d5262efcb168b37"
|
||||
integrity sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==
|
||||
|
||||
pg-int8@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
|
||||
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
|
||||
|
||||
pg-pool@^3.7.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.7.0.tgz#d4d3c7ad640f8c6a2245adc369bafde4ebb8cbec"
|
||||
integrity sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==
|
||||
|
||||
pg-protocol@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.7.0.tgz#ec037c87c20515372692edac8b63cf4405448a93"
|
||||
integrity sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==
|
||||
|
||||
pg-types@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
|
||||
integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
|
||||
dependencies:
|
||||
pg-int8 "1.0.1"
|
||||
postgres-array "~2.0.0"
|
||||
postgres-bytea "~1.0.0"
|
||||
postgres-date "~1.0.4"
|
||||
postgres-interval "^1.1.0"
|
||||
|
||||
pg@^8.13.0:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-8.13.0.tgz#e3d245342eb0158112553fcc1890a60720ae2a3d"
|
||||
integrity sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw==
|
||||
dependencies:
|
||||
pg-connection-string "^2.7.0"
|
||||
pg-pool "^3.7.0"
|
||||
pg-protocol "^1.7.0"
|
||||
pg-types "^2.1.0"
|
||||
pgpass "1.x"
|
||||
optionalDependencies:
|
||||
pg-cloudflare "^1.1.1"
|
||||
|
||||
pgpass@1.x:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d"
|
||||
integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==
|
||||
dependencies:
|
||||
split2 "^4.1.0"
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
@ -2814,28 +2758,6 @@ pkg-conf@^2.1.0:
|
||||
find-up "^2.0.0"
|
||||
load-json-file "^4.0.0"
|
||||
|
||||
postgres-array@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
|
||||
|
||||
postgres-bytea@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
|
||||
integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==
|
||||
|
||||
postgres-date@~1.0.4:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8"
|
||||
integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==
|
||||
|
||||
postgres-interval@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
|
||||
integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
|
||||
dependencies:
|
||||
xtend "^4.0.0"
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
@ -3272,11 +3194,6 @@ socks@^2.6.2:
|
||||
ip "^2.0.0"
|
||||
smart-buffer "^4.2.0"
|
||||
|
||||
split2@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4"
|
||||
integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -3748,11 +3665,6 @@ xdg-basedir@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
|
||||
|
||||
xtend@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
# 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
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
@ -45,6 +47,8 @@ RUN yarn install \
|
||||
|
||||
# add late to limit cache-busting by modifications
|
||||
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
|
||||
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
|
||||
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 \
|
||||
S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \
|
||||
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
|
||||
@ -17,18 +20,20 @@ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Task
|
||||
RUN cd /usr \
|
||||
&& curl -sL https://taskfile.dev/install.sh | sh \
|
||||
&& cd /root
|
||||
WORKDIR /usr
|
||||
RUN curl -sL https://taskfile.dev/install.sh | sh
|
||||
WORKDIR /root
|
||||
|
||||
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
|
||||
RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6
|
||||
RUN chmod 644 -R /root/.cache
|
||||
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
|
||||
ENTRYPOINT [ "/init" ]
|
||||
|
@ -1,29 +0,0 @@
|
||||
# WARNING: This is a CI docker-compose file used for building and testing of the entire app, it should not be used for production.
|
||||
services:
|
||||
|
||||
fullstack:
|
||||
environment:
|
||||
DB_POSTGRESQL_HOST: 'db'
|
||||
DB_POSTGRESQL_PORT: '5432'
|
||||
DB_POSTGRESQL_USER: 'npm'
|
||||
DB_POSTGRESQL_PASSWORD: 'npmpass'
|
||||
DB_POSTGRESQL_NAME: 'npm'
|
||||
depends_on:
|
||||
- db-postgresql
|
||||
|
||||
db-postgresql:
|
||||
image: postgres:14.2-alpine
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "npmpass"
|
||||
POSTGRES_USER: "npm"
|
||||
POSTGRES_DB: "npm"
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- postgres_vol:/var/lib/postgresql/data
|
||||
networks:
|
||||
- fulltest
|
||||
|
||||
|
||||
volumes:
|
||||
postgres_vol:
|
@ -9,6 +9,9 @@ services:
|
||||
environment:
|
||||
DEBUG: 'true'
|
||||
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:
|
||||
- 'npm_data_ci:/data'
|
||||
- 'npm_le_ci:/etc/letsencrypt'
|
||||
|
@ -1,7 +1,7 @@
|
||||
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
|
||||
services:
|
||||
|
||||
npm:
|
||||
fullstack:
|
||||
image: nginxproxymanager:dev
|
||||
container_name: npm_core
|
||||
build:
|
||||
@ -33,12 +33,20 @@ services:
|
||||
DB_MYSQL_NAME: 'npm'
|
||||
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||
# 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:
|
||||
- npm_data:/data
|
||||
- le_data:/etc/letsencrypt
|
||||
- './dev/resolv.conf:/etc/resolv.conf:ro'
|
||||
- ../backend:/app
|
||||
- ../frontend:/app/frontend
|
||||
- ../global:/app/global
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/bin/check-health"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
depends_on:
|
||||
- db
|
||||
working_dir: /app
|
||||
@ -58,6 +66,23 @@ services:
|
||||
volumes:
|
||||
- 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:
|
||||
image: swaggerapi/swagger-ui:latest
|
||||
container_name: npm_swagger
|
||||
@ -67,19 +92,78 @@ services:
|
||||
URL: "http://npm:81/api/schema"
|
||||
PORT: '80'
|
||||
depends_on:
|
||||
- npm
|
||||
- fullstack
|
||||
|
||||
squid:
|
||||
image: ubuntu/squid
|
||||
container_name: npm_squid
|
||||
volumes:
|
||||
- './dev/squid.conf:/etc/squid/squid.conf:ro'
|
||||
- './dev/resolv.conf:/etc/resolv.conf:ro'
|
||||
- '/etc/localtime:/etc/localtime:ro'
|
||||
networks:
|
||||
- nginx_proxy_manager
|
||||
ports:
|
||||
- 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:
|
||||
npm_data:
|
||||
name: npm_core_data
|
||||
@ -87,6 +171,8 @@ volumes:
|
||||
name: npm_le_data
|
||||
db_data:
|
||||
name: npm_db_data
|
||||
pdns_mysql:
|
||||
name: npm_pdns_mysql
|
||||
|
||||
networks:
|
||||
nginx_proxy_manager:
|
||||
|
@ -1,91 +0,0 @@
|
||||
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
|
||||
services:
|
||||
|
||||
npm:
|
||||
image: nginxproxymanager:dev
|
||||
container_name: npm_core
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./dev/Dockerfile
|
||||
ports:
|
||||
- 3080:80
|
||||
- 3081:81
|
||||
- 3443:443
|
||||
networks:
|
||||
- nginx_proxy_manager
|
||||
environment:
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
FORCE_COLOR: 1
|
||||
# specifically for dev:
|
||||
DEBUG: 'true'
|
||||
DEVELOPMENT: 'true'
|
||||
LE_STAGING: 'true'
|
||||
# db:
|
||||
DB_POSTGRESQL_HOST: 'db'
|
||||
DB_POSTGRESQL_PORT: '5432'
|
||||
DB_POSTGRESQL_USER: 'npm'
|
||||
DB_POSTGRESQL_PASSWORD: 'npmpass'
|
||||
DB_POSTGRESQL_NAME: 'npm'
|
||||
# DB_SQLITE_FILE: "/data/database.sqlite"
|
||||
# DISABLE_IPV6: "true"
|
||||
volumes:
|
||||
- npm_data:/data
|
||||
- le_data:/etc/letsencrypt
|
||||
- ../backend:/app
|
||||
- ../frontend:/app/frontend
|
||||
- ../global:/app/global
|
||||
depends_on:
|
||||
- db
|
||||
working_dir: /app
|
||||
|
||||
db:
|
||||
image: postgres:14.2-alpine
|
||||
container_name: npm_db
|
||||
ports:
|
||||
- 5432:5432
|
||||
networks:
|
||||
- nginx_proxy_manager
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "npmpass"
|
||||
POSTGRES_USER: "npm"
|
||||
POSTGRES_DB: "npm"
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: "admin@example.com"
|
||||
PGADMIN_DEFAULT_PASSWORD: "changeme"
|
||||
ports:
|
||||
- 5080:80
|
||||
networks:
|
||||
- nginx_proxy_manager
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
|
||||
swagger:
|
||||
image: swaggerapi/swagger-ui:latest
|
||||
container_name: npm_swagger
|
||||
ports:
|
||||
- 3082:80
|
||||
environment:
|
||||
URL: "http://npm:81/api/schema"
|
||||
PORT: '80'
|
||||
depends_on:
|
||||
- npm
|
||||
|
||||
volumes:
|
||||
npm_data:
|
||||
name: npm_core_data
|
||||
le_data:
|
||||
name: npm_le_data
|
||||
db_data:
|
||||
name: npm_db_data
|
||||
db_data1:
|
||||
name: npm_db_data1
|
||||
|
||||
networks:
|
||||
nginx_proxy_manager:
|
||||
name: npm_network
|
@ -492,7 +492,7 @@
|
||||
"package_name": "certbot-dns-wedos",
|
||||
"version": "~=2.2",
|
||||
"dependencies": "",
|
||||
"credentials": "dns_wedos_user = <wedos_registration>\ndns_wedos_auth = <wapi_sha256_password>",
|
||||
"credentials": "dns_wedos_user = <wedos_registration>\ndns_wedos_auth = <wapi_password>",
|
||||
"full_plugin_name": "dns-wedos"
|
||||
},
|
||||
"edgedns": {
|
||||
|
@ -15,3 +15,13 @@ COMPOSE_PROJECT_NAME="npmdev"
|
||||
COMPOSE_FILE="docker/docker-compose.dev.yml"
|
||||
|
||||
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"
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ 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
|
||||
docker-compose up -d --remove-orphans stepca squid
|
||||
docker-compose pull db-mysql || true # ok to fail
|
||||
docker-compose up -d --remove-orphans --pull=never fullstack
|
||||
|
||||
|
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
|
||||
cd "${DIR}/.."
|
||||
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 -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);
|
||||
},
|
||||
env: {
|
||||
swaggerBase: 'http://fullstack:81/api/schema',
|
||||
swaggerBase: '{{baseUrl}}/api/schema?ts=' + Date.now(),
|
||||
},
|
||||
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', () => {
|
||||
let token;
|
||||
let certID;
|
||||
|
||||
before(() => {
|
||||
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() {
|
||||
cy.task('backendApiPost', {
|
||||
token: token,
|
||||
|
62
test/cypress/e2e/api/FullCertProvision.cy.js
Normal file
62
test/cypress/e2e/api/FullCertProvision.cy.js
Normal file
@ -0,0 +1,62 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Full Certificate Provisions', () => {
|
||||
let token;
|
||||
|
||||
before(() => {
|
||||
cy.getToken().then((tok) => {
|
||||
token = tok;
|
||||
});
|
||||
});
|
||||
|
||||
it('Should be able to create new http certificate', function() {
|
||||
cy.task('backendApiPost', {
|
||||
token: token,
|
||||
path: '/api/nginx/certificates',
|
||||
data: {
|
||||
domain_names: [
|
||||
'website1.example.com'
|
||||
],
|
||||
meta: {
|
||||
letsencrypt_email: 'admin@example.com',
|
||||
letsencrypt_agree: true,
|
||||
dns_challenge: false
|
||||
},
|
||||
provider: 'letsencrypt'
|
||||
}
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.greaterThan(0);
|
||||
expect(data.provider).to.be.equal('letsencrypt');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should be able to create new DNS certificate with Powerdns', function() {
|
||||
cy.task('backendApiPost', {
|
||||
token: token,
|
||||
path: '/api/nginx/certificates',
|
||||
data: {
|
||||
domain_names: [
|
||||
'website2.example.com'
|
||||
],
|
||||
meta: {
|
||||
letsencrypt_email: "admin@example.com",
|
||||
dns_challenge: true,
|
||||
dns_provider: 'powerdns',
|
||||
dns_provider_credentials: 'dns_powerdns_api_url = http://ns1.pdns:8081\r\ndns_powerdns_api_key = npm',
|
||||
letsencrypt_agree: true,
|
||||
propagation_seconds: 5,
|
||||
},
|
||||
provider: 'letsencrypt'
|
||||
}
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.greaterThan(0);
|
||||
expect(data.provider).to.be.equal('letsencrypt');
|
||||
expect(data.meta.dns_provider).to.be.equal('powerdns');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
/// <reference types="Cypress" />
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Basic API checks', () => {
|
||||
it('Should return a valid health payload', function () {
|
||||
@ -12,7 +12,7 @@ describe('Basic API checks', () => {
|
||||
|
||||
it('Should return a valid schema payload', function () {
|
||||
cy.task('backendApiGet', {
|
||||
path: '/api/schema',
|
||||
path: '/api/schema?ts=' + Date.now(),
|
||||
}).then((data) => {
|
||||
expect(data.openapi).to.be.equal('3.1.0');
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
/// <reference types="Cypress" />
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Hosts endpoints', () => {
|
||||
describe('Proxy Hosts endpoints', () => {
|
||||
let token;
|
||||
|
||||
before(() => {
|
124
test/cypress/e2e/api/Settings.cy.js
Normal file
124
test/cypress/e2e/api/Settings.cy.js
Normal file
@ -0,0 +1,124 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Settings endpoints', () => {
|
||||
let token;
|
||||
|
||||
before(() => {
|
||||
cy.getToken().then((tok) => {
|
||||
token = tok;
|
||||
});
|
||||
});
|
||||
|
||||
it('Get all settings', function() {
|
||||
cy.task('backendApiGet', {
|
||||
token: token,
|
||||
path: '/api/settings',
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('get', 200, '/settings', data);
|
||||
expect(data.length).to.be.greaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Get default-site setting', function() {
|
||||
cy.task('backendApiGet', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('get', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
});
|
||||
});
|
||||
|
||||
it('Default Site congratulations', function() {
|
||||
cy.task('backendApiPut', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
data: {
|
||||
value: 'congratulations',
|
||||
},
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
expect(data).to.have.property('value');
|
||||
expect(data.value).to.be.equal('congratulations');
|
||||
});
|
||||
});
|
||||
|
||||
it('Default Site 404', function() {
|
||||
cy.task('backendApiPut', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
data: {
|
||||
value: '404',
|
||||
},
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
expect(data).to.have.property('value');
|
||||
expect(data.value).to.be.equal('404');
|
||||
});
|
||||
});
|
||||
|
||||
it('Default Site 444', function() {
|
||||
cy.task('backendApiPut', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
data: {
|
||||
value: '444',
|
||||
},
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
expect(data).to.have.property('value');
|
||||
expect(data.value).to.be.equal('444');
|
||||
});
|
||||
});
|
||||
|
||||
it('Default Site redirect', function() {
|
||||
cy.task('backendApiPut', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
data: {
|
||||
value: 'redirect',
|
||||
meta: {
|
||||
redirect: 'https://www.google.com',
|
||||
},
|
||||
},
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
expect(data).to.have.property('value');
|
||||
expect(data.value).to.be.equal('redirect');
|
||||
expect(data).to.have.property('meta');
|
||||
expect(data.meta).to.have.property('redirect');
|
||||
expect(data.meta.redirect).to.be.equal('https://www.google.com');
|
||||
});
|
||||
});
|
||||
|
||||
it('Default Site html', function() {
|
||||
cy.task('backendApiPut', {
|
||||
token: token,
|
||||
path: '/api/settings/default-site',
|
||||
data: {
|
||||
value: 'html',
|
||||
meta: {
|
||||
html: '<p>hello world</p>'
|
||||
},
|
||||
},
|
||||
}).then((data) => {
|
||||
cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data);
|
||||
expect(data).to.have.property('id');
|
||||
expect(data.id).to.be.equal('default-site');
|
||||
expect(data).to.have.property('value');
|
||||
expect(data.value).to.be.equal('html');
|
||||
expect(data).to.have.property('meta');
|
||||
expect(data.meta).to.have.property('html');
|
||||
expect(data.meta.html).to.be.equal('<p>hello world</p>');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
/// <reference types="Cypress" />
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Users endpoints', () => {
|
||||
let token;
|
||||
|
@ -7,7 +7,7 @@ const BackendApi = function(config, token) {
|
||||
|
||||
this.axios = axios.create({
|
||||
baseURL: config.baseUrl,
|
||||
timeout: 5000,
|
||||
timeout: 90000,
|
||||
});
|
||||
};
|
||||
|
||||
@ -80,7 +80,7 @@ BackendApi.prototype._handleError = function(err, resolve, reject, returnOnError
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
BackendApi.prototype.request = function (method, path, returnOnError, data) {
|
||||
logger(method.toUpperCase(), this.config.baseUrl + path);
|
||||
logger(method.toUpperCase(), path);
|
||||
const options = this._prepareOptions(returnOnError);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@jc21/cypress-swagger-validation": "^0.2.7",
|
||||
"@jc21/cypress-swagger-validation": "^0.3.1",
|
||||
"axios": "^1.7.7",
|
||||
"cypress": "^13.15.0",
|
||||
"cypress-multi-reporters": "^1.6.4",
|
||||
@ -19,8 +19,8 @@
|
||||
"mocha-junit-reporter": "^2.2.1"
|
||||
},
|
||||
"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:headless": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress run --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/ci.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
|
@ -11,14 +11,13 @@
|
||||
call-me-maybe "^1.0.1"
|
||||
js-yaml "^3.13.1"
|
||||
|
||||
"@apidevtools/json-schema-ref-parser@9.0.9":
|
||||
version "9.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b"
|
||||
integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==
|
||||
"@apidevtools/json-schema-ref-parser@^11.7.2":
|
||||
version "11.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz#cdf3e0aded21492364a70e193b45b7cf4177f031"
|
||||
integrity sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==
|
||||
dependencies:
|
||||
"@jsdevtools/ono" "^7.1.3"
|
||||
"@types/json-schema" "^7.0.6"
|
||||
call-me-maybe "^1.0.1"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
js-yaml "^4.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"
|
||||
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
|
||||
|
||||
"@jc21/cypress-swagger-validation@^0.2.7":
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.2.7.tgz#64642b12d98b884df8c30b72852162941285d2af"
|
||||
integrity sha512-4EQ0gfigRwVVl3DnVYbR48/EKGnn7oH5YYdMzf6zqypO+bqYvDHu9kgk/WqkGlT/aauGQ7e0YGMo8ZvR7mL0Ng==
|
||||
"@jc21/cypress-swagger-validation@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.3.1.tgz#1cdd49850a20f876ed62149623f99988264751be"
|
||||
integrity sha512-Vdt1gLfj8p0tJhA42Cfn43XBbsKocNfVCEVSwkn7RmZgWUyRKjqhBBRTVa9cKZTozyg8Co/yhBMsNyjmHFVXtQ==
|
||||
dependencies:
|
||||
"@apidevtools/json-schema-ref-parser" "^11.7.2"
|
||||
"@apidevtools/swagger-parser" "^10.1.0"
|
||||
ajv "^8.17.1"
|
||||
axios "^1.7.7"
|
||||
json-schema "^0.4.0"
|
||||
json-schema-ref-parser "^9.0.9"
|
||||
jsonpath "^1.1.1"
|
||||
lodash "^4.17.21"
|
||||
openapi-types "^12.1.3"
|
||||
@ -196,7 +196,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
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"
|
||||
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:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
|
Reference in New Issue
Block a user