Pin access token claim serialization - #517
Conversation
|
Approach: extend tests/Orbit.Infrastructure.Tests/Services/JwtTokenServiceTests.cs with a contract test that splits the token, base64url decodes payload segment 1, parses it with JsonDocument, and asserts the exact property set plus each value and JsonValueKind. Keep this beside the existing JwtTokenService tests because serialization is the service contract. Do not change JwtTokenService because the measured current payload is the required behavior. Reject JwtSecurityTokenHandler based assertions because inbound claim mapping hides raw key changes, and reject a separate fixture because deriving the payload from the real producer is the evidence this ticket requires. The contract comment will name apps/mobile/stores/auth-store.ts getUserFromPayload and OrbitWidgetModule.accountId as the consumers. |
There was a problem hiding this comment.
Important
This head has no changed files, so the promised access token serialization contract is not present and the PR is not ready to merge.
Reviewed changes I reviewed the only commit currently on chore/ticket-494-jwt-claim-pin against main.
- Setup commit:
9723455is empty; no service or test changes are available for review.
⚠️ The raw JWT payload remains unpinned
The existing tests check selected claims after parsing a token, but they do not assert the complete raw payload property set, JSON value kinds, or scalar representations consumed by the mobile app. Because this PR adds no contract assertion, merging it would leave the compatibility risk described in the title unresolved.
Technical details
# Add the serialization contract before merge
## Affected sites
- `tests/Orbit.Infrastructure.Tests/Services/JwtTokenServiceTests.cs:30`: the current tests do not pin the complete raw payload emitted by `JwtTokenService`.
- `apps/mobile/stores/auth-store.ts:65` in `orbit-ui-mobile`: installed clients decode the token payload directly and read serialized identity and expiry claims.
## Required outcome
- Add a test over a token generated by the real `JwtTokenService` that base64url decodes the payload and pins the expected property names, values, and JSON kinds.
- Preserve the raw claim keys and representations accepted by shipped mobile clients.GPT Sol | 𝕏
|
@pullfrog review |
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I reviewed the raw JWT payload contract added since the prior Pullfrog review.
- Serialization contract: Added a test over the real
JwtTokenServicethat base64url decodes the payload and pins the complete property set, literal claim keys, configured and identity values, and every JSON value kind consumed by clients.
GPT Sol | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I reviewed the full two-commit PR, including the claim contract added after the earlier empty setup commit.
- Raw payload extraction: The test base64url-decodes payload segment 1 from a token generated by the real
JwtTokenServiceand parses the serialized JSON directly. - Serialized claim contract: The assertion pins the complete property set, literal identity claim keys, configured values, JSON value kinds, GUID
jti, and integer timestamp representations. - Consumer context: The contract is colocated with existing service tests and identifies the mobile authentication and Android widget compatibility surfaces it protects.
GPT Sol | 𝕏




Closes #494
Summary
Contract evidence
The raw producer shape was derived by generating a token through the real JwtTokenService and decoding payload segment 1, as recorded in #494. The added test repeats that derivation from the real producer on every run.
Assumptions
Test evidence