From ba6f7b8d5e577553bc751815c81a8e5d9171a01f Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Mon, 31 Aug 2026 12:41:48 +0200 Subject: [PATCH] =?UTF-8?q?chore(deps):=20currency=20sweep=20=E2=80=94=20@?= =?UTF-8?q?types/node=2026,=20ai-kit=20v0.6.2,=20CI=20actions=20v7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exact bumps: - @types/node ^20.19.43 -> ^26.4.0 - ai-kit github:bitbaum/ai-kit#v0.5.0 -> #v0.6.2 (lock re-resolved to the v0.6.2 tag sha; npm kept the old sha on plain install, forced with npm install ai-kit@github:bitbaum/ai-kit#v0.6.2) - CI actions: already at v7-era across all workflows (checkout@v7, setup-node@v7, upload-artifact@v7, cache@v6) — no workflow changes - node-version/engines untouched per wave constraints Breakage fixed: @types/node 26 drops crypto.createCipher/createDecipher (removed in Node 22; never supported GCM). src/lib/payments/security.ts now uses createCipheriv/createDecipheriv with the already-generated IV and a sha256-derived 32-byte key. Functions are unused outside the file and the old code threw at runtime, so no stored ciphertext is affected. Verified: lint 0 errors, typecheck clean, jest 541 suites / 7780 tests passed. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn --- package-lock.json | 22 +++++++++++----------- package.json | 4 ++-- src/lib/payments/security.ts | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index f863cef5e..c92f287c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@tiptap/pm": "^3.30.5", "@tiptap/react": "^3.30.5", "@tiptap/starter-kit": "^3.30.5", - "ai-kit": "github:bitbaum/ai-kit#v0.5.0", + "ai-kit": "github:bitbaum/ai-kit#v0.6.2", "bcryptjs": "^2.4.3", "busboy": "^1.6.0", "clsx": "^2.1.1", @@ -71,7 +71,7 @@ "@types/jest": "^30.0.0", "@types/jsonwebtoken": "^9.0.5", "@types/leaflet": "^1.9.22", - "@types/node": "^20.19.43", + "@types/node": "^26.4.0", "@types/nodemailer": "^7.0.1", "@types/pg": "^8.23.1", "@types/qrcode": "^1.5.6", @@ -6570,12 +6570,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", - "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz", + "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==", "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~8.3.0" } }, "node_modules/@types/nodemailer": { @@ -7486,8 +7486,8 @@ } }, "node_modules/ai-kit": { - "version": "0.5.0", - "resolved": "git+ssh://git@github.com/bitbaum/ai-kit.git#de7319a29d8f85f9dc431993623da11084b9ead7", + "version": "0.6.2", + "resolved": "git+ssh://git@github.com/bitbaum/ai-kit.git#ace11f14d817079ae2bf4cdc010b6daa9faacbec", "license": "MIT", "dependencies": { "ai-forms": "^0.1.2" @@ -19518,9 +19518,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "license": "MIT" }, "node_modules/unified": { diff --git a/package.json b/package.json index bed752217..a32be6215 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "@tiptap/pm": "^3.30.5", "@tiptap/react": "^3.30.5", "@tiptap/starter-kit": "^3.30.5", - "ai-kit": "github:bitbaum/ai-kit#v0.5.0", + "ai-kit": "github:bitbaum/ai-kit#v0.6.2", "bcryptjs": "^2.4.3", "busboy": "^1.6.0", "clsx": "^2.1.1", @@ -161,7 +161,7 @@ "@types/jest": "^30.0.0", "@types/jsonwebtoken": "^9.0.5", "@types/leaflet": "^1.9.22", - "@types/node": "^20.19.43", + "@types/node": "^26.4.0", "@types/nodemailer": "^7.0.1", "@types/pg": "^8.23.1", "@types/qrcode": "^1.5.6", diff --git a/src/lib/payments/security.ts b/src/lib/payments/security.ts index 61b6d8c1e..8da34eae1 100644 --- a/src/lib/payments/security.ts +++ b/src/lib/payments/security.ts @@ -72,15 +72,25 @@ export function maskSensitiveData(data: string): string { return masked } +/** + * Derive a 32-byte AES-256 key from the configured secret. + * createCipher/createDecipher were removed in Node 22 (and never supported + * GCM), so we hash the secret to a fixed-length key for createCipheriv. + */ +function deriveEncryptionKey(): Buffer { + const secret = process.env.PAYMENT_ENCRYPTION_KEY || 'default-key-change-in-production' + return crypto.createHash('sha256').update(secret).digest() +} + /** * Encrypt sensitive data before storage */ export function encryptSensitiveData(data: string): string { const algorithm = 'aes-256-gcm' - const key = process.env.PAYMENT_ENCRYPTION_KEY || 'default-key-change-in-production' + const key = deriveEncryptionKey() const iv = crypto.randomBytes(16) - const cipher = crypto.createCipher(algorithm, key) + const cipher = crypto.createCipheriv(algorithm, key, iv) let encrypted = cipher.update(data, 'utf8', 'hex') encrypted += cipher.final('hex') @@ -102,8 +112,8 @@ export function decryptSensitiveData(encryptedData: string): string { try { const { encrypted, iv, authTag, algorithm } = JSON.parse(encryptedData) - const key = process.env.PAYMENT_ENCRYPTION_KEY || 'default-key-change-in-production' - const decipher = crypto.createDecipher(algorithm, key) + const key = deriveEncryptionKey() + const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(iv, 'hex')) decipher.setAuthTag(Buffer.from(authTag, 'hex')) let decrypted = decipher.update(encrypted, 'hex', 'utf8')