fix(test-apps): key OIDC sign-in records by userId instead of module state - #285
Open
ahmedhamouda78 wants to merge 1 commit into
Open
fix(test-apps): key OIDC sign-in records by userId instead of module state#285ahmedhamouda78 wants to merge 1 commit into
ahmedhamouda78 wants to merge 1 commit into
Conversation
The AuthOIDC `onSignIn` hooks recorded the signed-in user into module-level variables that the e2e then read back over a separate request. The hook runs while the callback is being served, so in a deployed environment the two requests can land on different Lambda instances: the reader gets its own null, or the record of whoever signed in last on that instance. The second case is the worse one, since the old assertions only checked `provider` and a leftover record from the same provider would pass while proving nothing. Same shape as the verification-code flake, different flow. Sign-in records now go to the existing oidc-profiles KVStore under `signin:<instance>:<userId>`, and `userId` is required on oidcGetLastSignInUser / oidcExtrasGetLastSignInUser, so "give me whoever signed in last" no longer type checks. The e2e before-hook runs tsc --noEmit, so that is enforced. Reusing oidc-profiles rather than adding a store: it already holds the per-user profile that the second instance upserts, and the keys are bounded here because the stub IdP returns a fixed user per provider, so each sign-in overwrites its own record. Tests now resolve their own userId from the session (via requireAuth) and poll for that record instead of reading once. New coverage: an unknown userId reads as null rather than the most recent sign-in, and the two AuthOIDC instances keep separate records. Both fail if the module-level semantics come back. Fixes #284
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
AuthOIDC'sonSignInhooks in the comprehensive test app recorded the signed-in user into module-level variables:The hook runs while the OIDC callback is being served. The e2e reads the result back over a later, separate request. In a deployed environment those two can land on different Lambda instances, so the reader either sees its own
nullor the record of whoever signed in last on whichever instance answered.The second case is the one that bothers me more than a plain failure. The old assertions only checked
provider, so a leftover record from the same provider would pass while proving nothing about the sign-in the test had just performed.Same class as the verification-code flake in #278, different flow. No red builds have been pinned on this one yet, so this is prevention.
How
Sign-in records go to the existing
oidc-profilesKVStore undersignin:<instance>:<userId>, anduserIdis now required onoidcGetLastSignInUserandoidcExtrasGetLastSignInUser. "Give me whoever signed in last" no longer type checks:That is a live gate, not just a convention:
test:e2e:localrunstsc --noEmitin its before-hook.I reused
oidc-profilesinstead of adding a store. It already holds the per-user profile the second instance upserts, which the code comments call the canonical post-sign-in pattern, and no code scans it, only keyed get/put. The keys are also bounded here, unlike the verification codes: the stub IdP returns a fixed user per provider, so each sign-in overwrites its own record rather than piling up. That is why there is no purge method in this one.The two consumers now resolve their own
userIdfrom the session viarequireAuthand poll for that record rather than reading once. The polling lives intest/poll-for-signin.ts, a sibling of thepoll-for-code.tsthat #278 adds. Worth folding the two into one generic poller once both have landed; I kept them separate here so this PR does not depend on that one.Tests
Two new tests, both with a control run showing they bite. Restoring module-level semantics (a per-instance
Recordholding the last sign-in, which is exactly what the old code did) makes both fail:With the fix both pass, along with the rest of the OIDC suite:
Also added sign-out cleanup to the
onSignIn firestest, which previously left its session open.Ran locally on Node 22:
npm run build,npm run test:unit(0 fail across every workspace), the comprehensive e2e local,check:api,check:exports-consistency, and all three changeset guards.verify-coveragereports no publishable packages changed, so no changeset is needed here.The e2e shows 372 pass / 2 fail. Both failures are
cli-client.test.tsshelling out tonpmand hitting my host's CodeArtifact registry with an expired token,E401. They are unrelated to this change and pass in CI.Fixes #284