Support disabling literal stripping when extracting operations.#1703
Support disabling literal stripping when extracting operations.#1703abernix merged 6 commits intoapollographql:masterfrom damondoucet:optionally-strip-literals
Conversation
|
@damondoucet: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/ |
|
I left the |
|
I also wasn't sure about the casing of the |
|
Thanks @damondoucet ! I'd like input from @jbaxleyiii and the team as to whether we should include the Cheers! |
|
👍 LGTM |
abernix
left a comment
There was a problem hiding this comment.
Thanks for opening this PR! I support this change and my suggestions below revolve purely around clarity of the flag name.
As some back-story, it's worth noting two things:
- The literal-stripping was originally introduced to ensure that no personally identifiable information which might be encapsulated within such literals was inadvertently shipped to the Apollo Graph Manager operation registry (e.g. API keys or passwords in string literals).
- The
client:extractcommand was originally intended to be a more observable/debuggable version of theclient:pushcommand.
With that second bullet-point in mind, my initial reaction to this PR was to welcome it but suggest that we maintain parity between the client:push and client:extract commands (i.e. also extend this flag to client:push). Upon further consideration, I realized that would create confusion/problems since the operation registry safe-listing plugin itself reads from the manifest published with client:push. This means that the plugin would also need to have the same preserveLiterals option introduced to it and passed along to its own invocation of defaultOperationRegistrySignature on the receiving side (read: Apollo Server). Therefore, we should keep client:push as-is and not allow it to use this flag.
Tangentially (writing this here purely for posterity, not as something you as the PR author needs to act on), in a future version of this command (and the operation registry), I'm hopeful that we can make preserving all literals the default behavior. However, I think that would be best coupled with reminders to users to (perhaps a per-operation blessing of sorts? idk, a directive?) to not use string and numeric literals, but rather use variables whenever possible for their many benefits.
Anyhow, my suggestion is that we use a more clear flag name. But note that I didn't make all necessary suggestions for renaming it. Thoughts? (On any of this, but particularly the name. 😸 )
| static flags = { | ||
| ...ClientCommand.flags | ||
| ...ClientCommand.flags, | ||
| stripLiterals: flags.boolean({ |
There was a problem hiding this comment.
Since "literals" also applies to object and list literals (which are not stripped), perhaps we should be a bit more clear with this option name. Even if it's a bit wordy, the intent is more clear, I think? (And its less necessary for someone to understand the notion of negated flags and perhaps more intrinsic understanding of the default behavior?). This change would require changing the default to false below and flipping other conditionals too, of course.)
| stripLiterals: flags.boolean({ | |
| preserveStringAndNumericLiterals: flags.boolean({ |
| stripLiterals: flags.boolean({ | ||
| description: | ||
| "Whether to strip literals from extracted queries. DEFAULT: true", | ||
| default: true, |
There was a problem hiding this comment.
If heeding my suggestion above, this default would become false.
| ...ClientCommand.flags, | ||
| stripLiterals: flags.boolean({ | ||
| description: | ||
| "Whether to strip literals from extracted queries. DEFAULT: true", |
There was a problem hiding this comment.
| "Whether to strip literals from extracted queries. DEFAULT: true", | |
| "Disable redaction of string and numerical literals. Without this flag, these values will be replaced with empty strings (`''`) and zeroes (`0`) respectively. This redaction is intended to avoid inadvertently outputting potentially personally identifiable information (e.g. embedded passwords or API keys) into operation manifests.", |
| description: | ||
| "Whether to strip literals from extracted queries. DEFAULT: true", | ||
| default: true, | ||
| allowNo: true |
There was a problem hiding this comment.
I believe we could get rid of this if the default was false.
| allowNo: true |
| task: async ctx => { | ||
| ctx.operations = getOperationManifestFromProject(this.project); | ||
| ctx.operations = getOperationManifestFromProject(this.project, { | ||
| stripLiterals: flags.stripLiterals |
There was a problem hiding this comment.
I would also suggest renaming this to more accurately describe its scope:
| stripLiterals: flags.stripLiterals | |
| preserveStringAndNumericLiterals: flags.preserveStringAndNumericLiterals |
| export function getOperationManifestFromProject( | ||
| project: GraphQLClientProject | ||
| project: GraphQLClientProject, | ||
| options: { stripLiterals: boolean } = { stripLiterals: true } |
There was a problem hiding this comment.
| options: { stripLiterals: boolean } = { stripLiterals: true } | |
| options: { | |
| preserveStringAndNumericLiterals: boolean, | |
| } = { | |
| preserveStringAndNumericLiterals: true, | |
| } |
There was a problem hiding this comment.
Presumably, the default should also flip to false? :)
| operationAST, | ||
| operationName | ||
| operationName, | ||
| { stripLiterals: options.stripLiterals } |
There was a problem hiding this comment.
| { stripLiterals: options.stripLiterals } | |
| { | |
| preserveStringAndNumericLiterals: | |
| options.preserveStringAndNumericLiterals | |
| } |
|
Hey Jesse, thanks for getting back to me! So as not to leave this hanging - I had a chance to skim your feedback and it generally makes sense, but I won't be able to update this PR until the new year. It'll be a high priority for us then (1/7 or so). Happy holidays! |
|
Thanks for the feedback @abernix. I read through and it all makes sense to me, so I've updated the PR with the corresponding changes. Let me know what you think! |
|
bump @abernix - would be great to get this merged as soon as we can since it's blocking a high priority feature for us. thanks! |
|
@abernix friendly bump - any updates on the timeline for getting this merged? |
There was a problem hiding this comment.
Thanks for the adjustments, and apologies for the delays in getting back to you.
I have one remaining thought and I think this is good to ship from my perspective.
(I sincerely apologize for not asking for this in my previous review. I think I got caught up with the flag name and also the holidays! If you're unable to make the change, I can make it this week and get it shipped.)
abernix
left a comment
There was a problem hiding this comment.
Yes, defaultOperationRegistrySignature is the public API and other packages are depending on it (internally and otherwise). We'll consider what changing those other packages to use the operationRegistrySignature method in the future looks like, but I think this is great for now.
We'll get this cut into a release as soon as possible. LGTM. Thanks so much! 😄
|
Woo, thanks!! |
|
@damondoucet Can you try and see if this is working for you in the latest version of the just-published |
|
it works, thanks @abernix! |
Fixes #1099
Adds a flag
--[no]-preserveStringAndNumericLiteralstoclient:extractthat controls whether literals are preserved in extracted queries. Prior to
this flag, object and list literals were already preserved; that's unaffected
by this change.
As noted in the linked issue, there are a few reasons to do this, but generally
they boil down to relying on the extracted queries for some functionality, and
literals in the queries controlling important behavior (e.g. generating mock data
for queries might rely on literal args).
A flag is preferred to changing the behavior outright since older clients likely
rely on the current behavior.
TODO:
*Make sure changelog entries note which project(s) has been affected. See older entries for examples on what this looks like.