From ec76bc816c202d234c47ef9358b81f2dd2620284 Mon Sep 17 00:00:00 2001 From: "HomePC\\Kevin" Date: Sun, 30 Aug 2026 12:16:20 +0200 Subject: [PATCH] feat(proxy-host): add configurable asset cache lifetime --- backend/internal/nginx.js | 1 + ...260825180010_proxy_host_asset_cache_ttl.js | 37 +++++++++ backend/package.json | 1 + backend/schema/common.json | 7 ++ .../schema/components/proxy-host-object.json | 4 + .../schema/paths/nginx/proxy-hosts/get.json | 1 + .../paths/nginx/proxy-hosts/hostID/get.json | 1 + .../paths/nginx/proxy-hosts/hostID/put.json | 4 + .../schema/paths/nginx/proxy-hosts/post.json | 4 + backend/templates/_assets.conf | 10 ++- backend/test/asset-cache-templates.test.js | 74 +++++++++++++++++ .../nginx/conf.d/include/assets-common.conf | 24 ++++++ .../etc/nginx/conf.d/include/assets.conf | 24 +----- frontend/src/api/backend/models.ts | 1 + .../Form/ProxyCacheOptionsFields.test.tsx | 38 +++++++++ .../Form/ProxyCacheOptionsFields.tsx | 80 +++++++++++++++++++ frontend/src/components/Form/index.ts | 1 + frontend/src/hooks/useProxyHost.ts | 1 + frontend/src/locale/src/bg.json | 6 ++ frontend/src/locale/src/cs.json | 6 ++ frontend/src/locale/src/de.json | 6 ++ frontend/src/locale/src/en.json | 6 ++ frontend/src/locale/src/es.json | 6 ++ frontend/src/locale/src/et.json | 6 ++ frontend/src/locale/src/fr.json | 6 ++ frontend/src/locale/src/ga.json | 6 ++ frontend/src/locale/src/hu.json | 6 ++ frontend/src/locale/src/id.json | 6 ++ frontend/src/locale/src/it.json | 6 ++ frontend/src/locale/src/ja.json | 6 ++ frontend/src/locale/src/ko.json | 6 ++ frontend/src/locale/src/nl.json | 6 ++ frontend/src/locale/src/no.json | 6 ++ frontend/src/locale/src/pl.json | 6 ++ frontend/src/locale/src/pt.json | 6 ++ frontend/src/locale/src/ru.json | 6 ++ frontend/src/locale/src/sk.json | 6 ++ frontend/src/locale/src/tr.json | 6 ++ frontend/src/locale/src/uk.json | 6 ++ frontend/src/locale/src/vi.json | 6 ++ frontend/src/locale/src/zh.json | 6 ++ frontend/src/modals/ProxyHostModal.tsx | 26 +----- .../cypress/e2e/api/ProxyHostAssetCache.cy.js | 74 +++++++++++++++++ 43 files changed, 503 insertions(+), 48 deletions(-) create mode 100644 backend/migrations/20260825180010_proxy_host_asset_cache_ttl.js create mode 100644 backend/test/asset-cache-templates.test.js create mode 100644 docker/rootfs/etc/nginx/conf.d/include/assets-common.conf create mode 100644 frontend/src/components/Form/ProxyCacheOptionsFields.test.tsx create mode 100644 frontend/src/components/Form/ProxyCacheOptionsFields.tsx create mode 100644 test/cypress/e2e/api/ProxyHostAssetCache.cy.js diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 128c004619..7b316c72ba 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -157,6 +157,7 @@ const internalNginx = { { certificate_id: host.certificate_id }, { ssl_forced: host.ssl_forced }, { caching_enabled: host.caching_enabled }, + { asset_cache_ttl: host.asset_cache_ttl }, { block_exploits: host.block_exploits }, { allow_websocket_upgrade: host.allow_websocket_upgrade }, { http2_support: host.http2_support }, diff --git a/backend/migrations/20260825180010_proxy_host_asset_cache_ttl.js b/backend/migrations/20260825180010_proxy_host_asset_cache_ttl.js new file mode 100644 index 0000000000..f7df604fb4 --- /dev/null +++ b/backend/migrations/20260825180010_proxy_host_asset_cache_ttl.js @@ -0,0 +1,37 @@ +import { migrate as logger } from "../logger.js"; + +const migrateName = "proxy_host_asset_cache_ttl"; + +/** + * @param {Object} knex + * @returns {Promise} + */ +const up = (knex) => { + logger.info(`[${migrateName}] Migrating Up...`); + + return knex.schema + .alterTable("proxy_host", (table) => { + table.integer("asset_cache_ttl").notNullable().unsigned().defaultTo(1800); + }) + .then(() => { + logger.info(`[${migrateName}] proxy_host Table altered`); + }); +}; + +/** + * @param {Object} knex + * @returns {Promise} + */ +const down = (knex) => { + logger.info(`[${migrateName}] Migrating Down...`); + + return knex.schema + .alterTable("proxy_host", (table) => { + table.dropColumn("asset_cache_ttl"); + }) + .then(() => { + logger.info(`[${migrateName}] proxy_host Table altered`); + }); +}; + +export { up, down }; diff --git a/backend/package.json b/backend/package.json index 8eda0451c5..02d1538328 100644 --- a/backend/package.json +++ b/backend/package.json @@ -8,6 +8,7 @@ "type": "module", "scripts": { "lint": "biome lint", + "test": "node --test test/**/*.test.js", "prettier": "biome format --write .", "validate-schema": "node validate-schema.js", "regenerate-config": "node scripts/regenerate-config" diff --git a/backend/schema/common.json b/backend/schema/common.json index 00b06e005f..29111b3206 100644 --- a/backend/schema/common.json +++ b/backend/schema/common.json @@ -128,6 +128,13 @@ "type": "boolean", "example": true }, + "asset_cache_ttl": { + "description": "Asset cache lifetime in seconds", + "type": "integer", + "minimum": 1, + "maximum": 31536000, + "example": 1800 + }, "email": { "description": "Email address", "type": "string", diff --git a/backend/schema/components/proxy-host-object.json b/backend/schema/components/proxy-host-object.json index 3ac6462136..25d64bfc85 100644 --- a/backend/schema/components/proxy-host-object.json +++ b/backend/schema/components/proxy-host-object.json @@ -13,6 +13,7 @@ "certificate_id", "ssl_forced", "caching_enabled", + "asset_cache_ttl", "block_exploits", "advanced_config", "meta", @@ -65,6 +66,9 @@ "caching_enabled": { "$ref": "../common.json#/properties/caching_enabled" }, + "asset_cache_ttl": { + "$ref": "../common.json#/properties/asset_cache_ttl" + }, "block_exploits": { "$ref": "../common.json#/properties/block_exploits" }, diff --git a/backend/schema/paths/nginx/proxy-hosts/get.json b/backend/schema/paths/nginx/proxy-hosts/get.json index 301e28bfdf..2cd7d20a43 100644 --- a/backend/schema/paths/nginx/proxy-hosts/get.json +++ b/backend/schema/paths/nginx/proxy-hosts/get.json @@ -46,6 +46,7 @@ "certificate_id": 1, "ssl_forced": false, "caching_enabled": false, + "asset_cache_ttl": 1800, "block_exploits": false, "advanced_config": "", "meta": { diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/get.json b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json index 2e677fed32..9aae1de0d5 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/get.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json @@ -43,6 +43,7 @@ "certificate_id": 0, "ssl_forced": false, "caching_enabled": false, + "asset_cache_ttl": 1800, "block_exploits": false, "advanced_config": "", "meta": { diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json index fc3198456b..92a51baa79 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json @@ -68,6 +68,9 @@ "caching_enabled": { "$ref": "../../../../components/proxy-host-object.json#/properties/caching_enabled" }, + "asset_cache_ttl": { + "$ref": "../../../../components/proxy-host-object.json#/properties/asset_cache_ttl" + }, "allow_websocket_upgrade": { "$ref": "../../../../components/proxy-host-object.json#/properties/allow_websocket_upgrade" }, @@ -112,6 +115,7 @@ "certificate_id": 0, "ssl_forced": false, "caching_enabled": false, + "asset_cache_ttl": 1800, "block_exploits": false, "advanced_config": "", "meta": { diff --git a/backend/schema/paths/nginx/proxy-hosts/post.json b/backend/schema/paths/nginx/proxy-hosts/post.json index 28ddad8fc2..2b0d68e611 100644 --- a/backend/schema/paths/nginx/proxy-hosts/post.json +++ b/backend/schema/paths/nginx/proxy-hosts/post.json @@ -60,6 +60,9 @@ "caching_enabled": { "$ref": "../../../components/proxy-host-object.json#/properties/caching_enabled" }, + "asset_cache_ttl": { + "$ref": "../../../components/proxy-host-object.json#/properties/asset_cache_ttl" + }, "allow_websocket_upgrade": { "$ref": "../../../components/proxy-host-object.json#/properties/allow_websocket_upgrade" }, @@ -112,6 +115,7 @@ "certificate_id": 0, "ssl_forced": false, "caching_enabled": false, + "asset_cache_ttl": 1800, "block_exploits": false, "advanced_config": "", "meta": {}, diff --git a/backend/templates/_assets.conf b/backend/templates/_assets.conf index dcb183c555..e635ab369b 100644 --- a/backend/templates/_assets.conf +++ b/backend/templates/_assets.conf @@ -1,4 +1,10 @@ {% if caching_enabled == 1 or caching_enabled == true -%} # Asset Caching - include conf.d/include/assets.conf; -{% endif %} \ No newline at end of file + location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|woff2|eot|ttf|svg|ico|css\.map|js\.map)$ { + proxy_cache_valid any {{ asset_cache_ttl | default: 1800 }}s; + proxy_cache_valid 404 1m; + expires {{ asset_cache_ttl | default: 1800 }}s; + + include conf.d/include/assets-common.conf; + } +{% endif %} diff --git a/backend/test/asset-cache-templates.test.js b/backend/test/asset-cache-templates.test.js new file mode 100644 index 0000000000..b6cd00a550 --- /dev/null +++ b/backend/test/asset-cache-templates.test.js @@ -0,0 +1,74 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import test from "node:test"; +import utils from "../lib/utils.js"; +import internalNginx from "../internal/nginx.js"; + +const render = async (templateName, data) => { + const template = fs.readFileSync(new URL(`../templates/${templateName}`, import.meta.url), "utf8"); + return utils.getRenderEngine().parseAndRender(template, data); +}; + +test("renders a numeric asset cache lifetime", async () => { + const config = await render("_assets.conf", { + asset_cache_ttl: 21600, + caching_enabled: true, + certificate: null, + }); + + assert.match(config, /proxy_cache_valid any 21600s;/); + assert.match(config, /expires 21600s;/); + assert.match(config, /include conf\.d\/include\/assets-common\.conf;/); +}); + +test("uses the proxy host cache lifetime inside custom locations", async () => { + const config = await render("_location.conf", { + access_list_id: 0, + advanced_config: "", + allow_websocket_upgrade: false, + asset_cache_ttl: 3600, + block_exploits: false, + caching_enabled: true, + certificate: null, + forward_host: "127.0.0.1", + forward_path: "", + forward_port: 80, + forward_scheme: "http", + hsts_enabled: false, + path: "/assets", + ssl_forced: false, + }); + + assert.match(config, /location \/assets \{/); + assert.match(config, /proxy_cache_valid any 3600s;/); +}); + +test("retains the 30-minute lifetime when no value is provided", async () => { + const config = await render("_assets.conf", { caching_enabled: true }); + assert.match(config, /proxy_cache_valid any 1800s;/); + assert.match(config, /expires 1800s;/); +}); + +test("does not emit a cache location when caching is disabled", async () => { + const config = await render("_assets.conf", { caching_enabled: false, asset_cache_ttl: 3600 }); + assert.equal(config.trim(), ""); +}); + +test("propagates the host lifetime when rendering its custom locations", async () => { + const config = await internalNginx.renderLocations({ + asset_cache_ttl: 86400, + caching_enabled: true, + locations: [ + { + path: "/custom", + forward_scheme: "http", + forward_host: "127.0.0.1", + forward_port: 8080, + advanced_config: "", + }, + ], + }); + assert.match(config, /location \/custom \{/); + assert.match(config, /proxy_cache_valid any 86400s;/); + assert.match(config, /expires 86400s;/); +}); diff --git a/docker/rootfs/etc/nginx/conf.d/include/assets-common.conf b/docker/rootfs/etc/nginx/conf.d/include/assets-common.conf new file mode 100644 index 0000000000..ab9489d607 --- /dev/null +++ b/docker/rootfs/etc/nginx/conf.d/include/assets-common.conf @@ -0,0 +1,24 @@ +if_modified_since off; + +# use the public cache +proxy_cache public-cache; +proxy_cache_key $host$request_uri; + +# ignore these headers for media +proxy_ignore_headers Set-Cookie Cache-Control Expires X-Accel-Expires; + +# strip this header to avoid If-Modified-Since requests +proxy_hide_header Last-Modified; +proxy_hide_header Cache-Control; +proxy_hide_header Vary; + +proxy_cache_bypass 0; +proxy_no_cache 0; + +proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_404; +proxy_connect_timeout 5s; +proxy_read_timeout 45s; + +access_log off; + +include conf.d/include/proxy.conf; diff --git a/docker/rootfs/etc/nginx/conf.d/include/assets.conf b/docker/rootfs/etc/nginx/conf.d/include/assets.conf index 5a90beb8ae..22efa08fe7 100644 --- a/docker/rootfs/etc/nginx/conf.d/include/assets.conf +++ b/docker/rootfs/etc/nginx/conf.d/include/assets.conf @@ -1,31 +1,9 @@ location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|woff2|eot|ttf|svg|ico|css\.map|js\.map)$ { - if_modified_since off; - - # use the public cache - proxy_cache public-cache; - proxy_cache_key $host$request_uri; - - # ignore these headers for media - proxy_ignore_headers Set-Cookie Cache-Control Expires X-Accel-Expires; - # cache 200s and also 404s (not ideal but there are a few 404 images for some reason) proxy_cache_valid any 30m; proxy_cache_valid 404 1m; - # strip this header to avoid If-Modified-Since requests - proxy_hide_header Last-Modified; - proxy_hide_header Cache-Control; - proxy_hide_header Vary; - - proxy_cache_bypass 0; - proxy_no_cache 0; - - proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_404; - proxy_connect_timeout 5s; - proxy_read_timeout 45s; - expires @30m; - access_log off; - include conf.d/include/proxy.conf; + include conf.d/include/assets-common.conf; } diff --git a/frontend/src/api/backend/models.ts b/frontend/src/api/backend/models.ts index 2ae0b08348..5c13c71caa 100644 --- a/frontend/src/api/backend/models.ts +++ b/frontend/src/api/backend/models.ts @@ -118,6 +118,7 @@ export interface ProxyHost { certificateId: number; sslForced: boolean; cachingEnabled: boolean; + assetCacheTtl: number; blockExploits: boolean; advancedConfig: string; meta: Record; diff --git a/frontend/src/components/Form/ProxyCacheOptionsFields.test.tsx b/frontend/src/components/Form/ProxyCacheOptionsFields.test.tsx new file mode 100644 index 0000000000..52565a8184 --- /dev/null +++ b/frontend/src/components/Form/ProxyCacheOptionsFields.test.tsx @@ -0,0 +1,38 @@ +import { fireEvent, render, waitFor } from "@testing-library/react"; +import { Form, Formik } from "formik"; +import { describe, expect, it } from "vitest"; +import { ProxyCacheOptionsFields } from "./ProxyCacheOptionsFields"; + +const renderFields = (overrides = {}) => + render( + undefined} + > +
+ + +
, + ); + +describe("ProxyCacheOptionsFields", () => { + it("shows the cache lifetime only while asset caching is enabled", async () => { + renderFields(); + + expect(document.getElementById("assetCacheTtl")).toBeNull(); + fireEvent.click(document.getElementById("cachingEnabled") as HTMLElement); + + await waitFor(() => { + expect(document.getElementById("assetCacheTtl")).not.toBeNull(); + }); + + fireEvent.click(document.getElementById("cachingEnabled") as HTMLElement); + await waitFor(() => { + expect(document.getElementById("assetCacheTtl")).toBeNull(); + }); + }); +}); diff --git a/frontend/src/components/Form/ProxyCacheOptionsFields.tsx b/frontend/src/components/Form/ProxyCacheOptionsFields.tsx new file mode 100644 index 0000000000..c1d4d9fbe4 --- /dev/null +++ b/frontend/src/components/Form/ProxyCacheOptionsFields.tsx @@ -0,0 +1,80 @@ +import cn from "classnames"; +import { Field, useFormikContext } from "formik"; +import { T } from "src/locale"; +import { validateNumber } from "src/modules/Validations"; + +type FormValues = { + assetCacheTtl: number; + cachingEnabled: boolean; +}; + +interface Props { + color?: string; +} + +export function ProxyCacheOptionsFields({ color = "bg-cyan" }: Props) { + const { values } = useFormikContext(); + const { assetCacheTtl, cachingEnabled } = values; + + const toggleRow = (name: "cachingEnabled", label: string, enabled: boolean) => ( +
+ +
+ ); + + return ( + <> + {toggleRow("cachingEnabled", "host.flags.cache-assets", cachingEnabled)} + {cachingEnabled ? ( +
+ + {({ field, form }: any) => ( +
+ + + {form.errors.assetCacheTtl && form.touched.assetCacheTtl ? ( +
{form.errors.assetCacheTtl}
+ ) : null} + + + +
+ )} +
+
+ ) : null} + + ); +} diff --git a/frontend/src/components/Form/index.ts b/frontend/src/components/Form/index.ts index f218b2e330..914e750a82 100644 --- a/frontend/src/components/Form/index.ts +++ b/frontend/src/components/Form/index.ts @@ -5,5 +5,6 @@ export * from "./DNSProviderFields"; export * from "./DomainNamesField"; export * from "./LocationsFields"; export * from "./NginxConfigField"; +export * from "./ProxyCacheOptionsFields"; export * from "./SSLCertificateField"; export * from "./SSLOptionsFields"; diff --git a/frontend/src/hooks/useProxyHost.ts b/frontend/src/hooks/useProxyHost.ts index 24e7f4fae2..3ea35a5352 100644 --- a/frontend/src/hooks/useProxyHost.ts +++ b/frontend/src/hooks/useProxyHost.ts @@ -15,6 +15,7 @@ const fetchProxyHost = (id: number | "new") => { certificateId: 0, sslForced: false, cachingEnabled: false, + assetCacheTtl: 1800, blockExploits: false, advancedConfig: "", meta: {}, diff --git a/frontend/src/locale/src/bg.json b/frontend/src/locale/src/bg.json index 5183fe315b..c82cda74d5 100644 --- a/frontend/src/locale/src/bg.json +++ b/frontend/src/locale/src/bg.json @@ -359,6 +359,12 @@ "footer.github-fork": { "defaultMessage": "Fork в GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Време за кеширане на ресурсите (секунди)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Примери: 3600 = 1 час, 21600 = 6 часа, 86400 = 1 ден." + }, "host.flags.block-exploits": { "defaultMessage": "Блокиране на често срещани експлойти" }, diff --git a/frontend/src/locale/src/cs.json b/frontend/src/locale/src/cs.json index cd86b678dc..ba970d5289 100644 --- a/frontend/src/locale/src/cs.json +++ b/frontend/src/locale/src/cs.json @@ -416,6 +416,12 @@ "footer.github-fork": { "defaultMessage": "Forkněte mě na GitHubu" }, + "host.cache-ttl": { + "defaultMessage": "Doba uložení prostředků v mezipaměti (sekundy)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Příklady: 3600 = 1 hodina, 21600 = 6 hodin, 86400 = 1 den." + }, "host.flags.block-exploits": { "defaultMessage": "Blokovat běžné exploity" }, diff --git a/frontend/src/locale/src/de.json b/frontend/src/locale/src/de.json index 6cdb64cf39..64f1b4a6db 100644 --- a/frontend/src/locale/src/de.json +++ b/frontend/src/locale/src/de.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Fork me on Github" }, + "host.cache-ttl": { + "defaultMessage": "Asset-Cache-Laufzeit (Sekunden)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Beispiele: 3600 = 1 Stunde, 21600 = 6 Stunden, 86400 = 1 Tag." + }, "host.flags.block-exploits": { "defaultMessage": "Gängige Exploits blockieren" }, diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index 88fdd724ed..3dc7707091 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -425,6 +425,12 @@ "footer.github-fork": { "defaultMessage": "Fork me on Github" }, + "host.cache-ttl": { + "defaultMessage": "Asset Cache Lifetime (seconds)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Examples: 3600 = 1 hour, 21600 = 6 hours, 86400 = 1 day." + }, "host.flags.block-exploits": { "defaultMessage": "Block Common Exploits" }, diff --git a/frontend/src/locale/src/es.json b/frontend/src/locale/src/es.json index c8b1edb075..19be0807ad 100644 --- a/frontend/src/locale/src/es.json +++ b/frontend/src/locale/src/es.json @@ -359,6 +359,12 @@ "footer.github-fork": { "defaultMessage": "Bifúrcame en Github" }, + "host.cache-ttl": { + "defaultMessage": "Duración de la caché de recursos (segundos)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Ejemplos: 3600 = 1 hora, 21600 = 6 horas, 86400 = 1 día." + }, "host.flags.block-exploits": { "defaultMessage": "Bloquear Exploits Comunes" }, diff --git a/frontend/src/locale/src/et.json b/frontend/src/locale/src/et.json index bb00ac3322..9558864b9d 100644 --- a/frontend/src/locale/src/et.json +++ b/frontend/src/locale/src/et.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Fork me on Github" }, + "host.cache-ttl": { + "defaultMessage": "Varade vahemälu kestus (sekundites)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Näited: 3600 = 1 tund, 21600 = 6 tundi, 86400 = 1 päev." + }, "host.flags.block-exploits": { "defaultMessage": "Block Common Exploits" }, diff --git a/frontend/src/locale/src/fr.json b/frontend/src/locale/src/fr.json index 0911eedc39..d5db71c1ff 100644 --- a/frontend/src/locale/src/fr.json +++ b/frontend/src/locale/src/fr.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Forkez-moi sur Github" }, + "host.cache-ttl": { + "defaultMessage": "Durée du cache des ressources (secondes)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Exemples : 3600 = 1 heure, 21600 = 6 heures, 86400 = 1 jour." + }, "host.flags.block-exploits": { "defaultMessage": "Bloquer les exploits courants" }, diff --git a/frontend/src/locale/src/ga.json b/frontend/src/locale/src/ga.json index 719b863bf0..f08cbd5254 100644 --- a/frontend/src/locale/src/ga.json +++ b/frontend/src/locale/src/ga.json @@ -347,6 +347,12 @@ "footer.github-fork": { "defaultMessage": "Forc mé ar Github" }, + "host.cache-ttl": { + "defaultMessage": "Saolré taisce sócmhainní (soicindí)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Samplaí: 3600 = 1 uair, 21600 = 6 huaire, 86400 = 1 lá." + }, "host.flags.block-exploits": { "defaultMessage": "Blocáil Easnaimh Choitianta" }, diff --git a/frontend/src/locale/src/hu.json b/frontend/src/locale/src/hu.json index 4caf058344..9829394485 100644 --- a/frontend/src/locale/src/hu.json +++ b/frontend/src/locale/src/hu.json @@ -416,6 +416,12 @@ "footer.github-fork": { "defaultMessage": "Fork-olj a GitHub-on" }, + "host.cache-ttl": { + "defaultMessage": "Eszköz-gyorsítótár élettartama (másodperc)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Példák: 3600 = 1 óra, 21600 = 6 óra, 86400 = 1 nap." + }, "host.flags.block-exploits": { "defaultMessage": "Gyakori exploitok blokkolása" }, diff --git a/frontend/src/locale/src/id.json b/frontend/src/locale/src/id.json index cb498f0d88..0da323eb0b 100644 --- a/frontend/src/locale/src/id.json +++ b/frontend/src/locale/src/id.json @@ -347,6 +347,12 @@ "footer.github-fork": { "defaultMessage": "Fork saya di GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Masa cache aset (detik)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Contoh: 3600 = 1 jam, 21600 = 6 jam, 86400 = 1 hari." + }, "host.flags.block-exploits": { "defaultMessage": "Blokir Eksploit Umum" }, diff --git a/frontend/src/locale/src/it.json b/frontend/src/locale/src/it.json index 7e5ca77113..a3ed4b40ee 100644 --- a/frontend/src/locale/src/it.json +++ b/frontend/src/locale/src/it.json @@ -344,6 +344,12 @@ "footer.github-fork": { "defaultMessage": "Forkami su GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Durata cache risorse (secondi)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Esempi: 3600 = 1 ora, 21600 = 6 ore, 86400 = 1 giorno." + }, "host.flags.block-exploits": { "defaultMessage": "Blocca Exploit Comuni" }, diff --git a/frontend/src/locale/src/ja.json b/frontend/src/locale/src/ja.json index 438dc218d3..03a59e1fef 100644 --- a/frontend/src/locale/src/ja.json +++ b/frontend/src/locale/src/ja.json @@ -344,6 +344,12 @@ "footer.github-fork": { "defaultMessage": "Fork me on Github" }, + "host.cache-ttl": { + "defaultMessage": "アセットキャッシュの有効期間(秒)" + }, + "host.cache-ttl-help": { + "defaultMessage": "例: 3600 = 1時間、21600 = 6時間、86400 = 1日。" + }, "host.flags.block-exploits": { "defaultMessage": "一般的なエクスプロイトをブロックする" }, diff --git a/frontend/src/locale/src/ko.json b/frontend/src/locale/src/ko.json index 9c0093591b..90e124e1e4 100644 --- a/frontend/src/locale/src/ko.json +++ b/frontend/src/locale/src/ko.json @@ -359,6 +359,12 @@ "footer.github-fork": { "defaultMessage": "GitHub에서 포크하기" }, + "host.cache-ttl": { + "defaultMessage": "에셋 캐시 수명(초)" + }, + "host.cache-ttl-help": { + "defaultMessage": "예: 3600 = 1시간, 21600 = 6시간, 86400 = 1일." + }, "host.flags.block-exploits": { "defaultMessage": "일반적인 공격 차단" }, diff --git a/frontend/src/locale/src/nl.json b/frontend/src/locale/src/nl.json index 86d49d95e2..c55615fc75 100644 --- a/frontend/src/locale/src/nl.json +++ b/frontend/src/locale/src/nl.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Maak een Fork op Github" }, + "host.cache-ttl": { + "defaultMessage": "Cacheduur voor assets (seconden)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Voorbeelden: 3600 = 1 uur, 21600 = 6 uur, 86400 = 1 dag." + }, "host.flags.block-exploits": { "defaultMessage": "Veelvoorkomende kwetsbaarheden blokkeren" }, diff --git a/frontend/src/locale/src/no.json b/frontend/src/locale/src/no.json index f14ea54b11..acb8e1e054 100644 --- a/frontend/src/locale/src/no.json +++ b/frontend/src/locale/src/no.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Fork meg på Github" }, + "host.cache-ttl": { + "defaultMessage": "Levetid for ressursbuffer (sekunder)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Eksempler: 3600 = 1 time, 21600 = 6 timer, 86400 = 1 dag." + }, "host.flags.block-exploits": { "defaultMessage": "Blokker vanlige utnyttelser" }, diff --git a/frontend/src/locale/src/pl.json b/frontend/src/locale/src/pl.json index a5fb2ad0be..c5f2efb7af 100644 --- a/frontend/src/locale/src/pl.json +++ b/frontend/src/locale/src/pl.json @@ -350,6 +350,12 @@ "footer.github-fork": { "defaultMessage": "Forkuj mnie na Github" }, + "host.cache-ttl": { + "defaultMessage": "Czas przechowywania zasobów w pamięci podręcznej (sekundy)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Przykłady: 3600 = 1 godzina, 21600 = 6 godzin, 86400 = 1 dzień." + }, "host.flags.block-exploits": { "defaultMessage": "Blokuj typowe exploity" }, diff --git a/frontend/src/locale/src/pt.json b/frontend/src/locale/src/pt.json index 0a789f484e..216ce6e678 100644 --- a/frontend/src/locale/src/pt.json +++ b/frontend/src/locale/src/pt.json @@ -347,6 +347,12 @@ "footer.github-fork": { "defaultMessage": "Faz fork no GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Duração da cache de recursos (segundos)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Exemplos: 3600 = 1 hora, 21600 = 6 horas, 86400 = 1 dia." + }, "host.flags.block-exploits": { "defaultMessage": "Bloquear Exploits Comuns" }, diff --git a/frontend/src/locale/src/ru.json b/frontend/src/locale/src/ru.json index c18be998f9..717ca2fce4 100644 --- a/frontend/src/locale/src/ru.json +++ b/frontend/src/locale/src/ru.json @@ -422,6 +422,12 @@ "footer.github-fork": { "defaultMessage": "Сделать форк на GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Время хранения ресурсов в кэше (секунды)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Примеры: 3600 = 1 час, 21600 = 6 часов, 86400 = 1 день." + }, "host.flags.block-exploits": { "defaultMessage": "Блокировать известные эксплойты" }, diff --git a/frontend/src/locale/src/sk.json b/frontend/src/locale/src/sk.json index 8d48cf811e..9a35f0fca8 100644 --- a/frontend/src/locale/src/sk.json +++ b/frontend/src/locale/src/sk.json @@ -416,6 +416,12 @@ "footer.github-fork": { "defaultMessage": "Forknite ma na GitHube" }, + "host.cache-ttl": { + "defaultMessage": "Doba uloženia prostriedkov vo vyrovnávacej pamäti (sekundy)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Príklady: 3600 = 1 hodina, 21600 = 6 hodín, 86400 = 1 deň." + }, "host.flags.block-exploits": { "defaultMessage": "Blokovať bežné exploity" }, diff --git a/frontend/src/locale/src/tr.json b/frontend/src/locale/src/tr.json index cc2d488811..f1207350d3 100644 --- a/frontend/src/locale/src/tr.json +++ b/frontend/src/locale/src/tr.json @@ -350,6 +350,12 @@ "footer.github-fork": { "defaultMessage": "Github'da Fork Yap" }, + "host.cache-ttl": { + "defaultMessage": "Varlık önbelleği ömrü (saniye)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Örnekler: 3600 = 1 saat, 21600 = 6 saat, 86400 = 1 gün." + }, "host.flags.block-exploits": { "defaultMessage": "Yaygın Saldırıları Engelle" }, diff --git a/frontend/src/locale/src/uk.json b/frontend/src/locale/src/uk.json index 3508ebbb01..2386b600ad 100644 --- a/frontend/src/locale/src/uk.json +++ b/frontend/src/locale/src/uk.json @@ -425,6 +425,12 @@ "footer.github-fork": { "defaultMessage": "Зробити форк на GitHub" }, + "host.cache-ttl": { + "defaultMessage": "Asset Cache Lifetime (seconds)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Examples: 3600 = 1 hour, 21600 = 6 hours, 86400 = 1 day." + }, "host.flags.block-exploits": { "defaultMessage": "Блокувати відомі експлойти" }, diff --git a/frontend/src/locale/src/vi.json b/frontend/src/locale/src/vi.json index 32d26d5590..be42d858c4 100644 --- a/frontend/src/locale/src/vi.json +++ b/frontend/src/locale/src/vi.json @@ -344,6 +344,12 @@ "footer.github-fork": { "defaultMessage": "Fork dự án này trên Github" }, + "host.cache-ttl": { + "defaultMessage": "Thời gian lưu bộ nhớ đệm tài nguyên (giây)" + }, + "host.cache-ttl-help": { + "defaultMessage": "Ví dụ: 3600 = 1 giờ, 21600 = 6 giờ, 86400 = 1 ngày." + }, "host.flags.block-exploits": { "defaultMessage": "Chặn các hoạt động khai thác phổ biến" }, diff --git a/frontend/src/locale/src/zh.json b/frontend/src/locale/src/zh.json index 72494bb64f..a02ffd5197 100644 --- a/frontend/src/locale/src/zh.json +++ b/frontend/src/locale/src/zh.json @@ -350,6 +350,12 @@ "footer.github-fork": { "defaultMessage": "在 Github 上复刻 (Fork) 本项目" }, + "host.cache-ttl": { + "defaultMessage": "资源缓存时长(秒)" + }, + "host.cache-ttl-help": { + "defaultMessage": "示例:3600 = 1 小时,21600 = 6 小时,86400 = 1 天。" + }, "host.flags.block-exploits": { "defaultMessage": "阻止常见攻击" }, diff --git a/frontend/src/modals/ProxyHostModal.tsx b/frontend/src/modals/ProxyHostModal.tsx index 3227be51bb..eeed973ac0 100644 --- a/frontend/src/modals/ProxyHostModal.tsx +++ b/frontend/src/modals/ProxyHostModal.tsx @@ -13,6 +13,7 @@ import { Loading, LocationsFields, NginxConfigField, + ProxyCacheOptionsFields, SSLCertificateField, SSLOptionsFields, } from "src/components"; @@ -78,6 +79,7 @@ const ProxyHostModal = EasyModal.create(({ id, visible, remove }: Props) => { forwardPort: data?.forwardPort || undefined, accessListId: data?.accessListId || 0, cachingEnabled: data?.cachingEnabled || false, + assetCacheTtl: data?.assetCacheTtl ?? 1800, blockExploits: data?.blockExploits || false, allowWebsocketUpgrade: data?.allowWebsocketUpgrade || false, // Locations tab @@ -259,29 +261,7 @@ const ProxyHostModal = EasyModal.create(({ id, visible, remove }: Props) => {
-
- -
+