From 83d31b94e27281f7eeebbe3827629bbaa70c004e Mon Sep 17 00:00:00 2001 From: Kushal <43465488+kushalshit27@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:31:01 +0530 Subject: [PATCH] fix: exporting SAML connections base64 encode the certificate (#1008) * Add Base64 encoding for SAML certificate options in connections * unit test added for encodeCertStringToBase64 --- src/context/directory/handlers/connections.ts | 13 ++++++++++++ src/context/yaml/handlers/connections.ts | 12 +++++++++++ src/utils.ts | 13 ++++++++++++ test/utils.test.js | 20 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/src/context/directory/handlers/connections.ts b/src/context/directory/handlers/connections.ts index f3e23ed8e..e53f24170 100644 --- a/src/context/directory/handlers/connections.ts +++ b/src/context/directory/handlers/connections.ts @@ -12,6 +12,7 @@ import { sanitize, ensureProp, mapClientID2NameSorted, + encodeCertStringToBase64, } from '../../../utils'; import { DirectoryHandler } from '.'; import DirectoryContext from '..'; @@ -88,6 +89,18 @@ async function dump(context: DirectoryContext): Promise { dumpedConnection.options.email.body = `./${connectionName}.html`; } + if (dumpedConnection.strategy === 'samlp' && dumpedConnection.options) { + if ('cert' in dumpedConnection.options) { + dumpedConnection.options.cert = encodeCertStringToBase64(dumpedConnection.options.cert); + } + + if ('signingCert' in dumpedConnection.options) { + dumpedConnection.options.signingCert = encodeCertStringToBase64( + dumpedConnection.options.signingCert + ); + } + } + const connectionFile = path.join(connectionsFolder, `${connectionName}.json`); dumpJSON(connectionFile, dumpedConnection); }); diff --git a/src/context/yaml/handlers/connections.ts b/src/context/yaml/handlers/connections.ts index 31abab412..c9dc30061 100644 --- a/src/context/yaml/handlers/connections.ts +++ b/src/context/yaml/handlers/connections.ts @@ -9,6 +9,7 @@ import { ensureProp, convertClientIdToName, mapClientID2NameSorted, + encodeCertStringToBase64, } from '../../../utils'; import { YAMLHandler } from '.'; import YAMLContext from '..'; @@ -90,6 +91,17 @@ async function dump(context: YAMLContext): Promise { dumpedConnection.options.email.body = `./${connectionName}.html`; } + if (dumpedConnection.strategy === 'samlp' && dumpedConnection.options) { + if ('cert' in dumpedConnection.options) { + dumpedConnection.options.cert = encodeCertStringToBase64(dumpedConnection.options.cert); + } + + if ('signingCert' in dumpedConnection.options) { + dumpedConnection.options.signingCert = encodeCertStringToBase64( + dumpedConnection.options.signingCert + ); + } + } return dumpedConnection; }), }; diff --git a/src/utils.ts b/src/utils.ts index fe68e1cf5..737baa09c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -259,3 +259,16 @@ export const findKeyPathWithValue = (obj: any, findKey: string, parentPath: stri return results; }; + +/** + * Encodes a certificate string to Base64 format if it starts with '-----BEGIN CERTIFICATE-----'. + * + * @param cert - The certificate string to be encoded. + * @returns The Base64 encoded certificate string if the input starts with '-----BEGIN CERTIFICATE-----', otherwise returns the original string. + */ +export const encodeCertStringToBase64 = (cert: string) => { + if (cert?.startsWith('-----BEGIN CERTIFICATE-----')) { + return Buffer.from(cert).toString('base64'); + } + return cert; +}; diff --git a/test/utils.test.js b/test/utils.test.js index ef3e6d605..a46b23878 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -19,6 +19,7 @@ import { sanitize, stripIdentifiers, toConfigFn, + encodeCertStringToBase64, } from '../src/utils'; const mockConfigFn = () => {}; @@ -269,4 +270,23 @@ describe('#utils', function () { expect(mapClientID2NameSorted(null, null)).deep.equal([]); }); }); + + describe('encodeCertStringToBase64', () => { + it('should encode certificate string to Base64', () => { + const cert = + '-----BEGIN CERTIFICATE-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7\n-----END CERTIFICATE-----'; + const expectedBase64 = Buffer.from(cert).toString('base64'); + expect(encodeCertStringToBase64(cert)).to.equal(expectedBase64); + }); + + it('should return the original string if it does not start with "-----BEGIN CERTIFICATE-----"', () => { + const nonCertString = 'This is not a certificate'; + expect(encodeCertStringToBase64(nonCertString)).to.equal(nonCertString); + }); + + it('should return the original string if it is null or undefined', () => { + expect(encodeCertStringToBase64(null)).to.equal(null); + expect(encodeCertStringToBase64(undefined)).to.equal(undefined); + }); + }); });