From 8bc5b819424c5a63485ff5022cc7888b13a96e8c Mon Sep 17 00:00:00 2001 From: BatLeDev Date: Mon, 12 May 2025 12:03:16 +0200 Subject: [PATCH] fix: the patch for secrets didn't work --- api/src/routers/processings.ts | 15 ++++++++++++--- api/src/utils/cipher.ts | 22 ---------------------- package-lock.json | 8 ++++---- package.json | 2 +- shared/cipher.ts | 32 ++++++++++++++++++++++++++++++++ tsconfig.json | 1 + worker/src/task/task.ts | 4 ++-- worker/src/utils/cipher.ts | 17 ----------------- 8 files changed, 52 insertions(+), 49 deletions(-) delete mode 100644 api/src/utils/cipher.ts create mode 100644 shared/cipher.ts delete mode 100644 worker/src/utils/cipher.ts diff --git a/api/src/routers/processings.ts b/api/src/routers/processings.ts index 0315fc2c..7b1ac5a1 100644 --- a/api/src/routers/processings.ts +++ b/api/src/routers/processings.ts @@ -15,6 +15,7 @@ import { reqOrigin, session } from '@data-fair/lib-express/index.js' import { httpError } from '@data-fair/lib-utils/http-errors.js' import { createNext } from '@data-fair/processings-shared/runs.ts' import { applyProcessing, deleteProcessing } from '../utils/runs.ts' +import { cipher, decipher } from '@data-fair/processings-shared/cipher.ts' import mongo from '#mongo' import config from '#config' import locks from '#locks' @@ -22,7 +23,6 @@ import { resolvedSchema as processingSchema } from '#types/processing/index.ts' import getApiDoc from '../utils/api-docs.ts' import findUtils from '../utils/find.ts' import permissions from '../utils/permissions.ts' -import { cipher } from '../utils/cipher.ts' const router = Router() export default router @@ -52,12 +52,21 @@ const validateFullProcessing = async (processing: Processing) => { // Get the plugin file and execute the prepare function if it exists const plugin = await import(path.resolve(process.cwd(), pluginsDir, processing.plugin, 'index.js')) if (plugin.prepare && typeof plugin.prepare === 'function') { - const res = await (plugin.prepare as PrepareFunction)({ processingConfig: processing.config }) + // Decipher the actuals secrets if they are present + const secrets: Record = {} + if (processing.secrets) { + Object.keys(processing.secrets).forEach(key => { + secrets[key] = decipher(processing.secrets![key], config.cipherPassword) + }) + } + + // Call the prepare function + const res = await (plugin.prepare as PrepareFunction)({ processingConfig: processing.config, secrets }) if (res.processingConfig) processing.config = res.processingConfig if (res.secrets) { processing.secrets = {} Object.keys(res.secrets).forEach(key => { - processing.secrets![key] = cipher(res.secrets![key]) + processing.secrets![key] = cipher(res.secrets![key], config.cipherPassword) }) } } diff --git a/api/src/utils/cipher.ts b/api/src/utils/cipher.ts deleted file mode 100644 index f95af525..00000000 --- a/api/src/utils/cipher.ts +++ /dev/null @@ -1,22 +0,0 @@ -import config from '#config' -import { createHash, randomBytes, createCipheriv } from 'node:crypto' - -export type CipheredContent = { iv: string, alg: 'aes256', data: string } - -// the secret key for cipher/decipher is a simple hash of config.cipherPassword -const hash = createHash('sha256') -hash.update(config.cipherPassword) -const securityKey = hash.digest() - -export const cipher = (content: string): CipheredContent => { - const initVector = randomBytes(16) - const algo = 'aes256' - const cipher = createCipheriv(algo, securityKey, initVector) - let encryptedData = cipher.update(content, 'utf-8', 'hex') - encryptedData += cipher.final('hex') - return { - iv: initVector.toString('hex'), - alg: algo, - data: encryptedData - } -} diff --git a/package-lock.json b/package-lock.json index 2b27467a..066063c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "devDependencies": { "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", - "@data-fair/lib-common-types": "^1.10.0", + "@data-fair/lib-common-types": "^1.10.1", "@data-fair/lib-node": "^2.4.0", "@data-fair/lib-utils": "^1.5.0", "@reporters/bail": "^1.2.1", @@ -457,9 +457,9 @@ "license": "MIT" }, "node_modules/@data-fair/lib-common-types": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@data-fair/lib-common-types/-/lib-common-types-1.10.0.tgz", - "integrity": "sha512-ElAx/oQIsYhxrHu28RV1midJWVAa2XOukgT4TvRcdd1Q8K2c6gZGLkSPzhvn/Ei3wGb87pF46RkT5k1Ae2hdlA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@data-fair/lib-common-types/-/lib-common-types-1.10.1.tgz", + "integrity": "sha512-JK2qbEGYhfR7WJxv0MU2Zz6Q0TdzN+UbVddzOPaF7UBoasPiTYse8cd9aS8wAm4a1SI9pHm7Z5jYU3ui1hp6jw==", "license": "MIT", "dependencies": { "@data-fair/lib-validation": "^1.0.0", diff --git a/package.json b/package.json index de9f2b6e..6e3d4938 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@data-fair/lib-types-builder": "^1.7.0" }, "devDependencies": { - "@data-fair/lib-common-types": "^1.10.0", + "@data-fair/lib-common-types": "^1.10.1", "@commitlint/cli": "^19.7.1", "@commitlint/config-conventional": "^19.7.1", "@data-fair/lib-node": "^2.4.0", diff --git a/shared/cipher.ts b/shared/cipher.ts new file mode 100644 index 00000000..2222a450 --- /dev/null +++ b/shared/cipher.ts @@ -0,0 +1,32 @@ +import type { CipheredContent } from '#api/type/processing/index.js' +import { createHash, createCipheriv, createDecipheriv, randomBytes } from 'node:crypto' + +const getSecurityKey = (password: string): Buffer => { + return createHash('sha256').update(password).digest() +} + +export const cipher = (content: CipheredContent | string, cipherPassword: string): CipheredContent => { + const securityKey = getSecurityKey(cipherPassword) + if (typeof content !== 'string') return content + + const initVector = randomBytes(16) + const algo = 'aes256' + const cipher = createCipheriv(algo, securityKey, initVector) + let encryptedData = cipher.update(content, 'utf-8', 'hex') + encryptedData += cipher.final('hex') + return { + iv: initVector.toString('hex'), + alg: algo, + data: encryptedData + } +} + +export const decipher = (cipheredContent: CipheredContent | string, cipherPassword: string): string => { + const securityKey = getSecurityKey(cipherPassword) + + if (typeof cipheredContent === 'string') return cipheredContent + const decipher = createDecipheriv(cipheredContent.alg, securityKey, Buffer.from(cipheredContent.iv, 'hex')) + let content = decipher.update(cipheredContent.data, 'hex', 'utf-8') + content += decipher.final('utf8') + return content +} diff --git a/tsconfig.json b/tsconfig.json index 1b0e352c..e0a0c886 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "skipLibCheck": true, "paths": { "#api/types": ["./api/types/index.ts"], + "#api/type/*": ["./api/types/*"] } }, "exclude": ["node_modules", ".type", "ui", "dev", "data", "test-it"] diff --git a/worker/src/task/task.ts b/worker/src/task/task.ts index 93dc2d0a..8d71e01d 100644 --- a/worker/src/task/task.ts +++ b/worker/src/task/task.ts @@ -13,8 +13,8 @@ import tmp from 'tmp-promise' import { DataFairWsClient } from '@data-fair/lib-node/ws-client.js' import { httpAgent, httpsAgent } from '@data-fair/lib-node/http-agents.js' import * as wsEmitter from '@data-fair/lib-node/ws-emitter.js' +import { decipher } from '@data-fair/processings-shared/cipher.ts' import { running } from '../utils/runs.ts' -import { decipher } from '../utils/cipher.ts' import config from '#config' fs.ensureDirSync(config.dataDir) @@ -188,7 +188,7 @@ export const run = async (db: Db, mailTransport: any) => { const secrets: Record = {} if (processing.secrets) { Object.keys(processing.secrets).forEach(key => { - secrets[key] = decipher(processing.secrets![key]) + secrets[key] = decipher(processing.secrets![key], config.cipherPassword) }) } diff --git a/worker/src/utils/cipher.ts b/worker/src/utils/cipher.ts deleted file mode 100644 index 9182740d..00000000 --- a/worker/src/utils/cipher.ts +++ /dev/null @@ -1,17 +0,0 @@ -import config from '#config' -import { createHash, createDecipheriv } from 'node:crypto' - -export type CipheredContent = { iv: string, alg: 'aes256', data: string } - -// the secret key for cipher/decipher is a simple hash of config.cipherPassword -const hash = createHash('sha256') -hash.update(config.cipherPassword) -const securityKey = hash.digest() - -export const decipher = (cipheredContent: CipheredContent | string): string => { - if (typeof cipheredContent === 'string') return cipheredContent - const decipher = createDecipheriv(cipheredContent.alg, securityKey, Buffer.from(cipheredContent.iv, 'hex')) - let content = decipher.update(cipheredContent.data, 'hex', 'utf-8') - content += decipher.final('utf8') - return content -}