Commit graph

3 commits

Author SHA1 Message Date
RissRIce
be75744248
fix(gopher): serve public files from SFTP storage (#115)
* test(gopher): cover SFTP public file paths

* fix(gopher): serve public files from SFTP storage
2026-08-12 19:20:06 -07:00
RissRIce
c2a06f1cdf
fix(gopher): block symlink escapes (#85)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
Co-authored-by: rissrice2105-agent <rissrice2105-agent@users.noreply.github.com>
2026-07-10 02:33:34 -07:00
ad76e7fa16
feat(gopher): serve BBS content over Gopher + SSH-authenticated "hedgehog" (#83)
Add Gopher (RFC 1436) as a co-located protocol service, following the
internal/news pattern. Two surfaces share one read-only Resolve engine:

  - Public Gopher on :70 (RFC 1436) for any gopher client (lynx, Lagrange).
    Classic gopher is stateless with no auth verb, so this surface serves
    only public content.
  - `ssh gopher@` = "hedgehog": the same gopher wire semantics carried over
    the authenticated SSH channel (the member's key is the credential), so it
    additionally reaches members-only selectors. Gopher where gopher can,
    our own gopher-like thing over SSH where it can't.

Menus surface the member directory + homepages (public_html), an About page
(brand + MOTD), public newsgroups (allowlisted on :70, all groups on
hedgehog), and members' public files. Selectors are confined to each member's
area (path-traversal guarded). New AGENTBBS_GOPHER* env vars; docs/gopher.md
and README updated (incl. the setcap note for binding privileged :70).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 05:39:35 -07:00