Fix assets:create 404: form-urlencoded mot /apps/richdocuments/assets, intern CODE över HTTP

- lib/bridge.js createAssetLink: POST <nextcloudUrl>/apps/richdocuments/assets
  (utan index.php), Content-Type application/x-www-form-urlencoded med body
  path=<urlencoded>, path trimmad utan ledande slash (userFolder->get relativt
  filrot), OCS-APIRequest borttagen. Fel inkluderar statusCode + svarskropp.
- Intern collaboraUrl är HTTP: http://code:9980 (fallback http://<bridge-ip>:9980)
  i nc-collab-config default, .env.example, example-flows.json, docker-compose,
  install.sh och integrate-into-nodered.sh resolve_collabora_url.
- Publik WOPI-URL dokumenterad som https://docs.domain.name.
- package-lock.json för deterministisk form-data-install i Docker.
This commit is contained in:
dev
2026-08-22 21:27:02 +02:00
parent 9e5a7c0aeb
commit 6e02c2d31e
11 changed files with 332 additions and 38 deletions
+8 -6
View File
@@ -6,15 +6,17 @@ NEXTCLOUD_URL=https://cloud.domain.name
NEXTCLOUD_PUBLIC_URL=https://cloud.domain.name
# Collabora CODE
# COLLABORA_URL: https://code:9980 när CODE delar Docker-nätverk med Node-RED
# (integrate-into-nodered.sh connectar CODE till nodernätet automatiskt).
# Fallback om 'code' inte kan resolvas: https://<CODE-IP>:9980.
# COLLABORA_URL: intern CODE kör HTTP — http://code:9980 när CODE delar
# Docker-nätverk med Node-RED (integrate-into-nodered.sh connectar CODE
# till nodernätet automatiskt; annars: docker network connect bridge nextcloud-node-red).
# Fallback om 'code' inte kan resolvas: http://<CODE-IP>:9980 (t.ex. 172.17.0.x).
# ALDRIG http://127.0.0.1:9980 eller http://host.docker.internal:9980 —
# CODE lyssnar bara på HTTPS internt och kör inte på Node-RED-värden.
# verifyTls=false sätts i nc-collab-config-noden (self-signed cert internt).
# CODE kör inte på Node-RED-värden.
# Publik URL (browser/WOPI) styrs av collaboraPublicUrl i nc-collab-config,
# t.ex. https://docs.domain.name.
CODE_CONTAINER=code
COLLABORA_IP=
COLLABORA_URL=https://code:9980
COLLABORA_URL=http://code:9980
# Existing Node-RED install (integrate mode)
NODERED_DIR=
+5
View File
@@ -50,6 +50,11 @@ Palette: **nextcloud collabora** — six nodes in the same purple, all wired to
`nc-collab-config` · `collabora-bridge` · `nc-office` · `collabora-convert` · `collabora-extract` · `collabora-transform` · `collabora-wopi`
## Collabora URLs — intern vs publik
- **Intern `collaboraUrl`** (Node-RED → CODE): plain **HTTP** — `http://code:9980` när CODE delar nätverk med Node-RED, eller fallback `http://<bridge-ip>:9980` (t.ex. `172.17.0.x`) efter `docker network connect bridge nextcloud-node-red`. Aldrig HTTPS mot bridge-IP.
- **Publik `collaboraPublicUrl`** (browser/WOPI): `https://docs.domain.name` — CODE via reverse proxy.
Full guide and examples: **[docs/NODES.md](docs/NODES.md)** · import **[flows/example-flows.json](flows/example-flows.json)**
## Install on any Nextcloud VM
+1 -1
View File
@@ -13,7 +13,7 @@ services:
PORT: "1881"
TZ: ${TZ:-Europe/Stockholm}
NEXTCLOUD_URL: ${NEXTCLOUD_URL:-https://cloud.domain.name}
COLLABORA_URL: ${COLLABORA_URL:-https://code:9980}
COLLABORA_URL: ${COLLABORA_URL:-http://code:9980}
extra_hosts:
- "host.docker.internal:host-gateway"
- "cloud.domain.name:${NC_HOST_IP:-192.168.1.10}"
+4 -2
View File
@@ -35,8 +35,10 @@ Sidecar `nextcloud-collabora-nodered` on :1881 is **not used** — integrate mod
| Use | URL |
|-----|-----|
| Nextcloud API / WebDAV | `https://cloud.example.com` |
| CODE from Node-RED container | `https://<bridge-ip>:9980` (verifyTls=false) |
| Browser editor / WOPI | `collaboraPublicUrl` — usually same as Nextcloud proxy |
| CODE from Node-RED container (intern) | `http://code:9980` — plain **HTTP**; fallback `http://<bridge-ip>:9980` efter `docker network connect bridge nextcloud-node-red` |
| Browser editor / WOPI (publik) | `collaboraPublicUrl` — t.ex. `https://docs.domain.name` (CODE via reverse proxy) |
Intern CODE lyssnar på HTTP — aldrig HTTPS mot bridge-IP. Publik åtkomst via reverse proxy.
## Gitea (optional)
+12 -3
View File
@@ -7,7 +7,7 @@ Six flow nodes in the palette plus one config node. All six point at the same **
| Backend | Typical URL | Role |
|---------|-------------|------|
| Nextcloud | `https://cloud.example.com` | Files (WebDAV) + Office API (OCS) |
| Collabora CODE | `https://172.17.0.2:9980` | Conversion (`/cool/...`) on Docker bridge |
| Collabora CODE | `http://code:9980` (intern HTTP; fallback `http://<bridge-ip>:9980`) | Conversion (`/cool/...`) on Docker bridge |
Auth: **username + app password**. Not your account password.
@@ -167,8 +167,17 @@ Create under the gear icon in Node-RED. All six flow nodes pick the same config
| Field | Example |
|-------|---------|
| nextcloudUrl | `https://cloud.example.com` |
| collaboraUrl | `https://172.17.0.2:9980` (bridge IP, verifyTls=false) |
| collaboraPublicUrl | `https://cloud.example.com` |
| collaboraUrl | `http://code:9980` — intern CODE är **HTTP**; fallback `http://<bridge-ip>:9980` efter `docker network connect bridge nextcloud-node-red` |
| collaboraPublicUrl | `https://docs.domain.name` (publik, browser/WOPI) |
| username + app password | Nextcloud login |
Intern CODE körs utan TLS (`http://`) — publik åtkomst går via reverse proxy (HTTPS).
### createAssetLink (assets)
`collabora-bridge createAssetLink` / `nc-office assets:create` POSTar form-urlencoded
(`path=Dokument/logotyp.png`, relativt användarens filrot) mot
`<nextcloudUrl>/apps/richdocuments/assets`. `200 {url}` = asset-URL skapad;
`404` = filen finns inte i användarens rot (eller fel `nextcloudUrl`) — felet innehåller status + svarskropp.
CODE IP is detected when you run `./install.sh` — see `.env.example`.
+1 -1
View File
@@ -11,7 +11,7 @@
"type": "nc-collab-config",
"name": "cloud.domain.name",
"nextcloudUrl": "https://cloud.domain.name",
"collaboraUrl": "https://172.17.0.2:9980",
"collaboraUrl": "http://code:9980",
"collaboraPublicUrl": "https://cloud.domain.name",
"username": "FILL_IN_USER",
"verifyTls": false
+3 -3
View File
@@ -35,11 +35,11 @@ NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}"
COLLABORA_IP="${COLLABORA_IP:-}"
# Aldrig http://127.0.0.1:9980 eller http://host.docker.internal:9980
case "${COLLABORA_URL:-https://code:9980}" in
# Intern CODE är HTTP. Aldrig http://127.0.0.1:9980 eller http://host.docker.internal:9980
case "${COLLABORA_URL:-http://code:9980}" in
http://127.0.0.1:*|http://localhost:*|http://host.docker.internal:*|\
https://127.0.0.1:*|https://localhost:*|https://host.docker.internal:*|"")
COLLABORA_URL="https://code:9980" ;;
COLLABORA_URL="http://code:9980" ;;
*) COLLABORA_URL="${COLLABORA_URL}" ;;
esac
NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.domain.name}"
+26 -12
View File
@@ -2,6 +2,7 @@
const { webdavGet, webdavPut, webdavPropfindFileId } = require('./webdav');
const { ocsRequest } = require('./ocs');
const { requestBuffer } = require('./http-client');
const { convertTo, extractStructure, transformStructure } = require('./collabora');
const {
resolveDestNcPath,
@@ -210,33 +211,46 @@ async function extractToPayload(config, msg) {
}
async function createAssetLink(config, msg) {
const assetPath = pickMsgField(msg, 'ncPath');
const assetPath = pickMsgField(msg, 'ncPath', 'path');
if (!assetPath) {
throw new Error('createAssetLink kräver msg.ncPath');
throw new Error('createAssetLink kräver msg.ncPath eller msg.path');
}
const relPath = normalizeNcPath(assetPath);
const { requestBuffer } = require('./http-client');
const base = config.nextcloudUrl.replace(/\/$/, '');
// richdocuments AssetsController::create($path) läser form-parametern 'path'
// och slår upp filen relativt användarens filrot → ingen ledande slash.
const relPath = String(assetPath).trim().replace(/^\/+/, '').replace(/\/{2,}/g, '/');
const base = String(config.nextcloudUrl || '').replace(/\/+$/, '');
const token = Buffer.from(`${config.username}:${config.password}`).toString('base64');
const res = await requestBuffer({
url: `${base}/index.php/apps/richdocuments/assets`,
url: `${base}/apps/richdocuments/assets`,
method: 'POST',
headers: {
Authorization: `Basic ${token}`,
'OCS-APIRequest': 'true',
'Content-Type': 'application/json',
Accept: 'application/json'
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: Buffer.from(JSON.stringify({ path: relPath }), 'utf8'),
body: Buffer.from(`path=${encodeURIComponent(relPath)}`, 'utf8'),
rejectUnauthorized: config.verifyTls !== false && config.verifyTls !== 'false'
});
const bodyText = res.body.toString('utf8').trim();
if (res.statusCode < 200 || res.statusCode >= 300) {
throw new Error(`assets:create misslyckades (${res.statusCode})`);
throw new Error(
`assets:create misslyckades (${res.statusCode}): ${bodyText || '<tom body>'} — ` +
`path=${relPath}, url=${base}/apps/richdocuments/assets. ` +
'404 = filen saknas i användarens rot eller fel nextcloudUrl.'
);
}
let json;
try {
json = JSON.parse(bodyText);
} catch (e) {
throw new Error(`assets:create: ogiltigt JSON-svar (${res.statusCode}): ${bodyText.slice(0, 200)}`);
}
const json = JSON.parse(res.body.toString('utf8'));
return {
assetUrl: json.url || json.assetUrl || json,
ncPath: relPath
+4 -4
View File
@@ -4,7 +4,7 @@
defaults: {
name: { value: '' },
nextcloudUrl: { value: 'https://cloud.domain.name', required: true },
collaboraUrl: { value: 'https://172.17.0.2:9980', required: true },
collaboraUrl: { value: 'http://code:9980', required: true },
collaboraPublicUrl: { value: 'https://cloud.domain.name' },
username: { value: '', required: true },
verifyTls: { value: false }
@@ -56,11 +56,11 @@
<h4>Two backends</h4>
<ul>
<li><strong>Nextcloud</strong> (<code>nextcloudUrl</code>) — files via WebDAV + Office API (OCS richdocuments)</li>
<li><strong>Collabora CODE</strong> (<code>collaboraUrl</code>) — conversion engine (<code>/cool/...</code>). Internal Docker bridge, e.g. <code>https://172.17.0.2:9980</code>. IP is detected at install — don't hardcode blindly on every host.</li>
<li><strong>Collabora CODE</strong> (<code>collaboraUrl</code>) — conversion engine (<code>/cool/...</code>). Internal CODE is plain <strong>HTTP</strong>: <code>http://code:9980</code> (shared Docker network) or fallback <code>http://&lt;bridge-ip&gt;:9980</code>, e.g. <code>http://172.17.0.2:9980</code> after <code>docker network connect bridge nextcloud-node-red</code>. Never HTTPS against the internal bridge.</li>
</ul>
<p><strong>Auth:</strong> username + <em>app password</em>. Not your normal account password.</p>
<p><code>collaboraPublicUrl</code> — what the browser sees for WOPI/editor links (CODE proxied via Nextcloud). Internal IP won't work in an iframe.</p>
<p><code>verifyTls</code> — turn off for internal CODE when the cert doesn't match IP/hostname.</p>
<p><code>collaboraPublicUrl</code> — what the browser sees for WOPI/editor links, e.g. <code>https://docs.domain.name</code> (CODE proxied via Nextcloud/reverse proxy). Internal HTTP URLs won't work in an iframe.</p>
<p><code>verifyTls</code> — only relevant if you point <code>collaboraUrl</code> at an HTTPS endpoint; the default internal HTTP needs no TLS at all.</p>
<p>Default output folder in bridge if you omit a destination: <code>/Dokument/OfficeOut/</code></p>
</script>
+261
View File
@@ -0,0 +1,261 @@
{
"name": "node-red-contrib-nextcloud-collabora",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "node-red-contrib-nextcloud-collabora",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"form-data": "^4.0.4"
},
"engines": {
"node": ">=18"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/form-data": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
"integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.4",
"mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
}
}
}
+7 -6
View File
@@ -409,15 +409,16 @@ recreate_nodered_service() {
log "ExtraHosts (${extra}): $(docker inspect -f '{{json .HostConfig.ExtraHosts}}' "${NODERED_CONTAINER}")"
}
# COLLABORA_URL: https://code:9980 primärt, fallback https://<CODE-IP>:9980.
# COLLABORA_URL: intern CODE är HTTP — http://code:9980 primärt,
# fallback http://<CODE-IP>:9980.
# Aldrig http://127.0.0.1:9980 eller http://host.docker.internal:9980.
resolve_collabora_url() {
local url="${COLLABORA_URL:-https://code:9980}"
local url="${COLLABORA_URL:-http://code:9980}"
case "${url}" in
http://127.0.0.1:*|http://localhost:*|http://host.docker.internal:*|\
https://127.0.0.1:*|https://localhost:*|https://host.docker.internal:*)
warn "Otillåten COLLABORA_URL '${url}' — tvingar https://code:9980"
url="https://code:9980"
warn "Otillåten COLLABORA_URL '${url}' — tvingar http://code:9980"
url="http://code:9980"
;;
esac
@@ -427,8 +428,8 @@ resolve_collabora_url() {
ip="$(docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{$v.IPAddress}} {{end}}' "${CODE_CONTAINER}" 2>/dev/null | awk '{print $1}')"
[ -n "${ip}" ] || ip="${COLLABORA_IP:-}"
if [ -n "${ip}" ]; then
warn "'code' inte resolvbart från ${NODERED_CONTAINER} — fallback https://${ip}:9980"
url="https://${ip}:9980"
warn "'code' inte resolvbart från ${NODERED_CONTAINER} — fallback http://${ip}:9980"
url="http://${ip}:9980"
else
die "Varken 'code'-DNS eller CODE-IP tillgänglig — kan inte sätta COLLABORA_URL"
fi