Flatten compliance portal package layout

Remove the root complianceportal package and the resolver
facade that existed only to break an IAM import cycle. Admin
policies, domain URL helpers, and actions live under
management; visitor OAuth metadata, brand URLs, and public
read paths live under visitor. Drop the duplicate trust API
magic-link mutations now that Connect handles portal auth, and
stop IAM from owning compliance page email branding.

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-07-17 16:19:39 +02:00
parent 4cec74c1a1
commit 7e0d187dcf
57 changed files with 737 additions and 1061 deletions

View File

@@ -23,6 +23,8 @@ package slug
import (
"regexp"
"strings"
"go.probo.inc/probo/pkg/crypto/rand"
)
var (
@@ -42,3 +44,14 @@ func Make(s string) string {
return s
}
func MakeWithEntropy(s string) string {
base := Make(s)
suffix := rand.MustHexString(4)
if base == "" {
return suffix
}
return base + "-" + suffix
}

View File

@@ -22,30 +22,73 @@ package slug
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMake(t *testing.T) {
t.Parallel()
tests := []struct {
name string
input string
expected string
}{
{"Hello World", "hello-world"},
{"This is a test", "this-is-a-test"},
{"Special characters: !@#$%^&*()", "special-characters"},
{"Multiple---Hyphens", "multiple-hyphens"},
{"-Trim-Hyphens-", "trim-hyphens"},
{"123 Numbers", "123-numbers"},
{" Spaces ", "spaces"},
{"", ""},
{"UPPERCASE", "uppercase"},
{"under_score", "under-score"},
{"dots.and.more.dots", "dotsandmoredots"},
{name: "hello world", input: "Hello World", expected: "hello-world"},
{name: "this is a test", input: "This is a test", expected: "this-is-a-test"},
{name: "special characters", input: "Special characters: !@#$%^&*()", expected: "special-characters"},
{name: "multiple hyphens", input: "Multiple---Hyphens", expected: "multiple-hyphens"},
{name: "trim hyphens", input: "-Trim-Hyphens-", expected: "trim-hyphens"},
{name: "numbers", input: "123 Numbers", expected: "123-numbers"},
{name: "spaces", input: " Spaces ", expected: "spaces"},
{name: "empty", input: "", expected: ""},
{name: "uppercase", input: "UPPERCASE", expected: "uppercase"},
{name: "underscore", input: "under_score", expected: "under-score"},
{name: "dots", input: "dots.and.more.dots", expected: "dotsandmoredots"},
}
for _, test := range tests {
slug := Make(test.input)
if slug != test.expected {
t.Errorf("Slug(%q) = %q; expected %q", test.input, slug, test.expected)
}
for _, tt := range tests {
t.Run(
tt.name,
func(t *testing.T) {
t.Parallel()
assert.Equal(t, tt.expected, Make(tt.input))
},
)
}
}
func TestMakeWithEntropy(t *testing.T) {
t.Parallel()
t.Run(
"empty input returns hex only",
func(t *testing.T) {
t.Parallel()
assert.Regexp(t, `^[0-9a-f]{8}$`, MakeWithEntropy(""))
},
)
t.Run(
"non-empty input returns base with hex suffix",
func(t *testing.T) {
t.Parallel()
got := MakeWithEntropy("Hello World")
assert.Regexp(t, `^hello-world-[0-9a-f]{8}$`, got)
},
)
t.Run(
"successive calls differ",
func(t *testing.T) {
t.Parallel()
first := MakeWithEntropy("Acme Corp")
second := MakeWithEntropy("Acme Corp")
assert.NotEqual(t, first, second, "MakeWithEntropy should produce distinct slugs")
},
)
}