8daa96afe22b19f18790bb56014429c3789e2376
Indieweb/kit Blog Server
Admin login
- The IndieKit admin uses root auth/session paths (for example:
/session/login,/auth,/auth/new-password). - Login uses
PASSWORD_SECRET(bcrypt hash), notINDIEKIT_PASSWORD. - If no
PASSWORD_SECRETexists yet, open/auth/new-passwordonce to generate it. - If login is blocked because
PASSWORD_SECRETis missing/invalid, setINDIEKIT_ALLOW_PASSWORD_SETUP=1temporarily, restart, generate a new hash via/auth/new-password, setPASSWORD_SECRETto that hash, then removeINDIEKIT_ALLOW_PASSWORD_SETUP. - If login appears passwordless, first check for an existing authenticated session cookie. Use
/session/logoutto force a fresh login challenge. - Upstream IndieKit auto-authenticates in dev mode (
NODE_ENV=development). This repository patches that behavior so dev auto-auth only works whenINDIEKIT_ALLOW_DEV_AUTH=1is explicitly set. - Production startup now fails closed when auth/session settings are unsafe (
NODE_ENVnotproduction,INDIEKIT_ALLOW_DEV_AUTH=1, weakSECRET, missing/invalidPASSWORD_SECRET, or empty-password hash). - Post management UI should use
/posts(@indiekit/endpoint-posts.mountPath). - Do not set post-management
mountPathto 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 - Homepage builder UI + API:
/homepage - Conversations + API:
/conversations - GitHub activity + API:
/github - Funkwhale activity + API:
/funkwhale - Last.fm activity + API:
/lastfmapi - ActivityPub federation + admin reader:
/activitypub - ActivityPub discovery:
/.well-known/webfinger,/nodeinfo/2.1
MongoDB
- Preferred: set
MONGO_USERNAMEandMONGO_PASSWORDexplicitly; config builds the URL fromMONGO_USERNAME,MONGO_PASSWORD,MONGO_HOST,MONGO_PORT,MONGO_DATABASE,MONGO_AUTH_SOURCE. - You can still use a full
MONGO_URL(example:mongodb://user:pass@host:27017/indiekit?authSource=admin). - If both
MONGO_URLandMONGO_USERNAME/MONGO_PASSWORDare set, decomposed credentials take precedence by default to avoid stale URL mismatches. SetMONGO_PREFER_URL=1to forceMONGO_URLprecedence. - Startup scripts now fail fast when
MONGO_URLis absent andMONGO_USERNAMEis missing, to avoid silent auth mismatches. - Startup now runs
scripts/preflight-mongo-connection.mjsbefore boot. Preflight is strict by default and aborts start on Mongo auth/connect failures; setREQUIRE_MONGO=0to bypass strict mode intentionally. - For
MongoServerError: Authentication failed, first verifyMONGO_PASSWORD, then tryMONGO_AUTH_SOURCE=admin.
Content paths
- This setup writes post files to the content repo
blogundercontent/. - Photo upload binaries are written to
images/{filename}and published at${PUBLICATION_URL}/images/{filename}. - Current paths in
publication.postTypesare: content/articles/{slug}.mdcontent/notes/{slug}.mdcontent/bookmarks/{slug}.mdcontent/likes/{slug}.mdcontent/photos/{slug}.mdcontent/replies/{slug}.mdcontent/pages/{slug}.md- If these paths do not match the content repo structure, edit/delete actions can fail with GitHub
Not Found. - Reposts are configured as a dedicated post type (
repost) and stored atcontent/reposts/{slug}.md.
Post URLs
- Current post URLs in
publication.postTypesare: https://blog.giersig.eu/articles/{slug}/https://blog.giersig.eu/notes/{slug}/https://blog.giersig.eu/bookmarks/{slug}/https://blog.giersig.eu/likes/{slug}/https://blog.giersig.eu/photos/{slug}/https://blog.giersig.eu/replies/{slug}/https://blog.giersig.eu/{slug}/(page post type)
GitHub tokens
- Recommended for two-repo setups:
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.GITHUB_USERNAME: GitHub user/owner name.- Backward compatibility: if
GH_CONTENT_TOKENorGH_ACTIVITY_TOKENare not set, config falls back toGITHUB_TOKEN.
Listening tokens
- Funkwhale endpoint requirements:
FUNKWHALE_INSTANCE(for examplehttps://your-funkwhale.example, root server URL only)FUNKWHALE_USERNAMEFUNKWHALE_TOKEN(read API token)- Last.fm endpoint requirements:
LASTFM_API_KEYLASTFM_USERNAME- Listening endpoint plugins target Node.js 20+; older runtimes can produce inconsistent fetch/JSON behavior.
- If
FUNKWHALE_INSTANCEpoints to a host that does not expose Funkwhale's API routes, API responses now degrade to empty data instead of repeated 500 errors. - If these variables are missing, the endpoints still exist but return empty activity until credentials are configured.
ActivityPub
- ActivityPub federation is enabled via
@rmdes/indiekit-endpoint-activitypub. - Actor handle resolution order is:
AP_HANDLE, thenACTIVITYPUB_HANDLE, thenGITHUB_USERNAME, then publication hostname first label. - Actor profile seed values come from
AUTHOR_NAME,AUTHOR_BIO,AUTHOR_AVATAR, andSITE_DESCRIPTION. AUTHOR_AVATARcan be absolute (https://...) or slash-relative (/images/avatar.jpg); startup normalizes it to an absolute URL.- Optional ActivityPub variables:
AP_ALSO_KNOWN_AS(Mastodon migration alias URL)AP_LOG_LEVEL(debug|info|warning|error|fatal, defaultinfo)AP_DEBUG(1ortrueenables debug dashboard)AP_DEBUG_PASSWORD(required when debug dashboard is enabled)REDIS_URL(recommended for production delivery queue durability)- Startup preflight
scripts/preflight-activitypub-rsa-key.mjsensuresap_keyscontains a usable RSA key pair (publicKeyPem+privateKeyPem) so outgoing inbox deliveries are HTTP-signed and not rejected withRequest not signed. - Startup preflight
scripts/preflight-activitypub-profile-urls.mjsnormalizes existing ActivityPub profile URL fields in MongoDB (url,icon,image,alsoKnownAs) so WebFinger/actor responses do not fail on invalid URL values. - The ActivityPub locale patch creates/repairs
locales/de.jsonfromlocales/en.jsonso backend UI keys do not render as rawactivitypub.*translation strings whenSITE_LOCALE=de. - Quick verification commands:
curl -s "https://blog.giersig.eu/.well-known/webfinger?resource=acct:<handle>@blog.giersig.eu" | jq .curl -s -H "Accept: application/activity+json" "https://blog.giersig.eu/" | jq .curl -s "https://blog.giersig.eu/nodeinfo/2.1" | jq .- If a reverse proxy serves static HTML, ensure AP requests are proxied to Indiekit for
/activitypub*,/.well-known/*,/nodeinfo/*, and content-negotiatedAccept: application/activity+json/application/ld+jsonrequests on/and post URLs.
Startup script
start.shis intentionally ignored by Git (.gitignore) so server secrets are not committed.- Use
start.example.shas the tracked template and keep real credentials in environment variables (or.envon the server). - Startup scripts parse
.envwith thedotenvparser (not shellsource), so values containing spaces are handled safely. - Startup scripts run preflight + patch helpers before boot (
scripts/preflight-production-security.mjs,scripts/preflight-mongo-connection.mjs,scripts/preflight-activitypub-rsa-key.mjs,scripts/preflight-activitypub-profile-urls.mjs,scripts/patch-lightningcss.mjs,scripts/patch-endpoint-media-scope.mjs,scripts/patch-endpoint-media-sharp-runtime.mjs,scripts/patch-frontend-sharp-runtime.mjs,scripts/patch-endpoint-files-upload-route.mjs,scripts/patch-endpoint-files-upload-locales.mjs,scripts/patch-endpoint-activitypub-locales.mjs,scripts/patch-frontend-serviceworker-file.mjs,scripts/patch-conversations-collection-guards.mjs,scripts/patch-indiekit-routes-rate-limits.mjs,scripts/patch-indiekit-error-production-stack.mjs,scripts/patch-indieauth-devmode-guard.mjs,scripts/patch-listening-endpoint-runtime-guards.mjs). - The production security preflight blocks startup on insecure auth/session configuration and catches empty-password bcrypt hashes.
- One-time recovery mode is available with
INDIEKIT_ALLOW_PASSWORD_SETUP=1to bootstrap/resetPASSWORD_SECRETwhen locked out. Remove this flag after setting a valid hash. - The media scope patch fixes a known upstream issue where file uploads can fail if the token scope is
create update deletewithout explicitmedia. - The ActivityPub RSA key preflight repairs or creates a usable
type="rsa"key document inap_keys, so outgoing federation requests can be signed and accepted by stricter inboxes. - The ActivityPub profile URL preflight repairs invalid URL fields in the
ap_profiledocument (for example relativeiconpaths), preventing/.well-known/webfingerand actor responses from failing withTypeError: Invalid URL. - The media sharp runtime patch makes image transformation resilient on FreeBSD: if
sharpcannot load, uploads continue without resize/rotation instead of crashing the server process. - The frontend sharp runtime patch makes icon generation non-fatal on FreeBSD when
sharpcannot load, preventing startup crashes in asset controller imports. - The files upload route patch fixes browser multi-upload by posting to
/files/upload(session-authenticated) instead of direct/mediacalls without bearer token. - The files upload locale patch adds missing
files.upload.dropText/files.upload.browse/files.upload.submitMultiplelabels in endpoint locale files so UI text does not render raw translation keys. - The ActivityPub locale patch backfills missing
delocale keys from the endpoint'senlocale and applies German admin title labels for notifications/profile. - The frontend serviceworker patch ensures
@indiekit/frontend/lib/serviceworker.jsexists at runtime, forces network-only handling for/authand/sessionpages, patches frontend layout templates to unregister stale service workers and clear caches on load, and suppresses sidebar rendering wheneverapp--minimaluiis present. - The conversations guard patch prevents
Cannot read properties of undefined (reading 'find')when theconversation_itemscollection is temporarily unavailable. - The indiekit routes rate-limit patch (ported from
rmdes/indiekit-cloudron) keeps strict limits on/session/*, applies generous limits to public API/well-known routes, and removes extra rate limiting from authenticated routes to avoid admin-side 429 spikes. - The indiekit error stack patch (ported from
rmdes/indiekit-cloudron) suppresses stack traces in production error pages/JSON responses to avoid leaking internal runtime details. - The indieauth dev-mode guard patch prevents accidental production auth bypass by requiring explicit
INDIEKIT_ALLOW_DEV_AUTH=1to enable dev auto-login, and broadens safe local redirect validation to allow common path characters (-,.,%) used by routes such as/auth/new-password.
Description
Languages
JavaScript
98.3%
Shell
1.7%