Compare commits

...
1 Commits
Author SHA1 Message Date
zemion ea5f76554a Publish Toolbox 0.18.1 with local-only Random Tools 2026-09-01 08:32:15 +02:00
14 changed files with 47 additions and 54 deletions
+2 -2
View File
@@ -5,5 +5,5 @@ TRAEFIK_NETWORK=internal
TRAEFIK_CERT_RESOLVER=netcup TRAEFIK_CERT_RESOLVER=netcup
# Keep these two values paired when deploying a newer published toolbox release. # Keep these two values paired when deploying a newer published toolbox release.
TOOLBOX_RELEASE_VERSION=0.18.0 TOOLBOX_RELEASE_VERSION=0.18.1
TOOLBOX_RELEASE_SHA256=77100c45531cb53cb0638ed9407b9246571308659215f2df457f09613fd5351c TOOLBOX_RELEASE_SHA256=bd9f088bac80071cfafc934bc7fc04ffbfb1ada5ef417dbbe85bde878cb34f85
+2 -2
View File
@@ -2,8 +2,8 @@ ARG NGINX_IMAGE=nginxinc/nginx-unprivileged:1.31.3-alpine@sha256:18d67281256ded3
FROM ${NGINX_IMAGE} AS release FROM ${NGINX_IMAGE} AS release
ARG TOOLBOX_RELEASE_VERSION=0.18.0 ARG TOOLBOX_RELEASE_VERSION=0.18.1
ARG TOOLBOX_RELEASE_SHA256=77100c45531cb53cb0638ed9407b9246571308659215f2df457f09613fd5351c ARG TOOLBOX_RELEASE_SHA256=bd9f088bac80071cfafc934bc7fc04ffbfb1ada5ef417dbbe85bde878cb34f85
ARG TOOLBOX_RELEASE_BASE_URL=https://git.add-ideas.de/lotobo/toolbox-portal/releases/download ARG TOOLBOX_RELEASE_BASE_URL=https://git.add-ideas.de/lotobo/toolbox-portal/releases/download
RUN set -eu; \ RUN set -eu; \
+16 -16
View File
@@ -1,7 +1,7 @@
# add·ideas Toolbox Portal # add·ideas Toolbox Portal
`toolbox-portal` is the static launcher and release assembler for the add·ideas `toolbox-portal` is the static launcher and release assembler for the add·ideas
browser toolbox. Version `0.2.20` reads one same-origin catalogue, shows each app browser toolbox. Version `0.2.21` reads one same-origin catalogue, shows each app
as a compact launch tile, and keeps personal pins, drag-and-drop ordering, as a compact launch tile, and keeps personal pins, drag-and-drop ordering,
visibility, and appearance in the current browser. Pinned tools have their own visibility, and appearance in the current browser. Pinned tools have their own
section; search, category, and clickable tag filters stay close to the tool section; search, category, and clickable tag filters stay close to the tool
@@ -74,7 +74,7 @@ privacy and executable-code warning. Light, dark, and system modes are supported
## Production deployment behind Traefik ## Production deployment behind Traefik
The committed `compose.yaml` is the shortest production path. Its release The committed `compose.yaml` is the shortest production path. Its release
container downloads the immutable Toolbox 0.18.0 ZIP during the image build, container downloads the immutable Toolbox 0.18.1 ZIP during the image build,
verifies SHA-256 before extracting it, and then copies only the verified static verifies SHA-256 before extracting it, and then copies only the verified static
files into the pinned unprivileged nginx image. Node.js and a local portal files into the pinned unprivileged nginx image. Node.js and a local portal
assembly are not required on the deployment host. assembly are not required on the deployment host.
@@ -138,7 +138,7 @@ The app release should also publish a matching `.sha256` sidecar. The manifest
must declare the pinned reverse-DNS id and version. Application and portal must declare the pinned reverse-DNS id and version. Application and portal
versions are independent. versions are independent.
`release/toolbox.lock.json` is the reviewed Toolbox v0.18.0 / Portal v0.2.20 `release/toolbox.lock.json` is the reviewed Toolbox v0.18.1 / Portal v0.2.21
lock. Its URLs and checksums pin the published PDF Tools 0.4.4, XSLT Tools lock. Its URLs and checksums pin the published PDF Tools 0.4.4, XSLT Tools
0.4.3, OneNote Tools 0.3.4, 0.4.3, OneNote Tools 0.3.4,
Audio & Video Tools 0.3.0, Regex Tools 0.4.2, SVG Tools 0.1.0, OTP & Passkey Audio & Video Tools 0.3.0, Regex Tools 0.4.2, SVG Tools 0.1.0, OTP & Passkey
@@ -166,7 +166,7 @@ npm run assemble -- \
--lock release/toolbox.lock.json \ --lock release/toolbox.lock.json \
--portal-dist dist \ --portal-dist dist \
--output build/toolbox \ --output build/toolbox \
--archive build/add-ideas-toolbox-0.18.0.zip --archive build/add-ideas-toolbox-0.18.1.zip
``` ```
Existing output is refused. Pass `--force` only when replacing those exact Existing output is refused. Pass `--force` only when replacing those exact
@@ -209,8 +209,8 @@ build/toolbox/
├── text/ ├── text/
└── unicode/ └── unicode/
build/add-ideas-toolbox-0.18.0.zip build/add-ideas-toolbox-0.18.1.zip
build/add-ideas-toolbox-0.18.0.zip.sha256 build/add-ideas-toolbox-0.18.1.zip.sha256
``` ```
The assembler verifies SHA-256 before opening an artifact, validates every app The assembler verifies SHA-256 before opening an artifact, validates every app
@@ -231,7 +231,7 @@ directory separately:
```sh ```sh
npm run package:static -- \ npm run package:static -- \
--input build/toolbox \ --input build/toolbox \
--output artifacts/add-ideas-toolbox-0.18.0.zip --output artifacts/add-ideas-toolbox-0.18.1.zip
``` ```
This also emits a `.sha256` sidecar. This also emits a `.sha256` sidecar.
@@ -249,9 +249,9 @@ default. It is granted to the dedicated `auth.toolbox.add-ideas.de` origin and,
on the shared Toolbox host, only to `/apps/barcode/`; both apps still request it on the shared Toolbox host, only to `/apps/barcode/`; both apps still request it
only after an explicit user action. If `AUTH_TOOLS_HOST` is customized, update only after an explicit user action. If `AUTH_TOOLS_HOST` is customized, update
the exact host entry in `deploy/nginx.conf` and Auth Tools' pinned WebAuthn host the exact host entry in `deploy/nginx.conf` and Auth Tools' pinned WebAuthn host
at the same time. Random Tools is the only app whose path-specific CSP permits at the same time. Every Toolbox app, including Random Tools, is constrained to
an external connection, and only to `https://www.random.org`; the app requires same-origin connections. Random Tools implements its random generators locally
explicit per-session consent before making that optional request. with browser APIs and never calls a third-party randomness service.
The packaged policy intentionally does not grant CSP `unsafe-eval`. SaxonJS's The packaged policy intentionally does not grant CSP `unsafe-eval`. SaxonJS's
`ixsl:eval()` extension is therefore unsupported in this deployment profile; `ixsl:eval()` extension is therefore unsupported in this deployment profile;
@@ -261,9 +261,9 @@ Assemble first, then:
```sh ```sh
podman build -f Containerfile \ podman build -f Containerfile \
-t git.add-ideas.de/lotobo/toolbox:0.18.0 . -t git.add-ideas.de/lotobo/toolbox:0.18.1 .
podman run --rm -p 8080:8080 \ podman run --rm -p 8080:8080 \
git.add-ideas.de/lotobo/toolbox:0.18.0 git.add-ideas.de/lotobo/toolbox:0.18.1
``` ```
For a direct-port local deployment after assembly, use the separate example: For a direct-port local deployment after assembly, use the separate example:
@@ -280,7 +280,7 @@ docker login git.add-ideas.de
docker buildx build \ docker buildx build \
--platform linux/amd64,linux/arm64 \ --platform linux/amd64,linux/arm64 \
--file Containerfile.release \ --file Containerfile.release \
--tag git.add-ideas.de/lotobo/toolbox:0.18.0 \ --tag git.add-ideas.de/lotobo/toolbox:0.18.1 \
--tag git.add-ideas.de/lotobo/toolbox:0.18 \ --tag git.add-ideas.de/lotobo/toolbox:0.18 \
--push . --push .
``` ```
@@ -306,8 +306,8 @@ needs permission to push code, releases, and container packages to
all 26 apps, switch between them, and confirm the encoded `toolbox` all 26 apps, switch between them, and confirm the encoded `toolbox`
context. context.
5. Verify the distribution with 5. Verify the distribution with
`(cd build && sha256sum -c add-ideas-toolbox-0.18.0.zip.sha256)`. `(cd build && sha256sum -c add-ideas-toolbox-0.18.1.zip.sha256)`.
6. Commit the reviewed lock, tag the toolbox release (for example `v0.18.0`), and 6. Commit the reviewed lock, tag the toolbox release (for example `v0.18.1`), and
push the branch and tag to Gitea. push the branch and tag to Gitea.
7. In Gitea, open **Releases → New release**, select the tag, and upload the 7. In Gitea, open **Releases → New release**, select the tag, and upload the
static ZIP plus its `.sha256` file. Do not use a mutable “latest” URL in a static ZIP plus its `.sha256` file. Do not use a mutable “latest” URL in a
@@ -344,7 +344,7 @@ must not re-resolve app versions or substitute a newer release.
| **`network-tools`** | Initial offline v0.1.0 release; dedicated repository | Calculate IP networks and construct or inspect common network values | IPv4/IPv6 canonicalization and CIDR ranges; URL/query parsing without navigation; DNS-record construction; response-header inspection; CSP builder; MIME reference | Performs no DNS, URL, HTTP or scanning request; pasted values remain bounded and inert; results are construction and calculation aids rather than live network observations | | **`network-tools`** | Initial offline v0.1.0 release; dedicated repository | Calculate IP networks and construct or inspect common network values | IPv4/IPv6 canonicalization and CIDR ranges; URL/query parsing without navigation; DNS-record construction; response-header inspection; CSP builder; MIME reference | Performs no DNS, URL, HTTP or scanning request; pasted values remain bounded and inert; results are construction and calculation aids rather than live network observations |
| **`geo-tools`** | Initial local-first v0.1.0 release; dedicated repository | Inspect, convert, simplify and analyse geospatial files | GeoJSON, GPX, KML and coordinate CSV; WGS 84 bounds, distance and elevation; DouglasPeucker simplification; decimal/DMS conversion; coordinate-only sketch | Small Point/LineString/Polygon model with scalar properties; conversion losses are explicit; no CRS transformation, basemap request or survey-grade claim | | **`geo-tools`** | Initial local-first v0.1.0 release; dedicated repository | Inspect, convert, simplify and analyse geospatial files | GeoJSON, GPX, KML and coordinate CSV; WGS 84 bounds, distance and elevation; DouglasPeucker simplification; decimal/DMS conversion; coordinate-only sketch | Small Point/LineString/Polygon model with scalar properties; conversion losses are explicit; no CRS transformation, basemap request or survey-grade claim |
| **`helper-tools`** | Initial v0.1.0 app and reusable package release | Encode, convert, inspect and calculate with shared bounded primitives | Base/byte/text/URL conversion; Unicode and line transforms; exact number and unit conversion; hashes; CIDR; timestamps; hardened JSON/CSV; secure and seeded random primitives; deep-linked calculator workspaces | Framework-free `@add-ideas/toolbox-helpers` package is consumed directly by eleven v0.1 apps; operations disclose strictness, limits and non-cryptographic seeded boundaries | | **`helper-tools`** | Initial v0.1.0 app and reusable package release | Encode, convert, inspect and calculate with shared bounded primitives | Base/byte/text/URL conversion; Unicode and line transforms; exact number and unit conversion; hashes; CIDR; timestamps; hardened JSON/CSV; secure and seeded random primitives; deep-linked calculator workspaces | Framework-free `@add-ideas/toolbox-helpers` package is consumed directly by eleven v0.1 apps; operations disclose strictness, limits and non-cryptographic seeded boundaries |
| **`rand-tools`** | Initial local-first v0.1.0 release; dedicated repository | Generate secure or reproducible random values through focused workspaces | Unbiased WebCrypto integers/strings; seeded reproducible generation; UUIDv4/v7 and ULID; dice; sampling, shuffle, passphrases and normal distribution; optional RANDOM.ORG integers | Secure local generation never falls back; deterministic output is not secret; the one remote source requires explicit per-session consent and a path-specific CSP and may still be unavailable through CORS or service limits | | **`rand-tools`** | Local-only v0.1.1 release; dedicated repository | Generate secure or reproducible random values through focused workspaces | Unbiased WebCrypto integers/strings; seeded reproducible generation; UUIDv4/v7 and ULID; dice; sampling, shuffle, passphrases and normal distribution; all generators run entirely in the browser | Secure local generation never falls back; deterministic output is reproducible rather than secret; the app makes no third-party randomness request and the Portal grants it no external network destination |
| **`data-tools`** | Initial local-first v0.1.0 release; dedicated repository | Inspect, format, query, flatten and convert structured data | JSON, YAML 1.2, TOML, XML, CSV, TSV and NDJSON; exact JSON numbers; bounded tree/table/leaf views; JSON Pointer and safe path queries; all-format conversion with loss/coercion reports; spreadsheet-formula neutralization | Disposable bounded parser worker; rejects active XML constructs and unsafe object keys; conversions surface information loss and round-trip instability | | **`data-tools`** | Initial local-first v0.1.0 release; dedicated repository | Inspect, format, query, flatten and convert structured data | JSON, YAML 1.2, TOML, XML, CSV, TSV and NDJSON; exact JSON numbers; bounded tree/table/leaf views; JSON Pointer and safe path queries; all-format conversion with loss/coercion reports; spreadsheet-formula neutralization | Disposable bounded parser worker; rejects active XML constructs and unsafe object keys; conversions surface information loss and round-trip instability |
| **`diff-tools`** | Initial local-first v0.1.0 release; dedicated repository | Compare text, JSON, XML and delimited data semantically | Line/word/code-point/grapheme text diff; exact newline state; object-aware exact-number JSON and RFC 6902; namespace-aware XML rules; keyed CSV/TSV; unified/side-by-side views and portable reports | Normalization settings and ignored distinctions remain visible; bounded disposable worker; v0.1 intentionally excludes images, binary documents, directories and archives | | **`diff-tools`** | Initial local-first v0.1.0 release; dedicated repository | Compare text, JSON, XML and delimited data semantically | Line/word/code-point/grapheme text diff; exact newline state; object-aware exact-number JSON and RFC 6902; namespace-aware XML rules; keyed CSV/TSV; unified/side-by-side views and portable reports | Normalization settings and ignored distinctions remain visible; bounded disposable worker; v0.1 intentionally excludes images, binary documents, directories and archives |
| **`time-tools`** | Initial local-first v0.1.0 release; dedicated repository | Convert timestamps and explore zones, arithmetic and recurrence | Exact signed nanosecond epochs; IANA-zone comparisons and DST ambiguity; wall-clock versus elapsed arithmetic; bounded cron and RRULE previews; business days; escaped UTC ICS export | Uses the browser's IANA data and does not model leap seconds; regional holidays are never inferred; recurrence and skipped/ambiguous local-time choices are explicit | | **`time-tools`** | Initial local-first v0.1.0 release; dedicated repository | Convert timestamps and explore zones, arithmetic and recurrence | Exact signed nanosecond epochs; IANA-zone comparisons and DST ambiguity; wall-clock versus elapsed arithmetic; bounded cron and RRULE previews; business days; escaped UTC ICS export | Uses the browser's IANA data and does not model leap seconds; regional holidays are never inferred; recurrence and skipped/ambiguous local-time choices are explicit |
+1 -1
View File
@@ -3,7 +3,7 @@ services:
build: build:
context: . context: .
dockerfile: Containerfile dockerfile: Containerfile
image: git.add-ideas.de/lotobo/toolbox:0.18.0 image: git.add-ideas.de/lotobo/toolbox:0.18.1
restart: unless-stopped restart: unless-stopped
read_only: true read_only: true
ports: ports:
+3 -3
View File
@@ -6,9 +6,9 @@ services:
context: . context: .
dockerfile: Containerfile.release dockerfile: Containerfile.release
args: args:
TOOLBOX_RELEASE_VERSION: "${TOOLBOX_RELEASE_VERSION:-0.18.0}" TOOLBOX_RELEASE_VERSION: "${TOOLBOX_RELEASE_VERSION:-0.18.1}"
TOOLBOX_RELEASE_SHA256: "${TOOLBOX_RELEASE_SHA256:-77100c45531cb53cb0638ed9407b9246571308659215f2df457f09613fd5351c}" TOOLBOX_RELEASE_SHA256: "${TOOLBOX_RELEASE_SHA256:-bd9f088bac80071cfafc934bc7fc04ffbfb1ada5ef417dbbe85bde878cb34f85}"
image: "git.add-ideas.de/lotobo/toolbox:${TOOLBOX_RELEASE_VERSION:-0.18.0}" image: "git.add-ideas.de/lotobo/toolbox:${TOOLBOX_RELEASE_VERSION:-0.18.1}"
restart: unless-stopped restart: unless-stopped
read_only: true read_only: true
tmpfs: tmpfs:
+1 -6
View File
@@ -20,11 +20,6 @@ map "$host:$uri" $toolbox_permissions_policy {
"~^[^:]+:/apps/barcode(?:/|$)" "camera=(self), microphone=(), geolocation=(), payment=(), usb=()"; "~^[^:]+:/apps/barcode(?:/|$)" "camera=(self), microphone=(), geolocation=(), payment=(), usb=()";
} }
map $uri $toolbox_connect_sources {
default "'self'";
"~^/apps/rand(?:/|$)" "'self' https://www.random.org";
}
server { server {
listen 8080; listen 8080;
listen [::]:8080; listen [::]:8080;
@@ -43,7 +38,7 @@ server {
add_header Cross-Origin-Resource-Policy $toolbox_resource_policy always; add_header Cross-Origin-Resource-Policy $toolbox_resource_policy always;
add_header Access-Control-Allow-Origin $toolbox_access_control_allow_origin always; add_header Access-Control-Allow-Origin $toolbox_access_control_allow_origin always;
add_header Permissions-Policy $toolbox_permissions_policy always; add_header Permissions-Policy $toolbox_permissions_policy always;
add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; connect-src $toolbox_connect_sources; worker-src 'self' blob:; manifest-src 'self'" always; add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; connect-src 'self'; worker-src 'self' blob:; manifest-src 'self'" always;
add_header Cache-Control $toolbox_cache_control always; add_header Cache-Control $toolbox_cache_control always;
gzip on; gzip on;
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "@add-ideas/toolbox-portal", "name": "@add-ideas/toolbox-portal",
"version": "0.2.20", "version": "0.2.21",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@add-ideas/toolbox-portal", "name": "@add-ideas/toolbox-portal",
"version": "0.2.20", "version": "0.2.21",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"dependencies": { "dependencies": {
"@add-ideas/toolbox-contract": "^0.2.3", "@add-ideas/toolbox-contract": "^0.2.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@add-ideas/toolbox-portal", "name": "@add-ideas/toolbox-portal",
"version": "0.2.20", "version": "0.2.21",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"private": true, "private": true,
"type": "module", "type": "module",
+2 -2
View File
@@ -1,8 +1,8 @@
# Corresponding source # Corresponding source
The source code corresponding to add·ideas Toolbox Portal 0.2.20 is available at: The source code corresponding to add·ideas Toolbox Portal 0.2.21 is available at:
https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.18.0 https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.18.1
Each bundled application contains its own `SOURCE.md`, license, and third-party Each bundled application contains its own `SOURCE.md`, license, and third-party
license materials. The application sources are also linked from the portal. license materials. The application sources are also linked from the portal.
+5 -5
View File
@@ -1,8 +1,8 @@
{ {
"$schema": "./toolbox-release-lock.schema.json", "$schema": "./toolbox-release-lock.schema.json",
"schemaVersion": 1, "schemaVersion": 1,
"releaseVersion": "0.18.0", "releaseVersion": "0.18.1",
"portalVersion": "0.2.20", "portalVersion": "0.2.21",
"catalogue": { "catalogue": {
"id": "de.add-ideas.toolbox", "id": "de.add-ideas.toolbox",
"name": "add·ideas Toolbox", "name": "add·ideas Toolbox",
@@ -155,9 +155,9 @@
}, },
{ {
"id": "de.add-ideas.rand-tools", "id": "de.add-ideas.rand-tools",
"version": "0.1.0", "version": "0.1.1",
"artifact": "https://git.add-ideas.de/lotobo/rand-tools/releases/download/v0.1.0/rand-tools-0.1.0.zip", "artifact": "https://git.add-ideas.de/lotobo/rand-tools/releases/download/v0.1.1/rand-tools-0.1.1.zip",
"sha256": "1dff2cf2165b04f171b12cb2303fe6b005eedf59c58ae839b77c40cc46c4bf25", "sha256": "02dffcbbf1c3ff65236a83466aa750c3848777e4a69ac389fe24da02abfc0e77",
"target": "rand" "target": "rand"
}, },
{ {
+5 -5
View File
@@ -1,8 +1,8 @@
{ {
"$schema": "./toolbox-release-lock.schema.json", "$schema": "./toolbox-release-lock.schema.json",
"schemaVersion": 1, "schemaVersion": 1,
"releaseVersion": "0.18.0", "releaseVersion": "0.18.1",
"portalVersion": "0.2.20", "portalVersion": "0.2.21",
"catalogue": { "catalogue": {
"id": "de.add-ideas.toolbox", "id": "de.add-ideas.toolbox",
"name": "add·ideas Toolbox", "name": "add·ideas Toolbox",
@@ -155,9 +155,9 @@
}, },
{ {
"id": "de.add-ideas.rand-tools", "id": "de.add-ideas.rand-tools",
"version": "0.1.0", "version": "0.1.1",
"artifact": "https://git.add-ideas.de/lotobo/rand-tools/releases/download/v0.1.0/rand-tools-0.1.0.zip", "artifact": "https://git.add-ideas.de/lotobo/rand-tools/releases/download/v0.1.1/rand-tools-0.1.1.zip",
"sha256": "1dff2cf2165b04f171b12cb2303fe6b005eedf59c58ae839b77c40cc46c4bf25", "sha256": "02dffcbbf1c3ff65236a83466aa750c3848777e4a69ac389fe24da02abfc0e77",
"target": "rand" "target": "rand"
}, },
{ {
+1 -1
View File
@@ -83,7 +83,7 @@ function makeLock(artifact: string, sha256: string) {
return { return {
schemaVersion: 1, schemaVersion: 1,
releaseVersion: '0.1.0', releaseVersion: '0.1.0',
portalVersion: '0.2.20', portalVersion: '0.2.21',
catalogue: { catalogue: {
id: 'de.add-ideas.toolbox', id: 'de.add-ideas.toolbox',
name: 'Test Toolbox', name: 'Test Toolbox',
+4 -6
View File
@@ -214,14 +214,12 @@ describe('production deployment', () => {
).toHaveLength(1); ).toHaveLength(1);
}); });
it('allows RANDOM.ORG only for the explicitly opt-in Random Tools path', () => { it('keeps application network connections same-origin', () => {
expect(nginxConfig).toMatch( expect(nginxConfig).toMatch(
/map \$uri \$toolbox_connect_sources\s*\{\s*default "'self'";\s*"~\^\/apps\/rand\(\?:\/\|\$\)" "'self' https:\/\/www\.random\.org";\s*\}/mu /^\s*add_header Content-Security-Policy "[^"]*connect-src 'self';[^"]*" always;$/mu
); );
expect(nginxConfig).toMatch( expect(nginxConfig).not.toContain('$toolbox_connect_sources');
/^\s*add_header Content-Security-Policy "[^"]*connect-src \$toolbox_connect_sources;[^"]*" always;$/mu expect(nginxConfig).not.toMatch(/https?:\/\//u);
);
expect(nginxConfig.match(/https:\/\/www\.random\.org/gu)).toHaveLength(1);
}); });
it('quotes nginx regular expressions that contain brace quantifiers', () => { it('quotes nginx regular expressions that contain brace quantifiers', () => {
+2 -2
View File
@@ -489,9 +489,9 @@ export default function App() {
</span> </span>
</p> </p>
<span> <span>
Portal v0.2.20 ·{' '} Portal v0.2.21 ·{' '}
<a <a
href="https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.18.0" href="https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.18.1"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >