Skip to content

Commit 062be3d

Browse files
authored
Merge pull request #7282 from BitGo/feat/ANT-1025/hmac-enhancements
feat(sdk-hmac): normalize HTTP methods and updated calculateHMAC types
2 parents fe3cfaf + 3068f37 commit 062be3d

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

commitlint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module.exports = {
6565
'COIN-',
6666
'FIAT-',
6767
'ME-',
68+
'ANT-',
6869
'#', // Prefix used by GitHub issues
6970
],
7071
},

modules/sdk-hmac/src/hmac.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createHmac } from 'crypto';
1+
import { type BinaryLike, createHmac, type KeyObject } from 'crypto';
22
import * as urlLib from 'url';
33
import * as sjcl from '@bitgo/sjcl';
44
import {
@@ -16,7 +16,7 @@ import {
1616
* @param message {String} - the actual message to HMAC
1717
* @returns {*} - the result of the HMAC operation
1818
*/
19-
export function calculateHMAC(key: string, message: string): string {
19+
export function calculateHMAC(key: string | BinaryLike | KeyObject, message: string | BinaryLike): string {
2020
return createHmac('sha256', key).update(message).digest('hex');
2121
}
2222

@@ -37,6 +37,10 @@ export function calculateHMACSubject({
3737
method,
3838
authVersion,
3939
}: CalculateHmacSubjectOptions): string {
40+
/* Normalize legacy 'del' to 'delete' for backward compatibility */
41+
if (method === 'del') {
42+
method = 'delete';
43+
}
4044
const urlDetails = urlLib.parse(urlPath);
4145
const queryPath = urlDetails.query && urlDetails.query.length > 0 ? urlDetails.path : urlDetails.pathname;
4246
if (statusCode !== undefined && isFinite(statusCode) && Number.isInteger(statusCode)) {

modules/sdk-hmac/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const supportedRequestMethods = ['get', 'post', 'put', 'del', 'patch', 'options'] as const;
1+
export const supportedRequestMethods = ['get', 'post', 'put', 'del', 'patch', 'options', 'delete'] as const;
22

33
export type AuthVersion = 2 | 3;
44

modules/sdk-hmac/test/hmac.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
verifyResponse,
99
} from '../src/hmac';
1010
import * as sjcl from '@bitgo/sjcl';
11+
import { createSecretKey } from 'crypto';
1112

1213
// Mock Date.now for consistent timestamp values
1314
const MOCK_TIMESTAMP = 1672531200000; // Example timestamp (e.g., Jan 1, 2023, 00:00:00 UTC)
@@ -30,6 +31,20 @@ describe('HMAC Utility Functions', () => {
3031
const expectedHmac = 'f8c2bb87c17608c9038eab4e92ef2775e42629c939d6fd3390d42f80af6bb712';
3132
expect(calculateHMAC(key, message)).to.equal(expectedHmac);
3233
});
34+
35+
it('should accept a Buffer key (BinaryLike) and match the string result', () => {
36+
const keyBuffer = Buffer.from('test-key', 'utf8');
37+
const message = Buffer.from('test-message');
38+
const expectedHmac = 'f8c2bb87c17608c9038eab4e92ef2775e42629c939d6fd3390d42f80af6bb712';
39+
expect(calculateHMAC(keyBuffer, message)).to.equal(expectedHmac);
40+
});
41+
42+
it('should accept a KeyObject key and match the string result', () => {
43+
const keyObject = createSecretKey(Buffer.from('test-key', 'utf8'));
44+
const message = 'test-message';
45+
const expectedHmac = 'f8c2bb87c17608c9038eab4e92ef2775e42629c939d6fd3390d42f80af6bb712';
46+
expect(calculateHMAC(keyObject, message)).to.equal(expectedHmac);
47+
});
3348
});
3449

3550
describe('calculateHMACSubject', () => {

0 commit comments

Comments
 (0)