Files
OpenFlare/.auto/results.tsv
T
Ryan 53ae3007d0 fix(cordis): fail-closed auth guards for user/message_gateway/admin (#1)
* autoresearch iter 23: fail-closed auth guarding for user/message_gateway

Both plugins resolve contracts.AuthService in Apply to build their route
middleware, but declared only DBService in Inject(). The kernel gates a
plugin's Apply solely on declared deps, and cmd/app.go registers user
before auth, so user mounted first, core.Inject failed, and loginMW
silently degraded to a pass-through closure — leaving /api/v1/user
change-password, profile and access-tokens unguarded. message_gateway
was saved only by its later list position.

Declare AuthService in Inject() for both, and pin the property with a
reconcile-level test that mirrors production registration order and
asserts the real auth middleware reaches the route table.

* autoresearch iter 24: make auth middleware fallbacks fail closed

user, message_gateway and admin each fell back to a c.Next() closure when
contracts.AuthService could not be resolved, so a route would be served as
if authenticated. For admin this is reachable at runtime: OnDispose calls
service.ResetServices(), which nils the global the per-request guard reads,
so requests still in flight during dispose bypass authorization entirely.

Add ginutil.AuthUnavailable() and bind every fallback to it, with a test
that drives each plugin's registered guard without an auth service present
and asserts the request is aborted rather than passed through.

* chore(autoresearch): log iter 23 (fail-open auth ordering, proven)

* autoresearch iter 24 follow-up: let staticcheck infer the auth guard type

* docs(autoresearch): log iters 24-25 and lessons 9-11 (declared-dep bug class, gate discipline)
2026-08-29 11:21:04 +08:00

4.0 KiB

1iterationcommitmetricdeltastatusguarddescription
20-1020.0baselinepassinitial measurement (pinned yardstick: repo gate + real-risk analyzers)
311c5731b100-2.0keeppasscore: Using2/Using3 now wrap dependency causes via errors.Join (proven: test fails on revert)
4237ad58695-5.0keeppasssentinel == comparisons -> errors.Is across admin/upload/cap-pow (5 sites)
53686e3ef93-2.0keeppassfilesrv.AbortUploadRecordError dedups error mapping + errors.As (2 sites, drops dead ErrInvalidUploadID)
647e6b9e7930.0keeppassPROVEN FIX: singleflight image generation no longer dies with the first caller canceled ctx (test fails on revert)
76ce3399792-1.0keeppassBUGFIX admin logs: negative cursor was accepted (bool ignored by callers) -> error-only contract; proven via revert (compile-level) + contract test
87c66399e89-3.0keeppasspush channels share title/content/level extraction (3 dead inits gone, ~20 fewer lines)
9818820b1890.0keeppassBUGFIX push: synthesized notification content had random field order (map iteration); sorted keys, test observed failing pre-fix
10922ecafd87-2.0keeppassunparam: always-nil error returns dropped, 4 unreachable branches removed
1110c4068ef84-3.0keeppasserrorlint cleared to 0: %%w at push test + telegram fallback, errors.As in config loader
12113d2038a80-4.0keeppassnilnil: unimplemented auth mocks now return a sentinel instead of (nil,nil)
1312101cb2f79-1.0keeppassnilnil: inproc driver GetExecution returns error, matching asynq driver semantics
14146932b54790.0keeppassDATA-LOSS BUGFIX: cache read error no longer clobbers buffered task log (proven: assertion fails on revert)
15152c41563790.0keeppassPERF: CORS origin check no longer hits DB per request (5s cached read); proven - loader count 0 vs 1 on revert
1616976f9b1790.0keeppassPERF: contract-level batch user lookup replaces N+1 in access-log enrichment (test proves 1 query vs 3)
17171b1c452790.0keeppassBUGFIX: orphan cron message_gateway:cleanup_pairing_codes now has a handler; invariant test added (proven by stash-revert)
18188c4955c790.0keeppassBUGFIX: removed phantom user:daily_audit cron (dispatched to unregistered task); cross-plugin invariant test added
191984eaf3f790.0keeppassCORDIS+BUGFIX: task handlers were asynq-typed so 4 upload tasks could not run under the in-process worker; made driver-agnostic + gate check 7 (proven: gate names all 3 files pre-fix)
2020efa7555790.0keeppassBUGFIX telegram: LongPoller.Timeout was 10 nanoseconds -> getUpdates timeout=0 -> busy polling; now 10s (proven by reverting the constant)
21211023fa3790.0keeppassDISK LEAK: telegram inbound media scratch dirs were never removed (no consumer reads them); cleanup on handler exit. No test possible (needs live download)
2222ad8384154-25.0keeppassdead lint suppressions removed (24); 2 were load-bearing -> restored+narrowed with reasons after guard veto exposed verified contextcheck FPs
2323de938de540.0keeppassSECURITY/BUGFIX fail-open auth: user+message_gateway consumed contracts.AuthService in Apply but declared only DBService, so reconcile mounted user before auth and loginMW degraded to a pass-through (user change-password/profile/access-tokens unguarded in production, deterministically); declared the dep + added reconcile-level ordering test (PROVED: assertion fails on revert)
242462b48e9540.0keeppassSECURITY: all three auth-middleware fallbacks were c.Next() (fail-open). Reachable at runtime in admin: OnDispose->ResetServices() nils the global the per-request guard reads, so in-flight requests pass as authenticated. Added ginutil.AuthUnavailable() + table test driving each registered guard (PROVED: abort assertion fails on revert to 577d795)
2525f58f5a4540.0keeppassstaticcheck ST1023 x4 from iter 24 (redundant gin.HandlerFunc on typed-RHS decls) - caught by GUARD only, go build/go test both stayed green; lesson: run checks.sh after EVERY commit, not just before ship