-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
feat(node/crypto): separate chacha20-poly1305 from CipherCCMTypes #71834
feat(node/crypto): separate chacha20-poly1305 from CipherCCMTypes #71834
Conversation
@hkleungai Thank you for submitting this PR! This is a live comment that I will keep updated. 1 package in this PRCode ReviewsBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged. You can test the changes of this PR in the Playground. Status
All of the items on the list are green. To merge, you need to post a comment including the string "Ready to merge" to bring in your changes. Diagnostic Information: What the bot saw about this PR{
"type": "info",
"now": "-",
"pr_number": 71834,
"author": "hkleungai",
"headCommitOid": "4fc2c02be83d65f7dff83cd71dfcf7f39de634e2",
"mergeBaseOid": "071ecffd6851e48242616b0c200a749e49e82c66",
"lastPushDate": "2025-02-04T17:14:14.000Z",
"lastActivityDate": "2025-03-03T17:38:26.000Z",
"mergeOfferDate": "2025-03-03T17:34:37.000Z",
"mergeRequestDate": "2025-03-03T17:38:26.000Z",
"mergeRequestUser": "hkleungai",
"hasMergeConflict": false,
"isFirstContribution": false,
"tooManyFiles": false,
"hugeChange": false,
"popularityLevel": "Critical",
"pkgInfo": [
{
"name": "node",
"kind": "edit",
"files": [
{
"path": "types/node/crypto.d.ts",
"kind": "definition"
},
{
"path": "types/node/test/crypto.ts",
"kind": "test"
},
{
"path": "types/node/v18/crypto.d.ts",
"kind": "definition"
},
{
"path": "types/node/v18/test/crypto.ts",
"kind": "test"
},
{
"path": "types/node/v20/crypto.d.ts",
"kind": "definition"
},
{
"path": "types/node/v20/test/crypto.ts",
"kind": "test"
}
],
"owners": [
"Microsoft",
"jkomyno",
"alvis",
"r3nya",
"btoueg",
"smac89",
"touffy",
"DeividasBakanas",
"eyqs",
"Hannes-Magnusson-CK",
"hoo29",
"kjin",
"ajafff",
"islishude",
"mwiktorczyk",
"mohsen1",
"galkin",
"parambirs",
"eps1lon",
"ThomasdenH",
"WilcoBakker",
"wwwy3y3",
"samuela",
"kuehlein",
"bhongy",
"chyzwar",
"trivikr",
"yoursunny",
"qwelias",
"ExE-Boss",
"peterblazejewicz",
"addaleax",
"victorperin",
"NodeJS",
"LinusU",
"wafuwafu13",
"mcollina",
"Semigradsky"
],
"addedOwners": [],
"deletedOwners": [],
"popularityLevel": "Critical"
}
],
"reviews": [
{
"type": "approved",
"reviewer": "gabritto",
"date": "2025-03-03T17:24:12.000Z",
"isMaintainer": true
},
{
"type": "stale",
"reviewer": "Renegade334",
"date": "2025-02-18T19:19:29.000Z",
"abbrOid": "d33be3f"
}
],
"mainBotCommentID": 2634590255,
"ciResult": "pass"
} |
🔔 @microsoft @jkomyno @alvis @r3nya @btoueg @smac89 @Touffy @DeividasBakanas @eyqs @Hannes-Magnusson-CK @hoo29 @kjin @ajafff @islishude @mwiktorczyk @mohsen1 @galkin @parambirs @eps1lon @ThomasdenH @WilcoBakker @wwwy3y3 @samuela @kuehlein @bhongy @chyzwar @trivikr @yoursunny @qwelias @ExE-Boss @peterblazejewicz @addaleax @victorperin @nodejs @LinusU @wafuwafu13 @mcollina @Semigradsky — please review this PR in the next few days. Be sure to explicitly select |
types/node/crypto.d.ts
Outdated
function createCipheriv<T extends string>( | ||
algorithm: Exclude<T, CipherCCMTypes | CipherGCMTypes | CipherOCBTypes | CipherChaCha20Poly1305Types>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attempting to exclude string literals from string
is a no-op. This would be best left as the catch-all signature that already exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, using type parameter will make it work. See https://tsplay.dev/mpdeMm.
And the original discussion points out that
When using chacha20-poly1305 without setting authTagLength, TypeScript incorrectly reports that getAuthTag does not exist on the Cipher type.
This is because with original plain string
type, when none the above overloads get passed, the function call would get into the last one. There, the last options
argument is allowed to be omitted, and hence Cipher
return type is inferred, hence causing the issue.
If you checkout the branch locally and switch it back to the original plain string type, you will see the newly added tests fail like the original post suggests.
To resolve the issue, I think original plain string
type has to be modified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your added overload solves the linked issue by itself, without any need to alter the catch-all here.
Unrelated to the linked issue, the separate behaviour that you're trying to address here is the notion of permissive catch-all signatures within the library, which is much wider than this one specific example.
In general, @types/node goes for a permissive approach when it comes to overloaded function signatures and catch-alls. Given that changing this behaviour is breaking, and that the existing catch-all behaviour of createCipherIv()
has existed ever since the narrowed overloads were first added (over 6 years ago) with no complaints from consumers, I think the best approach is to leave this as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Let me move the discussion back to this thread...}
Given that changing this behaviour is breaking, and that the existing catch-all behaviour of createCipherIv() has existed ever since the narrowed overloads were first added (over 6 years ago) with no complaints from consumers, I think the best approach is to leave this as-is.
I would say I kind of disagree with this.
With the current behaviour, createCipherIv()
types basically does not fully reflect the intention of its respective source code. Just like in this case, one working with CipherCCMTypes
for sure expect tsc to pick up the corresponding function signature to typecheck.
function createCipheriv(
algorithm: CipherCCMTypes,
key: CipherKey,
iv: BinaryLike,
options: CipherCCMOptions,
): CipherCCM;
Hence a missing options
will simply fails, instead of going to the catch-all
fallback one, which is both misleading and incorrect in nodejs source code's point of view.
I would argue that, doing it in the way you mentioned simply brings unneeded confusion to typescript consumers (especially those who are not familiar enough with the "permissive approach" you suggest). Like in this case, without reading till the end of all the overload typedefs, it is not even easy to see the exact cause of the issue raised by the original post.
Given that changing this behaviour is breaking
It should be fair to say that, any breaking behaviour caused by this change is due to insufficient typescript familiarity on consumer side.
From the notion of discriminated unions in typescript, together with the fact that the function overloads are basically "partitioned" by the algorithm
parameter, it should be natural for anyone to reach to the same understanding and expectation on the typing behaviour as I do.
Hence if any unfortunate breaking behaviour indeed happens, it would be those consumers' fault on not observing basic principle in typescript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@types/node prioritises allowing valid practice over being restrictive – it has to be this way, as a dependency of hundreds of millions of projects.
Yes, this slightly hacky overload might seem like it does what you want it to do, but then the day after pushing it, someone will come along with usage like the following:
function encrypt(
data: crypto.BinaryLike,
key: crypto.CipherKey,
algorithm: crypto.CipherCCMTypes | crypto.CipherGCMTypes
) {
// ...
const cipher = crypto.createCipheriv(algorithm, key, iv);
// ...
}
and come here to report that their case, which previously worked just fine (and is valid usage as far as the Node API goes), now results in a compiler error. There aren't a huge number of examples of this sort of usage that I can see for a brief search through Github, but the point is that there's no compelling motivation to break them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok... I have reverted this change of using template. Please help review again.
types/node/crypto.d.ts
Outdated
function createCipheriv<T extends string>( | ||
algorithm: Exclude<T, CipherCCMTypes | CipherGCMTypes | CipherOCBTypes | CipherChaCha20Poly1305Types>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your added overload solves the linked issue by itself, without any need to alter the catch-all here.
Unrelated to the linked issue, the separate behaviour that you're trying to address here is the notion of permissive catch-all signatures within the library, which is much wider than this one specific example.
In general, @types/node goes for a permissive approach when it comes to overloaded function signatures and catch-alls. Given that changing this behaviour is breaking, and that the existing catch-all behaviour of createCipherIv()
has existed ever since the narrowed overloads were first added (over 6 years ago) with no complaints from consumers, I think the best approach is to leave this as-is.
type CipherGCMTypes = "aes-128-gcm" | "aes-192-gcm" | "aes-256-gcm"; | ||
type CipherOCBTypes = "aes-128-ocb" | "aes-192-ocb" | "aes-256-ocb"; | ||
type CipherChaCha20Poly1305Types = "chacha20-poly1305"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This type is probably semantically unnecessary – by definition, the only type that would ever fit the definition of a ChaCha20Poly1305
type is chacha20-poly1305. This can probably be removed, in favour of just using the string literal in the function parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracting it is better I think. Repeatedly working with string literal may result in typo in string content, but CipherChaCha20Poly1305Types
as a ts type under tsc typecheck won't have such issue.
Re-ping @microsoft, @jkomyno, @alvis, @r3nya, @btoueg, @smac89, @Touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @galkin, @parambirs, @eps1lon, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @bhongy, @chyzwar, @trivikr, @yoursunny, @qwelias, @ExE-Boss, @peterblazejewicz, @addaleax, @victorperin, @nodejs, @LinusU, @wafuwafu13, @mcollina, @Semigradsky: This PR has been out for over a week, yet I haven't seen any reviews. Could someone please give it some attention? Thanks! |
@Renegade334 Do you want to pick up the previous reply comments that I have left? I see this PR remains unreviewed for some days already. |
a44fde5
to
d33be3f
Compare
@Renegade334 Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
d33be3f
to
ee9d3a9
Compare
@Renegade334 Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
It has been more than two weeks and this PR still has no reviews. I'll bump it to the DT maintainer queue. Thank you for your patience, @hkleungai. (Ping @microsoft, @jkomyno, @alvis, @r3nya, @btoueg, @smac89, @Touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @galkin, @parambirs, @eps1lon, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @bhongy, @chyzwar, @trivikr, @yoursunny, @qwelias, @ExE-Boss, @peterblazejewicz, @addaleax, @victorperin, @nodejs, @LinusU, @wafuwafu13, @mcollina, @Semigradsky.) |
@hkleungai Unfortunately, this pull request currently has a merge conflict 😥. Please update your PR branch to be up-to-date with respect to master. Have a nice day! |
ee9d3a9
to
d9d9759
Compare
@hkleungai The CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! Note: builds that are failing do not end up on the list of PRs for the DT maintainers to review. |
d9d9759
to
bb52a5d
Compare
bb52a5d
to
4fc2c02
Compare
@hkleungai: Everything looks good here. I am ready to merge this PR (at 4fc2c02) on your behalf whenever you think it's ready. If you'd like that to happen, please post a comment saying:
and I'll merge this PR almost instantly. Thanks for helping out! ❤️ (@microsoft, @jkomyno, @alvis, @r3nya, @btoueg, @smac89, @Touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @galkin, @parambirs, @eps1lon, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @bhongy, @chyzwar, @trivikr, @yoursunny, @qwelias, @ExE-Boss, @peterblazejewicz, @addaleax, @victorperin, @nodejs, @LinusU, @wafuwafu13, @mcollina, @Semigradsky: you can do this too.) |
Ready to merge |
Resolves discussions/71621.
Ref: https://nodejs.org/api/crypto.html#cryptocreatecipherivalgorithm-key-iv-options
Please fill in this template.
pnpm test <package to test>
.Select one of these and delete the others:
If changing an existing definition: