Add KeepOrg sync server: accounts, nested groups, versioned KDBX sync

Why: collaborative KeePass use needs one arbiter of "who wrote last" that
never sees a master password, plus access control that follows an org chart.

What: stdlib-only Go server. Metadata is a single JSON document with one
writer and atomic commit; KDBX payloads are versioned blobs on disk. Access
comes from a group tree where a grant on a group reaches every member below
it. Login is password+TOTP, invite links, or OIDC through a browser-approved
device flow. Pushes carry If-Match and are arbitrated by a per-database merge
strategy (server-wins by default). Updates are pushed to clients over SSE.

Proved: go test ./internal/... covers RFC 6238 vectors, ACL inheritance and
isolation, store rollback, blob pruning, every push verdict, and an
end-to-end HTTP pass over login, conflict, force, read-only grants, invite
redemption, TOTP enrolment, device login and the event stream.
This commit is contained in:
2026-10-29 15:54:10 +01:00
commit 8bbb3179a1
26 changed files with 3897 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
package secret
import "testing"
func TestHashVerifyRoundTrip(t *testing.T) {
h, err := Hash("correct horse")
if err != nil {
t.Fatal(err)
}
if !Verify(h, "correct horse") {
t.Fatal("correct password rejected")
}
if Verify(h, "wrong horse") {
t.Fatal("wrong password accepted")
}
}
func TestVerifyRejectsJunkVerifier(t *testing.T) {
for _, v := range []string{"", "x", "pbkdf2-sha256$1$a$b", "md5$1$a$b"} {
if Verify(v, "anything") {
t.Fatalf("verifier %q accepted", v)
}
}
}
func TestUserCodeShape(t *testing.T) {
c := UserCode()
if len(c) != 9 || c[4] != '-' {
t.Fatalf("user code %q", c)
}
}