@bitgo-beta/sdk-hmac 1.0.1-beta.13 → 1.0.1-beta.1300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/browser.d.ts +4 -0
- package/dist/src/browser.d.ts.map +1 -0
- package/dist/src/browser.js +20 -0
- package/dist/src/defaultStrategy.d.ts +11 -0
- package/dist/src/defaultStrategy.d.ts.map +1 -0
- package/dist/src/defaultStrategy.js +21 -0
- package/dist/src/hmac.d.ts +9 -6
- package/dist/src/hmac.d.ts.map +1 -1
- package/dist/src/hmac.js +41 -22
- package/dist/src/hmacv4.d.ts +185 -0
- package/dist/src/hmacv4.d.ts.map +1 -0
- package/dist/src/hmacv4.js +274 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/indexedDbTokenStore.d.ts +12 -0
- package/dist/src/indexedDbTokenStore.d.ts.map +1 -0
- package/dist/src/indexedDbTokenStore.js +79 -0
- package/dist/src/types.d.ts +115 -11
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +2 -2
- package/dist/src/util.d.ts +49 -0
- package/dist/src/util.d.ts.map +1 -0
- package/dist/src/util.js +85 -0
- package/dist/src/webCryptoStrategy.d.ts +75 -0
- package/dist/src/webCryptoStrategy.d.ts.map +1 -0
- package/dist/src/webCryptoStrategy.js +189 -0
- package/package.json +21 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./index"), exports);
|
|
18
|
+
__exportStar(require("./indexedDbTokenStore"), exports);
|
|
19
|
+
__exportStar(require("./webCryptoStrategy"), exports);
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9icm93c2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQ0FBd0I7QUFDeEIsd0RBQXNDO0FBQ3RDLHNEQUFvQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuZXhwb3J0ICogZnJvbSAnLi9pbmRleGVkRGJUb2tlblN0b3JlJztcbmV4cG9ydCAqIGZyb20gJy4vd2ViQ3J5cHRvU3RyYXRlZ3knO1xuIl19
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IHmacAuthStrategy, CalculateRequestHeadersOptions, RequestHeaders, VerifyResponseOptions, VerifyResponseInfo } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Default HMAC auth strategy that wraps the existing synchronous Node.js crypto
|
|
4
|
+
* functions. This is used when no custom strategy is provided to BitGoAPI.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DefaultHmacAuthStrategy implements IHmacAuthStrategy {
|
|
7
|
+
calculateRequestHeaders(params: CalculateRequestHeadersOptions): Promise<RequestHeaders>;
|
|
8
|
+
verifyResponse(params: VerifyResponseOptions): Promise<VerifyResponseInfo>;
|
|
9
|
+
calculateHMAC(key: string, message: string): Promise<string>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=defaultStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultStrategy.d.ts","sourceRoot":"","sources":["../../src/defaultStrategy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,8BAA8B,EAC9B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IACzD,uBAAuB,CAAC,MAAM,EAAE,8BAA8B,GAAG,OAAO,CAAC,cAAc,CAAC;IAIxF,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI1E,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGnE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultHmacAuthStrategy = void 0;
|
|
4
|
+
const hmac_1 = require("./hmac");
|
|
5
|
+
/**
|
|
6
|
+
* Default HMAC auth strategy that wraps the existing synchronous Node.js crypto
|
|
7
|
+
* functions. This is used when no custom strategy is provided to BitGoAPI.
|
|
8
|
+
*/
|
|
9
|
+
class DefaultHmacAuthStrategy {
|
|
10
|
+
async calculateRequestHeaders(params) {
|
|
11
|
+
return (0, hmac_1.calculateRequestHeaders)(params);
|
|
12
|
+
}
|
|
13
|
+
async verifyResponse(params) {
|
|
14
|
+
return (0, hmac_1.verifyResponse)(params);
|
|
15
|
+
}
|
|
16
|
+
async calculateHMAC(key, message) {
|
|
17
|
+
return (0, hmac_1.calculateHMAC)(key, message);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.DefaultHmacAuthStrategy = DefaultHmacAuthStrategy;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdFN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RlZmF1bHRTdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpQ0FBZ0Y7QUFTaEY7OztHQUdHO0FBQ0gsTUFBYSx1QkFBdUI7SUFDbEMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLE1BQXNDO1FBQ2xFLE9BQU8sSUFBQSw4QkFBdUIsRUFBQyxNQUFNLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUE2QjtRQUNoRCxPQUFPLElBQUEscUJBQWMsRUFBQyxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxHQUFXLEVBQUUsT0FBZTtRQUM5QyxPQUFPLElBQUEsb0JBQWEsRUFBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBWkQsMERBWUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjYWxjdWxhdGVSZXF1ZXN0SGVhZGVycywgY2FsY3VsYXRlSE1BQywgdmVyaWZ5UmVzcG9uc2UgfSBmcm9tICcuL2htYWMnO1xuaW1wb3J0IHR5cGUge1xuICBJSG1hY0F1dGhTdHJhdGVneSxcbiAgQ2FsY3VsYXRlUmVxdWVzdEhlYWRlcnNPcHRpb25zLFxuICBSZXF1ZXN0SGVhZGVycyxcbiAgVmVyaWZ5UmVzcG9uc2VPcHRpb25zLFxuICBWZXJpZnlSZXNwb25zZUluZm8sXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIERlZmF1bHQgSE1BQyBhdXRoIHN0cmF0ZWd5IHRoYXQgd3JhcHMgdGhlIGV4aXN0aW5nIHN5bmNocm9ub3VzIE5vZGUuanMgY3J5cHRvXG4gKiBmdW5jdGlvbnMuIFRoaXMgaXMgdXNlZCB3aGVuIG5vIGN1c3RvbSBzdHJhdGVneSBpcyBwcm92aWRlZCB0byBCaXRHb0FQSS5cbiAqL1xuZXhwb3J0IGNsYXNzIERlZmF1bHRIbWFjQXV0aFN0cmF0ZWd5IGltcGxlbWVudHMgSUhtYWNBdXRoU3RyYXRlZ3kge1xuICBhc3luYyBjYWxjdWxhdGVSZXF1ZXN0SGVhZGVycyhwYXJhbXM6IENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzT3B0aW9ucyk6IFByb21pc2U8UmVxdWVzdEhlYWRlcnM+IHtcbiAgICByZXR1cm4gY2FsY3VsYXRlUmVxdWVzdEhlYWRlcnMocGFyYW1zKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVJlc3BvbnNlKHBhcmFtczogVmVyaWZ5UmVzcG9uc2VPcHRpb25zKTogUHJvbWlzZTxWZXJpZnlSZXNwb25zZUluZm8+IHtcbiAgICByZXR1cm4gdmVyaWZ5UmVzcG9uc2UocGFyYW1zKTtcbiAgfVxuXG4gIGFzeW5jIGNhbGN1bGF0ZUhNQUMoa2V5OiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUhNQUMoa2V5LCBtZXNzYWdlKTtcbiAgfVxufVxuIl19
|
package/dist/src/hmac.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type BinaryLike, type KeyObject } from 'crypto';
|
|
1
2
|
import { CalculateHmacSubjectOptions, CalculateRequestHeadersOptions, CalculateRequestHmacOptions, RequestHeaders, VerifyResponseInfo, VerifyResponseOptions } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Calculate the HMAC for the given key and message
|
|
@@ -5,7 +6,7 @@ import { CalculateHmacSubjectOptions, CalculateRequestHeadersOptions, CalculateR
|
|
|
5
6
|
* @param message {String} - the actual message to HMAC
|
|
6
7
|
* @returns {*} - the result of the HMAC operation
|
|
7
8
|
*/
|
|
8
|
-
export declare function calculateHMAC(key: string, message: string): string;
|
|
9
|
+
export declare function calculateHMAC(key: string | BinaryLike | KeyObject, message: string | BinaryLike): string;
|
|
9
10
|
/**
|
|
10
11
|
* Calculate the subject string that is to be HMAC'ed for a HTTP request or response
|
|
11
12
|
* @param urlPath request url, including query params
|
|
@@ -13,19 +14,21 @@ export declare function calculateHMAC(key: string, message: string): string;
|
|
|
13
14
|
* @param timestamp request timestamp from `Date.now()`
|
|
14
15
|
* @param statusCode Only set for HTTP responses, leave blank for requests
|
|
15
16
|
* @param method request method
|
|
16
|
-
* @
|
|
17
|
+
* @param authVersion authentication version (2 or 3)
|
|
18
|
+
* @param useOriginalPath whether to use the original urlPath without parsing (default false)
|
|
19
|
+
* @returns {string | Buffer}
|
|
17
20
|
*/
|
|
18
|
-
export declare function calculateHMACSubject({ urlPath, text, timestamp, statusCode, method, authVersion
|
|
21
|
+
export declare function calculateHMACSubject<T extends string | Buffer = string>({ urlPath, text, timestamp, statusCode, method, authVersion }: CalculateHmacSubjectOptions<T>, useOriginalPath?: boolean): T;
|
|
19
22
|
/**
|
|
20
23
|
* Calculate the HMAC for an HTTP request
|
|
21
24
|
*/
|
|
22
|
-
export declare function calculateRequestHMAC({ url: urlPath, text, timestamp, token, method, authVersion
|
|
25
|
+
export declare function calculateRequestHMAC<T extends string | Buffer = string>({ url: urlPath, text, timestamp, token, method, authVersion }: CalculateRequestHmacOptions<T>, useOriginalPath?: boolean): string;
|
|
23
26
|
/**
|
|
24
27
|
* Calculate request headers with HMAC
|
|
25
28
|
*/
|
|
26
|
-
export declare function calculateRequestHeaders({ url, text, token, method, authVersion
|
|
29
|
+
export declare function calculateRequestHeaders<T extends string | Buffer = string>({ url, text, token, method, authVersion }: CalculateRequestHeadersOptions<T>, useOriginalPath?: boolean): RequestHeaders;
|
|
27
30
|
/**
|
|
28
31
|
* Verify the HMAC for an HTTP response
|
|
29
32
|
*/
|
|
30
|
-
export declare function verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac, method, authVersion
|
|
33
|
+
export declare function verifyResponse<T extends string | Buffer = string>({ url: urlPath, statusCode, text, timestamp, token, hmac, method, authVersion }: VerifyResponseOptions<T>, useOriginalPath?: boolean): VerifyResponseInfo<T>;
|
|
31
34
|
//# sourceMappingURL=hmac.d.ts.map
|
package/dist/src/hmac.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../../src/hmac.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../../src/hmac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGzD,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAGjB;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAExG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACrE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,2BAA2B,CAAC,CAAC,CAAC,EAC7F,eAAe,UAAQ,GACtB,CAAC,CA8BH;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACrE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,2BAA2B,CAAC,CAAC,CAAC,EAC7F,eAAe,UAAQ,GACtB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACxE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,8BAA8B,CAAC,CAAC,CAAC,EAC5E,eAAe,UAAQ,GACtB,cAAc,CAYhB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAC/D,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC,EACzG,eAAe,UAAQ,GACtB,kBAAkB,CAAC,CAAC,CAAC,CA+BvB"}
|
package/dist/src/hmac.js
CHANGED
|
@@ -38,9 +38,9 @@ exports.calculateHMACSubject = calculateHMACSubject;
|
|
|
38
38
|
exports.calculateRequestHMAC = calculateRequestHMAC;
|
|
39
39
|
exports.calculateRequestHeaders = calculateRequestHeaders;
|
|
40
40
|
exports.verifyResponse = verifyResponse;
|
|
41
|
-
const crypto_1 = require("crypto");
|
|
42
41
|
const urlLib = __importStar(require("url"));
|
|
43
42
|
const sjcl = __importStar(require("@bitgo-beta/sjcl"));
|
|
43
|
+
const util_1 = require("./util");
|
|
44
44
|
/**
|
|
45
45
|
* Calculate the HMAC for the given key and message
|
|
46
46
|
* @param key {String} - the key to use for the HMAC
|
|
@@ -48,7 +48,7 @@ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
|
|
|
48
48
|
* @returns {*} - the result of the HMAC operation
|
|
49
49
|
*/
|
|
50
50
|
function calculateHMAC(key, message) {
|
|
51
|
-
return (0,
|
|
51
|
+
return (0, util_1.createHmacWithSha256)(key, message);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Calculate the subject string that is to be HMAC'ed for a HTTP request or response
|
|
@@ -57,36 +57,53 @@ function calculateHMAC(key, message) {
|
|
|
57
57
|
* @param timestamp request timestamp from `Date.now()`
|
|
58
58
|
* @param statusCode Only set for HTTP responses, leave blank for requests
|
|
59
59
|
* @param method request method
|
|
60
|
-
* @
|
|
60
|
+
* @param authVersion authentication version (2 or 3)
|
|
61
|
+
* @param useOriginalPath whether to use the original urlPath without parsing (default false)
|
|
62
|
+
* @returns {string | Buffer}
|
|
61
63
|
*/
|
|
62
|
-
function calculateHMACSubject({ urlPath, text, timestamp, statusCode, method, authVersion,
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
function calculateHMACSubject({ urlPath, text, timestamp, statusCode, method, authVersion }, useOriginalPath = false) {
|
|
65
|
+
/* Normalize legacy 'del' to 'delete' for backward compatibility */
|
|
66
|
+
if (method === 'del') {
|
|
67
|
+
method = 'delete';
|
|
68
|
+
}
|
|
69
|
+
let queryPath = urlPath;
|
|
70
|
+
if (!useOriginalPath) {
|
|
71
|
+
const urlDetails = urlLib.parse(urlPath);
|
|
72
|
+
queryPath = urlDetails.query && urlDetails.query.length > 0 ? urlDetails.path : urlDetails.pathname;
|
|
73
|
+
}
|
|
74
|
+
let prefixedText;
|
|
65
75
|
if (statusCode !== undefined && isFinite(statusCode) && Number.isInteger(statusCode)) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
prefixedText =
|
|
77
|
+
authVersion === 3
|
|
78
|
+
? [method.toUpperCase(), timestamp, queryPath, statusCode].join('|')
|
|
79
|
+
: [timestamp, queryPath, statusCode].join('|');
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
prefixedText =
|
|
83
|
+
authVersion === 3
|
|
84
|
+
? [method.toUpperCase(), timestamp, '3.0', queryPath].join('|')
|
|
85
|
+
: [timestamp, queryPath].join('|');
|
|
70
86
|
}
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
const isBuffer = Buffer.isBuffer(text);
|
|
88
|
+
if (isBuffer) {
|
|
89
|
+
return Buffer.concat([Buffer.from(prefixedText + '|', 'utf-8'), text]);
|
|
73
90
|
}
|
|
74
|
-
return [
|
|
91
|
+
return [prefixedText, text].join('|');
|
|
75
92
|
}
|
|
76
93
|
/**
|
|
77
94
|
* Calculate the HMAC for an HTTP request
|
|
78
95
|
*/
|
|
79
|
-
function calculateRequestHMAC({ url: urlPath, text, timestamp, token, method, authVersion,
|
|
80
|
-
const signatureSubject = calculateHMACSubject({ urlPath, text, timestamp, method, authVersion });
|
|
96
|
+
function calculateRequestHMAC({ url: urlPath, text, timestamp, token, method, authVersion }, useOriginalPath = false) {
|
|
97
|
+
const signatureSubject = calculateHMACSubject({ urlPath, text, timestamp, method, authVersion }, useOriginalPath);
|
|
81
98
|
// calculate the HMAC
|
|
82
99
|
return calculateHMAC(token, signatureSubject);
|
|
83
100
|
}
|
|
84
101
|
/**
|
|
85
102
|
* Calculate request headers with HMAC
|
|
86
103
|
*/
|
|
87
|
-
function calculateRequestHeaders({ url, text, token, method, authVersion,
|
|
104
|
+
function calculateRequestHeaders({ url, text, token, method, authVersion }, useOriginalPath = false) {
|
|
88
105
|
const timestamp = Date.now();
|
|
89
|
-
const hmac = calculateRequestHMAC({ url, text, timestamp, token, method, authVersion });
|
|
106
|
+
const hmac = calculateRequestHMAC({ url, text, timestamp, token, method, authVersion }, useOriginalPath);
|
|
90
107
|
// calculate the SHA256 hash of the token
|
|
91
108
|
const hashDigest = sjcl.hash.sha256.hash(token);
|
|
92
109
|
const tokenHash = sjcl.codec.hex.fromBits(hashDigest);
|
|
@@ -99,7 +116,7 @@ function calculateRequestHeaders({ url, text, token, method, authVersion, }) {
|
|
|
99
116
|
/**
|
|
100
117
|
* Verify the HMAC for an HTTP response
|
|
101
118
|
*/
|
|
102
|
-
function verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac, method, authVersion,
|
|
119
|
+
function verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac, method, authVersion }, useOriginalPath = false) {
|
|
103
120
|
const signatureSubject = calculateHMACSubject({
|
|
104
121
|
urlPath,
|
|
105
122
|
text,
|
|
@@ -107,12 +124,14 @@ function verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac
|
|
|
107
124
|
statusCode,
|
|
108
125
|
method,
|
|
109
126
|
authVersion,
|
|
110
|
-
});
|
|
127
|
+
}, useOriginalPath);
|
|
111
128
|
// calculate the HMAC
|
|
112
129
|
const expectedHmac = calculateHMAC(token, signatureSubject);
|
|
113
|
-
// determine if the response is still within the validity window (5 minute window)
|
|
130
|
+
// determine if the response is still within the validity window (5-minute backwards window, 1-minute forward window)
|
|
114
131
|
const now = Date.now();
|
|
115
|
-
const
|
|
132
|
+
const backwardValidityWindow = 1000 * 60 * 5;
|
|
133
|
+
const forwardValidityWindow = 1000 * 60;
|
|
134
|
+
const isInResponseValidityWindow = timestamp >= now - backwardValidityWindow && timestamp <= now + forwardValidityWindow;
|
|
116
135
|
// verify the HMAC and timestamp
|
|
117
136
|
return {
|
|
118
137
|
isValid: expectedHmac === hmac,
|
|
@@ -122,4 +141,4 @@ function verifyResponse({ url: urlPath, statusCode, text, timestamp, token, hmac
|
|
|
122
141
|
verificationTime: now,
|
|
123
142
|
};
|
|
124
143
|
}
|
|
125
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG1hYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9obWFjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLHNDQUVDO0FBV0Qsb0RBb0JDO0FBS0Qsb0RBWUM7QUFLRCwwREFrQkM7QUFLRCx3Q0FrQ0M7QUFsSUQsbUNBQW9DO0FBQ3BDLDRDQUE4QjtBQUM5Qix1REFBeUM7QUFVekM7Ozs7O0dBS0c7QUFDSCxTQUFnQixhQUFhLENBQUMsR0FBVyxFQUFFLE9BQWU7SUFDeEQsT0FBTyxJQUFBLG1CQUFVLEVBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQUMsRUFDbkMsT0FBTyxFQUNQLElBQUksRUFDSixTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFDTixXQUFXLEdBQ2lCO0lBQzVCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7SUFDMUcsSUFBSSxVQUFVLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDckYsSUFBSSxXQUFXLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEYsQ0FBQztRQUNELE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUNELElBQUksV0FBVyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFDRCxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQUMsRUFDbkMsR0FBRyxFQUFFLE9BQU8sRUFDWixJQUFJLEVBQ0osU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sV0FBVyxHQUNpQjtJQUM1QixNQUFNLGdCQUFnQixHQUFHLG9CQUFvQixDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFFakcscUJBQXFCO0lBQ3JCLE9BQU8sYUFBYSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLHVCQUF1QixDQUFDLEVBQ3RDLEdBQUcsRUFDSCxJQUFJLEVBQ0osS0FBSyxFQUNMLE1BQU0sRUFDTixXQUFXLEdBQ29CO0lBQy9CLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM3QixNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUV4Rix5Q0FBeUM7SUFDekMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RCxPQUFPO1FBQ0wsSUFBSTtRQUNKLFNBQVM7UUFDVCxTQUFTO0tBQ1YsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGNBQWMsQ0FBQyxFQUM3QixHQUFHLEVBQUUsT0FBTyxFQUNaLFVBQVUsRUFDVixJQUFJLEVBQ0osU0FBUyxFQUNULEtBQUssRUFDTCxJQUFJLEVBQ0osTUFBTSxFQUNOLFdBQVcsR0FDVztJQUN0QixNQUFNLGdCQUFnQixHQUFHLG9CQUFvQixDQUFDO1FBQzVDLE9BQU87UUFDUCxJQUFJO1FBQ0osU0FBUztRQUNULFVBQVU7UUFDVixNQUFNO1FBQ04sV0FBVztLQUNaLENBQUMsQ0FBQztJQUVILHFCQUFxQjtJQUNyQixNQUFNLFlBQVksR0FBRyxhQUFhLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFFNUQsa0ZBQWtGO0lBQ2xGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QixNQUFNLDBCQUEwQixHQUFHLFNBQVMsSUFBSSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksU0FBUyxJQUFJLEdBQUcsQ0FBQztJQUV4RixnQ0FBZ0M7SUFDaEMsT0FBTztRQUNMLE9BQU8sRUFBRSxZQUFZLEtBQUssSUFBSTtRQUM5QixZQUFZO1FBQ1osZ0JBQWdCO1FBQ2hCLDBCQUEwQjtRQUMxQixnQkFBZ0IsRUFBRSxHQUFHO0tBQ3RCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSG1hYyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyB1cmxMaWIgZnJvbSAndXJsJztcbmltcG9ydCAqIGFzIHNqY2wgZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5pbXBvcnQge1xuICBDYWxjdWxhdGVIbWFjU3ViamVjdE9wdGlvbnMsXG4gIENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzT3B0aW9ucyxcbiAgQ2FsY3VsYXRlUmVxdWVzdEhtYWNPcHRpb25zLFxuICBSZXF1ZXN0SGVhZGVycyxcbiAgVmVyaWZ5UmVzcG9uc2VJbmZvLFxuICBWZXJpZnlSZXNwb25zZU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgSE1BQyBmb3IgdGhlIGdpdmVuIGtleSBhbmQgbWVzc2FnZVxuICogQHBhcmFtIGtleSB7U3RyaW5nfSAtIHRoZSBrZXkgdG8gdXNlIGZvciB0aGUgSE1BQ1xuICogQHBhcmFtIG1lc3NhZ2Uge1N0cmluZ30gLSB0aGUgYWN0dWFsIG1lc3NhZ2UgdG8gSE1BQ1xuICogQHJldHVybnMgeyp9IC0gdGhlIHJlc3VsdCBvZiB0aGUgSE1BQyBvcGVyYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUhNQUMoa2V5OiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjcmVhdGVIbWFjKCdzaGEyNTYnLCBrZXkpLnVwZGF0ZShtZXNzYWdlKS5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgc3ViamVjdCBzdHJpbmcgdGhhdCBpcyB0byBiZSBITUFDJ2VkIGZvciBhIEhUVFAgcmVxdWVzdCBvciByZXNwb25zZVxuICogQHBhcmFtIHVybFBhdGggcmVxdWVzdCB1cmwsIGluY2x1ZGluZyBxdWVyeSBwYXJhbXNcbiAqIEBwYXJhbSB0ZXh0IHJlcXVlc3QgYm9keSB0ZXh0XG4gKiBAcGFyYW0gdGltZXN0YW1wIHJlcXVlc3QgdGltZXN0YW1wIGZyb20gYERhdGUubm93KClgXG4gKiBAcGFyYW0gc3RhdHVzQ29kZSBPbmx5IHNldCBmb3IgSFRUUCByZXNwb25zZXMsIGxlYXZlIGJsYW5rIGZvciByZXF1ZXN0c1xuICogQHBhcmFtIG1ldGhvZCByZXF1ZXN0IG1ldGhvZFxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUhNQUNTdWJqZWN0KHtcbiAgdXJsUGF0aCxcbiAgdGV4dCxcbiAgdGltZXN0YW1wLFxuICBzdGF0dXNDb2RlLFxuICBtZXRob2QsXG4gIGF1dGhWZXJzaW9uLFxufTogQ2FsY3VsYXRlSG1hY1N1YmplY3RPcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsRGV0YWlscyA9IHVybExpYi5wYXJzZSh1cmxQYXRoKTtcbiAgY29uc3QgcXVlcnlQYXRoID0gdXJsRGV0YWlscy5xdWVyeSAmJiB1cmxEZXRhaWxzLnF1ZXJ5Lmxlbmd0aCA+IDAgPyB1cmxEZXRhaWxzLnBhdGggOiB1cmxEZXRhaWxzLnBhdGhuYW1lO1xuICBpZiAoc3RhdHVzQ29kZSAhPT0gdW5kZWZpbmVkICYmIGlzRmluaXRlKHN0YXR1c0NvZGUpICYmIE51bWJlci5pc0ludGVnZXIoc3RhdHVzQ29kZSkpIHtcbiAgICBpZiAoYXV0aFZlcnNpb24gPT09IDMpIHtcbiAgICAgIHJldHVybiBbbWV0aG9kLnRvVXBwZXJDYXNlKCksIHRpbWVzdGFtcCwgcXVlcnlQYXRoLCBzdGF0dXNDb2RlLCB0ZXh0XS5qb2luKCd8Jyk7XG4gICAgfVxuICAgIHJldHVybiBbdGltZXN0YW1wLCBxdWVyeVBhdGgsIHN0YXR1c0NvZGUsIHRleHRdLmpvaW4oJ3wnKTtcbiAgfVxuICBpZiAoYXV0aFZlcnNpb24gPT09IDMpIHtcbiAgICByZXR1cm4gW21ldGhvZC50b1VwcGVyQ2FzZSgpLCB0aW1lc3RhbXAsICczLjAnLCBxdWVyeVBhdGgsIHRleHRdLmpvaW4oJ3wnKTtcbiAgfVxuICByZXR1cm4gW3RpbWVzdGFtcCwgcXVlcnlQYXRoLCB0ZXh0XS5qb2luKCd8Jyk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBITUFDIGZvciBhbiBIVFRQIHJlcXVlc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJlcXVlc3RITUFDKHtcbiAgdXJsOiB1cmxQYXRoLFxuICB0ZXh0LFxuICB0aW1lc3RhbXAsXG4gIHRva2VuLFxuICBtZXRob2QsXG4gIGF1dGhWZXJzaW9uLFxufTogQ2FsY3VsYXRlUmVxdWVzdEhtYWNPcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3Qgc2lnbmF0dXJlU3ViamVjdCA9IGNhbGN1bGF0ZUhNQUNTdWJqZWN0KHsgdXJsUGF0aCwgdGV4dCwgdGltZXN0YW1wLCBtZXRob2QsIGF1dGhWZXJzaW9uIH0pO1xuXG4gIC8vIGNhbGN1bGF0ZSB0aGUgSE1BQ1xuICByZXR1cm4gY2FsY3VsYXRlSE1BQyh0b2tlbiwgc2lnbmF0dXJlU3ViamVjdCk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHJlcXVlc3QgaGVhZGVycyB3aXRoIEhNQUNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzKHtcbiAgdXJsLFxuICB0ZXh0LFxuICB0b2tlbixcbiAgbWV0aG9kLFxuICBhdXRoVmVyc2lvbixcbn06IENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzT3B0aW9ucyk6IFJlcXVlc3RIZWFkZXJzIHtcbiAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgaG1hYyA9IGNhbGN1bGF0ZVJlcXVlc3RITUFDKHsgdXJsLCB0ZXh0LCB0aW1lc3RhbXAsIHRva2VuLCBtZXRob2QsIGF1dGhWZXJzaW9uIH0pO1xuXG4gIC8vIGNhbGN1bGF0ZSB0aGUgU0hBMjU2IGhhc2ggb2YgdGhlIHRva2VuXG4gIGNvbnN0IGhhc2hEaWdlc3QgPSBzamNsLmhhc2guc2hhMjU2Lmhhc2godG9rZW4pO1xuICBjb25zdCB0b2tlbkhhc2ggPSBzamNsLmNvZGVjLmhleC5mcm9tQml0cyhoYXNoRGlnZXN0KTtcbiAgcmV0dXJuIHtcbiAgICBobWFjLFxuICAgIHRpbWVzdGFtcCxcbiAgICB0b2tlbkhhc2gsXG4gIH07XG59XG5cbi8qKlxuICogVmVyaWZ5IHRoZSBITUFDIGZvciBhbiBIVFRQIHJlc3BvbnNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlSZXNwb25zZSh7XG4gIHVybDogdXJsUGF0aCxcbiAgc3RhdHVzQ29kZSxcbiAgdGV4dCxcbiAgdGltZXN0YW1wLFxuICB0b2tlbixcbiAgaG1hYyxcbiAgbWV0aG9kLFxuICBhdXRoVmVyc2lvbixcbn06IFZlcmlmeVJlc3BvbnNlT3B0aW9ucyk6IFZlcmlmeVJlc3BvbnNlSW5mbyB7XG4gIGNvbnN0IHNpZ25hdHVyZVN1YmplY3QgPSBjYWxjdWxhdGVITUFDU3ViamVjdCh7XG4gICAgdXJsUGF0aCxcbiAgICB0ZXh0LFxuICAgIHRpbWVzdGFtcCxcbiAgICBzdGF0dXNDb2RlLFxuICAgIG1ldGhvZCxcbiAgICBhdXRoVmVyc2lvbixcbiAgfSk7XG5cbiAgLy8gY2FsY3VsYXRlIHRoZSBITUFDXG4gIGNvbnN0IGV4cGVjdGVkSG1hYyA9IGNhbGN1bGF0ZUhNQUModG9rZW4sIHNpZ25hdHVyZVN1YmplY3QpO1xuXG4gIC8vIGRldGVybWluZSBpZiB0aGUgcmVzcG9uc2UgaXMgc3RpbGwgd2l0aGluIHRoZSB2YWxpZGl0eSB3aW5kb3cgKDUgbWludXRlIHdpbmRvdylcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3cgPSB0aW1lc3RhbXAgPj0gbm93IC0gMTAwMCAqIDYwICogNSAmJiB0aW1lc3RhbXAgPD0gbm93O1xuXG4gIC8vIHZlcmlmeSB0aGUgSE1BQyBhbmQgdGltZXN0YW1wXG4gIHJldHVybiB7XG4gICAgaXNWYWxpZDogZXhwZWN0ZWRIbWFjID09PSBobWFjLFxuICAgIGV4cGVjdGVkSG1hYyxcbiAgICBzaWduYXR1cmVTdWJqZWN0LFxuICAgIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93LFxuICAgIHZlcmlmaWNhdGlvblRpbWU6IG5vdyxcbiAgfTtcbn1cbiJdfQ==
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG1hYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9obWFjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbUJBLHNDQUVDO0FBYUQsb0RBaUNDO0FBS0Qsb0RBUUM7QUFLRCwwREFlQztBQUtELHdDQWtDQztBQTFJRCw0Q0FBOEI7QUFDOUIsdURBQXlDO0FBU3pDLGlDQUE4QztBQUU5Qzs7Ozs7R0FLRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxHQUFvQyxFQUFFLE9BQTRCO0lBQzlGLE9BQU8sSUFBQSwyQkFBb0IsRUFBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FDbEMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBa0MsRUFDN0YsZUFBZSxHQUFHLEtBQUs7SUFFdkIsbUVBQW1FO0lBQ25FLElBQUksTUFBTSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQ3JCLE1BQU0sR0FBRyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUVELElBQUksU0FBUyxHQUFrQixPQUFPLENBQUM7SUFDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO0lBQ3RHLENBQUM7SUFFRCxJQUFJLFlBQW9CLENBQUM7SUFDekIsSUFBSSxVQUFVLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENB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SixTQUFTO1FBQ1QsVUFBVTtRQUNWLE1BQU07UUFDTixXQUFXO0tBQ1osRUFDRCxlQUFlLENBQ2hCLENBQUM7SUFFRixxQkFBcUI7SUFDckIsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBRTVELHFIQUFxSDtJQUNySCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDdkIsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM3QyxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7SUFDeEMsTUFBTSwwQkFBMEIsR0FDOUIsU0FBUyxJQUFJLEdBQUcsR0FBRyxzQkFBc0IsSUFBSSxTQUFTLElBQUksR0FBRyxHQUFHLHFCQUFxQixDQUFDO0lBRXhGLGdDQUFnQztJQUNoQyxPQUFPO1FBQ0wsT0FBTyxFQUFFLFlBQVksS0FBSyxJQUFJO1FBQzlCLFlBQVk7UUFDWixnQkFBZ0I7UUFDaEIsMEJBQTBCO1FBQzFCLGdCQUFnQixFQUFFLEdBQUc7S0FDdEIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIEJpbmFyeUxpa2UsIHR5cGUgS2V5T2JqZWN0IH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIHVybExpYiBmcm9tICd1cmwnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCB7XG4gIENhbGN1bGF0ZUhtYWNTdWJqZWN0T3B0aW9ucyxcbiAgQ2FsY3VsYXRlUmVxdWVzdEhlYWRlcnNPcHRpb25zLFxuICBDYWxjdWxhdGVSZXF1ZXN0SG1hY09wdGlvbnMsXG4gIFJlcXVlc3RIZWFkZXJzLFxuICBWZXJpZnlSZXNwb25zZUluZm8sXG4gIFZlcmlmeVJlc3BvbnNlT3B0aW9ucyxcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVIbWFjV2l0aFNoYTI1NiB9IGZyb20gJy4vdXRpbCc7XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBITUFDIGZvciB0aGUgZ2l2ZW4ga2V5IGFuZCBtZXNzYWdlXG4gKiBAcGFyYW0ga2V5IHtTdHJpbmd9IC0gdGhlIGtleSB0byB1c2UgZm9yIHRoZSBITUFDXG4gKiBAcGFyYW0gbWVzc2FnZSB7U3RyaW5nfSAtIHRoZSBhY3R1YWwgbWVzc2FnZSB0byBITUFDXG4gKiBAcmV0dXJucyB7Kn0gLSB0aGUgcmVzdWx0IG9mIHRoZSBITUFDIG9wZXJhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlSE1BQyhrZXk6IHN0cmluZyB8IEJpbmFyeUxpa2UgfCBLZXlPYmplY3QsIG1lc3NhZ2U6IHN0cmluZyB8IEJpbmFyeUxpa2UpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSG1hY1dpdGhTaGEyNTYoa2V5LCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHN1YmplY3Qgc3RyaW5nIHRoYXQgaXMgdG8gYmUgSE1BQydlZCBmb3IgYSBIVFRQIHJlcXVlc3Qgb3IgcmVzcG9uc2VcbiAqIEBwYXJhbSB1cmxQYXRoIHJlcXVlc3QgdXJsLCBpbmNsdWRpbmcgcXVlcnkgcGFyYW1zXG4gKiBAcGFyYW0gdGV4dCByZXF1ZXN0IGJvZHkgdGV4dFxuICogQHBhcmFtIHRpbWVzdGFtcCByZXF1ZXN0IHRpbWVzdGFtcCBmcm9tIGBEYXRlLm5vdygpYFxuICogQHBhcmFtIHN0YXR1c0NvZGUgT25seSBzZXQgZm9yIEhUVFAgcmVzcG9uc2VzLCBsZWF2ZSBibGFuayBmb3IgcmVxdWVzdHNcbiAqIEBwYXJhbSBtZXRob2QgcmVxdWVzdCBtZXRob2RcbiAqIEBwYXJhbSBhdXRoVmVyc2lvbiBhdXRoZW50aWNhdGlvbiB2ZXJzaW9uICgyIG9yIDMpXG4gKiBAcGFyYW0gdXNlT3JpZ2luYWxQYXRoIHdoZXRoZXIgdG8gdXNlIHRoZSBvcmlnaW5hbCB1cmxQYXRoIHdpdGhvdXQgcGFyc2luZyAoZGVmYXVsdCBmYWxzZSlcbiAqIEByZXR1cm5zIHtzdHJpbmcgfCBCdWZmZXJ9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVITUFDU3ViamVjdDxUIGV4dGVuZHMgc3RyaW5nIHwgQnVmZmVyID0gc3RyaW5nPihcbiAgeyB1cmxQYXRoLCB0ZXh0LCB0aW1lc3RhbXAsIHN0YXR1c0NvZGUsIG1ldGhvZCwgYXV0aFZlcnNpb24gfTogQ2FsY3VsYXRlSG1hY1N1YmplY3RPcHRpb25zPFQ+LFxuICB1c2VPcmlnaW5hbFBhdGggPSBmYWxzZVxuKTogVCB7XG4gIC8qIE5vcm1hbGl6ZSBsZWdhY3kgJ2RlbCcgdG8gJ2RlbGV0ZScgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgKi9cbiAgaWYgKG1ldGhvZCA9PT0gJ2RlbCcpIHtcbiAgICBtZXRob2QgPSAnZGVsZXRlJztcbiAgfVxuXG4gIGxldCBxdWVyeVBhdGg6IHN0cmluZyB8IG51bGwgPSB1cmxQYXRoO1xuICBpZiAoIXVzZU9yaWdpbmFsUGF0aCkge1xuICAgIGNvbnN0IHVybERldGFpbHMgPSB1cmxMaWIucGFyc2UodXJsUGF0aCk7XG4gICAgcXVlcnlQYXRoID0gdXJsRGV0YWlscy5xdWVyeSAmJiB1cmxEZXRhaWxzLnF1ZXJ5Lmxlbmd0aCA+IDAgPyB1cmxEZXRhaWxzLnBhdGggOiB1cmxEZXRhaWxzLnBhdGhuYW1lO1xuICB9XG5cbiAgbGV0IHByZWZpeGVkVGV4dDogc3RyaW5nO1xuICBpZiAoc3RhdHVzQ29kZSAhPT0gdW5kZWZpbmVkICYmIGlzRmluaXRlKHN0YXR1c0NvZGUpICYmIE51bWJlci5pc0ludGVnZXIoc3RhdHVzQ29kZSkpIHtcbiAgICBwcmVmaXhlZFRleHQgPVxuICAgICAgYXV0aFZlcnNpb24gPT09IDNcbiAgICAgICAgPyBbbWV0aG9kLnRvVXBwZXJDYXNlKCksIHRpbWVzdGFtcCwgcXVlcnlQYXRoLCBzdGF0dXNDb2RlXS5qb2luKCd8JylcbiAgICAgICAgOiBbdGltZXN0YW1wLCBxdWVyeVBhdGgsIHN0YXR1c0NvZGVdLmpvaW4oJ3wnKTtcbiAgfSBlbHNlIHtcbiAgICBwcmVmaXhlZFRleHQgPVxuICAgICAgYXV0aFZlcnNpb24gPT09IDNcbiAgICAgICAgPyBbbWV0aG9kLnRvVXBwZXJDYXNlKCksIHRpbWVzdGFtcCwgJzMuMCcsIHF1ZXJ5UGF0aF0uam9pbignfCcpXG4gICAgICAgIDogW3RpbWVzdGFtcCwgcXVlcnlQYXRoXS5qb2luKCd8Jyk7XG4gIH1cblxuICBjb25zdCBpc0J1ZmZlciA9IEJ1ZmZlci5pc0J1ZmZlcih0ZXh0KTtcbiAgaWYgKGlzQnVmZmVyKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHByZWZpeGVkVGV4dCArICd8JywgJ3V0Zi04JyksIHRleHRdKSBhcyBUO1xuICB9XG4gIHJldHVybiBbcHJlZml4ZWRUZXh0LCB0ZXh0XS5qb2luKCd8JykgYXMgVDtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIEhNQUMgZm9yIGFuIEhUVFAgcmVxdWVzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlUmVxdWVzdEhNQUM8VCBleHRlbmRzIHN0cmluZyB8IEJ1ZmZlciA9IHN0cmluZz4oXG4gIHsgdXJsOiB1cmxQYXRoLCB0ZXh0LCB0aW1lc3RhbXAsIHRva2VuLCBtZXRob2QsIGF1dGhWZXJzaW9uIH06IENhbGN1bGF0ZVJlcXVlc3RIbWFjT3B0aW9uczxUPixcbiAgdXNlT3JpZ2luYWxQYXRoID0gZmFsc2Vcbik6IHN0cmluZyB7XG4gIGNvbnN0IHNpZ25hdHVyZVN1YmplY3QgPSBjYWxjdWxhdGVITUFDU3ViamVjdCh7IHVybFBhdGgsIHRleHQsIHRpbWVzdGFtcCwgbWV0aG9kLCBhdXRoVmVyc2lvbiB9LCB1c2VPcmlnaW5hbFBhdGgpO1xuXG4gIC8vIGNhbGN1bGF0ZSB0aGUgSE1BQ1xuICByZXR1cm4gY2FsY3VsYXRlSE1BQyh0b2tlbiwgc2lnbmF0dXJlU3ViamVjdCk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHJlcXVlc3QgaGVhZGVycyB3aXRoIEhNQUNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzPFQgZXh0ZW5kcyBzdHJpbmcgfCBCdWZmZXIgPSBzdHJpbmc+KFxuICB7IHVybCwgdGV4dCwgdG9rZW4sIG1ldGhvZCwgYXV0aFZlcnNpb24gfTogQ2FsY3VsYXRlUmVxdWVzdEhlYWRlcnNPcHRpb25zPFQ+LFxuICB1c2VPcmlnaW5hbFBhdGggPSBmYWxzZVxuKTogUmVxdWVzdEhlYWRlcnMge1xuICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICBjb25zdCBobWFjID0gY2FsY3VsYXRlUmVxdWVzdEhNQUMoeyB1cmwsIHRleHQsIHRpbWVzdGFtcCwgdG9rZW4sIG1ldGhvZCwgYXV0aFZlcnNpb24gfSwgdXNlT3JpZ2luYWxQYXRoKTtcblxuICAvLyBjYWxjdWxhdGUgdGhlIFNIQTI1NiBoYXNoIG9mIHRoZSB0b2tlblxuICBjb25zdCBoYXNoRGlnZXN0ID0gc2pjbC5oYXNoLnNoYTI1Ni5oYXNoKHRva2VuKTtcbiAgY29uc3QgdG9rZW5IYXNoID0gc2pjbC5jb2RlYy5oZXguZnJvbUJpdHMoaGFzaERpZ2VzdCk7XG4gIHJldHVybiB7XG4gICAgaG1hYyxcbiAgICB0aW1lc3RhbXAsXG4gICAgdG9rZW5IYXNoLFxuICB9O1xufVxuXG4vKipcbiAqIFZlcmlmeSB0aGUgSE1BQyBmb3IgYW4gSFRUUCByZXNwb25zZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5UmVzcG9uc2U8VCBleHRlbmRzIHN0cmluZyB8IEJ1ZmZlciA9IHN0cmluZz4oXG4gIHsgdXJsOiB1cmxQYXRoLCBzdGF0dXNDb2RlLCB0ZXh0LCB0aW1lc3RhbXAsIHRva2VuLCBobWFjLCBtZXRob2QsIGF1dGhWZXJzaW9uIH06IFZlcmlmeVJlc3BvbnNlT3B0aW9uczxUPixcbiAgdXNlT3JpZ2luYWxQYXRoID0gZmFsc2Vcbik6IFZlcmlmeVJlc3BvbnNlSW5mbzxUPiB7XG4gIGNvbnN0IHNpZ25hdHVyZVN1YmplY3QgPSBjYWxjdWxhdGVITUFDU3ViamVjdChcbiAgICB7XG4gICAgICB1cmxQYXRoLFxuICAgICAgdGV4dCxcbiAgICAgIHRpbWVzdGFtcCxcbiAgICAgIHN0YXR1c0NvZGUsXG4gICAgICBtZXRob2QsXG4gICAgICBhdXRoVmVyc2lvbixcbiAgICB9LFxuICAgIHVzZU9yaWdpbmFsUGF0aFxuICApO1xuXG4gIC8vIGNhbGN1bGF0ZSB0aGUgSE1BQ1xuICBjb25zdCBleHBlY3RlZEhtYWMgPSBjYWxjdWxhdGVITUFDKHRva2VuLCBzaWduYXR1cmVTdWJqZWN0KTtcblxuICAvLyBkZXRlcm1pbmUgaWYgdGhlIHJlc3BvbnNlIGlzIHN0aWxsIHdpdGhpbiB0aGUgdmFsaWRpdHkgd2luZG93ICg1LW1pbnV0ZSBiYWNrd2FyZHMgd2luZG93LCAxLW1pbnV0ZSBmb3J3YXJkIHdpbmRvdylcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgYmFja3dhcmRWYWxpZGl0eVdpbmRvdyA9IDEwMDAgKiA2MCAqIDU7XG4gIGNvbnN0IGZvcndhcmRWYWxpZGl0eVdpbmRvdyA9IDEwMDAgKiA2MDtcbiAgY29uc3QgaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3cgPVxuICAgIHRpbWVzdGFtcCA+PSBub3cgLSBiYWNrd2FyZFZhbGlkaXR5V2luZG93ICYmIHRpbWVzdGFtcCA8PSBub3cgKyBmb3J3YXJkVmFsaWRpdHlXaW5kb3c7XG5cbiAgLy8gdmVyaWZ5IHRoZSBITUFDIGFuZCB0aW1lc3RhbXBcbiAgcmV0dXJuIHtcbiAgICBpc1ZhbGlkOiBleHBlY3RlZEhtYWMgPT09IGhtYWMsXG4gICAgZXhwZWN0ZWRIbWFjLFxuICAgIHNpZ25hdHVyZVN1YmplY3QsXG4gICAgaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3csXG4gICAgdmVyaWZpY2F0aW9uVGltZTogbm93LFxuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @prettier
|
|
3
|
+
*
|
|
4
|
+
* V4 HMAC Authentication Module
|
|
5
|
+
*
|
|
6
|
+
* This module implements the v4 authentication scheme which uses a canonical
|
|
7
|
+
* preimage construction with newline-separated fields and body hashing.
|
|
8
|
+
*
|
|
9
|
+
* Key differences from v2/v3:
|
|
10
|
+
* - Separator: newline (\n) instead of pipe (|)
|
|
11
|
+
* - Body: SHA256 hash of raw bytes instead of actual body content
|
|
12
|
+
* - Timestamp: seconds instead of milliseconds
|
|
13
|
+
* - New field: authRequestId for request tracking
|
|
14
|
+
* - Trailing newline in preimage
|
|
15
|
+
* - Support for x-original-* headers (proxy scenarios)
|
|
16
|
+
*/
|
|
17
|
+
import { type HashableData } from './util';
|
|
18
|
+
import { CalculateV4PreimageOptions, CalculateV4RequestHmacOptions, CalculateV4RequestHeadersOptions, V4RequestHeaders, VerifyV4ResponseOptions, VerifyV4ResponseInfo } from './types';
|
|
19
|
+
/**
|
|
20
|
+
* Build canonical preimage for v4 authentication.
|
|
21
|
+
*
|
|
22
|
+
* The preimage is constructed as newline-separated values with a trailing newline:
|
|
23
|
+
* ```
|
|
24
|
+
* {timestampSec}
|
|
25
|
+
* {METHOD}
|
|
26
|
+
* {pathWithQuery}
|
|
27
|
+
* {bodyHashHex}
|
|
28
|
+
* {authRequestId}
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* This function normalizes the HTTP method to uppercase and handles the
|
|
32
|
+
* legacy 'del' method conversion to 'DELETE'.
|
|
33
|
+
*
|
|
34
|
+
* @param options - The preimage components
|
|
35
|
+
* @returns Newline-separated canonical preimage string with trailing newline
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const preimage = calculateV4Preimage({
|
|
40
|
+
* timestampSec: 1761100000,
|
|
41
|
+
* method: 'post',
|
|
42
|
+
* pathWithQuery: '/v2/wallets/transfer?foo=bar',
|
|
43
|
+
* bodyHashHex: '0d5e3b7a8f9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e',
|
|
44
|
+
* authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Result:
|
|
48
|
+
* // "1761100000\nPOST\n/v2/wallets/transfer?foo=bar\n0d5e3b...d6e\n1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e\n"
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function calculateV4Preimage({ timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, }: CalculateV4PreimageOptions): string;
|
|
52
|
+
/**
|
|
53
|
+
* Calculate SHA256 hash of body and return as lowercase hex string.
|
|
54
|
+
*
|
|
55
|
+
* This is used to compute the bodyHashHex field for v4 authentication.
|
|
56
|
+
* The hash is computed over the raw bytes of the request body, ensuring
|
|
57
|
+
* that the exact bytes sent over the wire are used for signature calculation.
|
|
58
|
+
*
|
|
59
|
+
* Accepts common byte representations for Node.js and browser environments,
|
|
60
|
+
* including Uint8Array and ArrayBuffer for Fetch API compatibility.
|
|
61
|
+
*
|
|
62
|
+
* @param body - Raw request body (string, Buffer, Uint8Array, or ArrayBuffer)
|
|
63
|
+
* @returns Lowercase hex SHA256 hash (64 characters)
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Node.js with Buffer
|
|
68
|
+
* const hash1 = calculateBodyHash(Buffer.from('{"address":"tb1q...","amount":100000}'));
|
|
69
|
+
*
|
|
70
|
+
* // Browser with Uint8Array
|
|
71
|
+
* const hash2 = calculateBodyHash(new TextEncoder().encode('{"address":"tb1q..."}'));
|
|
72
|
+
*
|
|
73
|
+
* // Browser with ArrayBuffer
|
|
74
|
+
* const hash3 = calculateBodyHash(await response.arrayBuffer());
|
|
75
|
+
*
|
|
76
|
+
* // All return: '0d5e3b7a8f...' (64 character hex string)
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function calculateBodyHash(body: HashableData): string;
|
|
80
|
+
/**
|
|
81
|
+
* Calculate the HMAC-SHA256 signature for a v4 HTTP request.
|
|
82
|
+
*
|
|
83
|
+
* This function:
|
|
84
|
+
* 1. Builds the canonical preimage from the provided options
|
|
85
|
+
* 2. Computes HMAC-SHA256 of the preimage using the raw access token
|
|
86
|
+
*
|
|
87
|
+
* @param options - Request parameters and raw access token
|
|
88
|
+
* @returns Lowercase hex HMAC-SHA256 signature
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const hmac = calculateV4RequestHmac({
|
|
93
|
+
* timestampSec: 1761100000,
|
|
94
|
+
* method: 'POST',
|
|
95
|
+
* pathWithQuery: '/v2/wallets/transfer',
|
|
96
|
+
* bodyHashHex: '0d5e3b...',
|
|
97
|
+
* authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
|
|
98
|
+
* rawToken: 'your-token',
|
|
99
|
+
* });
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function calculateV4RequestHmac({ timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, rawToken, }: CalculateV4RequestHmacOptions): string;
|
|
103
|
+
/**
|
|
104
|
+
* Generate all headers required for v4 authenticated requests.
|
|
105
|
+
*
|
|
106
|
+
* This is a convenience function that:
|
|
107
|
+
* 1. Generates the current timestamp (in seconds)
|
|
108
|
+
* 2. Calculates the body hash from raw bytes
|
|
109
|
+
* 3. Computes the HMAC signature
|
|
110
|
+
* 4. Returns all values needed for request headers
|
|
111
|
+
*
|
|
112
|
+
* @param options - Request parameters including raw body and raw token
|
|
113
|
+
* @returns Object containing all v4 authentication header values
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const headers = calculateV4RequestHeaders({
|
|
118
|
+
* method: 'POST',
|
|
119
|
+
* pathWithQuery: '/v2/wallets/transfer?foo=bar',
|
|
120
|
+
* rawBody: Buffer.from('{"address":"tb1q..."}'),
|
|
121
|
+
* rawToken: 'your-token',
|
|
122
|
+
* authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* // Use headers to set:
|
|
126
|
+
* // - X-Request-Timestamp: headers.timestampSec
|
|
127
|
+
* // - X-Signature: headers.hmac
|
|
128
|
+
* // - X-Content-SHA256: headers.bodyHashHex
|
|
129
|
+
* // - X-Auth-Request-Id: headers.authRequestId
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export declare function calculateV4RequestHeaders({ method, pathWithQuery, rawBody, rawToken, authRequestId, }: CalculateV4RequestHeadersOptions): V4RequestHeaders;
|
|
133
|
+
/**
|
|
134
|
+
* Build canonical preimage for v4 response verification.
|
|
135
|
+
*
|
|
136
|
+
* Response preimage includes the status code and uses the same format:
|
|
137
|
+
* ```
|
|
138
|
+
* {timestampSec}
|
|
139
|
+
* {METHOD}
|
|
140
|
+
* {pathWithQuery}
|
|
141
|
+
* {statusCode}
|
|
142
|
+
* {bodyHashHex}
|
|
143
|
+
* {authRequestId}
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @param options - Response verification parameters
|
|
147
|
+
* @returns Newline-separated canonical preimage string with trailing newline
|
|
148
|
+
*/
|
|
149
|
+
export declare function calculateV4ResponsePreimage({ timestampSec, method, pathWithQuery, statusCode, bodyHashHex, authRequestId, }: Omit<VerifyV4ResponseOptions, 'hmac' | 'rawToken'>): string;
|
|
150
|
+
/**
|
|
151
|
+
* Verify the HMAC signature of a v4 HTTP response.
|
|
152
|
+
*
|
|
153
|
+
* This function:
|
|
154
|
+
* 1. Reconstructs the canonical preimage from response data
|
|
155
|
+
* 2. Calculates the expected HMAC
|
|
156
|
+
* 3. Compares with the received HMAC
|
|
157
|
+
* 4. Checks if the timestamp is within the validity window
|
|
158
|
+
*
|
|
159
|
+
* The validity window is:
|
|
160
|
+
* - 5 minutes backwards (to account for clock skew and network latency)
|
|
161
|
+
* - 1 minute forwards (to account for minor clock differences)
|
|
162
|
+
*
|
|
163
|
+
* @param options - Response data and raw token for verification
|
|
164
|
+
* @returns Verification result including validity and diagnostic info
|
|
165
|
+
*/
|
|
166
|
+
export declare function verifyV4Response({ hmac, timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, statusCode, rawToken, }: VerifyV4ResponseOptions): VerifyV4ResponseInfo;
|
|
167
|
+
/**
|
|
168
|
+
* Extract path with query from x-original-uri header or request URL.
|
|
169
|
+
* Always canonicalizes to pathname + search to handle absolute URLs.
|
|
170
|
+
*
|
|
171
|
+
* @param xOriginalUri - Value of x-original-uri header (if present)
|
|
172
|
+
* @param requestUrl - The actual request URL
|
|
173
|
+
* @returns The canonical path with query to use for preimage calculation
|
|
174
|
+
*
|
|
175
|
+
*/
|
|
176
|
+
export declare function getPathWithQuery(xOriginalUri: string | undefined, requestUrl: string): string;
|
|
177
|
+
/**
|
|
178
|
+
* Get method from x-original-method header or actual request method.
|
|
179
|
+
*
|
|
180
|
+
* @param xOriginalMethod - Value of x-original-method header (if present)
|
|
181
|
+
* @param requestMethod - The actual request method
|
|
182
|
+
* @returns The method to use for preimage calculation
|
|
183
|
+
*/
|
|
184
|
+
export declare function getMethod(xOriginalMethod: string | undefined, requestMethod: string): string;
|
|
185
|
+
//# sourceMappingURL=hmacv4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmacv4.d.ts","sourceRoot":"","sources":["../../src/hmacv4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,gCAAgC,EAChC,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,aAAa,EACb,WAAW,EACX,aAAa,GACd,EAAE,0BAA0B,GAAG,MAAM,CAOrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,aAAa,EACb,WAAW,EACX,aAAa,EACb,QAAQ,GACT,EAAE,6BAA6B,GAAG,MAAM,CAUxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,aAAa,GACd,EAAE,gCAAgC,GAAG,gBAAgB,CAmBrD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,YAAY,EACZ,MAAM,EACN,aAAa,EACb,UAAU,EACV,WAAW,EACX,aAAa,GACd,EAAE,IAAI,CAAC,uBAAuB,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG,MAAM,CAa7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,aAAa,EACb,WAAW,EACX,aAAa,EACb,UAAU,EACV,QAAQ,GACT,EAAE,uBAAuB,GAAG,oBAAoB,CAkChD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI7F;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAG5F"}
|