Skip to content

Fix shallow copy mutation in normalize payload functions#112

Merged
JustWalters merged 3 commits intomasterfrom
fix/normalize-payload-mutation
Mar 3, 2026
Merged

Fix shallow copy mutation in normalize payload functions#112
JustWalters merged 3 commits intomasterfrom
fix/normalize-payload-mutation

Conversation

@JustWalters
Copy link
Contributor

Summary

  • normalizeEntryPayload and normalizeInvitePayload were spreading the payload shallowly ({ ...payload }), leaving attributes as a shared reference with the original request body
  • Mutations to the normalized copy's attributes silently corrupted req.body.payload, so any second access to req.envoy.payload would pass already-ISO timestamps to DateTime.fromSQL(), which returns null
  • Fix: spread attributes into the new object — { ...payload, attributes: { ...payload.attributes } }

Tests

Added test/payloads/EntryPayload.test.ts and test/payloads/InvitePayload.test.ts covering:

  • SQL → ISO conversion for each timestamp field
  • Mutation safety (original payload unchanged after normalization)
  • Idempotency (calling twice on same payload produces consistent, non-null results)

Version

Patch bump: 2.5.02.5.1

JustWalters and others added 2 commits March 2, 2026 17:46
…ePayload

Both functions were doing a shallow spread of the payload, leaving the
`attributes` object as a shared reference. Mutations to `attributes` in
the normalized copy would silently affect the original payload on
`req.body`, causing double-normalization to corrupt timestamp fields
(DateTime.fromSQL on an ISO string returns null).

Fix: spread `attributes` into the new object so mutations are isolated.

Add tests covering SQL→ISO conversion, mutation safety, and idempotency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@JustWalters JustWalters requested a review from Copilot March 2, 2026 22:54
@JustWalters JustWalters marked this pull request as ready for review March 2, 2026 22:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a mutation bug in payload normalization where shallow-copying payload caused payload.attributes to be shared and unintentionally mutated across accesses, leading to invalid Luxon parsing on subsequent reads.

Changes:

  • Deepens the copy in normalizeEntryPayload / normalizeInvitePayload to also clone attributes.
  • Adds Jest coverage for timestamp normalization, mutation safety, and repeat-call stability for entry/invite payloads.
  • Bumps package version 2.5.02.5.1.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/payloads/EntryPayload.ts Clones attributes to prevent req.body.payload.attributes mutation during normalization.
src/payloads/InvitePayload.ts Clones attributes to prevent mutation when rewriting legal-docs.
test/payloads/EntryPayload.test.ts Adds tests for SQL→ISO conversion and verifies original payload is not mutated.
test/payloads/InvitePayload.test.ts Adds tests for legal-doc normalization and repeat-call behavior (but one mutation-safety assertion is currently ineffective).
package.json Patch version bump.
package-lock.json Lockfile version bump alignment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Import payload types as return type for makePayload, enabling direct
  access to optional attributes like legal-docs without type errors
- InvitePayload mutation test now asserts that payload.attributes['legal-docs']
  still references the original array (the previous assertion on legalDocs
  elements would have passed even with the old shallow-copy bug)
- Add blank lines between arrange/act/assert steps throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JustWalters JustWalters requested a review from a team March 2, 2026 23:20
@ryanflynndev
Copy link
Contributor

Would love to hear more about this bug

@JustWalters
Copy link
Contributor Author

@ryanflynndev What do you want to know? I was testing https://github.com/envoy/pacs-integration-service/pull/63 and when I signed an invite in, I saw we were creating the credential to start at the current time, even though I changed the signed in at time. I had ngrok running so it was easy to confirm the request had the value set, and I traced it down to this function.

@JustWalters JustWalters merged commit 611fb73 into master Mar 3, 2026
8 checks passed
@JustWalters JustWalters deleted the fix/normalize-payload-mutation branch March 3, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants