Skip to content

Commit

Permalink
[Data masking] Fix bug where masked field could be returned in parent…
Browse files Browse the repository at this point in the history
… query (#12014)
  • Loading branch information
jerelmiller committed Aug 28, 2024
1 parent 2eb3424 commit 0d757ce
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .size-limits.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"dist/apollo-client.min.cjs": 40818,
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 33647
"dist/apollo-client.min.cjs": 40870,
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 33688
}
38 changes: 38 additions & 0 deletions src/core/__tests__/masking.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,44 @@ describe("maskOperation", () => {
});
});

test("masks fragments from nested objects when query gets fields from same object", () => {
const query = gql`
query {
user {
profile {
__typename
id
}
...UserFields
}
}
fragment UserFields on User {
profile {
id
fullName
}
}
`;

const data = maskOperation(
deepFreeze({
user: {
__typename: "User",
profile: { __typename: "Profile", id: "1", fullName: "Test User" },
},
}),
query,
createFragmentMatcher(new InMemoryCache())
);

expect(data).toEqual({
user: {
__typename: "User",
profile: { __typename: "Profile", id: "1" },
},
});
});

test("deep freezes the masked result if the original data is frozen", () => {
const query = gql`
query {
Expand Down
8 changes: 7 additions & 1 deletion src/core/masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,13 @@ function maskSelectionSet(
__DEV__ ? `${path || ""}.${keyName}` : void 0
);

if (childChanged) {
if (
childChanged ||
// This check prevents cases where masked fields may accidentally be
// returned as part of this object when the fragment also selects
// additional fields from the same child selection.
Object.keys(masked).length !== Object.keys(data[keyName]).length
) {
memo[keyName] = masked;
changed = true;
}
Expand Down

0 comments on commit 0d757ce

Please sign in to comment.