fix(backend): harden endpoint and startup config

This commit is contained in:
svemagie
2026-03-08 00:42:02 +01:00
parent 9427dedaa9
commit b6d0340e7c
4 changed files with 82 additions and 11 deletions

View File

@@ -9,6 +9,16 @@
- Post management UI should use `/posts` (`@indiekit/endpoint-posts.mountPath`). - Post management UI should use `/posts` (`@indiekit/endpoint-posts.mountPath`).
- Do not set post-management `mountPath` to frontend routes like `/blog`, otherwise backend publishing can be shadowed by the public site. - Do not set post-management `mountPath` to frontend routes like `/blog`, otherwise backend publishing can be shadowed by the public site.
## Backend endpoints
- Configured endpoint mount paths:
- Posts management: `/posts`
- Files: `/files`
- Webmentions moderation + API: `/webmentions`
- Conversations + API: `/conversations`
- GitHub activity + API: `/github`
- If IndieKit is reverse-proxied behind `/admin`, these become `/admin/posts`, `/admin/files`, etc.
## MongoDB ## MongoDB
- Preferred: set a full `MONGO_URL` (example: `mongodb://user:pass@host:27017/indiekit?authSource=admin`). - Preferred: set a full `MONGO_URL` (example: `mongodb://user:pass@host:27017/indiekit?authSource=admin`).
@@ -46,4 +56,9 @@
- `GH_CONTENT_TOKEN`: token for content repo (`blog`), used by `@indiekit/store-github`. - `GH_CONTENT_TOKEN`: token for content repo (`blog`), used by `@indiekit/store-github`.
- `GH_ACTIVITY_TOKEN`: token for GitHub dashboard/activity endpoint, used by `@rmdes/indiekit-endpoint-github`. - `GH_ACTIVITY_TOKEN`: token for GitHub dashboard/activity endpoint, used by `@rmdes/indiekit-endpoint-github`.
- `GITHUB_USERNAME`: GitHub user/owner name. - `GITHUB_USERNAME`: GitHub user/owner name.
- Backward compatibility: if `GH_CONTENT_TOKEN` or `GH_ACTIVITY_TOKEN` are not set, config falls back to `GITHUB_TOKEN`. - Backward compatibility: if `GH_CONTENT_TOKEN` or `GH_ACTIVITY_TOKEN` are not set, config falls back to `GITHUB_TOKEN`.
## Startup script
- `start.sh` is intentionally ignored by Git (`.gitignore`) so server secrets are not committed.
- Use `start.example.sh` as the tracked template and keep real credentials in environment variables (or `.env` on the server).

View File

@@ -1,2 +1,15 @@
require('dotenv').config(); require("dotenv/config");
require('indiekit').serve(); const { spawn } = require("child_process");
const args = [
require.resolve("@indiekit/indiekit/bin/cli.js"),
"serve",
"--config",
"indiekit.config.mjs",
];
const child = spawn(process.execPath, args, { stdio: "inherit" });
child.on("exit", (code) => {
process.exit(code ?? 1);
});

View File

