Commit graph

164 commits

Author SHA1 Message Date
RissRIce
a64e4dc1b8 fix(games): reject duplicate queue entries 2026-08-12 21:03:08 -06:00
RissRIce
97ce177dd3 test(games): reproduce duplicate queue deadlock 2026-08-12 20:59:47 -06:00
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
f83edd4351
fix(mailbox): write messages before IMAP append wait (#113)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
Co-authored-by: rissrice2105-agent <289161642+rissrice2105-agent@users.noreply.github.com>
2026-08-11 17:44:33 -07:00
RissRIce
03a2ce3f8b
fix: validate provisioned account kind (#112)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
2026-08-10 20:18:44 -07:00
RissRIce
bf777a1475
fix(sites): remove stale domain links on sync (#110)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
2026-08-09 21:56:39 -07:00
dependabot[bot]
b48608c4e9
chore(deps): bump the github-actions group with 4 updates (#108)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
Bumps the github-actions group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-node](https://github.com/actions/setup-node), [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/github-script](https://github.com/actions/github-script).


Updates `actions/checkout` from 4 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v7)

Updates `actions/setup-node` from 4 to 7
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v7)

Updates `actions/upload-artifact` from 4 to 7
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

Updates `actions/github-script` from 7 to 9
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v9)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-07 18:20:49 -07:00
dependabot[bot]
92196b6440
chore(deps): bump modernc.org/sqlite in the go-modules group (#107)
Bumps the go-modules group with 1 update: [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).


Updates `modernc.org/sqlite` from 1.55.0 to 1.56.0
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.55.0...v1.56.0)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-version: 1.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-07 18:20:44 -07:00
595eec118b
ci: add ThreatCrush security scan (#105)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
Installs threatcrush-scan@1.1.0 from the sh1pt Actions Store.
Scans pull requests for hardcoded credentials, injection, SSRF, unsafe
deserialisation and dependency tampering; uploads SARIF to the Security
tab.

Report-only — it will not fail a pull request. Set the pack's failOn
input to critical,high once the existing findings are triaged.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 07:21:39 -07:00
262f2a74cc
ci: remove the vu1nz security scan (#106)
vu1nz reviews a diff by calling Claude, which needs ANTHROPIC_API_KEY
supplied through the ENV_FILE secret. That key is not present on this
repository, so the scanner has never reviewed a pull request. On pack
1.0.0 and 1.0.1 that failure was silent: the job reported "0 finding(s),
no high/critical issues" on a diff nothing had read, which is worse than
no scanner at all.

threatcrush-scan covers the same ground deterministically - credentials,
injection, SSRF, unsafe deserialisation, XXE, dependency tampering - with
no API key and no per-pull-request cost.

Reinstallable from the sh1pt Actions Store if the key is ever provisioned.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 07:16:28 -07:00
41174eec03
fix(join): stop rotating a returning member's webmail password (#104)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
handleJoin called setWebmailPassword unconditionally, so every visit to
join@ minted a fresh Roundcube password -- including for members who
registered and verified long ago.

join@ is the address people remember, so returning members type it out
of habit. Doing so silently invalidated their webmail login: the
replacement password scrolled past once in the join output, the old one
was already dead, and nothing in the session said a credential had
changed. The failure surfaces later, as "my password stopped working",
with no way to connect it back to having typed join@ -- and it reads
like a compromised account, which is an alarming thing to hand someone
over a no-op visit.

Mint the password only while actually onboarding: a new key registering,
or an account that completes email verification in this session. A
returning member is told the password is unchanged and pointed at
passwd@, which already sets one password across git, mail and chat and
is key-gated, so it doubles as the forgot-password path.

Also replace the bare webmail URL line shown when no password is minted
with the full url/login block, so the address and where to get
credentials are always visible, and distinguish "unchanged" (returning)
from "not set yet" (onboarding, but Mailu was unreachable).

Verified by inspection only: this box has no Go toolchain (repo needs
1.26), so the build is left to CI.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 01:44:37 -07:00
RissRIce
20cdb6432d
fix(config): reject non-positive integer settings (#102)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
2026-07-30 18:41:57 -07:00
dependabot[bot]
1849a25f10
chore(deps): bump the go-modules group with 2 updates (#103)
Bumps the go-modules group with 2 updates: [github.com/pion/webrtc/v4](https://github.com/pion/webrtc) and [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).


Updates `github.com/pion/webrtc/v4` from 4.2.17 to 4.2.18
- [Release notes](https://github.com/pion/webrtc/releases)
- [Commits](https://github.com/pion/webrtc/compare/v4.2.17...v4.2.18)

Updates `modernc.org/sqlite` from 1.54.0 to 1.55.0
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.54.0...v1.55.0)

---
updated-dependencies:
- dependency-name: github.com/pion/webrtc/v4
  dependency-version: 4.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: modernc.org/sqlite
  dependency-version: 1.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-30 18:41:40 -07:00
RissRIce
447b34b895
fix: reject invalid IRC server ports (#98)
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-23 19:33:43 -07:00
dependabot[bot]
158ea7b718
chore(deps): bump actions/setup-python in the github-actions group (#99)
Bumps the github-actions group with 1 update: [actions/setup-python](https://github.com/actions/setup-python).


Updates `actions/setup-python` from 6 to 7
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-23 19:33:29 -07:00
dependabot[bot]
bf045ef359
chore(deps): bump the go-modules group with 2 updates (#100)
Bumps the go-modules group with 2 updates: [github.com/livekit/protocol](https://github.com/livekit/protocol) and [github.com/pion/webrtc/v4](https://github.com/pion/webrtc).


Updates `github.com/livekit/protocol` from 1.50.0 to 1.50.4
- [Release notes](https://github.com/livekit/protocol/releases)
- [Changelog](https://github.com/livekit/protocol/blob/main/CHANGELOG.md)
- [Commits](https://github.com/livekit/protocol/compare/v1.50.0...v1.50.4)

Updates `github.com/pion/webrtc/v4` from 4.2.16 to 4.2.17
- [Release notes](https://github.com/pion/webrtc/releases)
- [Commits](https://github.com/pion/webrtc/compare/v4.2.16...v4.2.17)

---
updated-dependencies:
- dependency-name: github.com/livekit/protocol
  dependency-version: 1.50.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: github.com/pion/webrtc/v4
  dependency-version: 4.2.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-23 19:33:15 -07:00
RissRIce
7cb2aba24e
fix(qryptinvite): validate quota and TTL env values (#93)
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-16 19:01:41 -07:00
dependabot[bot]
db641c79bb
chore(deps): bump library/ubuntu from 24.04 to 26.04 in /pods (#94)
Bumps library/ubuntu from 24.04 to 26.04.

---
updated-dependencies:
- dependency-name: library/ubuntu
  dependency-version: '26.04'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 19:01:26 -07:00
dependabot[bot]
452d2b344d
chore(deps): bump actions/setup-go (#95)
Bumps the github-actions group with 1 update in the / directory: [actions/setup-go](https://github.com/actions/setup-go).


Updates `actions/setup-go` from 6 to 7
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 19:01:10 -07:00
dependabot[bot]
f99f2060f6
chore(deps): bump the go-modules group across 1 directory with 4 updates (#96)
Bumps the go-modules group with 4 updates in the / directory: [github.com/livekit/protocol](https://github.com/livekit/protocol), [github.com/livekit/server-sdk-go/v2](https://github.com/livekit/server-sdk-go), [github.com/pkg/sftp](https://github.com/pkg/sftp) and [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).


Updates `github.com/livekit/protocol` from 1.49.0 to 1.50.0
- [Release notes](https://github.com/livekit/protocol/releases)
- [Changelog](https://github.com/livekit/protocol/blob/main/CHANGELOG.md)
- [Commits](https://github.com/livekit/protocol/compare/v1.49.0...v1.50.0)

Updates `github.com/livekit/server-sdk-go/v2` from 2.17.0 to 2.18.1
- [Commits](https://github.com/livekit/server-sdk-go/compare/v2.17.0...v2.18.1)

Updates `github.com/pkg/sftp` from 1.13.10 to 1.13.11
- [Release notes](https://github.com/pkg/sftp/releases)
- [Commits](https://github.com/pkg/sftp/compare/v1.13.10...v1.13.11)

Updates `modernc.org/sqlite` from 1.53.0 to 1.54.0
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.53.0...v1.54.0)

---
updated-dependencies:
- dependency-name: github.com/livekit/protocol
  dependency-version: 1.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: github.com/livekit/server-sdk-go/v2
  dependency-version: 2.18.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: github.com/pkg/sftp
  dependency-version: 1.13.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: modernc.org/sqlite
  dependency-version: 1.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 19:00:53 -07:00
ralyodio
3bfbd7059f ci(vu1nz-scan): don't fail the scan when the PR comment can't be posted
Dependabot PRs run with a read-only GITHUB_TOKEN, and GitHub was returning
503 (the HTML "Unicorn" page) for the comment write; the step's catch only
handled 403 and re-threw everything else, failing the whole scan even though
the security scan itself passed.

- skip the comment step for github.actor == 'dependabot[bot]'
- continue-on-error: true
- warn-and-continue on any status instead of only 403

Mirrors sh1pt pack vu1nz-scan@1.0.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 01:56:01 +00:00
RissRIce
24269b6799
fix(files): honor forwarded HTTPS proxy chains (#92)
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-15 06:21:31 -07:00
2048229cbb fix(setup): robustly move admin sshd off :22 on Ubuntu 24.04
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
The provision step aborted at "admin sshd is NOT listening on 2202"
because it decided ssh was socket-activated purely from `systemctl cat
ssh.socket` succeeding — but that unit file exists on every modern box,
including DigitalOcean images where the real listener is the standalone
ssh.service. It then restarted only ssh.socket, so nothing ended up
bound on the admin port and the safety check killed the deploy.

- Detect socket vs. standalone mode via `is-active`/`is-enabled`, not
  mere unit-file existence.
- In socket mode, stop the standalone ssh.service first so it can't
  fight the socket for the port.
- Fall back to the other restart path if the first doesn't bind.
- Dump listener + unit diagnostics before aborting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 07:09:07 +00:00
RissRIce
b777bd72e8
fix(files): encode download filenames (#91)
Co-authored-by: rissrice2105-agent <rissrice2105-agent@users.noreply.github.com>
2026-07-13 23:54:18 -07:00
SabFabDev
21630c2d17
fix(news): stop IHAVE when duplicate lookup fails (#89)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
Co-authored-by: SabFabDev <SabFabDev@users.noreply.github.com>
2026-07-12 00:43:24 -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
dependabot[bot]
e38c0935f4
chore(deps): bump the go-modules group with 3 updates (#87)
Bumps the go-modules group with 3 updates: [github.com/livekit/server-sdk-go/v2](https://github.com/livekit/server-sdk-go), [golang.org/x/crypto](https://github.com/golang/crypto) and [golang.org/x/term](https://github.com/golang/term).


Updates `github.com/livekit/server-sdk-go/v2` from 2.16.7 to 2.17.0
- [Commits](https://github.com/livekit/server-sdk-go/compare/v2.16.7...v2.17.0)

Updates `golang.org/x/crypto` from 0.53.0 to 0.54.0
- [Commits](https://github.com/golang/crypto/compare/v0.53.0...v0.54.0)

Updates `golang.org/x/term` from 0.44.0 to 0.45.0
- [Commits](https://github.com/golang/term/compare/v0.44.0...v0.45.0)

---
updated-dependencies:
- dependency-name: github.com/livekit/server-sdk-go/v2
  dependency-version: 2.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/crypto
  dependency-version: 0.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/term
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-10 02:33:00 -07:00
b51fa5c0e6
Add himalaya + meli mail clients and Shedding Snake arcade game (#88)
Mail clients (internal/mailclients): launch himalaya and meli as
alternatives to the built-in AgentMail reader, pointed at the member's
mailbox with the same master IMAP / loopback-SMTP creds. They run
host-side (secrets never enter a pod), from a throwaway per-session
config that is deleted on exit; operators can override the config
template and argv via env. Wired into the hub ("Mail · Himalaya/Meli",
locked when the binary is absent) and the mail@ route
(ssh -t mail@host himalaya|meli).

Shedding Snake (plugins/arcade): a molting twist on Snake inspired by
cha.rlie.co/shedding-snake. The snake barely grows — each apple sheds
its whole body as a permanent field of scales you must not bite. Walls
wrap, speed ramps up, scales age fresh-teal → dusty-gray, and molt
counts feed a global "shedsnake" leaderboard. Grace period lets you
slither off a fresh molt.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 02:30:12 -07:00
Luna Ops
ff9eef907d
Require POST for file web mutations (#82)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
2026-07-07 05:41:16 -07:00
RissRIce
ee06082ce1
fix(mailbox): reject invalid bot toggle values (#80)
Co-authored-by: rissrice2105-agent <rissrice2105-agent@users.noreply.github.com>
2026-07-07 05:40:35 -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
9d0c0a0193
Fix hangman: lowercase r swallowed by restart binding during play (#79)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
The Update key switch bound "r" to restart, but returned early even when
the game was still active, so lowercase r could never be entered as a
letter guess (Shift+R worked because "R" didn't match the case). Now r
only restarts when dead; otherwise it falls through to the guess logic.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 06:21:06 -07:00
47a88b2fc5
fix: point web client link to chat.<root> not chat.<full-host> (#78)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
The setup help page hardcoded chat.${DOMAIN}, producing
chat.bbs.profullstack.com — a host the Caddy route never serves. The
The Lounge web IRC client is fronted at ${CHAT_DOMAIN}
(chat.${DOMAIN#*.} = chat.profullstack.com). Use ${CHAT_DOMAIN} so the
"web client" link and label match the actual host.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 18:27:29 -07:00
RissRIce
3a4d7ed8d8
fix(mailbox): validate bot list limits (#77) 2026-07-04 17:39:31 -07:00
forgou37
6a086eb7cc
fix(nntp): handle open-ended OVER range like '5-' (#75)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
2026-07-02 17:20:39 -07:00
dependabot[bot]
11f7b8ea2e
chore(deps): bump the go-modules group with 3 updates (#76)
Bumps the go-modules group with 3 updates: [github.com/livekit/protocol](https://github.com/livekit/protocol), [golang.org/x/crypto](https://github.com/golang/crypto) and [golang.org/x/term](https://github.com/golang/term).


Updates `github.com/livekit/protocol` from 1.48.2 to 1.49.0
- [Release notes](https://github.com/livekit/protocol/releases)
- [Changelog](https://github.com/livekit/protocol/blob/main/CHANGELOG.md)
- [Commits](https://github.com/livekit/protocol/compare/v1.48.2...v1.49.0)

Updates `golang.org/x/crypto` from 0.52.0 to 0.53.0
- [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.53.0)

Updates `golang.org/x/term` from 0.43.0 to 0.44.0
- [Commits](https://github.com/golang/term/compare/v0.43.0...v0.44.0)

---
updated-dependencies:
- dependency-name: github.com/livekit/protocol
  dependency-version: 1.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/crypto
  dependency-version: 0.53.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/term
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-02 17:19:36 -07:00
43dbdf0e06
ci(deploy): preempt self-update timer so it can't starve the deploy lock (#72)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
* ci(deploy): preempt self-update timer so it can't starve the deploy lock

The self-update systemd timer redeploys from source (no SKIP_BUILD) and
can hold setup.sh's flock for >5min while compiling on a tiny droplet.
When it fires close to a CI push it starves the deploy, which waits the
full 5min on the lock and then fails with 'another setup.sh run is in
progress (lock held >5m)'.

The CI push is authoritative (ships prebuilt binaries + resets to the
exact commit), so stop any in-flight timer run to release the lock and
pause the timer before taking it. setup.sh re-enables the timer at the
end of its run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(files): isolate over-quota test from seeded-README baseline

TestWebSaveOverQuotaPreservesExistingFile set quota=5 but left sess.used
at the newSession baseline, which already counts the README.txt that
ensureUserPub seeds into /public (added in d19c5c4). That baseline alone
exceeds 5 bytes, so the initial 2-byte save was rejected with
'quota exceeded' before the test could exercise the over-quota replace.

Reset sess.used to 0 after setting the tiny quota, mirroring
TestQuotaEnforced, so the writer starts from a clean gauge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 01:32:10 -07:00
Kyle Zengo
c8718f25ea
fix: canonicalize root in safeJoin to handle symlinked storage roots (#64)
When the configured storage root (or a system temp dir on macOS where
/var → /private/var) is reached through a symlink, filepath.EvalSymlinks
on a child path resolves to the canonical form, but within() was comparing
against the lexical root — causing valid paths to be rejected with
"files: path escapes its area".

Fix: resolve the root once with EvalSymlinks before the symlink guard
loop, and compare resolved paths against the canonical root. The initial
lexical containment check (line 108) still uses the original root so
that the returned path keeps the caller's expected prefix.

Adds two regression tests:
  - TestSafeJoinSymlinkedRoot: valid file under a symlinked root is accepted
  - TestSafeJoinChildSymlinkEscapeStillBlocked: escaping child symlink is still rejected

Fixes #62

Co-authored-by: Kyle Paul Zengo <kylezengo@mac2012kylezengo.tail2f018b.ts.net>
2026-07-01 01:10:20 -07:00
RissRIce
3e28a57b5d
fix(files): preserve existing file on failed quota upload (#68)
Co-authored-by: rissrice2105-agent <289161642+rissrice2105-agent@users.noreply.github.com>
2026-07-01 01:09:01 -07:00
dependabot[bot]
51273e9a4a
chore(deps): bump the github-actions group with 4 updates (#70)
Bumps the github-actions group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-go](https://github.com/actions/setup-go), [actions/setup-python](https://github.com/actions/setup-python) and [actions/github-script](https://github.com/actions/github-script).


Updates `actions/checkout` from 4 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v7)

Updates `actions/setup-go` from 5 to 6
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

Updates `actions/setup-python` from 5 to 6
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

Updates `actions/github-script` from 7 to 9
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v9)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 01:08:44 -07:00
dependabot[bot]
83a02f6d6c
chore(deps): bump the go-modules group with 6 updates (#71)
Bumps the go-modules group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/livekit/protocol](https://github.com/livekit/protocol) | `1.46.0` | `1.48.2` |
| [github.com/livekit/server-sdk-go/v2](https://github.com/livekit/server-sdk-go) | `2.16.6` | `2.16.7` |
| [github.com/pion/webrtc/v4](https://github.com/pion/webrtc) | `4.2.15` | `4.2.16` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.50.0` | `0.52.0` |
| [golang.org/x/term](https://github.com/golang/term) | `0.42.0` | `0.43.0` |
| [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | `1.52.0` | `1.53.0` |


Updates `github.com/livekit/protocol` from 1.46.0 to 1.48.2
- [Release notes](https://github.com/livekit/protocol/releases)
- [Changelog](https://github.com/livekit/protocol/blob/main/CHANGELOG.md)
- [Commits](https://github.com/livekit/protocol/compare/v1.46.0...v1.48.2)

Updates `github.com/livekit/server-sdk-go/v2` from 2.16.6 to 2.16.7
- [Commits](https://github.com/livekit/server-sdk-go/compare/v2.16.6...v2.16.7)

Updates `github.com/pion/webrtc/v4` from 4.2.15 to 4.2.16
- [Release notes](https://github.com/pion/webrtc/releases)
- [Commits](https://github.com/pion/webrtc/compare/v4.2.15...v4.2.16)

Updates `golang.org/x/crypto` from 0.50.0 to 0.52.0
- [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.52.0)

Updates `golang.org/x/term` from 0.42.0 to 0.43.0
- [Commits](https://github.com/golang/term/compare/v0.42.0...v0.43.0)

Updates `modernc.org/sqlite` from 1.52.0 to 1.53.0
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.52.0...v1.53.0)

---
updated-dependencies:
- dependency-name: github.com/livekit/protocol
  dependency-version: 1.48.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: github.com/livekit/server-sdk-go/v2
  dependency-version: 2.16.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: github.com/pion/webrtc/v4
  dependency-version: 4.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: golang.org/x/crypto
  dependency-version: 0.52.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: golang.org/x/term
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
- dependency-name: modernc.org/sqlite
  dependency-version: 1.53.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 01:08:25 -07:00
807ecf2530
chore: keep all agentbbs services on latest software (#69)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
* ci: add mailu-update workflow to keep the mail stack current

The deploy/mailu compose stack pins the floating series tags
(ghcr.io/mailu/*:2024.06); patch releases within the series only land when
someone runs `docker compose pull`, so the box drifts behind on security fixes.

Add a scheduled (weekly) + on-demand workflow that SSHes to the droplet
(reusing deploy.yml's DEPLOY_* secrets), backs up DKIM keys + the admin DB,
pulls the latest images for the pinned series, recreates the containers, and
health-checks the Mailu front on 127.0.0.1:8080. Shares deploy.yml's
concurrency group so it never races a code deploy. Stays within the pinned
series on purpose — crossing to a future series stays a deliberate PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: bump Forgejo to 11.0.15 + add Dependabot to keep deps current

Audit of every version pin in the repo: Ergo (2.18.0), Go (1.26 → latest
patch via setup-go), the Ubuntu pod base (24.04 LTS), and the GitHub Action
majors are all already current. Only Forgejo was stale — bump 11.0.1 →
11.0.15 (latest patch of the 11.x LTS line; a 15.x major stays a deliberate,
tested upgrade because of DB migrations).

Add .github/dependabot.yml so github-actions, Go modules, and the Docker
image tags (Mailu compose + pod Containerfile) get review-gated update PRs
weekly. Shell-string pins (FORGEJO_VERSION/ERGO_VERSION in setup.sh) can't be
watched by Dependabot; noted inline. Mailu runtime patch level is handled by
the mailu-update workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* mailu: document RECIPIENT_DELIMITER=+ in mailu.env.example

Plus-addressing (chovy+tag@ -> chovy@) is a hard prerequisite for qaaas.dev's
packages/mail but was missing from the example, so tagged mail bounces as an
unknown recipient until an operator sets it by hand. Add it with a note that it
governs DELIVERY only, not login (Mailu auths the exact address; base <name>@
is the single login and already receives all +tagged mail).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:06:06 -07:00
d19c5c4c3e files: seed a default README.txt into every member's public area
ensureUserPub only ran os.MkdirAll, so a freshly-provisioned /public
(and thus ~<name>/public on the web) came up empty — only ~chovy had a
README because it was uploaded by hand. Embed that help text as a
default and write it whenever the area has no README.txt.

ensureUserPub is hit on SFTP connect (fs.go) and when the web host
materializes ~<name>/public (AnonRoot), so this self-heals every
existing empty member the next time they connect or their page is
viewed — no manual backfill. A member's own README is never clobbered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 02:47:27 +00:00
042166b05f members: show joined date in admin + public lists; 'last active: X ago'
Admin Users view appends 'joined YYYY-MM-DD'. Public member directory
shows 'last active: N days ago' for offline members plus the joined date,
both sourced from store.User.CreatedAt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 02:40:24 +00:00
28ad36834e irc(ergo): allow chrome-extension:// + irc domain origins for WS
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
TronBrowser's in-extension IRC client connects to the Ergo WebSocket from a
chrome-extension:// page; the ID is path-derived (differs per install) so use a
wildcard. Safe — the network is members-only and every WS client still passes
SASL, so Origin isn't the access gate. Also add the irc domain itself.

Needs deploy (push to main → setup.sh re-renders /etc/ergo/ircd.yaml + restarts
ergo) for the web/extension client to connect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:28:29 +00:00
105ff0ed8a
fix(passwd): also reset The Lounge web-login password (#61)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled
passwd@ reset the IRC SASL credential (Ergo store + The Lounge saslPassword) but
NOT The Lounge's own web-login password (the bcrypt field used to sign in to
chat.<domain> itself). So a member who reset their password could connect to IRC
but got "auth failed" at chat.profullstack.com/sign-in.

set-irc-password.sh now sets all THREE chat credentials to the new password:
Ergo SASL, the Lounge saslPassword, and the Lounge web-login password via
`thelounge reset <member>` (AGENTBBS_LOUNGE_RESET_CMD, default targets the
dockerized The Lounge). The password is piped on stdin to `thelounge reset`, so
it never lands on a command line. Best-effort: a Lounge web-reset failure warns
but doesn't fail the run (Ergo SASL stays the primary IRC secret).

Bumped ircpass SetPassword's context timeout 20s→60s since the helper now also
runs a `docker exec thelounge ...` step.

Verified live on bbs.profullstack.com: the modified helper sets all three for an
existing member (web bcrypt match + saslPassword + Ergo store), and the affected
member's web login was reconciled.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:40:28 -07:00
54ede811f9
Merge pull request #60 from profullstack/feat/group-broadcast-messaging
feat(messaging): group & broadcast messages + email-all
2026-06-27 07:03:41 -07:00
103ddeb7c9 feat(messaging): group & broadcast messages + email-all
Members can now message a group or everyone, and the operator can announce to
the whole membership by email.

Inbox channel (any member):
  - msg@ recipient spec accepts a comma list (alice,bob,carol) or all/*/everyone
    to broadcast: `ssh msg@host alice,bob hi`, `ssh msg@host all hi`.
  - Members hub TUI gains multi-select: space toggles, `a` selects all, `m`
    messages the selected group (header names the audience); selection clears
    after send.
  - store.SendMessageMulti delivers one body to many inboxes in a single
    transaction (dedupes, skips empties); resolveRecipients validates names,
    excludes the sender, and skips banned members on broadcast.

Email channel (operator, explicit):
  - new `agentbbs broadcast` subcommand sends an announcement to ALL members via
    inbox + email. Preview by default (like notify-creds); --send delivers;
    --no-inbox/--no-email pick a channel; --subject/--from/--user refine it.
    Email reaches only verified addresses and refuses --send without SMTP.

Tests: SendMessageMulti (dedupe/empty), resolveRecipients (list/unknown/all
tokens, banned + sender exclusion), TUI selection (toggle/select-all/group
compose). Docs: docs/messaging.md. build/vet/gofmt/`go test ./...` green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 12:18:41 +00:00
54da317f4e
feat(passwd): self-service password reset across git, mail & chat (#59)
Add a key-gated `ssh passwd@host` route (alias `password@`) that sets ONE
member-chosen password across every service with its own credential:

  - git  (Forgejo)        new forgejo.SetPassword (PATCH /admin/users, clears
                          must_change; EnsureUser first so the account exists)
  - mail (Mailu webmail)  existing mailu.SetPassword
  - chat (IRC/Ergo + The Lounge)  new internal/ircpass package

Because the route authenticates by the member's registered SSH key, it also
serves as the forgot-password path — no old password required.

The BBS runs as a non-root service user, but the Ergo password store and The
Lounge user files are root-owned. internal/ircpass bridges this by shelling out
to scripts/set-irc-password.sh through a narrow sudoers rule (installed by
setup.sh). The new password travels on stdin (a new `set-irc-password.sh
<member> -` form), so it never appears in the process table or sudo's log.

UX: masked entry typed twice (readSecret); no-PTY reads stdin; empty input
generates a strong password and shows it once. Each service leg is independent
and best-effort with a per-service ✓/✗ summary, plus a confirmation email that
never contains the password.

Tests: ircpass (stdin contract + member/password rejection), forgejo.SetPassword,
auth IsPasswdName + reservation. Docs: credentials.md (passwd@ section) + irc.md.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 03:46:23 -07:00
f2bcb7e063 files: /me and /public are two separate per-user areas
Per feedback: /me is PRIVATE and the public folder must be its own
top-level area, not nested under /me.

- A member now has two sibling areas over SFTP: /me (private,
  <root>/files/users/<name>) and /public (their own public files,
  <root>/files/public/<name>), served anonymously at ~<name>/public.
- Drop the global shared /public web route and the /me/public nesting.
  The anon surface only exposes ~name/public; /me has no anon route.
- Both owned areas count toward the quota gauge.
- Index publish hint, docs, and setup.sh updated to scp :/public/.

files.<host> stays a file server; member sites remain on the BBS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 01:36:43 +00:00