TLS by default; plain Protocol A only after the user agrees #40

Merged
littlefox merged 3 commits from issue-39-tls into main 2026-10-17 11:04:40 +00:00
Owner

Closes #39

Built on #38 (FAQs); merge that first.

TLS by default (D-026), plain Protocol A only after the user agrees.

What exists: lyskomd 2.1.2 and upstream have no TLS. The Emacs client tunnels through ssh instead. kom.lysator.liu.se:4894 is plain, and no other TLS port answers. So against kom.lysator.liu.se you'll see the question until Lysator puts a TLS front end such as stunnel in place.

Client:

  • Desktop: rustls (ring), Mozilla roots, plus optional NEOKOM_TLS_CA.
  • Browser: kom-relay does the TLS and closes with 4001/4002 on no TLS or a bad certificate.
  • Login: always tries TLS. On "no TLS" it asks; "Kom ihåg för den här servern" is optional. A server that had TLS before always gets a downgrade warning, with no remember option. A bad certificate is an error and never falls back.
  • Top bar: shows TLS / TLS från reläet / Okrypterad, with an SVG padlock.

Tests:

  • Devserver: stunnel on 4896 with a test CA (devserver/tls, key discarded); the image is already pushed to the registry.
  • e2e: all specs now run over TLS. tls.spec.ts covers the default TLS connection, confirm/cancel/remember, and the downgrade warning (33/33).
  • Integration test tls_front_end: TLS works, plain port gives NotTls, unknown CA gives a certificate error.
  • Desktop smoke test over TLS: passed locally.
  • CI uses lyskomd:4896.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8

Closes #39 Built on #38 (FAQs); merge that first. TLS by default (D-026), plain Protocol A only after the user agrees. **What exists:** lyskomd 2.1.2 and upstream have no TLS. The Emacs client tunnels through ssh instead. kom.lysator.liu.se:4894 is plain, and no other TLS port answers. So against kom.lysator.liu.se you'll see the question until Lysator puts a TLS front end such as stunnel in place. **Client:** - **Desktop:** rustls (ring), Mozilla roots, plus optional `NEOKOM_TLS_CA`. - **Browser:** kom-relay does the TLS and closes with 4001/4002 on no TLS or a bad certificate. - **Login:** always tries TLS. On "no TLS" it asks; "Kom ihåg för den här servern" is optional. A server that had TLS before always gets a downgrade warning, with no remember option. A bad certificate is an error and never falls back. - **Top bar:** shows TLS / TLS från reläet / Okrypterad, with an SVG padlock. **Tests:** - Devserver: stunnel on 4896 with a test CA (devserver/tls, key discarded); the image is already pushed to the registry. - e2e: all specs now run over TLS. tls.spec.ts covers the default TLS connection, confirm/cancel/remember, and the downgrade warning (33/33). - Integration test tls_front_end: TLS works, plain port gives NotTls, unknown CA gives a certificate error. - Desktop smoke test over TLS: passed locally. - CI uses lyskomd:4896. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Post images: pick, scale to the server's limit, send
All checks were successful
ci / check (push) Successful in 6m3s
ci / e2e (push) Successful in 9m40s
ci / desktop (push) Successful in 10m8s
ae53de722a
Like jskom (D-024): the composer takes an image file, keeps it as it is
when it already fits, otherwise scales it down on a canvas to a JPEG.
The canvas works the same in the browser and the desktop webview. Alone
the image is posted the elisp/jskom way (subject line plus raw image);
with a caption it is posted as multipart/mixed. The server's text limit
is learnt from string-too-long, and sending re-scales and retries once.

Refs #33

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Requested by the user: the README still described an early reader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Unread FAQs first on entering a conference, remembered the elisp way
All checks were successful
ci / check (push) Successful in 6m31s
ci / e2e (push) Successful in 8m22s
ci / desktop (push) Successful in 9m4s
50b5d71316
Entering a conference queues its unread FAQs (faq-text) ahead of
reading. Showing a text with faq-for-conf records it as read with
elisp-client-read-faq on the letterbox, exactly as the Emacs client
does, so both clients agree (D-024). The server's FAQs are queued at
login.

Refs #35

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
TLS by default; plain Protocol A only after the user agrees
All checks were successful
ci / desktop (push) Successful in 8m27s
ci / check (push) Successful in 9m33s
ci / e2e (push) Successful in 11m16s
packaging / arch (push) Successful in 11m53s
packaging / nix (push) Successful in 22m59s
packaging / debian (push) Successful in 25m44s
packaging / fedora (push) Successful in 27m29s
1d436f1be2
lyskomd has no TLS of its own and kom.lysator.liu.se has no TLS front
end today (D-026), but the client now always tries TLS first. If the
server doesn't answer in TLS, the login page asks before connecting
unencrypted, optionally remembering the answer per server. A server that
had TLS before always gets a downgrade warning instead. Untrusted
certificates are errors, never a reason to fall back.

Desktop does TLS itself (rustls/ring); in the browser, kom-relay does it
and reports "no TLS" with WebSocket close code 4001. The devserver gains
an stunnel port (4896) with a test CA, so e2e, the desktop smoke test,
the integration tests and CI all run over TLS and test the fallback.

Refs #39

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Merge main into issue-39-tls
All checks were successful
ci / check (push) Successful in 8m40s
ci / e2e (push) Successful in 11m23s
ci / desktop (push) Successful in 11m59s
572e97e32e
Sign in to join this conversation.
No description provided.