diff --git a/CHANGELOG.md b/CHANGELOG.md index 5afad1585..ff56302c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] ### Added - Add release details to releasing.md ([319](https://github.com/opensearch-project/opensearch-js/pull/319)) +- Allow overriding the aws service identifier in AwsSigv4Signer ([333](https://github.com/opensearch-project/opensearch-js/pull/333)) ### Dependencies ### Changed ### Deprecated diff --git a/lib/aws/AwsSigv4Signer.js b/lib/aws/AwsSigv4Signer.js index d3253e139..4e1e74d43 100644 --- a/lib/aws/AwsSigv4Signer.js +++ b/lib/aws/AwsSigv4Signer.js @@ -58,19 +58,22 @@ const awsDefaultCredentialsProvider = () => }); }); -function AwsSigv4Signer(opts) { +function AwsSigv4Signer(opts = {}) { const credentialsState = { credentials: null, }; - if (opts && (!opts.region || opts.region === null || opts.region === '')) { + if (!opts.region) { throw new AwsSigv4SignerError('Region cannot be empty'); } - if (opts && typeof opts.getCredentials !== 'function') { + if (!opts.service) { + opts.service = 'es'; + } + if (typeof opts.getCredentials !== 'function') { opts.getCredentials = awsDefaultCredentialsProvider; } function buildSignedRequestObject(request = {}) { - request.service = 'es'; + request.service = opts.service; request.region = opts.region; request.headers = request.headers || {}; request.headers['host'] = request.hostname; diff --git a/test/unit/lib/aws/awssigv4signer.test.js b/test/unit/lib/aws/awssigv4signer.test.js index f1dfc084f..b15fb51b7 100644 --- a/test/unit/lib/aws/awssigv4signer.test.js +++ b/test/unit/lib/aws/awssigv4signer.test.js @@ -16,7 +16,7 @@ const { Connection } = require('../../../../index'); const { Client, buildServer } = require('../../../utils'); test('Sign with SigV4', (t) => { - t.plan(2); + t.plan(3); const mockCreds = { accessKeyId: uuidv4(), @@ -50,30 +50,70 @@ test('Sign with SigV4', (t) => { const signedRequest = auth.buildSignedRequestObject(request); t.hasProp(signedRequest.headers, 'X-Amz-Date'); t.hasProp(signedRequest.headers, 'Authorization'); + t.same(signedRequest.service, 'es'); }); test('Sign with SigV4 failure (with empty region)', (t) => { - t.plan(2); + const mockCreds = { + accessKeyId: uuidv4(), + secretAccessKey: uuidv4(), + }; + + const mockRegions = [{ region: undefined }, { region: null }, { region: '' }, {}]; + + const AwsSigv4SignerOptions = { + getCredentials: () => + new Promise((resolve) => { + setTimeout(() => resolve(mockCreds), 100); + }), + }; + + mockRegions.forEach((region) => { + try { + AwsSigv4Signer(Object.assign({}, AwsSigv4SignerOptions, region)); + t.fail('Should fail'); + } catch (err) { + t.ok(err instanceof AwsSigv4SignerError); + t.same(err.message, 'Region cannot be empty'); + } + }); + + t.end(); +}); + +test('Sign with SigV4 and provided service', (t) => { + t.plan(1); const mockCreds = { accessKeyId: uuidv4(), secretAccessKey: uuidv4(), }; + const mockRegion = 'us-west-2'; + const mockService = 'foo'; + const AwsSigv4SignerOptions = { getCredentials: () => new Promise((resolve) => { setTimeout(() => resolve(mockCreds), 100); }), + region: mockRegion, + service: mockService, }; - try { - AwsSigv4Signer(AwsSigv4SignerOptions); - t.fail('Should fail'); - } catch (err) { - t.ok(err instanceof AwsSigv4SignerError); - t.same(err.message, 'Region cannot be empty'); - } + const auth = AwsSigv4Signer(AwsSigv4SignerOptions); + + const connection = new Connection({ + url: new URL('https://localhost:9200'), + }); + + const request = connection.buildRequestObject({ + path: '/hello', + method: 'GET', + }); + + const signedRequest = auth.buildSignedRequestObject(request); + t.same(signedRequest.service, mockService); }); test('Sign with SigV4 using default getCredentials provider', (t) => {