Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Data masking] Core data masking algorithm #11686

Merged
merged 39 commits into from May 16, 2024

Conversation

jerelmiller
Copy link
Member

@jerelmiller jerelmiller commented Mar 14, 2024

Part of #11671

Adds the core algorithm for removing fragments from queries. This work only includes the mechanism to strip out fragments from queries themselves, but does not use this anywhere or include any kind of registry to store the data. This work also does not include any kind of caching against the work. These changes will be done in a future PR.

Here I'm looking for feedback on the initial implementation to look for optimizations or holes in the solution that haven't been accounted for.

Copy link

changeset-bot bot commented Mar 14, 2024

⚠️ No Changeset found

Latest commit: d4f02f2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@phryneas
Copy link
Member

Just out of interest - is there a reason you're not hooking into that as part of the cache, about here?

const fragment = getFragmentFromSelection(
selection,
context.lookupFragment
);
if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) {
throw newInvariantError(`No fragment named %s`, selection.name.value);
}
if (fragment && policies.fragmentMatches(fragment, typename)) {
fragment.selectionSet.selections.forEach(workSet.add, workSet);
}

@jerelmiller jerelmiller changed the title [WIP] Data masking algorithm Core data masking algorithm May 15, 2024
@jerelmiller jerelmiller changed the title Core data masking algorithm [Data masking] Core data masking algorithm May 16, 2024
@jerelmiller jerelmiller added the 🎭 data-masking Issues/PRs related to data masking label May 16, 2024
@jerelmiller jerelmiller marked this pull request as ready for review May 16, 2024 00:03
>(
data: TData,
document: TypedDocumentNode<TData> | DocumentNode,
matchesFragment: MatchesFragmentFn
Copy link
Member Author

Choose a reason for hiding this comment

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

I think this name could be changed. This is really only used to check against a type condition on an inline fragment to see if we should dig into its selection set. Perhaps name this something like matchesTypeCondition, matchesInlineFragment, or matchesInlineFragmentCondition?

Copy link
Member

@phryneas phryneas left a comment

Choose a reason for hiding this comment

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

These are mostly nitpicks, this looks very good to me!

src/core/masking.ts Outdated Show resolved Hide resolved
return [memo, true];
}
},
[Object.create(Object.getPrototypeOf(data)), false]
Copy link
Member

Choose a reason for hiding this comment

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

any particular reason we can't at least stay with null here? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Mostly because I was trying to make the replacement object as much like the original, including its prototype. I suppose we could use null directly since we know we create objects with null prototypes, but does it hurt to leave this?

Copy link
Member

Choose a reason for hiding this comment

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

Only if we want to count bytes 🤷

Copy link
Member Author

Choose a reason for hiding this comment

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

Haha fair 😂

Copy link
Member Author

Choose a reason for hiding this comment

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

user {
__typename
id
fullName: name
Copy link
Member

Choose a reason for hiding this comment

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

Maybe also add a test that shows that a fragment/inline fragment inside an aliased field is also honored correctly.

Copy link
Member Author

Choose a reason for hiding this comment

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

},
];
const drink = { __typename: "Espresso" };
const originalData = { user, post, authors, industries, drink };
Copy link
Member

Choose a reason for hiding this comment

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

Maybe also deep-freeze this to show it's not modified?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call! Added in 7a33acf

@github-actions github-actions bot added the auto-cleanup 🤖 label May 16, 2024
@jerelmiller jerelmiller merged commit 3f98266 into data-masking May 16, 2024
26 of 28 checks passed
@jerelmiller jerelmiller deleted the jerel/data-masking-algorithm branch May 16, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-cleanup 🤖 🎭 data-masking Issues/PRs related to data masking
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants