Author SHA1 Message Date
Lotus CIandClaude Opus 5.5 bf770fed83 fix(cinny-web): no-cache for the app shell on SPA routes; keep old hashed assets 14 days (#23)
Lint / Shell (shellcheck) (push) Successful in 24s
Lint / JS (eslint) (push) Successful in 15s
Lint / No secrets in webhook configs (push) Successful in 7s
Lint / Landing page is rendered (matrix (push) Successful in 42s
Lint / Python (ruff) (push) Successful in 11s
Lint / Python deps (pip-audit) (push) Successful in 40s
Lint / Secret scan (gitleaks) (push) Successful in 6s
Lint / Shell (shellcheck) (pull_request) Successful in 9s
Lint / JS (eslint) (pull_request) Successful in 7s
Lint / No secrets in webhook configs (pull_request) Successful in 5s
Lint / Landing page is rendered (matrix (pull_request) Successful in 4s
Lint / Python (ruff) (pull_request) Successful in 6s
Lint / Python deps (pip-audit) (pull_request) Successful in 1m59s
Lint / Secret scan (gitleaks) (pull_request) Successful in 15s
SPA URLs (/, /home/…, /login/…) are rewritten to /index.html inside
location /, which set no cache headers, so browsers heuristically reused
a stale shell after a deploy, and rsync --delete had just removed the
assets it referenced: a blank app until the shell expired. Send
no-cache for the rewritten shell (map on $uri; location / now includes
the security headers, since add_header drops the inherited ones), and
stop deleting previous builds' hashed assets: prune after 14 days.

Fixes #23

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 01:26:02 -04:00
jared b1335a830f Merge pull request 'docs: registration is closed (SSO/LLDAP only); note Draupnir encryption status' (#29) from readme-sso-registration into main
Lint / Shell (shellcheck) (push) Successful in 6s
Lint / JS (eslint) (push) Successful in 5s
Lint / No secrets in webhook configs (push) Successful in 3s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 32s
Lint / Secret scan (gitleaks) (push) Successful in 5s
2026-10-16 18:55:36 -04:00
Lotus CIandClaude Opus 5.5 cf42d0aab0 docs: registration is closed (SSO/LLDAP only); note Draupnir encryption status
Lint / Shell (shellcheck) (pull_request) Successful in 10s
Lint / JS (eslint) (pull_request) Successful in 9s
Lint / No secrets in webhook configs (pull_request) Successful in 4s
Lint / Landing page is rendered (matrix (pull_request) Successful in 5s
Lint / Python (ruff) (pull_request) Successful in 6s
Lint / Python deps (pip-audit) (pull_request) Successful in 52s
Lint / Secret scan (gitleaks) (pull_request) Successful in 6s
Lint / Shell (shellcheck) (push) Successful in 11s
Lint / JS (eslint) (push) Successful in 8s
Lint / No secrets in webhook configs (push) Successful in 4s
Lint / Landing page is rendered (matrix (push) Successful in 5s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 43s
Lint / Secret scan (gitleaks) (push) Successful in 5s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-16 18:52:37 -04:00
jared 6c50f51feb Merge pull request 'Revert Draupnir Rust crypto (#26)' (#28) from revert-draupnir-rust-crypto into main
Lint / Shell (shellcheck) (push) Successful in 7s
Lint / JS (eslint) (push) Successful in 5s
Lint / No secrets in webhook configs (push) Successful in 3s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 39s
Lint / Secret scan (gitleaks) (push) Successful in 8s
2026-10-16 18:40:05 -04:00
Lotus CIandClaude Opus 5.5 cabc393b6b Revert Draupnir Rust crypto (#26): it fails to start without a device-bound token
Lint / Shell (shellcheck) (pull_request) Successful in 7s
Lint / JS (eslint) (pull_request) Successful in 6s
Lint / No secrets in webhook configs (pull_request) Successful in 3s
Lint / Landing page is rendered (matrix (pull_request) Successful in 4s
Lint / Python (ruff) (pull_request) Successful in 5s
Lint / Python deps (pip-audit) (pull_request) Successful in 32s
Lint / Secret scan (gitleaks) (pull_request) Successful in 4s
Lint / Shell (shellcheck) (push) Successful in 6s
Lint / JS (eslint) (push) Successful in 5s
Lint / No secrets in webhook configs (push) Successful in 4s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 4s
Lint / Python deps (pip-audit) (push) Successful in 34s
Lint / Secret scan (gitleaks) (push) Successful in 7s
With experimentalRustCrypto: true, Draupnir 2.9.0 exits on startup with
"Encryption not possible: server not revealing device ID": its access
token is not bound to a device, which matrix-bot-sdk crypto requires.
Restores experimentalRustCrypto: false so the deploy hook brings it back.

To enable encryption later, give Draupnir a device-bound access token
(a normal password login) first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-16 18:36:16 -04:00
jared 72a3e3ba17 Merge pull request 'draupnir: enable Rust crypto so it can read commands in the encrypted management room' (#26) from draupnir-rust-crypto into main
Lint / Shell (shellcheck) (push) Successful in 1m30s
Lint / JS (eslint) (push) Successful in 11s
Lint / No secrets in webhook configs (push) Successful in 9s
Lint / Landing page is rendered (matrix (push) Successful in 10s
Lint / Python (ruff) (push) Successful in 7s
Lint / Python deps (pip-audit) (push) Successful in 36s
Lint / Secret scan (gitleaks) (push) Successful in 8s
2026-10-16 18:34:55 -04:00
jared 162d8b5a80 Merge pull request 'landing: describe SSO sign-up, drop dashes and hyphens from the page text' (#27) from landing-sso-wording into main
Lint / Shell (shellcheck) (push) Successful in 15s
Lint / JS (eslint) (push) Successful in 13s
Lint / No secrets in webhook configs (push) Successful in 9s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 6s
Lint / Python deps (pip-audit) (push) Successful in 44s
Lint / Secret scan (gitleaks) (push) Successful in 10s
2026-10-13 02:48:19 -04:00
Lotus CIandClaude Opus 5.5 77e719183a draupnir: enable Rust crypto so it can read commands in the encrypted management room
Lint / Shell (shellcheck) (pull_request) Successful in 10s
Lint / JS (eslint) (pull_request) Successful in 9s
Lint / No secrets in webhook configs (pull_request) Successful in 4s
Lint / Landing page is rendered (matrix (pull_request) Successful in 4s
Lint / Python (ruff) (pull_request) Successful in 5s
Lint / Python deps (pip-audit) (pull_request) Successful in 1m17s
Lint / Secret scan (gitleaks) (pull_request) Successful in 10s
Lint / Shell (shellcheck) (push) Successful in 10s
Lint / JS (eslint) (push) Successful in 7s
Lint / No secrets in webhook configs (push) Successful in 5s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 8s
Lint / Python deps (pip-audit) (push) Successful in 1m13s
Lint / Secret scan (gitleaks) (push) Successful in 6s
The management room is end-to-end encrypted, but Draupnir ran with
experimentalRustCrypto: false and Pantalaimon off, so it could post there
(its own messages are unencrypted) but never saw commands: its last reply
to a command was ~57 days ago, and `!draupnir rooms add …` sent from Lotus
on 2026-10-13 was ignored. The same command sent unencrypted worked at
once (✅, joined dco-memes-minecraft).

Merging deploys via lxc110-draupnir.sh, which restarts draupnir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-13 01:34:10 -04:00
3 changed files with 21 additions and 2 deletions
+2 -1
View File
@@ -84,6 +84,7 @@ matrix/
- Service: `draupnir.service`
- Management room: `#management:matrix.lotusguild.org` (`!mEvR5fe3jMmzwd-FwNygD72OY_yu8H3UP_N-57oK7MI`)
- Bot account: `@draupnir:matrix.lotusguild.org` (power level 100 in all protected rooms and the Lotus Guild space)
- Encryption: off (`experimentalRustCrypto: false`), so Draupnir cannot read commands sent in the encrypted management room; send them unencrypted for now. Turning it on needs a device-bound access token first: with the current token, 2.9.0 exits with "Encryption not possible: server not revealing device ID" (tried and reverted 2026-10-16, #26 / #28).
- Subscribed ban lists: `#community-moderation-effort-bl:neko.dev`, `#matrix-org-coc-bl:matrix.org`
- Rebuild: `NODE_OPTIONS="--max_old_space_size=6144" npm run build`
- Healthz endpoint: `http://10.10.10.24:8081/healthz` (200 = healthy, 418 = disconnected)
@@ -798,7 +799,7 @@ Leaving a space does **not** leave its child rooms; they are independent rooms w
- [ ] `synchronous_commit = off` — **deliberately NOT applied.** Would be a real write-latency win, but this cluster hard-resets every few hours (HA self-fences on corosync quorum loss + the large1 DIMM), so it would drop up to ~600ms of committed messages *per reset* rather than once in a blue moon. Revisit once the cluster is stable.
### Auth & SSO
- [x] Token-based registration
- [x] Open registration disabled (`enable_registration: false`, 2026-10-16): accounts come from LLDAP and are created on first sign-in through Lotus SSO (Authelia OIDC, which keeps its own registration on). The old registration token was deleted.
- [x] SSO/OIDC via Authelia
- [x] `allow_existing_users: true` for linking accounts to SSO
- [x] Password auth alongside SSO
+7 -1
View File
@@ -160,7 +160,13 @@ echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deploying to $WEBROOT..."
# /var/www/html/config.json by lxc106-cinny.sh. The build ships a DEV default
# (allowCustomHomeservers:true); rsyncing it would clobber the production config
# on every deploy. Keep the app bundle and the runtime config separate.
rsync -a --delete --exclude config.json dist/ "$WEBROOT/"
# [matrix #23] Keep the previous builds' hashed assets for a while: a browser
# still holding an older index.html (or service-worker precache) asks for its
# assets/index-<old hash>.js, and deleting them on every deploy broke the app
# for those users until their cached shell expired. Prune after 14 days.
rsync -a --delete --exclude config.json --exclude assets/ dist/ "$WEBROOT/"
rsync -a dist/assets/ "$WEBROOT/assets/"
find "$WEBROOT/assets" -type f -mtime +14 -delete
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ===== Deploy complete ($VITE_APP_VERSION) ====="
+12
View File
@@ -1,3 +1,12 @@
# [matrix #23] SPA routes (/, /home/…, /login/…) are rewritten to /index.html
# inside `location /`, where no cache headers were set: browsers then reused a
# heuristically fresh shell after a deploy and requested deleted assets. Only
# the rewritten shell gets no-cache; other files there keep their defaults.
map $uri $lotus_shell_cache_control {
/index.html "no-cache, no-store, must-revalidate";
default "";
}
server {
listen 80;
listen [::]:80;
@@ -99,6 +108,9 @@ server {
}
location / {
# add_header here drops the server-level headers, so include them again.
include snippets/cinny-security-headers.conf;
add_header Cache-Control $lotus_shell_cache_control always;
rewrite ^/config\.json$ /config.json break;
rewrite ^/manifest\.json$ /manifest.json break;
rewrite ^/sw\.js$ /sw.js break;