diff --git a/src/client.ts b/src/client.ts index 7d97449c0..ed40d1836 100644 --- a/src/client.ts +++ b/src/client.ts @@ -201,10 +201,32 @@ export default class Client extends API { // @ts-expect-error kChild symbol is for internal use only if ((opts.cloud != null) && opts[kChild] === undefined) { const { id } = opts.cloud + if (typeof id !== 'string') { + throw new errors.ConfigurationError('Cloud ID must be a string.') + } + + const parts = id.split(':') + if (parts.length !== 2 || parts[1] === '') { + throw new errors.ConfigurationError( + 'Cloud ID must be in the format "name:base64string".' + ) + } + // the cloud id is `cluster-name:base64encodedurl` // the url is a string divided by two '$', the first is the cloud url // the second the elasticsearch instance, the third the kibana instance - const cloudUrls = Buffer.from(id.split(':')[1], 'base64').toString().split('$') + + let cloudUrls + try { + cloudUrls = Buffer.from(parts[1], 'base64').toString().split('$') + } catch (err) { + throw new errors.ConfigurationError('Cloud ID base64 decoding failed.') + } + if (cloudUrls.length < 2 || cloudUrls[0] === '' || cloudUrls[1] === '') { + throw new errors.ConfigurationError( + 'Cloud ID base64 must contain at least two "$" separated parts: "$[$]".' + ) + } opts.node = `https://${cloudUrls[1]}.${cloudUrls[0]}` diff --git a/test/unit/client.test.ts b/test/unit/client.test.ts index 97cba4186..d7679a7fe 100644 --- a/test/unit/client.test.ts +++ b/test/unit/client.test.ts @@ -300,9 +300,25 @@ test('Elastic Cloud config', t => { t.equal(connection?.url.hostname, 'abcd.localhost') t.equal(connection?.url.protocol, 'https:') + t.test('Invalid Cloud ID will throw ConfigurationError', t => { + t.throws(() => new Client({ + cloud : { + id : 'invalidCloudIdThatIsNotBase64' + }, + auth : { + username: 'elastic', + password: 'changeme' + } + + }), errors.ConfigurationError) + t.end() + }) + t.end() }) + + test('Override default Elastic Cloud options', t => { const client = new Client({ cloud: {