Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4c3aefa
feat(crypto): add RSA-PSS codemod for DEP0154
nievasdev Aug 5, 2025
90bb8ba
chore: update author from Claude Code to Mauro Nievas
nievasdev Aug 5, 2025
2998555
chore: update package-lock.json to register crypto-rsa-pss-update wor…
nievasdev Aug 5, 2025
3ba20fe
Merge remote-tracking branch 'upstream/main' into feat/crypto-rsa-pss…
nievasdev Aug 5, 2025
1492821
feat(crypto): enhance RSA-PSS codemod to handle all import patterns
nievasdev Aug 8, 2025
c89dc4b
Merge remote-tracking branch 'upstream/main' into feat/crypto-rsa-pss…
nievasdev Aug 8, 2025
df65682
refactor(crypto): simplify namespace import handling using resolveBin…
nievasdev Aug 13, 2025
ab88911
fix(crypto): handle variable values in property transformations
nievasdev Aug 13, 2025
4ee7879
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Aug 13, 2025
50086cd
refactor(crypto): simplify getCryptoBindings using resolveBindingPath…
nievasdev Aug 13, 2025
6c0a199
feat(crypto-rsa-pss): add template literal support and optimize test …
nievasdev Aug 14, 2025
c6b7d75
refactor(crypto-rsa-pss):
nievasdev Aug 14, 2025
2993107
test(crypto-rsa-pss): consolidate import pattern tests
nievasdev Aug 14, 2025
3fa7277
test(crypto-rsa-pss): remove redundant destructured-renamed test case
nievasdev Aug 14, 2025
2e93c36
test(crypto-rsa-pss): add comprehensive edge case test coverage
nievasdev Aug 14, 2025
f101d13
docs(crypto-rsa-pss): update documentation and metadata
nievasdev Aug 14, 2025
098c35b
feat(crypto-rsa-pss): support variable type detection for 'rsa-pss'
nievasdev Aug 14, 2025
29a500d
feat(crypto-rsa-pss): add promisified wrapper support
nievasdev Aug 14, 2025
a7c6048
feat: improve promisify detection using resolveBindingPath
nievasdev Aug 14, 2025
76bd8f7
fix: resolve yamllint errors in crypto-rsa-pss YAML files
nievasdev Aug 14, 2025
05dcd05
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Aug 16, 2025
77da176
feat(crypto-rsa-pss): add this.property support and refactor codebase
nievasdev Aug 17, 2025
ae2b431
refactor(crypto-rsa-pss): consolidate modular architecture into singl…
nievasdev Aug 17, 2025
6831416
deps: bump @biomejs/biome from 2.1.2 to 2.1.3 (#163)
dependabot[bot] Aug 5, 2025
73143b4
deps: bump @types/node from 24.1.0 to 24.2.0 (#160)
dependabot[bot] Aug 5, 2025
3551f66
deps: bump @types/node from 24.2.0 to 24.2.1 (#170)
dependabot[bot] Aug 12, 2025
a39aa02
chore: remove `@next` and clean (#176)
AugustinMauroy Aug 12, 2025
129294d
refactor(crypto-rsa-pss): remove type wrappers, consolidate tests, ad…
nievasdev Aug 19, 2025
ae8161b
fix: regenerate package-lock.json to resolve npm ci compatibility
nievasdev Aug 20, 2025
ba5b05e
fix(crypto-rsa-pss): resolve TypeScript type compatibility issues
nievasdev Aug 21, 2025
9e6cdf5
fix: remove unnecessary type assertions and update test snapshot
nievasdev Aug 21, 2025
f101067
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Aug 23, 2025
1e9e147
fix: resolve TypeScript type compatibility issues
nievasdev Aug 24, 2025
366a99c
fix(deps): restore Darwin binaries in package-lock for macOS CI compa…
nievasdev Aug 24, 2025
493b355
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Sep 4, 2025
61904af
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Sep 7, 2025
259d497
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Sep 16, 2025
6ce24b4
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Sep 17, 2025
f1fe1ac
Merge branch 'main' into feat/crypto-rsa-pss-update
nievasdev Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions recipes/crypto-rsa-pss-update/src/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import { resolveBindingPath } from "@nodejs/codemod-utils/ast-grep/resolve-bindi
* 2. Function call targeting: Only crypto.generateKeyPair() and crypto.generateKeyPairSync()
* 3. Key type filtering: Only applies to 'rsa-pss' key type (ignores 'rsa', 'ed25519', etc.)
* 4. Import pattern support: ES6 imports, CommonJS requires, destructuring, aliases, namespace imports
* 5. Value preservation: Maintains string literals, identifiers, template literals, and variable references
* 6. Template literal handling: Extracts identifiers from template strings like `${variable}`
* 5. Variable key type support: Handles variables containing 'rsa-pss' (e.g., const keyType = 'rsa-pss')
* 6. Promisified wrapper support: Handles util.promisify(crypto.generateKeyPair) patterns
* 7. Value preservation: Maintains string literals, identifiers, template literals, and variable references
* 8. Template literal handling: Extracts identifiers from template strings like `${variable}`
*
* Only applies to crypto.generateKeyPair() and crypto.generateKeyPairSync()
* calls with 'rsa-pss' as the first argument.
Expand Down Expand Up @@ -217,9 +219,43 @@ function getCryptoBindings(root: SgRoot<JS>): string[] {
}
}

// Find promisified assignments that use the discovered bindings
const promisifiedBindings = getPromisifiedBindings(root, bindings);
bindings.push(...promisifiedBindings);

return bindings;
}

/**
* Find promisified wrappers that use crypto bindings discovered by resolveBindingPath
*/
function getPromisifiedBindings(root: SgRoot<JS>, existingBindings: string[]): string[] {
const promisifiedBindings: string[] = [];
const rootNode = root.root();

for (const binding of existingBindings) {
// Find: const someVar = util.promisify(crypto.generateKeyPair)
// or: const someVar = util.promisify(generateKeyPair)
const promisified = rootNode.findAll({
rule: {
pattern: `const $BINDING = util.promisify(${binding})`
}
});

for (const decl of promisified) {
const bindingMatch = decl.getMatch("BINDING");
if (bindingMatch) {
const bindingName = bindingMatch.text()?.trim();
if (bindingName) {
promisifiedBindings.push(bindingName);
}
}
}
}

return promisifiedBindings;
}

/**
* Find all function calls that match the crypto bindings
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const crypto = require('crypto');
const util = require('util');

// Case 1: Basic promisified wrapper
const generateKeyPairAsync = util.promisify(crypto.generateKeyPair);

generateKeyPairAsync('rsa-pss', {
modulusLength: 2048,
hashAlgorithm: 'sha256',
mgf1HashAlgorithm: 'sha1',
saltLength: 32
});

// Case 2: Promisified sync version
const generateKeyPairSyncAsync = util.promisify(crypto.generateKeyPairSync);

generateKeyPairSyncAsync('rsa-pss', {
modulusLength: 2048,
hashAlgorithm: 'sha512'
});

// Case 3: Different variable name
const keyGenAsync = util.promisify(crypto.generateKeyPair);

keyGenAsync('rsa-pss', {
mgf1HashAlgorithm: 'sha256'
});

// Case 4: Destructured import with promisify
const { generateKeyPair } = require('crypto');
const generateKeyPairPromise = util.promisify(generateKeyPair);

generateKeyPairPromise('rsa-pss', {
hashAlgorithm: 'sha1',
mgf1HashAlgorithm: 'sha256'
});

// Case 5: Mixed with regular calls
crypto.generateKeyPair('rsa-pss', {
hashAlgorithm: 'sha256'
});

// Case 6: Non-rsa-pss should not transform
generateKeyPairAsync('rsa', {
hash: 'sha256'
});
46 changes: 46 additions & 0 deletions recipes/crypto-rsa-pss-update/tests/input/promisified-wrappers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const crypto = require('crypto');
const util = require('util');

// Case 1: Basic promisified wrapper
const generateKeyPairAsync = util.promisify(crypto.generateKeyPair);

generateKeyPairAsync('rsa-pss', {
modulusLength: 2048,
hash: 'sha256',
mgf1Hash: 'sha1',
saltLength: 32
});

// Case 2: Promisified sync version
const generateKeyPairSyncAsync = util.promisify(crypto.generateKeyPairSync);

generateKeyPairSyncAsync('rsa-pss', {
modulusLength: 2048,
hash: 'sha512'
});

// Case 3: Different variable name
const keyGenAsync = util.promisify(crypto.generateKeyPair);

keyGenAsync('rsa-pss', {
mgf1Hash: 'sha256'
});

// Case 4: Destructured import with promisify
const { generateKeyPair } = require('crypto');
const generateKeyPairPromise = util.promisify(generateKeyPair);

generateKeyPairPromise('rsa-pss', {
hash: 'sha1',
mgf1Hash: 'sha256'
});

// Case 5: Mixed with regular calls
crypto.generateKeyPair('rsa-pss', {
hash: 'sha256'
});

// Case 6: Non-rsa-pss should not transform
generateKeyPairAsync('rsa', {
hash: 'sha256'
});