@@ -27,6 +27,18 @@ const githubContentToken =
process.env.GH_CONTENT_TOKEN || process.env.GITHUB_TOKEN; process.env.GH_CONTENT_TOKEN || process.env.GITHUB_TOKEN;
const githubActivityToken = const githubActivityToken =
process.env.GH_ACTIVITY_TOKEN || process.env.GITHUB_TOKEN; process.env.GH_ACTIVITY_TOKEN || process.env.GITHUB_TOKEN;
const publicationBaseUrl = (
process.env.PUBLICATION_URL || "https://blog.giersig.eu"
).replace(/\/+$/, "");
let webmentionDomain = process.env.WEBMENTION_IO_DOMAIN;
if (!webmentionDomain) {
try {
webmentionDomain = new URL(publicationBaseUrl).hostname;
} catch {
webmentionDomain = "blog.giersig.eu";
}
}
export default { export default {
debug: "indiekit:*", debug: "indiekit:*",
@@ -35,55 +47,55 @@ export default {
mongodbUrl: mongoUrl, mongodbUrl: mongoUrl,
}, },
publication: { publication: {
me: "https://blog.giersig.eu", me: publicationBaseUrl,
postTypes: { postTypes: {
article: { article: {
name: "Artikel", name: "Artikel",
post: { post: {
path: "content/articles/{slug}.md", path: "content/articles/{slug}.md",
url: "https://blog.giersig.eu/articles/{slug}/", url: `${publicationBaseUrl}/articles/{slug}/`,
}, },
}, },
note: { note: {
name: "Notiz", name: "Notiz",
post: { post: {
path: "content/notes/{slug}.md", path: "content/notes/{slug}.md",
url: "https://blog.giersig.eu/notes/{slug}/", url: `${publicationBaseUrl}/notes/{slug}/`,
}, },
}, },
bookmark: { bookmark: {
name: "Lesezeichen", name: "Lesezeichen",
post: { post: {
path: "content/bookmarks/{slug}.md", path: "content/bookmarks/{slug}.md",
url: "https://blog.giersig.eu/bookmarks/{slug}/", url: `${publicationBaseUrl}/bookmarks/{slug}/`,
}, },
}, },
like: { like: {
name: "Like", name: "Like",
post: { post: {
path: "content/likes/{slug}.md", path: "content/likes/{slug}.md",
url: "https://blog.giersig.eu/likes/{slug}/", url: `${publicationBaseUrl}/likes/{slug}/`,
}, },
}, },
photo: { photo: {
name: "Foto", name: "Foto",
post: { post: {
path: "content/photos/{slug}.md", path: "content/photos/{slug}.md",
url: "https://blog.giersig.eu/photos/{slug}/", url: `${publicationBaseUrl}/photos/{slug}/`,
}, },
}, },
reply: { reply: {
name: "Antwort", name: "Antwort",
post: { post: {
path: "content/replies/{slug}.md", path: "content/replies/{slug}.md",
url: "https://blog.giersig.eu/replies/{slug}/", url: `${publicationBaseUrl}/replies/{slug}/`,
}, },
}, },
page: { page: {
name: "Seite", name: "Seite",
post: { post: {
path: "content/pages/{slug}.md", path: "content/pages/{slug}.md",
url: "https://blog.giersig.eu/{slug}/", url: `${publicationBaseUrl}/{slug}/`,
}, },
}, },
}, },
@@ -113,6 +125,7 @@ export default {
}, },
"@rmdes/indiekit-endpoint-webmention-io": { "@rmdes/indiekit-endpoint-webmention-io": {
token: process.env.WEBMENTION_IO_TOKEN, token: process.env.WEBMENTION_IO_TOKEN,
domain: webmentionDomain,
}, },
"@rmdes/indiekit-endpoint-conversations": { "@rmdes/indiekit-endpoint-conversations": {
mountPath: "/conversations", mountPath: "/conversations",

30
start.example.sh Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
set -eu
cd /usr/local/indiekit
# Optional: load environment from local .env file.
if [ -f .env ]; then
set -a
. ./.env
set +a
fi
: "${SECRET:?SECRET is required}"
: "${PASSWORD_SECRET:?PASSWORD_SECRET is required}"
# Allow either full Mongo URL or decomposed credentials.
if [ -z "${MONGO_URL:-}" ]; then
: "${MONGO_PASSWORD:?MONGO_PASSWORD is required when MONGO_URL is not set}"
export MONGO_USERNAME="${MONGO_USERNAME:-indiekit}"
export MONGO_AUTH_SOURCE="${MONGO_AUTH_SOURCE:-admin}"
fi
if [ -z "${GH_CONTENT_TOKEN:-}" ] && [ -z "${GITHUB_TOKEN:-}" ]; then
echo "GH_CONTENT_TOKEN or GITHUB_TOKEN is required" >&2
exit 1
fi
export NODE_ENV="${NODE_ENV:-production}"
exec /usr/local/bin/node node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs