mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
Autonomous deploy + free-pod/Premium-email membership (#1)
Deploy automation (idempotent, runs on every deploy): - .github/workflows/deploy.yml: push to main/master (or dispatch) SSHes to the droplet and re-runs setup.sh; deploys the pushed branch; smoke-tests :22. - scripts/self-update.sh + agentbbs-update.timer: autonomous backstop that redeploys only when origin advances. - setup.sh hardened: flock, fetch+reset (survives force-push), fixed the always-skipped arcade asset fetch path. Membership model: - Free, email-verified members get their own Docker pod (pod@ paywall removed) and a /~name homepage (seeded at join@). - join@ is now interactive: email -> emailed 6-digit code -> enter code. - Premium ($10 one-time, lifetime via CoinPay) grants a personal <name>@host email (new internal/forwardemail; forwardemail.net aliases) and custom domains (domain@ gated to Premium). - ensurePremium() silently verifies/grants/provisions on hub login, join@, and domain@. New-signup details emailed to AGENTBBS_SIGNUP_NOTIFY (subject "bbs"). Store: User.Premium + premium/premium_ref cols, ConfirmEmailCode, GrantPremium. Tests: store_premium_test.go, forwardemail_test.go. Build/vet/gofmt/test green. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1086d57a4d
commit
7a85f2dbbb
11 changed files with 900 additions and 101 deletions
27
internal/forwardemail/forwardemail_test.go
Normal file
27
internal/forwardemail/forwardemail_test.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package forwardemail
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestConfiguredAndAddress(t *testing.T) {
|
||||
var empty Config
|
||||
if empty.Configured() {
|
||||
t.Fatal("empty config must not be Configured")
|
||||
}
|
||||
if (Config{APIKey: "k"}).Configured() {
|
||||
t.Fatal("API key without domain must not be Configured")
|
||||
}
|
||||
c := Config{APIKey: "k", Domain: "bbs.profullstack.com", Webmail: "https://webmail.example"}
|
||||
if !c.Configured() {
|
||||
t.Fatal("API key + domain should be Configured")
|
||||
}
|
||||
if got := c.Address("alice"); got != "alice@bbs.profullstack.com" {
|
||||
t.Fatalf("Address = %q", got)
|
||||
}
|
||||
if c.WebmailURL() != "https://webmail.example" {
|
||||
t.Fatalf("WebmailURL = %q", c.WebmailURL())
|
||||
}
|
||||
// Creating an alias without config is a clean error, not a panic.
|
||||
if err := empty.CreateAlias("alice", "alice@x.com"); err == nil {
|
||||
t.Fatal("CreateAlias on unconfigured must error")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue