PR #4 of the 11-PR completion sequence. Fixes the go vet SA1029 class of bug in the auth middleware and stops abusing http.ErrMissingFile as an auth sentinel.
Unexported ctxKey type + three constants (ctxKeyUserAddress, ctxKeyUserTrack, ctxKeyAuthenticated) replace the bare string keys "user_address" / "user_track" / "authenticated".
New sentinel ErrMissingAuthorization replaces misuse of http.ErrMissingFile (which belongs to multipart/form-data parsing) as an "auth header missing" signal.
Call sites migrated
backend/api/middleware/auth.go — RequireAuth, OptionalAuth, RequireTrack, extractAuth all use the typed helpers. Unused context import dropped.
backend/api/track4/operator_scripts_test.go — four fixtures now seed the context through middleware.ContextWithAuth(..., 4, true) instead of context.WithValue with a bare string key. This is load-bearing: a bare string key no longer reaches the middleware helpers, so anyone regressing the type discipline will fail these tests immediately.
TestContextKeyIsolation — a caller that writes context.WithValue(ctx, "user_address", "injected") with a bare string must NOT be visible to UserAddress(ctx). This specifically catches SA1029-class collisions.
TestErrMissingAuthorizationIsSentinel — errors.Is smoke test for the new sentinel.
Verification
go build ./... — clean.
go vet ./... — clean (SA1029 hits on the old bare keys are gone).
go test ./api/middleware/... ./api/track4/... ./api/rest/... — all PASS.
Completion criterion advanced
3. Auth correctness — "No bare-string context keys in backend/api/middleware or its callers; the auth-missing sentinel is a package-local errors.New, not http.ErrMissingFile."
## Summary
PR #4 of the 11-PR completion sequence. Fixes the `go vet` SA1029 class of bug in the auth middleware and stops abusing `http.ErrMissingFile` as an auth sentinel.
## `backend/api/middleware/context.go` (new)
<ref_snippet file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context.go" lines="1-60" />
- Unexported `ctxKey` type + three constants (`ctxKeyUserAddress`, `ctxKeyUserTrack`, `ctxKeyAuthenticated`) replace the bare string keys `"user_address"` / `"user_track"` / `"authenticated"`.
- Helpers: `ContextWithAuth`, `UserAddress`, `UserTrack`, `IsAuthenticated`.
- New sentinel `ErrMissingAuthorization` replaces misuse of `http.ErrMissingFile` (which belongs to `multipart/form-data` parsing) as an "auth header missing" signal.
## Call sites migrated
- `backend/api/middleware/auth.go` — `RequireAuth`, `OptionalAuth`, `RequireTrack`, `extractAuth` all use the typed helpers. Unused `context` import dropped.
- `backend/api/track4/operator_scripts.go`, `backend/api/track4/endpoints.go`, `backend/api/rest/features.go` — read address / track via `middleware.UserAddress()` / `middleware.UserTrack()`.
- `backend/api/track4/operator_scripts_test.go` — four fixtures now seed the context through `middleware.ContextWithAuth(..., 4, true)` instead of `context.WithValue` with a bare string key. This is load-bearing: a bare string key no longer reaches the middleware helpers, so anyone regressing the type discipline will fail these tests immediately.
## Tests
<ref_file file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context_test.go" />
- `TestContextWithAuthRoundTrip` — address / track / authenticated round-trip.
- `TestUserTrackDefaultsToTrack1OnBareContext` — Track 1 is the safe default for an un-seeded context.
- `TestUserAddressEmptyOnBareContext`, `TestIsAuthenticatedFalseOnBareContext` — default-deny defaults.
- `TestContextKeyIsolation` — a caller that writes `context.WithValue(ctx, "user_address", "injected")` with a bare string must NOT be visible to `UserAddress(ctx)`. This specifically catches SA1029-class collisions.
- `TestErrMissingAuthorizationIsSentinel` — `errors.Is` smoke test for the new sentinel.
## Verification
- `go build ./...` — clean.
- `go vet ./...` — clean (SA1029 hits on the old bare keys are gone).
- `go test ./api/middleware/... ./api/track4/... ./api/rest/...` — all PASS.
## Completion criterion advanced
> **3. Auth correctness** — "No bare-string context keys in `backend/api/middleware` or its callers; the auth-missing sentinel is a package-local `errors.New`, not `http.ErrMissingFile`."
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
PR #4 of the 11-PR completion sequence. Fixes the
go vetSA1029 class of bug in the auth middleware and stops abusinghttp.ErrMissingFileas an auth sentinel.backend/api/middleware/context.go(new)<ref_snippet file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context.go" lines="1-60" />
ctxKeytype + three constants (ctxKeyUserAddress,ctxKeyUserTrack,ctxKeyAuthenticated) replace the bare string keys"user_address"/"user_track"/"authenticated".ContextWithAuth,UserAddress,UserTrack,IsAuthenticated.ErrMissingAuthorizationreplaces misuse ofhttp.ErrMissingFile(which belongs tomultipart/form-dataparsing) as an "auth header missing" signal.Call sites migrated
backend/api/middleware/auth.go—RequireAuth,OptionalAuth,RequireTrack,extractAuthall use the typed helpers. Unusedcontextimport dropped.backend/api/track4/operator_scripts.go,backend/api/track4/endpoints.go,backend/api/rest/features.go— read address / track viamiddleware.UserAddress()/middleware.UserTrack().backend/api/track4/operator_scripts_test.go— four fixtures now seed the context throughmiddleware.ContextWithAuth(..., 4, true)instead ofcontext.WithValuewith a bare string key. This is load-bearing: a bare string key no longer reaches the middleware helpers, so anyone regressing the type discipline will fail these tests immediately.Tests
<ref_file file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context_test.go" />
TestContextWithAuthRoundTrip— address / track / authenticated round-trip.TestUserTrackDefaultsToTrack1OnBareContext— Track 1 is the safe default for an un-seeded context.TestUserAddressEmptyOnBareContext,TestIsAuthenticatedFalseOnBareContext— default-deny defaults.TestContextKeyIsolation— a caller that writescontext.WithValue(ctx, "user_address", "injected")with a bare string must NOT be visible toUserAddress(ctx). This specifically catches SA1029-class collisions.TestErrMissingAuthorizationIsSentinel—errors.Issmoke test for the new sentinel.Verification
go build ./...— clean.go vet ./...— clean (SA1029 hits on the old bare keys are gone).go test ./api/middleware/... ./api/track4/... ./api/rest/...— all PASS.Completion criterion advanced