Node 22 and Azure Functions v4 migration#13
Node 22 and Azure Functions v4 migration#13MarcAstr0 wants to merge 8 commits intoboostercloud:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates the Azure Webhook Rocket to Node 22 and Azure Functions v4 compatibility (Booster Framework v4.x), while also updating dependency constraints and applying dependency overrides to address vulnerabilities.
Changes:
- Bump peer dependency compatibility across packages from Booster Framework v3.x to v4.x.
- Update Azure infrastructure generation for Functions v4 (including Node 22 runtime in the Function App stack and new V4 function mounting path).
- Update tooling/dependencies (Lerna 9, cdktf/provider versions, Node typings) and add root
overridesfor vulnerability mitigation.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/rocket-webhook-types/package.json | Update peer dependency minimums to Booster Framework v4. |
| packages/rocket-webhook-core/package.json | Update peer dependency minimums to Booster Framework v4. |
| packages/rocket-webhook-local-infrastructure/package.json | Update peer deps to v4, bump express, update local infra provider + Node typings for Node 22. |
| packages/rocket-webhook-azure-infrastructure/package.json | Update peer deps/dev deps to Booster v4 ecosystem, bump cdktf/provider + Node typings. |
| packages/rocket-webhook-azure-infrastructure/src/synth/terraform-function-app.ts | Set Azure Function App Node runtime to ~22 and Functions extension ~4. |
| packages/rocket-webhook-azure-infrastructure/src/synth/synth.ts | Minor refactor/formatting; continues wiring gateway overrides to the Function App. |
| packages/rocket-webhook-azure-infrastructure/src/index.ts | Switch infra rocket entrypoint to expose mountFunctionsV4. |
| packages/rocket-webhook-azure-infrastructure/src/functions/functions.ts | Implement mountFunctionsV4 returning v4 function app definitions and generated code. |
| packages/rocket-webhook-azure-infrastructure/src/functions/webhook-function.ts | Replace v3 function.json-style definition with generated @azure/functions v4 registration code. |
| package.json | Update peer deps to v4, bump lerna, add overrides to mitigate vulnerabilities. |
| lerna.json | Remove legacy command config (bootstrap/hoist settings). |
| .nvmrc | Update Node LTS to Node 22 (lts/jod). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/rocket-webhook-azure-infrastructure/src/functions/webhook-function.ts
Outdated
Show resolved
Hide resolved
packages/rocket-webhook-azure-infrastructure/src/functions/webhook-function.ts
Outdated
Show resolved
Hide resolved
packages/rocket-webhook-azure-infrastructure/src/functions/functions.ts
Outdated
Show resolved
Hide resolved
| app.http('${name}', { | ||
| methods: ['POST', 'GET'], | ||
| authLevel: 'anonymous', | ||
| route: '${endpoint}', |
There was a problem hiding this comment.
endpoint is embedded verbatim into generated JS (app.http(... route: '...')). If a route contains quotes/newlines/backticks, it will generate invalid JS (and can allow code injection during generation). Escape/sanitize endpoint (and the derived name) when embedding, e.g. by using JSON.stringify to emit a safe string literal.
| app.http('${name}', { | |
| methods: ['POST', 'GET'], | |
| authLevel: 'anonymous', | |
| route: '${endpoint}', | |
| app.http(${JSON.stringify(name)}, { | |
| methods: ['POST', 'GET'], | |
| authLevel: 'anonymous', | |
| route: ${JSON.stringify(endpoint)}, |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/rocket-webhook-azure-infrastructure/src/functions/webhook-function.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| static generateFunctionsCode(endpoint: string): string { | ||
| const name = endpoint.replace(/\//g, '_') | ||
| return { | ||
| name: name, | ||
| config: { | ||
| bindings: [ | ||
| { | ||
| type: 'httpTrigger', | ||
| direction: 'in', | ||
| name: 'rawRequest', | ||
| authLevel: 'anonymous', | ||
| methods: ['post', 'get'], | ||
| route: `${endpoint}`, | ||
| }, | ||
| { | ||
| type: 'http', | ||
| direction: 'out', | ||
| name: '$return', | ||
| }, | ||
| ], | ||
| scriptFile: config.functionRelativePath, | ||
| entryPoint: config.rocketDispatcherHandler.split('.')[1], | ||
| return ` | ||
| app.http('${name}', { | ||
| methods: ['POST', 'GET'], | ||
| authLevel: 'anonymous', | ||
| route: '${endpoint}', | ||
| handler: async (request, context) => { |
There was a problem hiding this comment.
generateFunctionsCode() interpolates name and endpoint directly into single-quoted JS string literals. If a route contains quotes, backslashes, or newlines (or even {}/: etc depending on conventions), the generated module can become invalid JS or allow unintended code injection during synthesis. Generate these literals using a safe escaping strategy (e.g., serialize with JSON.stringify(...) and embed the resulting string literal) and ensure the derived function name is sanitized to a valid Azure Functions identifier.
| const webhookRequest = { | ||
| ROCKET_FUNCTION_ID: process.env.ROCKET_FUNCTION_ID, | ||
| req: { | ||
| method: request.method, |
There was a problem hiding this comment.
The generated request object hardcodes the function id key as ROCKET_FUNCTION_ID. Elsewhere in this repo the key comes from rocketFunctionIDEnvVar (local controller, terraform app settings), so hardcoding it here risks subtle breakage if the constant ever changes and makes the code inconsistent across providers. Consider importing rocketFunctionIDEnvVar in sharedImports() and using it as a computed property key when building webhookRequest.
| mountStack: Synth.mountStack.bind(Synth, params), | ||
| mountFunctions: Functions.mountFunctions.bind(Synth, params), | ||
| mountFunctionsV4: Functions.mountFunctionsV4.bind(Functions, params), | ||
| getFunctionAppName: Functions.getFunctionAppName.bind(Synth, params), |
There was a problem hiding this comment.
getFunctionAppName is bound with thisArg set to Synth, but the function is a static on Functions. While it may work today (because it doesn’t use this), this is an easy copy/paste footgun and makes the binding inconsistent with mountFunctionsV4. Bind it to Functions for clarity and to avoid future refactors accidentally depending on this.
| getFunctionAppName: Functions.getFunctionAppName.bind(Synth, params), | |
| getFunctionAppName: Functions.getFunctionAppName.bind(Functions, params), |
## Description
This PR adds Node 22 support to the Webhook Rocket. The changes in this PR are similar to those introduced in #1593 of the framework. This PR also addresses several vulnerabilities found in the dependencies.
This version of the rocket is compatible with 4.x versions of the main framework.
Changes
rocket-webhook-azure-infrastructurepackage to generate v4-compatible Azure Functionsrocket-webhook-azureto work with the v4@azure/functionsSDKpackage.jsonto address several vulnerabilities across dependencies