Skip to content

Commit 4e88199

Browse files
committed
add aws4 as dev dependency and verify our code generates the same signatures
1 parent 178b90a commit 4e88199

4 files changed

Lines changed: 37 additions & 17 deletions

File tree

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
},
2727
"dependencies": {
2828
"@mongodb-js/saslprep": "^1.3.0",
29+
"aws4": "^1.13.2",
2930
"bson": "^7.0.0",
3031
"mongodb-connection-string-url": "^7.0.0"
3132
},

src/cmap/auth/aws4.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ export async function aws4Sign(
138138
'x-mongodb-gs2-cb-flag': convertHeaderValue(options.headers['X-MongoDB-GS2-CB-Flag']),
139139
'x-mongodb-server-nonce': convertHeaderValue(options.headers['X-MongoDB-Server-Nonce'])
140140
});
141+
// If session token is provided, include it in the headers
142+
if ('sessionToken' in credentials && credentials.sessionToken) {
143+
headers.append('x-amz-security-token', convertHeaderValue(credentials.sessionToken));
144+
}
141145

142146
// Canonical headers are lowercased and sorted.
143147
const canonicalHeaders = Array.from(headers.entries())

test/unit/aws4.test.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import * as aws4sign from 'aws4';
12
import { expect } from 'chai';
3+
import * as sinon from 'sinon';
24

35
import { aws4Sign, type AwsSigv4Options } from '../../src/cmap/auth/aws4';
46

@@ -31,43 +33,49 @@ describe('Verify AWS4 signature generation', () => {
3133
date
3234
};
3335

36+
beforeEach(() => {
37+
sinon.stub(aws4sign.RequestSigner.prototype, 'getDateTime').returns('20251215T123456Z');
38+
});
39+
40+
afterEach(() => {
41+
sinon.restore();
42+
});
43+
3444
it('should generate correct credentials for permanent credentials', async () => {
3545
const headers = await aws4Sign(request, awsCredentials);
3646

47+
// Verify generated headers
3748
expect(headers['X-Amz-Date']).to.exist;
3849
expect(headers['X-Amz-Date']).to.equal('20251215T123456Z');
3950
expect(headers['Authorization']).to.exist;
4051
expect(headers['Authorization']).to.equal(
4152
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20251215/us-east-1/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-mongodb-gs2-cb-flag;x-mongodb-server-nonce, Signature=48a66f9fc76829002a7a7ac5b92e4089395d9b88ea7d417ab146949b90eeab08'
4253
);
4354

44-
// Uncomment the following lines if you want to compare with the old aws4 library.
45-
// Remember to import aws4 at the top of the file, like this: import * as aws4sign from 'aws4';
46-
47-
// const oldSigned = aws4sign.sign(request, awsCredentials);
48-
// expect(oldSigned.headers['X-Amz-Date']).to.exist;
49-
// expect(oldSigned.headers['X-Amz-Date']).to.equal(signed.headers['X-Amz-Date']);
50-
// expect(oldSigned.headers['Authorization']).to.exist;
51-
// expect(oldSigned.headers['Authorization']).to.equal(signed.headers['Authorization']);
55+
// Verify against aws4 library
56+
const oldSigned = aws4sign.sign(request, awsCredentials);
57+
expect(oldSigned.headers['X-Amz-Date']).to.exist;
58+
expect(oldSigned.headers['X-Amz-Date']).to.equal(headers['X-Amz-Date']);
59+
expect(oldSigned.headers['Authorization']).to.exist;
60+
expect(oldSigned.headers['Authorization']).to.equal(headers['Authorization']);
5261
});
5362

5463
it('should generate correct credentials for session credentials', async () => {
5564
const headers = await aws4Sign(request, awsSessionCredentials);
5665

66+
// Verify generated headers
5767
expect(headers['X-Amz-Date']).to.exist;
5868
expect(headers['X-Amz-Date']).to.equal('20251215T123456Z');
5969
expect(headers['Authorization']).to.exist;
6070
expect(headers['Authorization']).to.equal(
61-
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20251215/us-east-1/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-mongodb-gs2-cb-flag;x-mongodb-server-nonce, Signature=7bfe0c6c8c0aa9f853eb10c5822ab42446ad87789e5b6e47a6fbd7a9bffc834a'
71+
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20251215/us-east-1/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-mongodb-gs2-cb-flag;x-mongodb-server-nonce, Signature=bbcb06e2feb8651dced329789743ba283f92ef1302d34a7398cb1d35808a1a66'
6272
);
6373

64-
// Uncomment the following lines if you want to compare with the old aws4 library.
65-
// Remember to import aws4 at the top of the file, like this: import * as aws4sign from 'aws4';
66-
67-
// const oldSigned = aws4sign.sign(request, awsSessionCredentials);
68-
// expect(oldSigned.headers['X-Amz-Date']).to.exist;
69-
// expect(oldSigned.headers['X-Amz-Date']).to.equal(signed.headers['X-Amz-Date']);
70-
// expect(oldSigned.headers['Authorization']).to.exist;
71-
// expect(oldSigned.headers['Authorization']).to.equal(signed.headers['Authorization']);
74+
// Verify against aws4 library
75+
const oldSigned = aws4sign.sign(request, awsSessionCredentials);
76+
expect(oldSigned.headers['X-Amz-Date']).to.exist;
77+
expect(oldSigned.headers['X-Amz-Date']).to.equal(headers['X-Amz-Date']);
78+
expect(oldSigned.headers['Authorization']).to.exist;
79+
expect(oldSigned.headers['Authorization']).to.equal(headers['Authorization']);
7280
});
7381
});

0 commit comments

Comments
 (0)