-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Codemod for webhook verifier option renaming (#4675)
- Loading branch information
Showing
6 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
packages/codemods/src/codemods/v0.48.x/renameVerifierTimestamp/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Rename `timestamp` webhook verifier option | ||
|
||
This codemod renames the `timestamp` webhook verifier option to `currentTimestampOverride` | ||
|
||
The first thing it does is find all files that needs to be updated. We need to | ||
look through all functions in the api/functions directory. In those functions | ||
we're looking for calls to the `verifyEvent`, `verifySignature` or | ||
`signPayload` functions. | ||
|
||
A call can look like this: | ||
|
||
```js | ||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
secret: process.env.STRIPE_WEBHOOK_SECRET, | ||
options, | ||
}) | ||
``` | ||
|
||
Finally we need to find that `options` object and rename `timestamp` (if it | ||
exists) to `currentTimestampOverride` |
35 changes: 35 additions & 0 deletions
35
...es/codemods/src/codemods/v0.48.x/renameVerifierTimestamp/__testfixtures__/simple.input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { verifyEvent, signPayload } from '@redwoodjs/api/webhooks' | ||
|
||
export const handler = async (event, _context) => { | ||
signPayload('timestampSchemeVerifier', { | ||
event, | ||
options: { | ||
timestamp: Date.now(), | ||
}, | ||
}) | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options: { | ||
timestamp: Date.now() - 60 * 1000, // one minute ago | ||
}, | ||
}) | ||
|
||
const options = { | ||
timestamp: Date.now(), | ||
} | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options, | ||
}) | ||
|
||
const verifierOptions = { | ||
timestamp: Date.now(), | ||
} | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options: verifierOptions, | ||
}) | ||
} |
38 changes: 38 additions & 0 deletions
38
...s/codemods/src/codemods/v0.48.x/renameVerifierTimestamp/__testfixtures__/simple.output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { | ||
verifyEvent, | ||
signPayload, | ||
} from '@redwoodjs/api/webhooks' | ||
|
||
export const handler = async (event, _context) => { | ||
signPayload('timestampSchemeVerifier', { | ||
event, | ||
options: { | ||
currentTimestampOverride: Date.now() | ||
} | ||
}) | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options: { | ||
currentTimestampOverride: Date.now() - 60*1000 // one minute ago | ||
} | ||
}) | ||
|
||
const options = { | ||
currentTimestampOverride: Date.now(), | ||
} | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options, | ||
}) | ||
|
||
const verifierOptions = { | ||
currentTimestampOverride: Date.now(), | ||
} | ||
|
||
verifyEvent('timestampSchemeVerifier', { | ||
event, | ||
options: verifierOptions, | ||
}) | ||
} |
5 changes: 5 additions & 0 deletions
5
...ds/src/codemods/v0.48.x/renameVerifierTimestamp/__tests__/renameVerifierTimestamp.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('Rename verifier timestamp option', () => { | ||
it('Modifies simple Function', async () => { | ||
await matchTransformSnapshot('renameVerifierTimestamp', 'simple') | ||
}) | ||
}) |
80 changes: 80 additions & 0 deletions
80
packages/codemods/src/codemods/v0.48.x/renameVerifierTimestamp/renameVerifierTimestamp.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import type { FileInfo, API, Identifier, ASTNode, ASTPath } from 'jscodeshift' | ||
import core from 'jscodeshift' | ||
|
||
function renameTimestamp( | ||
j: core.JSCodeshift, | ||
optionsObject: ASTNode | ASTNode[] | ASTPath | ASTPath[] | ||
) { | ||
j(optionsObject) | ||
.find(j.ObjectProperty, { key: { name: 'timestamp' } }) | ||
.replaceWith((objectProperty) => { | ||
const currentTimestampOverride = j.objectProperty.from({ | ||
key: j.identifier('currentTimestampOverride'), | ||
value: objectProperty.value.value, | ||
// @ts-expect-error - trailingComments | ||
comments: objectProperty.value.trailingComments || null, | ||
}) | ||
return currentTimestampOverride | ||
}) | ||
} | ||
|
||
export default function transform(file: FileInfo, api: API) { | ||
const j = api.jscodeshift | ||
const ast = j(file.source) | ||
|
||
ast | ||
.find(j.CallExpression, (callExpression) => { | ||
const calleeName = (callExpression.callee as Identifier).name | ||
|
||
// Find all calls to | ||
// `signPayload('timestampSchemeVerifier', ...)` | ||
// `verifyEvent('timestampSchemeVerifier', ...)` | ||
// `verifySignature('timestampSchemeVerifier', ...)` | ||
return ( | ||
(calleeName === 'signPayload' || | ||
calleeName === 'verifyEvent' || | ||
calleeName === 'verifySignature') && | ||
callExpression.arguments[0]?.type === 'StringLiteral' && | ||
callExpression.arguments[0]?.value === 'timestampSchemeVerifier' | ||
) | ||
}) | ||
.forEach(({ node: callExpression }) => { | ||
j(callExpression) | ||
// Find all object properties called `options` | ||
.find(j.ObjectProperty, { key: { name: 'options' } }) | ||
.forEach(({ value: options }) => { | ||
// This codemod supports inline options object, like: | ||
// | ||
// verifyEvent('timestampSchemeVerifier', { | ||
// event, | ||
// options: { | ||
// timestamp: Date.now() - 60 * 1000, // one minute ago | ||
// }, | ||
// }) | ||
// | ||
// or when the options object is declared elsewhere, like: | ||
// | ||
// const verifierOptions = { | ||
// timestamp: Date.now(), | ||
// } | ||
// | ||
// verifyEvent('timestampSchemeVerifier', { | ||
// event, | ||
// options: verifierOptions, | ||
// }) | ||
|
||
if (j.ObjectExpression.check(options.value)) { | ||
// An inline options object is an ObjectExpression | ||
renameTimestamp(j, options.value) | ||
} else if (j.Identifier.check(options.value)) { | ||
// An options object referenced by name is an Identifier. | ||
// Identifiers have a `name` | ||
ast.findVariableDeclarators(options.value.name).forEach((n) => { | ||
renameTimestamp(j, n.node) | ||
}) | ||
} | ||
}) | ||
}) | ||
|
||
return ast.toSource({ trailingComma: true, quote: 'single' }) | ||
} |
48 changes: 48 additions & 0 deletions
48
...es/codemods/src/codemods/v0.48.x/renameVerifierTimestamp/renameVerifierTimestamp.yargs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import path from 'path' | ||
|
||
import fg from 'fast-glob' | ||
import task from 'tasuku' | ||
|
||
import getRWPaths from '../../../lib/getRWPaths' | ||
import runTransform from '../../../lib/runTransform' | ||
|
||
export const command = 'rename-verifier-timestamp' | ||
export const description = | ||
'(v0.47.x->v0.48.x) Renames the timestamp webhook verifier option' | ||
|
||
/** | ||
* The functions dir can look like like... | ||
* | ||
* functions | ||
* ├── graphql.js | ||
* ├── healthz.js | ||
* ├── jsonproduct.js | ||
* ├── payment.js | ||
* ├── paysonCallback.js | ||
* ├── prisma.js | ||
* ├── shipping | ||
* │ ├── shipping.scenarios.ts | ||
* │ ├── shipping.test.ts | ||
* │ └── shipping.ts | ||
* ├── snipcartWebhooks.js | ||
* ├── swishCallback.js | ||
* └── swishCheckout.js | ||
*/ | ||
export const handler = () => { | ||
task( | ||
'Rename timestamp to currentTimestampOverride', | ||
async ({ setError }: task.TaskInnerApi) => { | ||
try { | ||
await runTransform({ | ||
transformPath: path.join(__dirname, 'renameVerifierTimestamp.js'), | ||
targetPaths: fg.sync('/**/*.{js,ts}', { | ||
cwd: getRWPaths().api.functions, | ||
absolute: true, | ||
}), | ||
}) | ||
} catch (e: any) { | ||
setError('Failed to codemod your project \n' + e?.message) | ||
} | ||
} | ||
) | ||
} |