mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
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>
27 lines
849 B
Go
27 lines
849 B
Go
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")
|
|
}
|
|
}
|