diff --git a/cmd/server/main.go b/cmd/server/main.go index 6c66b58..448188d 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -127,12 +127,33 @@ func runroomsrv() error { return fmt.Errorf("https-domain can't be empty. See '%s -h' for a full list of options", os.Args[0]) } + // validate listen addresses to bail out on invalid flag input before doing anything else + _, muxrpcPortStr, err := net.SplitHostPort(listenAddrShsMux) + if err != nil { + return fmt.Errorf("invalid muxrpc listener: %w", err) + } + + portMUXRPC, err := net.LookupPort("tcp", muxrpcPortStr) + if err != nil { + return fmt.Errorf("invalid tcp port for muxrpc listener: %w", err) + } + + _, portHTTPStr, err := net.SplitHostPort(listenAddrHTTP) + if err != nil { + return fmt.Errorf("invalid http listener: %w", err) + } + + portHTTP, err := net.LookupPort("tcp", portHTTPStr) + if err != nil { + return fmt.Errorf("invalid tcp port for muxrpc listener: %w", err) + } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() ak, err := base64.StdEncoding.DecodeString(appKey) if err != nil { - return fmt.Errorf("application key: %w", err) + return fmt.Errorf("secret-handshake appkey is invalid base64: %w", err) } opts := []roomsrv.Option{ @@ -213,7 +234,12 @@ func runroomsrv() error { dashboardH, err := handlers.New( kitlog.With(log, "package", "web"), repo.New(repoDir), - httpsDomain, + handlers.NetworkInfo{ + Domain: httpsDomain, + PortHTTPS: uint(portHTTP), + PortMUXRPC: uint(portMUXRPC), + PubKey: roomsrv.Whoami().PubKey(), + }, roomsrv.StateManager, handlers.Databases{ AuthWithSSB: db.AuthWithSSB, diff --git a/web/handlers/http.go b/web/handlers/http.go index 901bc60..aa759b4 100644 --- a/web/handlers/http.go +++ b/web/handlers/http.go @@ -17,6 +17,7 @@ import ( "go.mindeco.de/http/auth" "go.mindeco.de/http/render" "go.mindeco.de/logging" + "golang.org/x/crypto/ed25519" "github.com/ssb-ngi-pointer/go-ssb-room/admindb" "github.com/ssb-ngi-pointer/go-ssb-room/internal/repo" @@ -49,11 +50,21 @@ type Databases struct { PinnedNotices admindb.PinnedNoticesService } +// NetworkInfo encapsulates the domain name of the room, it's ssb/secret-handshake public key and the HTTP and MUXRPC TCP ports. +type NetworkInfo struct { + PortMUXRPC uint + PortHTTPS uint // 0 assumes default (443) + + PubKey ed25519.PublicKey + + Domain string +} + // New initializes the whole web stack for rooms, with all the sub-modules and routing. func New( logger logging.Interface, repo repo.Interface, - domainName string, + netInfo NetworkInfo, roomState *roomstate.Manager, dbs Databases, @@ -211,7 +222,7 @@ func New( roomsAuth.Handler(m, r, a) adminHandler := admin.Handler( - domainName, + netInfo.Domain, r, roomState, admin.Databases{ @@ -247,6 +258,9 @@ func New( var ih = inviteHandler{ invites: dbs.Invites, + + roomPubKey: netInfo.PubKey, + muxrpcHostAndPort: fmt.Sprintf("%s:%d", netInfo.Domain, netInfo.PortMUXRPC), } m.Get(router.CompleteInviteAccept).Handler(r.HTML("invite/accept.tmpl", ih.acceptForm)) m.Get(router.CompleteInviteConsume).Handler(r.HTML("invite/consumed.tmpl", ih.consume)) diff --git a/web/handlers/invites.go b/web/handlers/invites.go index 0c6526e..2fcc93b 100644 --- a/web/handlers/invites.go +++ b/web/handlers/invites.go @@ -1,11 +1,14 @@ package handlers import ( + "encoding/base64" "errors" + "fmt" "net/http" "go.mindeco.de/http/render" "go.mindeco.de/logging" + "golang.org/x/crypto/ed25519" "github.com/go-kit/kit/log/level" "github.com/gorilla/csrf" @@ -19,6 +22,9 @@ type inviteHandler struct { invites admindb.InviteService alaises admindb.AliasService + + muxrpcHostAndPort string + roomPubKey ed25519.PublicKey } func (h inviteHandler) acceptForm(rw http.ResponseWriter, req *http.Request) (interface{}, error) { @@ -71,7 +77,11 @@ func (h inviteHandler) consume(rw http.ResponseWriter, req *http.Request) (inter ) } + // TODO: hardcoded here just to be replaced soon with next version of ssb-uri + roomPubKey := base64.StdEncoding.EncodeToString(h.roomPubKey) + roomAddr := fmt.Sprintf("net:%s~shs:%s:SSB+Room+PSK3TLYC2T86EHQCUHBUHASCASE18JBV24=", h.muxrpcHostAndPort, roomPubKey) + return map[string]interface{}{ - "TunnelAddress": "pew pew", + "RoomAddress": roomAddr, }, nil } diff --git a/web/handlers/invites_test.go b/web/handlers/invites_test.go index 92d3a46..eb82812 100644 --- a/web/handlers/invites_test.go +++ b/web/handlers/invites_test.go @@ -2,9 +2,11 @@ package handlers import ( "bytes" + "encoding/base64" "net/http" "net/http/cookiejar" "net/url" + "strings" "testing" "github.com/PuerkitoBio/goquery" @@ -219,5 +221,12 @@ func TestInviteConsumeInvite(t *testing.T) { consumedDoc, err := goquery.NewDocumentFromReader(resp.Body) r.NoError(err) - t.Log(consumedDoc.Find("body").Text()) + + gotRA := consumedDoc.Find("#room-address").Text() + + // TODO: this is just a cheap stub for actual ssb-uri parsing + a.True(strings.HasPrefix(gotRA, "net:localhost:8008~shs:"), "not for the test host: %s", gotRA) + a.True(strings.Contains(gotRA, base64.StdEncoding.EncodeToString(ts.NetworkInfo.PubKey)), "public key missing? %s", gotRA) + a.True(strings.HasSuffix(gotRA, ":SSB+Room+PSK3TLYC2T86EHQCUHBUHASCASE18JBV24="), "magic suffix missing: %s", gotRA) + } diff --git a/web/handlers/setup_test.go b/web/handlers/setup_test.go index 0f97b8e..6c42729 100644 --- a/web/handlers/setup_test.go +++ b/web/handlers/setup_test.go @@ -39,6 +39,8 @@ type testSession struct { NoticeDB *mockdb.FakeNoticesService RoomState *roomstate.Manager + + NetworkInfo NetworkInfo } var testI18N = justTheKeys() @@ -69,6 +71,14 @@ func setup(t *testing.T) *testSession { ts.PinnedDB.GetReturns(defaultNotice, nil) ts.NoticeDB = new(mockdb.FakeNoticesService) + ts.NetworkInfo = NetworkInfo{ + Domain: "localhost", + PortMUXRPC: 8008, + PortHTTPS: 443, + + PubKey: bytes.Repeat([]byte("test"), 8), + } + log, _ := logtest.KitLogger("complete", t) ctx := context.TODO() ts.RoomState = roomstate.NewManager(ctx, log) @@ -78,7 +88,7 @@ func setup(t *testing.T) *testSession { h, err := New( log, testRepo, - "localhost", + ts.NetworkInfo, ts.RoomState, Databases{ AuthWithSSB: ts.AuthDB, diff --git a/web/templates/invite/consumed.tmpl b/web/templates/invite/consumed.tmpl index cefcb3c..240b4e2 100644 --- a/web/templates/invite/consumed.tmpl +++ b/web/templates/invite/consumed.tmpl @@ -7,6 +7,7 @@ class="text-center" >{{i18n "InviteConsumedWelcome"}} -

TODO: present tunnel address and ssb uri redirect

+

TODO: this is just a room v1 invite. present tunnel address and ssb uri redirect

+
{{.RoomAddress}}
{{end}} \ No newline at end of file