mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
bbs.profullstack.com launch kit: provisioner, custom domains, email verify, ascii-live
- setup.sh: idempotent one-shot droplet provisioner — agentbbs on :22 (admin OpenSSH moved to :2202), rootless podman, Caddy front end for https://bbs.profullstack.com with tilde-style /~user homepages - internal/sites + domain@ SSH route: self-service custom domains (ssh domain@host add example.com) backed by a symlink farm and an on-demand-TLS ask endpoint so Caddy only issues certs for mapped hosts - internal/mail + join@ email verification: optional email at signup, confirmation link served by a loopback /verify endpoint behind Caddy - internal/source + cmd/ascii-live: live video → terminal ASCII groundwork (docs/ascii-live.md) - store: additive sqlite migrations (email/verify columns, domains table) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9b0f465946
commit
f3f8e70996
14 changed files with 2005 additions and 27 deletions
80
internal/source/source_test.go
Normal file
80
internal/source/source_test.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package source
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClassify(t *testing.T) {
|
||||
cases := []struct {
|
||||
raw string
|
||||
want Kind
|
||||
wantErr bool
|
||||
}{
|
||||
{"https://youtube.com/live/abc123", KindYouTube, false},
|
||||
{"https://www.youtube.com/watch?v=abc", KindYouTube, false},
|
||||
{"https://youtu.be/abc123", KindYouTube, false},
|
||||
{"https://example.com/path/stream.m3u8", KindHLS, false},
|
||||
{"http://cdn.example.com/live.m3u8?token=x", KindHLS, false},
|
||||
{"https://example.com/whatever", KindHLS, false}, // unknown http(s) → HLS handling
|
||||
{"file:///etc/passwd", "", true},
|
||||
{"rtmp://example.com/live", "", true},
|
||||
{"ftp://example.com/x", "", true},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got, err := Classify(c.raw)
|
||||
if c.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("Classify(%q): expected error, got kind %q", c.raw, got)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Classify(%q): unexpected error: %v", c.raw, err)
|
||||
continue
|
||||
}
|
||||
if got != c.want {
|
||||
t.Errorf("Classify(%q) = %q, want %q", c.raw, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsBlockedIP(t *testing.T) {
|
||||
blocked := []string{
|
||||
"127.0.0.1", // loopback
|
||||
"::1", // loopback v6
|
||||
"10.0.0.5", // private
|
||||
"172.16.3.4", // private
|
||||
"192.168.1.1", // private
|
||||
"169.254.169.254", // link-local / cloud metadata
|
||||
"fe80::1", // link-local v6
|
||||
"fc00::1", // unique-local v6 (private)
|
||||
"0.0.0.0", // unspecified
|
||||
"224.0.0.1", // multicast
|
||||
}
|
||||
for _, s := range blocked {
|
||||
ip := net.ParseIP(s)
|
||||
if ip == nil {
|
||||
t.Fatalf("bad test IP %q", s)
|
||||
}
|
||||
if !isBlockedIP(ip) {
|
||||
t.Errorf("isBlockedIP(%s) = false, want true", s)
|
||||
}
|
||||
}
|
||||
|
||||
allowed := []string{
|
||||
"8.8.8.8", // public
|
||||
"1.1.1.1", // public
|
||||
"142.250.72.46", // public (googlevideo-ish)
|
||||
"2606:4700:4700::1111", // public v6
|
||||
}
|
||||
for _, s := range allowed {
|
||||
ip := net.ParseIP(s)
|
||||
if ip == nil {
|
||||
t.Fatalf("bad test IP %q", s)
|
||||
}
|
||||
if isBlockedIP(ip) {
|
||||
t.Errorf("isBlockedIP(%s) = true, want false", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue