carlos / platform Public

console: pin that operator status buys nothing on the member email doors

Fix round 2's gap: emailOperatorToken was only ever exercised against the
pause door, so a regression that leaked I3's IsOperator gate onto one of
the other eight member doors would have shipped unnoticed. Added
TestOperatorStatusBuysNothingOnMemberDoors — a fleet operator who is NOT a
member of the target account must get the same byte-identical
"404 page not found\n" a stranger gets on declare (write) and status
(read). Verified by mutation: an IsOperator short-circuit ahead of
apiAccountApp on the declare door made the test fail; reverted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev a376c38d70ca2676e257e864000522307115a4d1 parent 96291e5
1 file changed, +27 −0
  • internal/console/apimail_test.go +27 −0
diff --git a/internal/console/apimail_test.go b/internal/console/apimail_test.go
index 7b2295c1c..f0549173b 100644
--- a/internal/console/apimail_test.go
+++ b/internal/console/apimail_test.go
@@ -262,6 +262,33 @@ func TestEmailDoorsAre404WithNoProvisioner(t *testing.T) {
}
}
+// TestOperatorStatusBuysNothingOnMemberDoors: I3 moved the pause door off
+// apiAccountApp's member gate onto store.IsOperator — this proves that
+// move did not leak into the other eight. A fleet operator (IsOperator
+// true) who is NOT a member of the target account gets the exact same
+// byte-identical 404 an ordinary stranger gets on a WRITE (declare) and a
+// READ (status) member door. Operator status must buy nothing here.
+func TestOperatorStatusBuysNothingOnMemberDoors(t *testing.T) {
+ fx, _ := emailFixture(t, "code-email-operator-not-member")
+ ops := emailOperatorToken(t, fx, "code-email-operator-not-member-ops")
+
+ status, body := postRaw(t, emailURL(fx, "titogo"), map[string]any{"from": "hello@example.com"}, ops)
+ if status != http.StatusNotFound {
+ t.Fatalf("declare by a non-member operator = %d %q, want 404", status, body)
+ }
+ if body != "404 page not found\n" {
+ t.Fatalf("declare refusal body = %q, want the stdlib http.NotFound output", body)
+ }
+
+ status, body = getRaw(t, emailURL(fx, "titogo"), ops)
+ if status != http.StatusNotFound {
+ t.Fatalf("status by a non-member operator = %d %q, want 404", status, body)
+ }
+ if body != "404 page not found\n" {
+ t.Fatalf("status refusal body = %q, want the stdlib http.NotFound output", body)
+ }
+}
+
// ---- declare and its changed-gating ------------------------------------
// TestAPIEmailDeclareWritesTheRecord: the happy path. From is required (a