• v3.7.1 04e1e916cd

    v3.7.1
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-13 06:00:24 +00:00 | 0 commits to main since this release

    Release v3.7.1

    Downloads
  • v3.6.4 56ddb7d845

    v3.6.4
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-13 05:45:50 +00:00 | 2 commits to main since this release

    Release v3.6.4

    Downloads
  • v3.6.3 5380bca6e7

    v3.6.3
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-13 05:42:25 +00:00 | 3 commits to main since this release

    Release v3.6.3

    Downloads
  • v3.6.2 a167fb592d

    v3.6.2
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 09:56:00 +00:00 | 4 commits to main since this release

    Release v3.6.2

    Downloads
  • v3.6.1 033a785e39

    v3.6.1
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 09:35:07 +00:00 | 5 commits to main since this release

    Release v3.6.1

    Downloads
  • v3.6.0 8dc052adb9

    v3.6.0
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 09:18:40 +00:00 | 6 commits to main since this release

    Release v3.6.0

    Downloads
  • v3.5.0 0db4d8415e

    v3.5.0
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 09:08:23 +00:00 | 7 commits to main since this release

    Added

    • scripts/set-endpoint.mjs — set the AI endpoint, model and key from the command
      line, without a browser. Useful on a headless machine and essential when you carry a
      database to another network, because the AI address lives in the database, not in
      .env: .env only seeds it the first time the app runs against an empty database.

      npm run endpoint                                            # show the current setting
      node scripts/set-endpoint.mjs http://10.0.0.5:8200/v1 MyModel
      node scripts/set-endpoint.mjs --list --test                 # verify it works
      node scripts/set-endpoint.mjs --clear-key                   # local service, no key
      

      It rejects anything that is not an http(s) URL, and --list/--test confirm the
      endpoint before you rely on it. Shipped inside the offline bundle.

    Documentation

    • docs/OFFLINE.md now explains the AI-address behaviour explicitly, and answers the
      folder question: nothing has to be created by hand — the app creates its data
      directory (0700) and database (0600) itself, and the bundle already contains
      every other path it reads. The only directory you place is the extracted app/.
    Downloads
  • v3.4.0 bcc5ef1dee

    v3.4.0
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 09:05:48 +00:00 | 8 commits to main since this release

    Added

    • Offline bundle for isolated networks. scripts/offline-bundle.sh collects the
      application, the checksum-verified SimpleAuth binary and (optionally) the official
      Node.js runtime into one tarball, because the target machine cannot download
      anything. scripts/offline-install.sh verifies the runtime version, writes .env
      from the example and prints the run command plus a systemd unit — without touching
      the network. See docs/OFFLINE.md.
    • --no-node to skip the ~28 MB Node tarball when the target already has Node >= 22.5,
      and ARCH= for a different CPU.
    • The guide also covers carrying existing data across (copying data/app.db or using
      the built-in backup) and the one thing that genuinely cannot work offline: building
      the Docker images, which must be saved with docker save and loaded with
      docker load.
    Downloads
  • v3.3.0 ea7103e633

    v3.3.0
    All checks were successful
    build-and-release / docker (push) Successful in 2s
    Stable

    debe released this 2026-10-12 09:01:34 +00:00 | 9 commits to main since this release

    Second audit pass: the items deliberately left unfixed in 3.2.0.

    Fixed

    • An archived topic could lose its archive flag. Trashing an archived topic and then
      unarchiving it cleared archived_at, so restoring it dropped the topic into the main
      list instead of the archive. Unarchiving a trashed topic is now refused with
      409 topic_trashed, and restoring returns it to the archive.
    • Wrong method returned 404. POST /api/health (and every other known path with an
      unsupported verb) looked like a missing route. Known paths now answer 405 with a
      proper Allow header; unknown paths stay 404.
    • Sign-in failures reached the browser as English prose. They now travel as stable
      codes (signin_expired, state_mismatch, provider_rejected, account_disabled,
      signin_failed, sauth_unconfigured) and are translated like every other error.
    • Markdown: emphasis ran across code spans, producing crossed <em>/<code> tags
      (_a b_c d_). Code spans are now extracted first and re-inserted last.
    • Markdown: a link whose URL contains parentheses was cut at the first ), leaving a
      stray bracket and a truncated href. Balanced parentheses are now accepted.
    • The topic list was mouse-only. Cards are <article tabindex="0" role="button">
      with an aria-label, and Enter/Space opens them.
    • Escape did nothing. It now closes the confirm dialog (as "cancel") and the
      create-topic modal; the confirm dialog remembers and restores focus, and focuses the
      safe button first so the destructive one needs a deliberate move.
    • English content rendered inside the RTL document without bidi isolation. Update
      summaries, raw text, topic summaries and reports now carry dir="auto", and long
      unbroken tokens wrap instead of overflowing.
    • Removed 34 dead translation entries in both dictionaries (and their orphaned CSS).

    Tests

    • 2 more regression tests (140 total) covering the 405/Allow behaviour and the
      archive-while-trashed guard.
    Downloads
  • v3.2.0 16d098f5f2

    v3.2.0
    All checks were successful
    build-and-release / docker (push) Successful in 3s
    Stable

    debe released this 2026-10-12 08:52:13 +00:00 | 10 commits to main since this release

    Full audit pass (security, API edge cases, frontend, data integrity, load) with fixes.

    Fixed — data safety

    • purge could destroy a live topic. deleteTopic() now only ever deletes a topic
      that is already in the trash, so a stray DELETE can never wipe live data.
    • Editing an update discarded the edit when the AI was unreachable (the request
      returned 500 and the new text was lost). The edit is now saved first and the analysis
      is marked failed, exactly like creating an update.
    • An update inside a trashed topic could be deleted while the topic was still
      recoverable; that path is now refused.
    • /api/restore accepted anything and replaced the whole database with it (empty
      titles, unknown statuses, non-timestamp dates, orphan updates, duplicate ids). Backup
      files are now validated before a single row is touched, and failures return 400 with
      invalid_backup instead of a raw SQLite 500.
    • NUL characters silently truncated text on write (SQLite stops at \0). They are
      now rejected with invalid_characters.
    • owner was accepted when creating a topic and then silently dropped.

    Fixed — security

    • Stored XSS: formatDate() returned non-timestamp input verbatim into innerHTML
      in three places, and statusBadge() injected a crafted status unescaped. Both are now
      escaped/whitelisted, and restore validation rejects the payload that carried them.
    • /api/models was not admin-gated and honoured a caller-supplied ?base=, which
      forwarded the stored AI key to any host (SSRF + key exfiltration). It is now
      administrator-only, together with /api/backup and /api/restore.
    • Open redirect: ?next=//evil.com passed the startsWith('/') check. Only
      same-origin absolute paths are accepted now.
    • No session expiry server-side — a 400-day-old session still authenticated. Idle
      (7 days) and absolute (30 days) limits are enforced on every request.
    • Malformed cookies (%zz) and a JSON null body produced 500s; both are handled.
    • Security headers were missing entirely. Every response now carries a CSP
      (frame-ancestors 'none', no inline scripts), nosniff, DENY and Referrer-Policy.
    • Session cookies get Secure when the app is served over HTTPS.
    • The data directory is 0700 and the database 0600 (they hold session tokens and keys).
    • /api/health no longer discloses the AI endpoint or model to unauthenticated callers.
    • Saving an unreachable SimpleAuth URL is refused, so it can no longer lock every
      administrator out with no way back through the UI.
    • Removed the dead sauth_admin_key setting.

    Fixed — robustness

    • No outbound timeouts: a hung AI or identity provider held a request open for
      300 s and leaked the socket. All outbound calls now time out (AI 180 s, models 20 s,
      SimpleAuth 15 s).
    • The advertised 413 is now delivered instead of resetting the connection.
    • Field length caps (title 500, description 20 000, owner/author 200, update 50 000) so
      one request can no longer store megabytes.
    • ai_base set to an empty string no longer silently reverts to the DeepSeek default,
      and a JSON null no longer becomes the literal string "null".
    • AI failures now return 502 ai_unreachable instead of a generic 500.
    • GET /api/topics/:id/updates without a cursor returns the most recent page instead of
      an empty list.

    Fixed — interface

    • "Add update" was broken whenever sign-in was disabled: the client stopped sending
      an author but the server still required one. The composer now shows a name field in
      that mode only.
    • .hidden had no CSS rule, so the admin-only Settings entry stayed visible to members.

    Added

    • 13 regression tests covering every fix above, plus migration tests for the two older
      database schemas (v1 and 2.6-era) proving that an existing installation upgrades with
      no data loss.
    Downloads