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

feat(node/crypto): separate chacha20-poly1305 from CipherCCMTypes #71834

Conversation

hkleungai
Copy link
Contributor

Resolves discussions/71621.

Ref: https://nodejs.org/api/crypto.html#cryptocreatecipherivalgorithm-key-iv-options


Please fill in this template.

Select one of these and delete the others:

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: <>

@typescript-bot
Copy link
Contributor

typescript-bot commented Feb 4, 2025

@hkleungai Thank you for submitting this PR!

This is a live comment that I will keep updated.

1 package in this PR

Code Reviews

Because 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

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • ✅ Most recent commit is approved by a DT maintainer

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"
}

Comment on lines 759 to 760
function createCipheriv<T extends string>(
algorithm: Exclude<T, CipherCCMTypes | CipherGCMTypes | CipherOCBTypes | CipherChaCha20Poly1305Types>,
Copy link
Contributor

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.

Copy link
Contributor Author

@hkleungai hkleungai Feb 5, 2025

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@hkleungai hkleungai requested a review from Renegade334 February 5, 2025 10:50
Comment on lines 759 to 760
function createCipheriv<T extends string>(
algorithm: Exclude<T, CipherCCMTypes | CipherGCMTypes | CipherOCBTypes | CipherChaCha20Poly1305Types>,
Copy link
Contributor

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";
Copy link
Contributor

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.

Copy link
Contributor Author

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.

@typescript-bot typescript-bot added the Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. label Feb 15, 2025
@typescript-bot
Copy link
Contributor

@hkleungai
Copy link
Contributor Author

hkleungai commented Feb 17, 2025

@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.

@hkleungai hkleungai force-pushed the node-crypto-chacha20-poly1305 branch from a44fde5 to d33be3f Compare February 18, 2025 18:57
@typescript-bot
Copy link
Contributor

@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?

@hkleungai hkleungai force-pushed the node-crypto-chacha20-poly1305 branch from d33be3f to ee9d3a9 Compare February 18, 2025 19:22
@typescript-bot
Copy link
Contributor

@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?

@typescript-bot
Copy link
Contributor

@typescript-bot typescript-bot added Has Merge Conflict This PR can't be merged because it has a merge conflict. The author needs to update it. and removed Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. labels Feb 28, 2025
@typescript-bot
Copy link
Contributor

@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!

@hkleungai hkleungai force-pushed the node-crypto-chacha20-poly1305 branch from ee9d3a9 to d9d9759 Compare February 28, 2025 13:32
@typescript-bot typescript-bot added Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. The CI failed When GH Actions fails and removed Has Merge Conflict This PR can't be merged because it has a merge conflict. The author needs to update it. Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. labels Feb 28, 2025
@typescript-bot
Copy link
Contributor

@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.

@hkleungai hkleungai force-pushed the node-crypto-chacha20-poly1305 branch from d9d9759 to bb52a5d Compare March 1, 2025 06:05
@typescript-bot typescript-bot added Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. and removed The CI failed When GH Actions fails labels Mar 1, 2025
@hkleungai hkleungai force-pushed the node-crypto-chacha20-poly1305 branch from bb52a5d to 4fc2c02 Compare March 3, 2025 17:17
@typescript-bot typescript-bot added Maintainer Approved Self Merge This PR can now be self-merged by the PR author or an owner and removed Unreviewed No one showed up to review this PR, so it'll be reviewed by a DT maintainer. labels Mar 3, 2025
@typescript-bot
Copy link
Contributor

@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:

Ready to merge

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.)

@hkleungai
Copy link
Contributor Author

Ready to merge

@typescript-bot typescript-bot merged commit 895cfb8 into DefinitelyTyped:master Mar 3, 2025
15 checks passed
@hkleungai hkleungai deleted the node-crypto-chacha20-poly1305 branch March 3, 2025 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Critical package Maintainer Approved Self Merge This PR can now be self-merged by the PR author or an owner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants