diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.util.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.util.ts index 2cbc7aaea..275eeb7e5 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.util.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.util.ts @@ -1,4 +1,9 @@ -import { createCipheriv, createDecipheriv, createHash } from 'crypto'; +import { + createCipheriv, + createDecipheriv, + createHash, + randomBytes, +} from 'crypto'; import * as bcrypt from 'bcrypt'; @@ -16,41 +21,34 @@ export const compareHash = async (password: string, passwordHash: string) => { return bcrypt.compare(password, passwordHash); }; -export const encryptText = ( - textToEncrypt: string, - key: string, - iv: string, -): string => { +export const encryptText = (textToEncrypt: string, key: string): string => { const keyHash = createHash('sha512') .update(key) .digest('hex') .substring(0, 32); - const ivHash = createHash('sha512').update(iv).digest('hex').substring(0, 16); + const iv = randomBytes(16); - const cipher = createCipheriv('aes-256-ctr', keyHash, ivHash); - - return Buffer.concat([cipher.update(textToEncrypt), cipher.final()]).toString( - 'base64', - ); -}; - -export const decryptText = ( - textToDecrypt: string, - key: string, - iv: string, -): string => { - const keyHash = createHash('sha512') - .update(key) - .digest('hex') - .substring(0, 32); - - const ivHash = createHash('sha512').update(iv).digest('hex').substring(0, 16); - - const decipher = createDecipheriv('aes-256-ctr', keyHash, ivHash); + const cipher = createCipheriv('aes-256-ctr', keyHash, iv); return Buffer.concat([ - decipher.update(Buffer.from(textToDecrypt, 'base64')), - decipher.final(), - ]).toString(); + iv, + cipher.update(textToEncrypt), + cipher.final(), + ]).toString('base64'); +}; + +export const decryptText = (textToDecrypt: string, key: string): string => { + const textBuffer = Buffer.from(textToDecrypt, 'base64'); + const iv = textBuffer.subarray(0, 16); + const text = textBuffer.subarray(16); + + const keyHash = createHash('sha512') + .update(key) + .digest('hex') + .substring(0, 32); + + const decipher = createDecipheriv('aes-256-ctr', keyHash, iv); + + return Buffer.concat([decipher.update(text), decipher.final()]).toString(); }; diff --git a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.service.ts b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.service.ts index c16b048a3..185c1f41b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-server.service.ts @@ -53,8 +53,6 @@ export class RemoteServerService { const encryptedPassword = await encryptText( remoteServerInput.userMappingOptions.password, key, - // TODO: check if we should use a separated IV - key, ); remoteServerToCreate = { diff --git a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/utils/remote-table-postgres.util.ts b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/utils/remote-table-postgres.util.ts index a044ebe9f..66c789909 100644 --- a/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/utils/remote-table-postgres.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/utils/remote-table-postgres.util.ts @@ -17,11 +17,7 @@ export const buildPostgresUrl = ( const foreignDataWrapperOptions = remoteServer.foreignDataWrapperOptions; const userMappingOptions = remoteServer.userMappingOptions; - const password = decryptText( - userMappingOptions.password, - secretKey, - secretKey, - ); + const password = decryptText(userMappingOptions.password, secretKey); const url = `postgres://${userMappingOptions.username}:${password}@${foreignDataWrapperOptions.host}:${foreignDataWrapperOptions.port}/${foreignDataWrapperOptions.dbname}`;