DUNGEONS-30: support Node 18 runtime and Docker

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
2026-09-05 17:18:40 +05:00
parent b87a8ef70e
commit eb135ac6ef
5 changed files with 95 additions and 30 deletions

2
.nvmrc
View File

@@ -1 +1 @@
22 18.20.8

View File

@@ -1,4 +1,4 @@
FROM node:22-alpine FROM node:18.20.8-alpine
WORKDIR /app WORKDIR /app
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci --omit=dev --no-fund && mkdir -p /app/data && chown node:node /app/data RUN npm ci --omit=dev --no-fund && mkdir -p /app/data && chown node:node /app/data

View File

@@ -8,9 +8,10 @@ The gateway forwards the configured Dungeons-Ground site on the same public orig
## Local start ## Local start
Use Node.js **22.15+ on the Node 22 line** (the `.nvmrc` selects Node 22), Node 24, or Node 26+. Use Node.js **18.20.5 or newer on the Node 18 line**, or Node 20.9+. The `.nvmrc` and Docker image select **Node 18.20.8**. The proxy uses the Node 18-compatible `http-proxy-middleware` 3.x line.
```sh ```sh
nvm install
nvm use nvm use
npm ci npm ci
cp .env.example .env cp .env.example .env
@@ -25,6 +26,8 @@ npm start
With the default local URLs, open `http://localhost:8080`; the upstream is `http://127.0.0.1:3000`. `npm run dev` restarts on source changes. Environment variables supplied by a host override `.env`. The server reads `.env` from the directory in which it starts. With the default local URLs, open `http://localhost:8080`; the upstream is `http://127.0.0.1:3000`. `npm run dev` restarts on source changes. Environment variables supplied by a host override `.env`. The server reads `.env` from the directory in which it starts.
When updating an existing checkout from the Node 22 version, pull `main`, select Node 18 with `nvm install && nvm use`, and run `npm ci` to replace the old proxy dependencies before `npm start`. Keep your existing `.env` and `data` directory.
For a visual preview, development mode may run with both tokens empty. It displays an honest unavailable message in place of bot links; there is no built-in bypass number. Production requires at least one configured provider and an HTTPS `PUBLIC_URL`. For a visual preview, development mode may run with both tokens empty. It displays an honest unavailable message in place of bot links; there is no built-in bypass number. Production requires at least one configured provider and an HTTPS `PUBLIC_URL`.
## Telegram setup ## Telegram setup
@@ -116,4 +119,4 @@ npm test
The suite covers both bot adapters with mocked provider APIs, administrator authorization, failed DM recovery, duplicate reviews, reusable codes and expiry/renewal, persistent sessions, rate limits, signed Discord interactions, unauthenticated HTTP/WebSocket denial, streaming proxy requests, redirects, cookies, logout, and upstream outages. It requires no external credentials. Live Telegram/Discord delivery still needs an installation with real tokens, configured admins and working DMs. The suite covers both bot adapters with mocked provider APIs, administrator authorization, failed DM recovery, duplicate reviews, reusable codes and expiry/renewal, persistent sessions, rate limits, signed Discord interactions, unauthenticated HTTP/WebSocket denial, streaming proxy requests, redirects, cookies, logout, and upstream outages. It requires no external credentials. Live Telegram/Discord delivery still needs an installation with real tokens, configured admins and working DMs.
Protocol references: [Telegram Bot API](https://core.telegram.org/bots/api), [Discord interactions](https://docs.discord.com/developers/interactions/receiving-and-responding), [Discord application commands](https://docs.discord.com/developers/interactions/application-commands), [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware). Protocol references: [Telegram Bot API](https://core.telegram.org/bots/api), [Discord interactions](https://docs.discord.com/developers/interactions/receiving-and-responding), [Discord application commands](https://docs.discord.com/developers/interactions/application-commands), [http-proxy-middleware 3.x](https://github.com/chimurai/http-proxy-middleware/tree/v3.0.7).

110
package-lock.json generated
View File

@@ -9,13 +9,31 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"dotenv": "17.4.2", "dotenv": "17.4.2",
"http-proxy-middleware": "4.2.0" "http-proxy-middleware": "3.0.7"
}, },
"devDependencies": { "devDependencies": {
"ws": "8.21.0" "ws": "8.21.0"
}, },
"engines": { "engines": {
"node": "^22.15.0 || ^24.0.0 || >=26.0.0" "node": "^18.20.5 || >=20.9.0"
}
},
"node_modules/@types/http-proxy": {
"version": "1.17.17",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz",
"integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "26.4.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.1.tgz",
"integrity": "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==",
"license": "MIT",
"dependencies": {
"undici-types": "~8.3.0"
} }
}, },
"node_modules/braces": { "node_modules/braces": {
@@ -59,6 +77,12 @@
"url": "https://dotenvx.com" "url": "https://dotenvx.com"
} }
}, },
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"license": "MIT"
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -71,28 +95,57 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/http-proxy-middleware": { "node_modules/follow-redirects": {
"version": "4.2.0", "version": "1.16.0",
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-4.2.0.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
"integrity": "sha512-ZA+oNOoM+GLoFTIzhkJptVQov73Srep2LBqhF8hG8CIPKO3nam1jonXVQ/QUH8RbwsmaaVz2SOJdzBNBHNtKbw==", "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "^4.4.3", "eventemitter3": "^4.0.0",
"httpxy": "^0.5.4", "follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-proxy-middleware": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.7.tgz",
"integrity": "sha512-iwbQltVlx8bCrqePUM8C+hllHvdawVhQJaLrj1X7qllkvFQdXFsr16pW/mo9+JDVjN+QO2XUx9jd8SmoFkE5qw==",
"license": "MIT",
"dependencies": {
"@types/http-proxy": "^1.17.15",
"debug": "^4.3.6",
"http-proxy": "^1.18.1",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
"is-plain-obj": "^4.1.0", "is-plain-object": "^5.0.0",
"micromatch": "^4.0.8" "micromatch": "^4.0.8"
}, },
"engines": { "engines": {
"node": "^22.15.0 || ^24.0.0 || >=26.0.0" "node": "^14.18.0 || ^16.10.0 || >=18.0.0"
} }
}, },
"node_modules/httpxy": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.5.5.tgz",
"integrity": "sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==",
"license": "MIT"
},
"node_modules/is-extglob": { "node_modules/is-extglob": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -123,16 +176,13 @@
"node": ">=0.12.0" "node": ">=0.12.0"
} }
}, },
"node_modules/is-plain-obj": { "node_modules/is-plain-object": {
"version": "4.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.1.0.tgz",
"integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "integrity": "sha512-bUi/yjmtKYcRVUtWRGr0UA6xEFh2I6zWUwMrUXB3s7bmYCaZ8a+0ZsTRkrawh/mzlSD1Y0Ph8bp/U+TvBpWDNw==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=12" "node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/micromatch": { "node_modules/micromatch": {
@@ -166,6 +216,12 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT"
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -178,6 +234,12 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/undici-types": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
"license": "MIT"
},
"node_modules/ws": { "node_modules/ws": {
"version": "8.21.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",

View File

@@ -4,7 +4,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"description": "Dungeons & Ground private-alpha access gateway with Telegram and Discord approval", "description": "Dungeons & Ground private-alpha access gateway with Telegram and Discord approval",
"engines": { "node": "^22.15.0 || ^24.0.0 || >=26.0.0" }, "engines": { "node": "^18.20.5 || >=20.9.0" },
"scripts": { "scripts": {
"start": "node src/index.js", "start": "node src/index.js",
"dev": "node --watch src/index.js", "dev": "node --watch src/index.js",
@@ -15,7 +15,7 @@
}, },
"dependencies": { "dependencies": {
"dotenv": "17.4.2", "dotenv": "17.4.2",
"http-proxy-middleware": "4.2.0" "http-proxy-middleware": "3.0.7"
}, },
"devDependencies": { "ws": "8.21.0" } "devDependencies": { "ws": "8.21.0" }
} }