diff --git a/Dockerfile b/Dockerfile index 986a96d5..1090a22d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,10 +29,10 @@ RUN apk upgrade --no-cache -a && \ apk add --no-cache ca-certificates nodejs yarn file && \ yarn global add clean-modules && \ if [ "$TARGETARCH" = "amd64" ]; then \ - npm_config_target_platform=linux npm_config_target_arch=x64 yarn install --no-lockfile && \ + npm_config_arch=x64 npm_config_target_arch=x64 yarn install --no-lockfile && \ for file in $(find /app/node_modules -name "*.node" -type f -exec file {} \; | grep -v "x86-64\|x86_64" | grep "aarch64\|arm64" | sed "s|\([^:]\):.*|\1|g"); do rm -v "$file"; done; \ elif [ "$TARGETARCH" = "arm64" ]; then \ - npm_config_target_platform=linux npm_config_target_arch=arm64 yarn install --no-lockfile && \ + npm_config_arch=arm64 npm_config_target_arch=arm64 yarn install --no-lockfile && \ for file in $(find /app/node_modules -name "*.node" -type f -exec file {} \; | grep -v "aarch64\|arm64" | grep "x86-64\|x86_64" | sed "s|\([^:]\):.*|\1|g"); do rm -v "$file"; done; \ fi && \ yarn cache clean --all && \ @@ -67,11 +67,11 @@ RUN apk upgrade --no-cache -a && \ sed -i "s|BOUNCING_ON_TYPE=all|BOUNCING_ON_TYPE=ban|g" /src/crowdsec-nginx-bouncer/lua-mod/config_example.conf -FROM zoeyvid/nginx-quic:296-python +FROM zoeyvid/nginx-quic:297-python SHELL ["/bin/ash", "-eo", "pipefail", "-c"] COPY rootfs / COPY --from=zoeyvid/certbot-docker:43 /usr/local /usr/local -COPY --from=zoeyvid/curl-quic:397 /usr/local/bin/curl /usr/local/bin/curl +COPY --from=zoeyvid/curl-quic:399 /usr/local/bin/curl /usr/local/bin/curl ARG CRS_VER=v4.4.0 RUN apk upgrade --no-cache -a && \ @@ -138,6 +138,7 @@ ENV PUID=0 \ NGINX_LOG_NOT_FOUND=false \ NGINX_404_REDIRECT=false \ NGINX_DISABLE_PROXY_BUFFERING=false \ + DISABLE_NGINX_BEAUTIFIER=false \ CLEAN=true \ FULLCLEAN=false \ SKIP_IP_RANGES=false \ diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 4ad0fe44..298f06e9 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -806,9 +806,8 @@ const internalCertificate = { logger.info(`Requesting Certbot certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); const credentialsLocation = '/data/tls/certbot/credentials/credentials-' + certificate.id; - // Escape single quotes and backslashes - const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll("'", "\\'").replaceAll('\\', '\\\\'); - const credentialsCmd = `echo '${escapedCredentials}' | tee '${credentialsLocation}'`; + fs.mkdirSync('/data/tls/certbot/credentials', { recursive: true }); + fs.writeFileSync(credentialsLocation, certificate.meta.dns_provider_credentials, { mode: 0o600 }); let mainCmd = certbotCommand + ' certonly ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--domains "' + certificate.domain_names.join(',') + '" ' + '--authenticator ' + dnsPlugin.full_plugin_name + ' ' + '--' + dnsPlugin.full_plugin_name + '-credentials "' + credentialsLocation + '"' + (certificate.meta.propagation_seconds !== undefined ? ' --' + dnsPlugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds : ''); @@ -818,17 +817,15 @@ const internalCertificate = { mainCmd = mainCmd + ' --email "' + certificate.meta.letsencrypt_email + '" '; } - logger.info('Command:', `${credentialsCmd} && ${mainCmd}`); + logger.info('Command:', mainCmd); try { - await utils.exec(credentialsCmd); const result = await utils.exec(mainCmd); logger.info(result); return result; } catch (err) { - // Don't fail if file does not exist - const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`; - await utils.exec(delete_credentialsCmd); + // Don't fail if file does not exist, so no need for action in the callback + fs.unlink(credentialsLocation, () => {}); throw err; } }, diff --git a/backend/lib/access.js b/backend/lib/access.js index fe5715bf..5cd8d426 100644 --- a/backend/lib/access.js +++ b/backend/lib/access.js @@ -10,7 +10,6 @@ const _ = require('lodash'); const logger = require('../logger').access; -const validator = require('ajv'); const error = require('./error'); const userModel = require('../models/user'); const proxyHostModel = require('../models/proxy_host'); @@ -18,6 +17,9 @@ const TokenModel = require('../models/token'); const roleSchema = require('./access/roles.json'); const permsSchema = require('./access/permissions.json'); +const Ajv = require('ajv'); +const addFormats = require('ajv-formats'); + module.exports = function (token_string) { const Token = new TokenModel(); let token_data = null; @@ -272,15 +274,15 @@ module.exports = function (token_string) { // logger.info('permissionSchema', JSON.stringify(permissionSchema, null, 2)); // logger.info('data_schema', JSON.stringify(data_schema, null, 2)); - const ajv = validator({ + const ajv = new Ajv({ verbose: true, allErrors: true, - format: 'full', - missingRefs: 'fail', breakOnError: true, coerceTypes: true, schemas: [roleSchema, permsSchema, objectSchema, permissionSchema], + strict: false, }); + addFormats(ajv); return ajv.validate('permissions', data_schema).then(() => { return data_schema[permission]; diff --git a/backend/lib/config.js b/backend/lib/config.js index e7c1b9c1..4ea383f5 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -55,7 +55,7 @@ const configure = () => { database: { engine: 'knex-native', knex: { - client: 'sqlite3', + client: 'better-sqlite3', connection: { filename: envSqliteFile, }, @@ -145,7 +145,7 @@ module.exports = { */ isSqlite: function () { instance === null && configure(); - return instance.database.knex && instance.database.knex.client === 'sqlite3'; + return instance.database.knex && instance.database.knex.client === 'better-sqlite3'; }, /** diff --git a/backend/lib/express/cors.js b/backend/lib/express/cors.js index 8a529784..60d18f85 100644 --- a/backend/lib/express/cors.js +++ b/backend/lib/express/cors.js @@ -10,7 +10,7 @@ module.exports = function (req, res, next) { }, { type: 'string', - pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}\\:?)+\\])?/?(:[0-9]+)?$', + pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}:?)+\\])?/?(:[0-9]+)?$', }, ], }; diff --git a/backend/lib/validator/api.js b/backend/lib/validator/api.js index 9b577cde..2d5c574e 100644 --- a/backend/lib/validator/api.js +++ b/backend/lib/validator/api.js @@ -2,13 +2,16 @@ const error = require('../error'); const path = require('path'); const parser = require('@apidevtools/json-schema-ref-parser'); -const ajv = require('ajv')({ +const Ajv = require('ajv'); +const addFormats = require('ajv-formats'); +const ajv = new Ajv({ verbose: true, validateSchema: true, allErrors: false, - format: 'full', coerceTypes: true, + strict: false, }); +addFormats(ajv); /** * @param {Object} schema diff --git a/backend/lib/validator/index.js b/backend/lib/validator/index.js index 419a9cf4..5afa3642 100644 --- a/backend/lib/validator/index.js +++ b/backend/lib/validator/index.js @@ -4,13 +4,16 @@ const definitions = require('../../schema/definitions.json'); RegExp.prototype.toJSON = RegExp.prototype.toString; -const ajv = require('ajv')({ +const Ajv = require('ajv'); +const addFormats = require('ajv-formats'); +const ajv = new Ajv({ verbose: true, allErrors: true, - format: 'full', // strict regexes for format checks coerceTypes: true, schemas: [definitions], + strict: false, }); +addFormats(ajv); /** * diff --git a/backend/migrations/20240711144745_change_incoming_port_to_string.js b/backend/migrations/20240711144745_change_incoming_port_to_string.js new file mode 100644 index 00000000..3d1e6866 --- /dev/null +++ b/backend/migrations/20240711144745_change_incoming_port_to_string.js @@ -0,0 +1,42 @@ +const migrate_name = 'change_incoming_port_to_string'; +const logger = require('../logger').migrate; + +/** + * Migrate + * + * @see http://knexjs.org/#Schema + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.up = function (knex /*, Promise */) { + logger.info('[' + migrate_name + '] Migrating Up...'); + + return knex.schema + .alterTable('stream', (table) => { + table.string('incoming_port', 11).notNull().alter(); + }) + .then(function () { + logger.info('[' + migrate_name + '] stream Table altered'); + }); +}; + +/** + * Undo Migrate + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.down = function (knex /*, Promise */) { + logger.info('[' + migrate_name + '] Migrating Down...'); + + return knex.schema + .alterTable('stream', (table) => { + table.integer('incoming_port').notNull().unsigned().alter(); + }) + .then(function () { + logger.info('[' + migrate_name + '] stream Table altered'); + }); +}; diff --git a/backend/package.json b/backend/package.json index 82a4a488..119bae82 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,10 +5,11 @@ "main": "index.js", "dependencies": { "@apidevtools/json-schema-ref-parser": "11.6.4", - "ajv": "6.12.6", + "ajv": "8.16.0", "archiver": "7.0.1", "batchflow": "0.4.0", "bcrypt": "5.1.1", + "better-sqlite3": "11.1.2", "body-parser": "1.20.2", "compression": "1.7.4", "express": "4.19.2", @@ -16,15 +17,14 @@ "gravatar": "1.8.2", "jsonwebtoken": "9.0.2", "knex": "3.1.0", - "liquidjs": "10.14.0", + "liquidjs": "10.15.0", "lodash": "4.17.21", "moment": "2.30.1", "mysql": "2.18.1", "node-rsa": "1.1.1", "objection": "3.1.4", "path": "0.12.7", - "signale": "1.4.0", - "sqlite3": "5.1.6" + "signale": "1.4.0" }, "author": "Jamie Curnow and ZoeyVid ", "license": "MIT", @@ -33,7 +33,7 @@ "eslint": "9.6.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-prettier": "5.1.3", - "globals": "15.6.0", + "globals": "15.8.0", "prettier": "3.3.2" } } diff --git a/backend/password-reset.js b/backend/password-reset.js index c12df7b7..3f82036e 100755 --- a/backend/password-reset.js +++ b/backend/password-reset.js @@ -4,7 +4,7 @@ const fs = require('fs'); const bcrypt = require('bcrypt'); -const sqlite3 = require('sqlite3'); +const Database = require('better-sqlite3'); function usage() { console.log(`usage: node ${process.argv[1]} USER_EMAIL PASSWORD @@ -39,21 +39,33 @@ if (fs.existsSync(process.env.DB_SQLITE_FILE)) { console.error(err); process.exit(1); } + const db = new Database(process.env.DB_SQLITE_FILE); - const db = new sqlite3.Database(process.env.DB_SQLITE_FILE); - db.run( - `UPDATE auth SET secret = ? WHERE EXISTS - (SELECT * FROM user WHERE user.id = auth.user_id AND user.email = ?)`, - [PASSWORD_HASH, USER_EMAIL], - function (err) { - if (err) { - console.error(err); - process.exit(1); - } + try { + const stmt = db.prepare(` + UPDATE auth + SET secret = ? + WHERE EXISTS ( + SELECT * + FROM user + WHERE user.id = auth.user_id AND user.email = ? + ) + `); + const result = stmt.run(PASSWORD_HASH, USER_EMAIL); + + if (result.changes > 0) { console.log(`Password for user ${USER_EMAIL} has been reset.`); - process.exit(0); - }, - ); + } else { + console.log(`No user found with email ${USER_EMAIL}.`); + } + } catch (error) { + console.error(error); + process.exit(1); + } finally { + db.close(); + } + + process.exit(0); }); } diff --git a/backend/schema/endpoints/streams.json b/backend/schema/endpoints/streams.json index c52fec34..cc4dd6f5 100644 --- a/backend/schema/endpoints/streams.json +++ b/backend/schema/endpoints/streams.json @@ -16,9 +16,9 @@ "$ref": "../definitions.json#/definitions/modified_on" }, "incoming_port": { - "type": "integer", - "minimum": 1, - "maximum": 65535 + "type": "string", + "pattern": "^([0-9]+|[0-9]+-[0-9]+)$", + "maxLength": 11 }, "forwarding_host": { "anyOf": [ diff --git a/backend/sqlite-vaccum.js b/backend/sqlite-vaccum.js index bbf7e42b..b922640c 100755 --- a/backend/sqlite-vaccum.js +++ b/backend/sqlite-vaccum.js @@ -1,23 +1,9 @@ #!/usr/bin/env node -const fs = require('fs'); -const sqlite3 = require('sqlite3'); +const Database = require('better-sqlite3'); +const db = new Database(process.env.DB_SQLITE_FILE); -if (fs.existsSync(process.env.DB_SQLITE_FILE)) { - const db = new sqlite3.Database(process.env.DB_SQLITE_FILE, sqlite3.OPEN_READWRITE, (err) => { - if (err) { - console.error(err.message); - } else { - db.run('VACUUM; PRAGMA auto_vacuum = 1;', [], (err) => { - if (err) { - console.error(err.message); - } - db.close((err) => { - if (err) { - console.error(err.message); - } - }); - }); - } - }); -} +db.pragma('journal_mode = WAL'); +db.pragma('auto_vacuum = 1'); +db.exec('VACUUM;'); +db.close(); diff --git a/compose.yaml b/compose.yaml index 22d07ba6..b2c6b32d 100644 --- a/compose.yaml +++ b/compose.yaml @@ -33,6 +33,7 @@ services: # - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors, default false # - "NGINX_404_REDIRECT=true" # Redirect to / instead of showing a 404 error page, default false # - "NGINX_DISABLE_PROXY_BUFFERING=true" # Disables the proxy-buffering option of nginx, default false +# - "DISABLE_NGINX_BEAUTIFIER=true" # disables nginxbeautifier, useful when it fails parsing non-standard configs, default false # - "CLEAN=false" # Clean folders, default true # - "FULLCLEAN=true" # Clean unused config folders, default false # - "SKIP_IP_RANGES=true" # Skip feteching/whitelisting ip ranges from aws and cloudflare, default false @@ -43,7 +44,7 @@ services: # - "GOA=true" # Enables goaccess, requires LOGROTATE, default false --- if you download the GeoLite2-Country.mmdb, GeoLite2-City.mmdb AND GeoLite2-ASN.mmdb file from MaxMind and place them in /opt/npm/etc/goaccess/geoip it will automatically enable GeoIP in goaccess after restarting NPMplus (no need to change GOACLA below), you may also use the compose.geoip.yaml # - "GOACLA=--agent-list --real-os --double-decode --anonymize-ip --anonymize-level=2 --keep-last=7 --with-output-resolver --no-query-string" # Arguments that should be passed to goaccess, default: https://github.com/ZoeyVid/NPMplus/blob/develop/rootfs/usr/local/bin/launch.sh#L50 and: --agent-list --real-os --double-decode --anonymize-ip --anonymize-level=1 --keep-last=30 --with-output-resolver --no-query-string # - "PHP82=true" # Activate PHP82, default false -# - "PHP82_APKS=php82-curl php-82-openssl" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.20&repo=community&arch=x86_64&name=php82-*, default none, requires PHP82 +# - "PHP82_APKS=php82-curl php82-openssl" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.20&repo=community&arch=x86_64&name=php82-*, default none, requires PHP82 # - "PHP83=true" # Activate PHP83, default false # - "PHP83_APKS=php83-curl php83-openssl" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.20&repo=community&arch=x86_64&name=php83-*, default none, requires PHP83 # - "PHP_APKS=php-pecl-apcu php-pecl-redis" # Add php extensions, see available packages here: https://pkgs.alpinelinux.org/packages?branch=v3.20&repo=community&arch=x86_64&name=php-*, default none, requires PHP82 and/or PHP83, not recommended, please use PHP82_APKS or PHP83_APKS @@ -57,4 +58,4 @@ services: # ports: # - "80:80" # environment: -# - "TZ=Europe/Berlin" \ No newline at end of file +# - "TZ=Europe/Berlin" diff --git a/frontend/js/app/nginx/stream/form.ejs b/frontend/js/app/nginx/stream/form.ejs index 1fc4f134..1267719a 100644 --- a/frontend/js/app/nginx/stream/form.ejs +++ b/frontend/js/app/nginx/stream/form.ejs @@ -9,13 +9,13 @@
- +
- +
diff --git a/frontend/js/app/nginx/stream/form.js b/frontend/js/app/nginx/stream/form.js index be8fc8bc..72bf25c2 100644 --- a/frontend/js/app/nginx/stream/form.js +++ b/frontend/js/app/nginx/stream/form.js @@ -43,7 +43,6 @@ module.exports = Mn.View.extend({ } // Manipulate - data.incoming_port = parseInt(data.incoming_port, 10); data.forwarding_port = parseInt(data.forwarding_port, 10); data.tcp_forwarding = !!data.tcp_forwarding; data.udp_forwarding = !!data.udp_forwarding; diff --git a/frontend/package.json b/frontend/package.json index b866b7e7..e50f1d95 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,7 +27,7 @@ "messageformat-loader": "0.8.1", "mini-css-extract-plugin": "1.6.2", "moment": "2.30.1", - "node-sass": "7.0.3", + "node-sass": "9.0.0", "nodemon": "3.1.4", "numeral": "2.0.6", "sass-loader": "10.5.2", diff --git a/global/certbot-dns-plugins.json b/global/certbot-dns-plugins.json index e1f813e7..fd14d76c 100644 --- a/global/certbot-dns-plugins.json +++ b/global/certbot-dns-plugins.json @@ -113,6 +113,12 @@ "credentials": "dns_domeneshop_client_token=YOUR_DOMENESHOP_CLIENT_TOKEN\ndns_domeneshop_client_secret=YOUR_DOMENESHOP_CLIENT_SECRET", "full_plugin_name": "dns-domeneshop" }, + "dreamhost": { + "name": "Dreamhost", + "package_name": "certbot-dns-dreamhost", + "credentials": "dns_dreamhost_baseurl=API_BASE_URL\ndns_dreamhost_api_key=API_KEY", + "full_plugin_name": "dns-dreamhost" + }, "dynu": { "name": "Dynu", "package_name": "certbot-dns-dynu", diff --git a/rootfs/usr/local/bin/start.sh b/rootfs/usr/local/bin/start.sh index 06b8e88c..62895ef8 100755 --- a/rootfs/usr/local/bin/start.sh +++ b/rootfs/usr/local/bin/start.sh @@ -180,6 +180,11 @@ if ! echo "$NGINX_DISABLE_PROXY_BUFFERING" | grep -q "^true$\|^false$"; then sleep inf fi +if ! echo "$DISABLE_NGINX_BEAUTIFIER" | grep -q "^true$\|^false$"; then + echo "DISABLE_NGINX_BEAUTIFIER needs to be true or false." + sleep inf +fi + if ! echo "$CLEAN" | grep -q "^true$\|^false$"; then echo "CLEAN needs to be true or false." sleep inf @@ -737,7 +742,7 @@ sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9]\+\)/listen sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9]\+\)/listen $IPV4_BINDING:\2/g" /app/templates/default.conf sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\({{ incoming_port }}\)/listen $IPV4_BINDING:\2/g" /app/templates/stream.conf find /usr/local/nginx/conf/conf.d -type f -name '*.conf' -exec sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9]\+\)/listen $IPV4_BINDING:\2/g" {} \; -find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9]\+\)/listen $IPV4_BINDING:\2/g" {} \; +find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9-]\+\)/listen $IPV4_BINDING:\2/g" {} \; if [ "$DISABLE_IPV6" = "true" ]; then sed -i "s|ipv6=on;|ipv6=off;|g" /usr/local/nginx/conf/nginx.conf @@ -745,14 +750,14 @@ if [ "$DISABLE_IPV6" = "true" ]; then sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/#listen \[\1\]:\2/g" /app/templates/default.conf sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\({{ incoming_port }}\)/#listen \[\1\]:\2/g" /app/templates/stream.conf find /usr/local/nginx/conf/conf.d -type f -name '*.conf' -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/#listen \[\1\]:\2/g" {} \; - find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/#listen \[\1\]:\2/g" {} \; + find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9-]\+\)/#listen \[\1\]:\2/g" {} \; else sed -i "s|ipv6=off;|ipv6=on;|g" /usr/local/nginx/conf/nginx.conf sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/listen $IPV6_BINDING:\2/g" /app/templates/_listen.conf sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/listen $IPV6_BINDING:\2/g" /app/templates/default.conf sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\({{ incoming_port }}\)/listen $IPV6_BINDING:\2/g" /app/templates/stream.conf find /usr/local/nginx/conf/conf.d -type f -name '*.conf' -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/listen $IPV6_BINDING:\2/g" {} \; - find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9]\+\)/listen $IPV6_BINDING:\2/g" {} \; + find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s/#\?listen \[\([0-9a-f:]\+\)\]:\([0-9-]\+\)/listen $IPV6_BINDING:\2/g" {} \; fi sed -i "s/#\?listen \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+:\)\?\([0-9]\+\)/listen $NPM_IPV4_BINDING:$NPM_PORT/g" /usr/local/nginx/conf/conf.d/npm.conf @@ -883,7 +888,9 @@ elif [ "$FULLCLEAN" = "true" ]; then rm -vrf /data/etc/goaccess fi -nginxbeautifier -s 4 -r /data/nginx +if [ "$DISABLE_NGINX_BEAUTIFIER" = "false" ]; then + nginxbeautifier -s 4 -r /data/nginx +fi #find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s|add_header alt-svc 'h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400';|add_header Alt-Svc 'h3=\":443\"; ma=86400';|g" {} \; #find /data/nginx -type f -name '*.conf' -not -path "/data/nginx/custom/*" -exec sed -i "s|add_header alt-svc 'h3=\":443\";|add_header Alt-Svc 'h3=\":443\"; ma=86400';|g" {} \; @@ -920,11 +927,12 @@ if [ "$PUID" != "0" ]; then echo "ERROR: Unable to set group against the user properly" sleep inf fi - find /usr/local \ + find /proc/self/fd \ + /usr/local \ /data \ /run \ /tmp \ - -not \( -uid "$PUID" -and -gid "$PGID" \) \ + -not \( -uid "$PUID" -and -gid "$PGID" \) \ -exec chown "$PUID:$PGID" {} \; if [ "$PHP82" = "true" ]; then sed -i "s|user =.*|;user = root|" /data/php/82/php-fpm.d/www.conf @@ -937,11 +945,12 @@ if [ "$PUID" != "0" ]; then sed -i "s|user root;|#user root;|g" /usr/local/nginx/conf/nginx.conf exec su-exec "$PUID:$PGID" launch.sh else - find /usr/local \ + find /proc/self/fd \ + /usr/local \ /data \ /run \ /tmp \ - -not \( -uid 0 -and -gid 0 \) \ + -not \( -uid 0 -and -gid 0 \) \ -exec chown 0:0 {} \; if [ "$PHP82" = "true" ]; then sed -i "s|;user =.*|user = root|" /data/php/82/php-fpm.d/www.conf