From de62b10e12f916e83e7bd48533475ef3eb9d89be Mon Sep 17 00:00:00 2001 From: mfrindt Date: Thu, 2 Jan 2025 16:11:53 +0100 Subject: [PATCH 1/6] obscure sensitive bucket credentials --- lib/models/account.js | 10 +++-- lib/routes/api/accounts.js | 51 ++++++++++++++++++---- lib/routes/api/utils.js | 19 +++++++- lib/utils/encrypt-decrypt.js | 85 +++++++++++++++++++++++++++++++++--- 4 files changed, 148 insertions(+), 17 deletions(-) diff --git a/lib/models/account.js b/lib/models/account.js index ea9026cf..5e5c866e 100644 --- a/lib/models/account.js +++ b/lib/models/account.js @@ -56,9 +56,13 @@ AND effective_end_date IS NULL AND pending = 0`; const extractBucketCredential = (obj) => { - const {bucket_credential} = obj; - if (bucket_credential) { - obj.bucket_credential = JSON.parse(decrypt(bucket_credential)); + try { + const {bucket_credential} = obj; + if (bucket_credential) { + obj.bucket_credential = JSON.parse(decrypt(bucket_credential)); + } + } catch (error) { + console.error('Error while decrypting data', error); } }; diff --git a/lib/routes/api/accounts.js b/lib/routes/api/accounts.js index 0eef65c5..7369cdb9 100644 --- a/lib/routes/api/accounts.js +++ b/lib/routes/api/accounts.js @@ -19,11 +19,12 @@ const { parseCallSid, enableSubspace, disableSubspace, - parseVoipCarrierSid + parseVoipCarrierSid, + hasValue, } = require('./utils'); const short = require('short-uuid'); const VoipCarrier = require('../../models/voip-carrier'); -const { encrypt } = require('../../utils/encrypt-decrypt'); +const { encrypt, obscureBucketCredentialsSensitiveData, isObscureKey } = require('../../utils/encrypt-decrypt'); const { testS3Storage, testGoogleStorage, testAzureStorage } = require('../../utils/storage-utils'); const translator = short(); @@ -557,6 +558,9 @@ router.get('/:sid', async(req, res) => { const service_provider_sid = req.user.hasServiceProviderAuth ? req.user.service_provider_sid : null; const results = await Account.retrieve(account_sid, service_provider_sid); if (results.length === 0) return res.status(404).end(); + + results[0].bucket_credential = obscureBucketCredentialsSensitiveData(results[0]); + return res.status(200).json(results[0]); } catch (err) { @@ -639,19 +643,21 @@ router.delete('/:sid/SubspaceTeleport', async(req, res) => { } }); -function encryptBucketCredential(obj) { - if (!obj.bucket_credential) return; +function encryptBucketCredential(obj, storedCredentials = {}) { + if (!hasValue(obj?.bucket_credential)) return; const { vendor, region, name, access_key_id, - secret_access_key, tags, - service_key, - connection_string, endpoint } = obj.bucket_credential; + let { + secret_access_key, + service_key, + connection_string + } = obj.bucket_credential; switch (vendor) { case 'aws_s3': @@ -659,6 +665,9 @@ function encryptBucketCredential(obj) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(region, 'invalid aws bucket region: region is required'); + if (isObscureKey(storedCredentials && obj.bucket_credential)) { + secret_access_key = storedCredentials.secret_access_key; + } const awsData = JSON.stringify({vendor, region, name, access_key_id, secret_access_key, tags}); obj.bucket_credential = encrypt(awsData); @@ -668,18 +677,27 @@ function encryptBucketCredential(obj) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(endpoint, 'invalid endpoint uri: endpoint is required'); + if (isObscureKey(storedCredentials && obj.bucket_credential)) { + secret_access_key = storedCredentials.secret_access_key; + } const s3Data = JSON.stringify({vendor, endpoint, name, access_key_id, secret_access_key, tags}); obj.bucket_credential = encrypt(s3Data); break; case 'google': assert(service_key, 'invalid google cloud storage credential: service_key is required'); + if (isObscureKey(storedCredentials && obj.bucket_credential)) { + service_key = storedCredentials.service_key; + } const googleData = JSON.stringify({vendor, name, service_key, tags}); obj.bucket_credential = encrypt(googleData); break; case 'azure': assert(name, 'invalid azure container name: name is required'); assert(connection_string, 'invalid azure cloud storage credential: connection_string is required'); + if (isObscureKey(storedCredentials && obj.bucket_credential)) { + connection_string = storedCredentials.connection_string; + } const azureData = JSON.stringify({vendor, name, connection_string, tags}); obj.bucket_credential = encrypt(azureData); break; @@ -737,7 +755,17 @@ router.put('/:sid', async(req, res) => { delete obj.registration_hook; delete obj.queue_event_hook; - encryptBucketCredential(obj); + let storedBucketCredentials = {}; + if (isObscureKey(obj?.bucket_credential)) { + const [account] = await Account.retrieve(sid) || []; + /* to avoid overwriting valid credentials with the obscured secret, + * that the frontend might send, we pass the stored account bucket credentials + * in the case it is a obscured key, we replace it with the stored one + */ + storedBucketCredentials = account.bucket_credential; + } + + encryptBucketCredential(obj, storedBucketCredentials); const rowsAffected = await Account.update(sid, obj); if (rowsAffected === 0) { @@ -837,6 +865,13 @@ router.post('/:sid/BucketCredentialTest', async(req, res) => { try { const account_sid = parseAccountSid(req); await validateRequest(req, account_sid); + /* if the req.body bucket credentials contain an obscured key, replace with stored account.bucket_credential */ + if (isObscureKey(req.body)) { + const service_provider_sid = req.user.hasServiceProviderAuth ? req.user.service_provider_sid : null; + const [account] = await Account.retrieve(account_sid, service_provider_sid) || []; + if (!account) return res.status(404).end(); + req.body = account.bucket_credential; + } const {vendor, name, region, access_key_id, secret_access_key, service_key, connection_string, endpoint} = req.body; const ret = { status: 'not tested' diff --git a/lib/routes/api/utils.js b/lib/routes/api/utils.js index 068edbb7..b9d7a224 100644 --- a/lib/routes/api/utils.js +++ b/lib/routes/api/utils.js @@ -440,6 +440,22 @@ const validatePasswordSettings = async(password) => { return; }; +function hasValue(data) { + if (typeof data === 'string') { + return data && data.length > 0; + } else if (Array.isArray(data)) { + return data && data.length > 0; + } else if (typeof data === 'object') { + return data && Object.keys(data).length > 0; + } else if (typeof data === 'number') { + return data !== null; + } else if (typeof data === 'boolean') { + return data !== null; + } else { + return false; + } +} + module.exports = { setupFreeTrial, createTestCdrs, @@ -460,5 +476,6 @@ module.exports = { checkLimits, enableSubspace, disableSubspace, - validatePasswordSettings + validatePasswordSettings, + hasValue, }; diff --git a/lib/utils/encrypt-decrypt.js b/lib/utils/encrypt-decrypt.js index 78f32a3c..e202c558 100644 --- a/lib/utils/encrypt-decrypt.js +++ b/lib/utils/encrypt-decrypt.js @@ -17,10 +17,15 @@ const encrypt = (text) => { }; const decrypt = (data) => { - const hash = JSON.parse(data); - const decipher = crypto.createDecipheriv(algorithm, secretKey, Buffer.from(hash.iv, 'hex')); - const decrpyted = Buffer.concat([decipher.update(Buffer.from(hash.content, 'hex')), decipher.final()]); - return decrpyted.toString(); + try { + const hash = JSON.parse(data); + const decipher = crypto.createDecipheriv(algorithm, secretKey, Buffer.from(hash.iv, 'hex')); + const decrpyted = Buffer.concat([decipher.update(Buffer.from(hash.content, 'hex')), decipher.final()]); + return decrpyted.toString(); + } catch (error) { + console.error('Error while decrypting data', error); + return '{}'; + } }; const obscureKey = (key, key_spoiler_length = 6) => { @@ -33,8 +38,78 @@ const obscureKey = (key, key_spoiler_length = 6) => { return `${key.slice(0, key_spoiler_length)}${key_spoiler_char.repeat(key.length - key_spoiler_length)}`; }; +function isObscureKey(bucketCredentials) { + if (!bucketCredentials) { + return false; + } + + try { + const { + vendor, + secret_access_key = '', + service_key = '', + connection_string = '' + } = bucketCredentials || {}; + const pattern = /^EFEU2f[A-Za-z0-9]{4,6}X+$/; + + switch (vendor) { + case 'aws_s3': + case 's3_compatible': + return pattern.test(secret_access_key); + case 'azure': + return pattern.test(connection_string); + + case 'google': { + const res = JSON.parse(service_key); + return pattern.test(res?.private_key || ''); + } + } + return false; + } catch (error) { + console.log('Error in isObscureKey', error); + return false; + } +} + +/** + * obscure sensitive data in bucket credentials + * an obscured key contains of 6 'spoiled' characters of the key followed by 'X' characters + * '123456XXXXXXXXXXXXXXXXXXXXXXXX' + * @param {*} obj + * @returns + */ +function obscureBucketCredentialsSensitiveData(obj) { + if (!obj) return obj; + const {vendor, service_key, connection_string, secret_access_key} = obj; + switch (vendor) { + case 'aws_s3': + case 's3_compatible': + obj.secret_access_key = obscureKey(secret_access_key); + break; + case 'google': + const o = JSON.parse(service_key); + const key_header = '-----BEGIN PRIVATE KEY-----\n'; + const obscured = { + ...o, + private_key: `${key_header}${isObscureKey ? + obscureKey(o.private_key.slice(key_header.length, o.private_key.length)) : + o.private_key.slice(key_header.length, o.private_key.length)}` + }; + obj.service_key = JSON.stringify(obscured); + break; + case 'azure': + obj.connection_string = obscureKey(connection_string); + break; + } + + return obj; +} + + module.exports = { encrypt, decrypt, - obscureKey + obscureKey, + isObscureKey, + obscureBucketCredentialsSensitiveData, }; From 77a8824727d6c70874c4dcdc2f25de07466f08b0 Mon Sep 17 00:00:00 2001 From: mfrindt Date: Thu, 2 Jan 2025 17:57:58 +0100 Subject: [PATCH 2/6] npm audit fix --- package-lock.json | 36 ++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12635a59..6c4db913 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4523,9 +4523,10 @@ "dev": true }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4553,10 +4554,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5354,16 +5356,17 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -5377,7 +5380,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -5392,6 +5395,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express-rate-limit": { @@ -8209,9 +8216,10 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/pause": { "version": "0.0.1", diff --git a/package.json b/package.json index f76a4bd5..8e4b30ee 100644 --- a/package.json +++ b/package.json @@ -71,4 +71,4 @@ "request-promise-native": "^1.0.9", "tape": "^5.7.5" } -} +} \ No newline at end of file From 12a00e88c95d758c169f441670ca54f5f53191e7 Mon Sep 17 00:00:00 2001 From: mfrindt Date: Thu, 2 Jan 2025 18:03:21 +0100 Subject: [PATCH 3/6] fix condition --- lib/routes/api/accounts.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/routes/api/accounts.js b/lib/routes/api/accounts.js index 7369cdb9..13560c71 100644 --- a/lib/routes/api/accounts.js +++ b/lib/routes/api/accounts.js @@ -665,7 +665,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(region, 'invalid aws bucket region: region is required'); - if (isObscureKey(storedCredentials && obj.bucket_credential)) { + if (isObscureKey(obj.bucket_credential) && storedCredentials) { secret_access_key = storedCredentials.secret_access_key; } const awsData = JSON.stringify({vendor, region, name, access_key_id, @@ -677,7 +677,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(endpoint, 'invalid endpoint uri: endpoint is required'); - if (isObscureKey(storedCredentials && obj.bucket_credential)) { + if (isObscureKey(obj.bucket_credential) && storedCredentials) { secret_access_key = storedCredentials.secret_access_key; } const s3Data = JSON.stringify({vendor, endpoint, name, access_key_id, @@ -686,7 +686,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { break; case 'google': assert(service_key, 'invalid google cloud storage credential: service_key is required'); - if (isObscureKey(storedCredentials && obj.bucket_credential)) { + if (isObscureKey(obj.bucket_credential) && storedCredentials) { service_key = storedCredentials.service_key; } const googleData = JSON.stringify({vendor, name, service_key, tags}); @@ -695,7 +695,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { case 'azure': assert(name, 'invalid azure container name: name is required'); assert(connection_string, 'invalid azure cloud storage credential: connection_string is required'); - if (isObscureKey(storedCredentials && obj.bucket_credential)) { + if (isObscureKey(obj.bucket_credential) && storedCredentials) { connection_string = storedCredentials.connection_string; } const azureData = JSON.stringify({vendor, name, connection_string, tags}); From 699c784dc9b8d000ce97314003e5ea0ab36f275b Mon Sep 17 00:00:00 2001 From: mfrindt Date: Fri, 3 Jan 2025 12:01:34 +0100 Subject: [PATCH 4/6] add test suite encrypt-decrypt.test --- lib/routes/api/accounts.js | 16 ++--- lib/utils/encrypt-decrypt.js | 23 +++--- package.json | 1 + test/docker_start.js | 2 +- test/docker_stop.js | 2 +- test/encrypt-decrypt.test.js | 132 +++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 18 deletions(-) create mode 100644 test/encrypt-decrypt.test.js diff --git a/lib/routes/api/accounts.js b/lib/routes/api/accounts.js index 13560c71..7a39c21d 100644 --- a/lib/routes/api/accounts.js +++ b/lib/routes/api/accounts.js @@ -556,12 +556,12 @@ router.get('/:sid', async(req, res) => { const account_sid = parseAccountSid(req); await validateRequest(req, account_sid); const service_provider_sid = req.user.hasServiceProviderAuth ? req.user.service_provider_sid : null; - const results = await Account.retrieve(account_sid, service_provider_sid); - if (results.length === 0) return res.status(404).end(); + const [result] = await Account.retrieve(account_sid, service_provider_sid) || []; + if (!result) return res.status(404).end(); - results[0].bucket_credential = obscureBucketCredentialsSensitiveData(results[0]); + result.bucket_credential = obscureBucketCredentialsSensitiveData(result.bucket_credential); - return res.status(200).json(results[0]); + return res.status(200).json(result); } catch (err) { sysError(logger, res, err); @@ -665,7 +665,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(region, 'invalid aws bucket region: region is required'); - if (isObscureKey(obj.bucket_credential) && storedCredentials) { + if (isObscureKey(obj.bucket_credential) && hasValue(storedCredentials)) { secret_access_key = storedCredentials.secret_access_key; } const awsData = JSON.stringify({vendor, region, name, access_key_id, @@ -677,7 +677,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { assert(secret_access_key, 'invalid aws S3 bucket credential: secret_access_key is required'); assert(name, 'invalid aws bucket name: name is required'); assert(endpoint, 'invalid endpoint uri: endpoint is required'); - if (isObscureKey(obj.bucket_credential) && storedCredentials) { + if (isObscureKey(obj.bucket_credential) && hasValue(storedCredentials)) { secret_access_key = storedCredentials.secret_access_key; } const s3Data = JSON.stringify({vendor, endpoint, name, access_key_id, @@ -686,7 +686,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { break; case 'google': assert(service_key, 'invalid google cloud storage credential: service_key is required'); - if (isObscureKey(obj.bucket_credential) && storedCredentials) { + if (isObscureKey(obj.bucket_credential) && hasValue(storedCredentials)) { service_key = storedCredentials.service_key; } const googleData = JSON.stringify({vendor, name, service_key, tags}); @@ -695,7 +695,7 @@ function encryptBucketCredential(obj, storedCredentials = {}) { case 'azure': assert(name, 'invalid azure container name: name is required'); assert(connection_string, 'invalid azure cloud storage credential: connection_string is required'); - if (isObscureKey(obj.bucket_credential) && storedCredentials) { + if (isObscureKey(obj.bucket_credential) && hasValue(storedCredentials)) { connection_string = storedCredentials.connection_string; } const azureData = JSON.stringify({vendor, name, connection_string, tags}); diff --git a/lib/utils/encrypt-decrypt.js b/lib/utils/encrypt-decrypt.js index e202c558..7eb6299b 100644 --- a/lib/utils/encrypt-decrypt.js +++ b/lib/utils/encrypt-decrypt.js @@ -50,18 +50,22 @@ function isObscureKey(bucketCredentials) { service_key = '', connection_string = '' } = bucketCredentials || {}; - const pattern = /^EFEU2f[A-Za-z0-9]{4,6}X+$/; - + let pattern; switch (vendor) { case 'aws_s3': case 's3_compatible': + pattern = /^([A-Za-z0-9]{4,6}X+$)/; return pattern.test(secret_access_key); case 'azure': + pattern = /^https:[A-Za-z0-9\/.:?=&_-]+$/; return pattern.test(connection_string); case 'google': { - const res = JSON.parse(service_key); - return pattern.test(res?.private_key || ''); + pattern = /^([A-Za-z0-9]{4,6}X+$)/; + let {private_key} = JSON.parse(service_key); + const key_header = '-----BEGIN PRIVATE KEY-----\n'; + private_key = private_key.slice(key_header.length, private_key.length); + return pattern.test(private_key || ''); } } return false; @@ -88,12 +92,15 @@ function obscureBucketCredentialsSensitiveData(obj) { break; case 'google': const o = JSON.parse(service_key); - const key_header = '-----BEGIN PRIVATE KEY-----\n'; + let private_key = o.private_key; + if (!isObscureKey(obj)) { + const key_header = '-----BEGIN PRIVATE KEY-----\n'; + private_key = o.private_key.slice(key_header.length, o.private_key.length); + private_key = `${key_header}${obscureKey(private_key)}`; + } const obscured = { ...o, - private_key: `${key_header}${isObscureKey ? - obscureKey(o.private_key.slice(key_header.length, o.private_key.length)) : - o.private_key.slice(key_header.length, o.private_key.length)}` + private_key }; obj.service_key = JSON.stringify(obscured); break; diff --git a/package.json b/package.json index 8e4b30ee..f1006845 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "start": "node app.js", "test": "NODE_ENV=test APPLY_JAMBONZ_DB_LIMITS=1 JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_LOGLEVEL=error JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall K8S=true K8S_FEATURE_SERVER_SERVICE_NAME=127.0.0.1 K8S_FEATURE_SERVER_SERVICE_PORT=3100 node test/ ", + "test:encrypt-decrypt": "ENCRYPTION_SECRET=12345 node --test ./test/encrypt-decrypt.test.js", "integration-test": "NODE_ENV=test JAMBONES_AUTH_USE_JWT=1 JAMBONES_TIME_SERIES_HOST=127.0.0.1 AWS_REGION='us-east-1' JAMBONES_CURRENCY=USD JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=debug JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/serve-integration.js", "upgrade-db": "node ./db/upgrade-jambonz-db.js", "coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test", diff --git a/test/docker_start.js b/test/docker_start.js index 48c584ba..be008757 100644 --- a/test/docker_start.js +++ b/test/docker_start.js @@ -3,7 +3,7 @@ const exec = require('child_process').exec ; test('starting docker network..', (t) => { t.plan(1); - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { setTimeout(() => { t.pass('docker started'); }, 15000); diff --git a/test/docker_stop.js b/test/docker_stop.js index 11db6ec7..8fe3d4c4 100644 --- a/test/docker_stop.js +++ b/test/docker_stop.js @@ -3,7 +3,7 @@ const exec = require('child_process').exec ; test('stopping docker network..', (t) => { t.timeoutAfter(10000); - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { //console.log(`stderr: ${stderr}`); process.exit(0); }); diff --git a/test/encrypt-decrypt.test.js b/test/encrypt-decrypt.test.js new file mode 100644 index 00000000..7d790acc --- /dev/null +++ b/test/encrypt-decrypt.test.js @@ -0,0 +1,132 @@ +const assert = require('node:assert'); +const { describe, it, beforeEach, before } = require('node:test'); +const { obscureBucketCredentialsSensitiveData, isObscureKey, obscureKey } = require('../lib/utils/encrypt-decrypt'); +const { randomUUID } = require('node:crypto'); + +let bucket_credential = {}; +let service_key = {}; + +describe('encrypt-decrypt test suite', { skip: false }, () => { + before(() => { + process.env.ENCRYPTION_SECRET = "12345"; + }); + beforeEach(() => { + service_key = { + "type": "service_account", + "project_id": "voice-gateway", + "private_key_id": randomUUID(), + "private_key": "-----BEGIN PRIVATE KEY-----\nJ6T2sQmBAD8TBm0frkGeyw0FA0aVAASVBJcwggSjBgEAAoabAQDUbiVwgufJm9R3\nv7YpECxRnQgHduX8jnbjtubi6FVqqVx78W3NM/gFNJFBC7NXtpsslqefKM6SmlkK\nNP6XqXy/ppXO8u00se7+cOFhsS6crncnsCeIYPxLFPV8P4BjExi7v88RBdektLeV\nX6sRWhxiYeWe+ORxkyC0KR4IKZjHt7ZHrg0kNQyuNx1KOhJnN3rRUkKSP2zozd1c\n3V+4EfpZjGmlQegXNHzkwUjvTOe6nuyxynWe3smjsSw/3RQda5m674Kh9tnVWEiX\n5KWnfRbWDdEBp5azzOAdeSR5W+qQfS0Jo6blREDQxWfMNmut87m81gmn+DKMhq6k\nV0JVRQStAgMBAAECggEAAf7AsAdI24zUdXkZv98gEuC4S10e2Luoz6Yvm41V3sP6\nWx0mdgY7RB9RW8U4WPnu3GhPGGJj03SyHUuI8Ix15MNM9WGDAaV3S+kRb1LqChLO\nCoNSO/qYPPg4t1iQ9+s7sWTnM93MAXjujmSveHJd7+MrUQOxOdPjB7I/ozMkBXBb\nWYsBIfeOG/7DsC4N4V/hKVXAq9NekGQv85yCUPR/DpuG9vqpztXwaSC1Wihntlu3\nNJYmMave4PbO3OxAekBl70WmukERZo7ksR+34WWse4HXlphaUVbpvnbQdGT1EzXW\nZukanqpfkIwrHme2Ko5NdP0C54pRhg6kpmWszVUMQQKBgQD6yWMuuwdPuFLg0wc2\nnDUeyHZSq/SEMSrb1wNXhL3qhaL2tCjBZwG9CHDuFMhqDLU5F36mEdAsM5MHCzyC\nTJ7VbqvCFz69SRt1CVp76Hu4HO/1Nhxm1GhF+NKSDIbnUg3o4DaC7EUtLpqYXcWj\nsXHEqVEhkrNVQ/JOIfJr42LDfQKBgQDM0U3ghGg9ufe9mb0dOonwtJA/ay/pd08Q\nyq3ue9C3yoQiNf28bP3AGKIjhA6wtd0KTSkQs6ktabGHIM8o/eTrMAMQllKh/3xe\nON7iND8Xz2GFMuIraQ7Mq9RvYWiqqIkVg1GQfJmiQ9wcmGj2PHy25LfjBXfHAYqK\nQ++P/i+s8QKBgD0pRi4MYNEZY+T+skCoQfA69VheJWjj0M8ClgcPEX4Tj1XZRCM+\nqtbeKyR1Hxd19/BvgWyg5YMSJOZP4Dbq1sW4ktzn7F4faTnWySF05k9Vh1PnGXAe\nlzuRXlFOCsx5X3kOzVyKoKhPOFa2b8/nI5bRsD6e12uRAZP6hXO4ZcrFAoGABVJ/\nCpGGP+xgMq4XCvZldTrL8MnxQcjW5iHOKT9QaiY6DsWGZWoTofVB6VhaJV9kcgsV\nQRjaEZMIiPFiULdgRnhF7B1r4kfITI5/xDMFXLIH37U1yVj+iHUCnS5T0PN2NHfo\nG7ARMfU/eALB33ws5XfGC4Et3p78oaEoTX6WcJECgYEAhysSt4qieGRSXn24V0+u\ny/ubU4dysn4SFe8BB4bjgYa8v+6VwucU+nnU4wOwykEgJmzN/ukzpvFN0CkN8eAN\n8xwtjBX9Zc1S90Wf7/7IrQGlUnsSFpDh5TW+oCqVo8JK7UGxJHR1mCvJmYVmSk3c\nD4AMvJ2x/Z5d9NKIAzdET4o=\n-----END PRIVATE KEY-----\n", + "client_email": "voicegatewayteam@voice-gateway.iam.gserviceaccount.com", + "client_id": "333827616171177028875", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/cognigyvoicegatewayteam%40cognigy-voice-gateway.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" + }; + bucket_credential = { + "vendor": "google", + "service_key": "", + "connection_string": "", + "secret_access_key": "" + } + }); + + describe('obscureBucketCredentialsSensitiveData', { skip: false }, () => { + it('should obscure "private_key" - vendor: google', { skip: false }, () => { + bucket_credential = { + ...bucket_credential, + "vendor": "google", + "service_key": JSON.stringify(service_key), + }; + const result = obscureBucketCredentialsSensitiveData(bucket_credential); + const googleCredentials = JSON.parse(result.service_key); + assert.strictEqual(googleCredentials.private_key, '-----BEGIN PRIVATE KEY-----\nJ6T2sQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); + assert.strictEqual(googleCredentials.private_key_id, googleCredentials.private_key_id); + assert.strictEqual(googleCredentials.project_id, googleCredentials.project_id); + assert.strictEqual(googleCredentials.client_email, googleCredentials.client_email); + assert.strictEqual(googleCredentials.client_id, googleCredentials.client_id); + assert.strictEqual(googleCredentials.auth_uri, googleCredentials.auth_uri); + assert.strictEqual(googleCredentials.token_uri, googleCredentials.token_uri); + }); + + it('should skip obscure since it is already obscured. vendor: google - "private key"', { skip: false }, () => { + service_key.private_key = '-----BEGIN PRIVATE KEY-----\nJ6T2sQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; + bucket_credential = { + ...bucket_credential, + "vendor": "google", + "service_key": JSON.stringify(service_key), + }; + const result = obscureBucketCredentialsSensitiveData(bucket_credential); + const googleCredentials = JSON.parse(result.service_key); + assert.strictEqual(googleCredentials.private_key, '-----BEGIN PRIVATE KEY-----\nJ6T2sQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); + assert.strictEqual(googleCredentials.private_key_id, googleCredentials.private_key_id); + assert.strictEqual(googleCredentials.project_id, googleCredentials.project_id); + assert.strictEqual(googleCredentials.client_email, googleCredentials.client_email); + assert.strictEqual(googleCredentials.client_id, googleCredentials.client_id); + assert.strictEqual(googleCredentials.auth_uri, googleCredentials.auth_uri); + assert.strictEqual(googleCredentials.token_uri, googleCredentials.token_uri); + }); + }); + + describe('isObscureKey', { skip: false }, () => { + it('vendor: google - should return true', { skip: false }, () => { + service_key.private_key = '-----BEGIN PRIVATE KEY-----\nJ6T2sQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; + bucket_credential = { + ...bucket_credential, + "vendor": "google", + "service_key": JSON.stringify(service_key), + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, true); + }); + it('vendor: google - should return false', { skip: false }, () => { + bucket_credential = { + ...bucket_credential, + "vendor": "google", + "service_key": JSON.stringify(service_key), + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, false); + }); + it('vendor: aws_s3 - should return true', { skip: false }, () => { + const obscuredKey = "J6T2sQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; + bucket_credential = { + ...bucket_credential, + "vendor": "aws_s3", + "secret_access_key": obscuredKey, + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, true); + }); + it('vendor: aws_s3 - should return false', { skip: false }, () => { + bucket_credential = { + ...bucket_credential, + "vendor": "aws_s3", + "service_key": "EFEU2fhcbqiw3211ffw3f1kezhcbqiw3211ffw3f", + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, false); + }); + it('vendor: azure - should return true', { skip: false }, () => { + const obscuredKey = 'https:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; + bucket_credential = { + ...bucket_credential, + "vendor": "azure", + "connection_string": obscuredKey, + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, true); + }); + it('vendor: azure - should return false', { skip: false }, () => { + bucket_credential = { + ...bucket_credential, + "vendor": "azure", + connection_string: 'https://cognigydevstorage.blob.core.windows.net/voicegateway-test?sp=rw&st=2023-09-10T13:35:44Z&se=2023-09-11T21:35:44Z&spr=https&sv=2022-11-02&sr=c&sig=9WN8Bg5UMOvnV1h1cJpCnTUG%2FnonTbRZ1Q1rbKnDUl4%3D', + }; + const result = isObscureKey(bucket_credential); + assert.strictEqual(result, false); + }); + }); +}); + From bc2893c97f9ccc1b2458e9d0afbb004d11cba58a Mon Sep 17 00:00:00 2001 From: mfrindt Date: Fri, 3 Jan 2025 12:02:02 +0100 Subject: [PATCH 5/6] revert docker-compose --- test/docker_start.js | 2 +- test/docker_stop.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/docker_start.js b/test/docker_start.js index be008757..48c584ba 100644 --- a/test/docker_start.js +++ b/test/docker_start.js @@ -3,7 +3,7 @@ const exec = require('child_process').exec ; test('starting docker network..', (t) => { t.plan(1); - exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { + exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { setTimeout(() => { t.pass('docker started'); }, 15000); diff --git a/test/docker_stop.js b/test/docker_stop.js index 8fe3d4c4..11db6ec7 100644 --- a/test/docker_stop.js +++ b/test/docker_stop.js @@ -3,7 +3,7 @@ const exec = require('child_process').exec ; test('stopping docker network..', (t) => { t.timeoutAfter(10000); - exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { + exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { //console.log(`stderr: ${stderr}`); process.exit(0); }); From f97f5828b835953979897d9c84c5efecad173e4c Mon Sep 17 00:00:00 2001 From: mfrindt Date: Fri, 3 Jan 2025 12:07:59 +0100 Subject: [PATCH 6/6] update pipeline --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1abbc3ed..b35f1bd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,5 +23,6 @@ jobs: sudo chmod +x /usr/local/bin/docker-compose docker-compose --version - run: npm test + - run: npm run test:encrypt-decrypt