@bitgo-beta/sdk-hmac 1.0.1-beta.97 → 1.0.1-beta.970

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.
@@ -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
- * @returns {string}
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, }: CalculateHmacSubjectOptions): string;
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, }: CalculateRequestHmacOptions): string;
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, }: CalculateRequestHeadersOptions): RequestHeaders;
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, }: VerifyResponseOptions): VerifyResponseInfo;
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
@@ -1 +1 @@
1
- {"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../../src/hmac.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,IAAI,EACJ,SAAS,EACT,UAAU,EACV,MAAM,EACN,WAAW,GACZ,EAAE,2BAA2B,GAAG,MAAM,CAatC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,GAAG,EAAE,OAAO,EACZ,IAAI,EACJ,SAAS,EACT,KAAK,EACL,MAAM,EACN,WAAW,GACZ,EAAE,2BAA2B,GAAG,MAAM,CAKtC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,WAAW,GACZ,EAAE,8BAA8B,GAAG,cAAc,CAYjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EAAE,OAAO,EACZ,UAAU,EACV,IAAI,EACJ,SAAS,EACT,KAAK,EACL,IAAI,EACJ,MAAM,EACN,WAAW,GACZ,EAAE,qBAAqB,GAAG,kBAAkB,CAyB5C"}
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, crypto_1.createHmac)('sha256', key).update(message).digest('hex');
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
- * @returns {string}
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
- const urlDetails = urlLib.parse(urlPath);
64
- const queryPath = urlDetails.query && urlDetails.query.length > 0 ? urlDetails.path : urlDetails.pathname;
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
- if (authVersion === 3) {
67
- return [method.toUpperCase(), timestamp, queryPath, statusCode, text].join('|');
68
- }
69
- return [timestamp, queryPath, statusCode, text].join('|');
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
- if (authVersion === 3) {
72
- return [method.toUpperCase(), timestamp, '3.0', queryPath, text].join('|');
87
+ const isBuffer = Buffer.isBuffer(text);
88
+ if (isBuffer) {
89
+ return Buffer.concat([Buffer.from(prefixedText + '|', 'utf-8'), text]);
73
90
  }
74
- return [timestamp, queryPath, text].join('|');
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 isInResponseValidityWindow = timestamp >= now - 1000 * 60 * 5 && timestamp <= now;
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG1hYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9obWFjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLHNDQUVDO0FBV0Qsb0RBb0JDO0FBS0Qsb0RBWUM7QUFLRCwwREFrQkM7QUFLRCx3Q0FrQ0M7QUFsSUQsbUNBQW9DO0FBQ3BDLDRDQUE4QjtBQUM5Qix1REFBeUM7QUFVekM7Ozs7O0dBS0c7QUFDSCxTQUFnQixhQUFhLENBQUMsR0FBVyxFQUFFLE9BQWU7SUFDeEQsT0FBTyxJQUFBLG1CQUFVLEVBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQUMsRUFDbkMsT0FBTyxFQUNQLElBQUksRUFDSixTQUFTLEVBQ1QsVUFBVSxFQUNWLE1BQU0sRUFDTixXQUFXLEdBQ2lCO0lBQzVCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7SUFDMUcsSUFBSSxVQUFVLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDckYsSUFBSSxXQUFXLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFVBQVUs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XG5pbXBvcnQgKiBhcyB1cmxMaWIgZnJvbSAndXJsJztcbmltcG9ydCAqIGFzIHNqY2wgZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5pbXBvcnQge1xuICBDYWxjdWxhdGVIbWFjU3ViamVjdE9wdGlvbnMsXG4gIENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzT3B0aW9ucyxcbiAgQ2FsY3VsYXRlUmVxdWVzdEhtYWNPcHRpb25zLFxuICBSZXF1ZXN0SGVhZGVycyxcbiAgVmVyaWZ5UmVzcG9uc2VJbmZvLFxuICBWZXJpZnlSZXNwb25zZU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgSE1BQyBmb3IgdGhlIGdpdmVuIGtleSBhbmQgbWVzc2FnZVxuICogQHBhcmFtIGtleSB7U3RyaW5nfSAtIHRoZSBrZXkgdG8gdXNlIGZvciB0aGUgSE1BQ1xuICogQHBhcmFtIG1lc3NhZ2Uge1N0cmluZ30gLSB0aGUgYWN0dWFsIG1lc3NhZ2UgdG8gSE1BQ1xuICogQHJldHVybnMgeyp9IC0gdGhlIHJlc3VsdCBvZiB0aGUgSE1BQyBvcGVyYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUhNQUMoa2V5OiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjcmVhdGVIbWFjKCdzaGEyNTYnLCBrZXkpLnVwZGF0ZShtZXNzYWdlKS5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgc3ViamVjdCBzdHJpbmcgdGhhdCBpcyB0byBiZSBITUFDJ2VkIGZvciBhIEhUVFAgcmVxdWVzdCBvciByZXNwb25zZVxuICogQHBhcmFtIHVybFBhdGggcmVxdWVzdCB1cmwsIGluY2x1ZGluZyBxdWVyeSBwYXJhbXNcbiAqIEBwYXJhbSB0ZXh0IHJlcXVlc3QgYm9keSB0ZXh0XG4gKiBAcGFyYW0gdGltZXN0YW1wIHJlcXVlc3QgdGltZXN0YW1wIGZyb20gYERhdGUubm93KClgXG4gKiBAcGFyYW0gc3RhdHVzQ29kZSBPbmx5IHNldCBmb3IgSFRUUCByZXNwb25zZXMsIGxlYXZlIGJsYW5rIGZvciByZXF1ZXN0c1xuICogQHBhcmFtIG1ldGhvZCByZXF1ZXN0IG1ldGhvZFxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUhNQUNTdWJqZWN0KHtcbiAgdXJsUGF0aCxcbiAgdGV4dCxcbiAgdGltZXN0YW1wLFxuICBzdGF0dXNDb2RlLFxuICBtZXRob2QsXG4gIGF1dGhWZXJzaW9uLFxufTogQ2FsY3VsYXRlSG1hY1N1YmplY3RPcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsRGV0YWlscyA9IHVybExpYi5wYXJzZSh1cmxQYXRoKTtcbiAgY29uc3QgcXVlcnlQYXRoID0gdXJsRGV0YWlscy5xdWVyeSAmJiB1cmxEZXRhaWxzLnF1ZXJ5Lmxlbmd0aCA+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"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /**
3
+ * @prettier
4
+ *
5
+ * V4 HMAC Authentication Module
6
+ *
7
+ * This module implements the v4 authentication scheme which uses a canonical
8
+ * preimage construction with newline-separated fields and body hashing.
9
+ *
10
+ * Key differences from v2/v3:
11
+ * - Separator: newline (\n) instead of pipe (|)
12
+ * - Body: SHA256 hash of raw bytes instead of actual body content
13
+ * - Timestamp: seconds instead of milliseconds
14
+ * - New field: authRequestId for request tracking
15
+ * - Trailing newline in preimage
16
+ * - Support for x-original-* headers (proxy scenarios)
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.calculateV4Preimage = calculateV4Preimage;
20
+ exports.calculateBodyHash = calculateBodyHash;
21
+ exports.calculateV4RequestHmac = calculateV4RequestHmac;
22
+ exports.calculateV4RequestHeaders = calculateV4RequestHeaders;
23
+ exports.calculateV4ResponsePreimage = calculateV4ResponsePreimage;
24
+ exports.verifyV4Response = verifyV4Response;
25
+ exports.getPathWithQuery = getPathWithQuery;
26
+ exports.getMethod = getMethod;
27
+ const crypto_1 = require("crypto");
28
+ const util_1 = require("./util");
29
+ /**
30
+ * Build canonical preimage for v4 authentication.
31
+ *
32
+ * The preimage is constructed as newline-separated values with a trailing newline:
33
+ * ```
34
+ * {timestampSec}
35
+ * {METHOD}
36
+ * {pathWithQuery}
37
+ * {bodyHashHex}
38
+ * {authRequestId}
39
+ * ```
40
+ *
41
+ * This function normalizes the HTTP method to uppercase and handles the
42
+ * legacy 'del' method conversion to 'DELETE'.
43
+ *
44
+ * @param options - The preimage components
45
+ * @returns Newline-separated canonical preimage string with trailing newline
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const preimage = calculateV4Preimage({
50
+ * timestampSec: 1761100000,
51
+ * method: 'post',
52
+ * pathWithQuery: '/v2/wallets/transfer?foo=bar',
53
+ * bodyHashHex: '0d5e3b7a8f9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e',
54
+ * authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
55
+ * });
56
+ *
57
+ * // Result:
58
+ * // "1761100000\nPOST\n/v2/wallets/transfer?foo=bar\n0d5e3b...d6e\n1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e\n"
59
+ * ```
60
+ */
61
+ function calculateV4Preimage({ timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, }) {
62
+ const normalizedMethod = (0, util_1.normalizeMethod)(method);
63
+ // Build newline-separated preimage with trailing newline
64
+ const components = [timestampSec.toString(), normalizedMethod, pathWithQuery, bodyHashHex, authRequestId];
65
+ return components.join('\n') + '\n';
66
+ }
67
+ /**
68
+ * Calculate SHA256 hash of body and return as lowercase hex string.
69
+ *
70
+ * This is used to compute the bodyHashHex field for v4 authentication.
71
+ * The hash is computed over the raw bytes of the request body, ensuring
72
+ * that the exact bytes sent over the wire are used for signature calculation.
73
+ *
74
+ * Accepts common byte representations for Node.js and browser environments,
75
+ * including Uint8Array and ArrayBuffer for Fetch API compatibility.
76
+ *
77
+ * @param body - Raw request body (string, Buffer, Uint8Array, or ArrayBuffer)
78
+ * @returns Lowercase hex SHA256 hash (64 characters)
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // Node.js with Buffer
83
+ * const hash1 = calculateBodyHash(Buffer.from('{"address":"tb1q...","amount":100000}'));
84
+ *
85
+ * // Browser with Uint8Array
86
+ * const hash2 = calculateBodyHash(new TextEncoder().encode('{"address":"tb1q..."}'));
87
+ *
88
+ * // Browser with ArrayBuffer
89
+ * const hash3 = calculateBodyHash(await response.arrayBuffer());
90
+ *
91
+ * // All return: '0d5e3b7a8f...' (64 character hex string)
92
+ * ```
93
+ */
94
+ function calculateBodyHash(body) {
95
+ return (0, util_1.sha256Hex)(body);
96
+ }
97
+ /**
98
+ * Calculate the HMAC-SHA256 signature for a v4 HTTP request.
99
+ *
100
+ * This function:
101
+ * 1. Builds the canonical preimage from the provided options
102
+ * 2. Computes HMAC-SHA256 of the preimage using the raw access token
103
+ *
104
+ * @param options - Request parameters and raw access token
105
+ * @returns Lowercase hex HMAC-SHA256 signature
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const hmac = calculateV4RequestHmac({
110
+ * timestampSec: 1761100000,
111
+ * method: 'POST',
112
+ * pathWithQuery: '/v2/wallets/transfer',
113
+ * bodyHashHex: '0d5e3b...',
114
+ * authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
115
+ * rawToken: 'your-token',
116
+ * });
117
+ * ```
118
+ */
119
+ function calculateV4RequestHmac({ timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, rawToken, }) {
120
+ const preimage = calculateV4Preimage({
121
+ timestampSec,
122
+ method,
123
+ pathWithQuery,
124
+ bodyHashHex,
125
+ authRequestId,
126
+ });
127
+ return (0, util_1.createHmacWithSha256)(rawToken, preimage);
128
+ }
129
+ /**
130
+ * Generate all headers required for v4 authenticated requests.
131
+ *
132
+ * This is a convenience function that:
133
+ * 1. Generates the current timestamp (in seconds)
134
+ * 2. Calculates the body hash from raw bytes
135
+ * 3. Computes the HMAC signature
136
+ * 4. Returns all values needed for request headers
137
+ *
138
+ * @param options - Request parameters including raw body and raw token
139
+ * @returns Object containing all v4 authentication header values
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const headers = calculateV4RequestHeaders({
144
+ * method: 'POST',
145
+ * pathWithQuery: '/v2/wallets/transfer?foo=bar',
146
+ * rawBody: Buffer.from('{"address":"tb1q..."}'),
147
+ * rawToken: 'your-token',
148
+ * authRequestId: '1b7a1d2b-7a2f-4e4b-a1f8-c2a5a0f84e3e',
149
+ * });
150
+ *
151
+ * // Use headers to set:
152
+ * // - X-Request-Timestamp: headers.timestampSec
153
+ * // - X-Signature: headers.hmac
154
+ * // - X-Content-SHA256: headers.bodyHashHex
155
+ * // - X-Auth-Request-Id: headers.authRequestId
156
+ * ```
157
+ */
158
+ function calculateV4RequestHeaders({ method, pathWithQuery, rawBody, rawToken, authRequestId, }) {
159
+ const timestampSec = (0, util_1.getTimestampSec)();
160
+ const bodyHashHex = calculateBodyHash(rawBody);
161
+ const hmac = calculateV4RequestHmac({
162
+ timestampSec,
163
+ method,
164
+ pathWithQuery,
165
+ bodyHashHex,
166
+ authRequestId,
167
+ rawToken,
168
+ });
169
+ return {
170
+ hmac,
171
+ timestampSec,
172
+ bodyHashHex,
173
+ authRequestId,
174
+ };
175
+ }
176
+ /**
177
+ * Build canonical preimage for v4 response verification.
178
+ *
179
+ * Response preimage includes the status code and uses the same format:
180
+ * ```
181
+ * {timestampSec}
182
+ * {METHOD}
183
+ * {pathWithQuery}
184
+ * {statusCode}
185
+ * {bodyHashHex}
186
+ * {authRequestId}
187
+ * ```
188
+ *
189
+ * @param options - Response verification parameters
190
+ * @returns Newline-separated canonical preimage string with trailing newline
191
+ */
192
+ function calculateV4ResponsePreimage({ timestampSec, method, pathWithQuery, statusCode, bodyHashHex, authRequestId, }) {
193
+ const normalizedMethod = (0, util_1.normalizeMethod)(method);
194
+ const components = [
195
+ timestampSec.toString(),
196
+ normalizedMethod,
197
+ pathWithQuery,
198
+ statusCode.toString(),
199
+ bodyHashHex,
200
+ authRequestId,
201
+ ];
202
+ return components.join('\n') + '\n';
203
+ }
204
+ /**
205
+ * Verify the HMAC signature of a v4 HTTP response.
206
+ *
207
+ * This function:
208
+ * 1. Reconstructs the canonical preimage from response data
209
+ * 2. Calculates the expected HMAC
210
+ * 3. Compares with the received HMAC
211
+ * 4. Checks if the timestamp is within the validity window
212
+ *
213
+ * The validity window is:
214
+ * - 5 minutes backwards (to account for clock skew and network latency)
215
+ * - 1 minute forwards (to account for minor clock differences)
216
+ *
217
+ * @param options - Response data and raw token for verification
218
+ * @returns Verification result including validity and diagnostic info
219
+ */
220
+ function verifyV4Response({ hmac, timestampSec, method, pathWithQuery, bodyHashHex, authRequestId, statusCode, rawToken, }) {
221
+ // Build the response preimage
222
+ const preimage = calculateV4ResponsePreimage({
223
+ timestampSec,
224
+ method,
225
+ pathWithQuery,
226
+ statusCode,
227
+ bodyHashHex,
228
+ authRequestId,
229
+ });
230
+ // Calculate expected HMAC
231
+ const expectedHmac = (0, util_1.createHmacWithSha256)(rawToken, preimage);
232
+ // Use constant-time comparison to prevent timing side-channel attacks
233
+ const hmacBuffer = Buffer.from(hmac, 'hex');
234
+ const expectedHmacBuffer = Buffer.from(expectedHmac, 'hex');
235
+ const isHmacValid = hmacBuffer.length === expectedHmacBuffer.length && (0, crypto_1.timingSafeEqual)(hmacBuffer, expectedHmacBuffer);
236
+ // Check timestamp validity window
237
+ const nowSec = (0, util_1.getTimestampSec)();
238
+ const backwardValidityWindowSec = 5 * 60; // 5 minutes
239
+ const forwardValidityWindowSec = 1 * 60; // 1 minute
240
+ const isInResponseValidityWindow = timestampSec >= nowSec - backwardValidityWindowSec && timestampSec <= nowSec + forwardValidityWindowSec;
241
+ return {
242
+ isValid: isHmacValid,
243
+ expectedHmac,
244
+ preimage,
245
+ isInResponseValidityWindow,
246
+ verificationTime: Date.now(),
247
+ };
248
+ }
249
+ /**
250
+ * Extract path with query from x-original-uri header or request URL.
251
+ * Always canonicalizes to pathname + search to handle absolute URLs.
252
+ *
253
+ * @param xOriginalUri - Value of x-original-uri header (if present)
254
+ * @param requestUrl - The actual request URL
255
+ * @returns The canonical path with query to use for preimage calculation
256
+ *
257
+ */
258
+ function getPathWithQuery(xOriginalUri, requestUrl) {
259
+ // Prefer x-original-uri if available (proxy scenario)
260
+ const rawPath = xOriginalUri ?? requestUrl;
261
+ return (0, util_1.extractPathWithQuery)(rawPath);
262
+ }
263
+ /**
264
+ * Get method from x-original-method header or actual request method.
265
+ *
266
+ * @param xOriginalMethod - Value of x-original-method header (if present)
267
+ * @param requestMethod - The actual request method
268
+ * @returns The method to use for preimage calculation
269
+ */
270
+ function getMethod(xOriginalMethod, requestMethod) {
271
+ // Prefer x-original-method if available (proxy scenario)
272
+ return xOriginalMethod ?? requestMethod;
273
+ }
274
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG1hY3Y0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2htYWN2NC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHOztBQW9ESCxrREFhQztBQTZCRCw4Q0FFQztBQXdCRCx3REFpQkM7QUErQkQsOERBeUJDO0FBa0JELGtFQW9CQztBQWtCRCw0Q0EyQ0M7QUFXRCw0Q0FJQztBQVNELDhCQUdDO0FBN1RELG1DQUF5QztBQUN6QyxpQ0FPZ0I7QUFVaEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQkc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxFQUNsQyxZQUFZLEVBQ1osTUFBTSxFQUNOLGFBQWEsRUFDYixXQUFXLEVBQ1gsYUFBYSxHQUNjO0lBQzNCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBQSxzQkFBZSxFQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRWpELHlEQUF5RDtJQUN6RCxNQUFNLFVBQVUsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRTFHLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDdEMsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCRztBQUNILFNBQWdCLGlCQUFpQixDQUFDLElBQWtCO0lBQ2xELE9BQU8sSUFBQSxnQkFBUyxFQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsU0FBZ0Isc0JBQXNCLENBQUMsRUFDckMsWUFBWSxFQUNaLE1BQU0sRUFDTixhQUFhLEVBQ2IsV0FBVyxFQUNYLGFBQWEsRUFDYixRQUFRLEdBQ3NCO0lBQzlCLE1BQU0sUUFBUSxHQUFHLG1CQUFtQixDQUFDO1FBQ25DLFlBQVk7UUFDWixNQUFN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QUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxZQUFnQyxFQUFFLFVBQWtCO0lBQ25GLHNEQUFzRDtJQUN0RCxNQUFNLE9BQU8sR0FBRyxZQUFZLElBQUksVUFBVSxDQUFDO0lBQzNDLE9BQU8sSUFBQSwyQkFBb0IsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLGVBQW1DLEVBQUUsYUFBcUI7SUFDbEYseURBQXlEO0lBQ3pELE9BQU8sZUFBZSxJQUFJLGFBQWEsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqXG4gKiBWNCBITUFDIEF1dGhlbnRpY2F0aW9uIE1vZHVsZVxuICpcbiAqIFRoaXMgbW9kdWxlIGltcGxlbWVudHMgdGhlIHY0IGF1dGhlbnRpY2F0aW9uIHNjaGVtZSB3aGljaCB1c2VzIGEgY2Fub25pY2FsXG4gKiBwcmVpbWFnZSBjb25zdHJ1Y3Rpb24gd2l0aCBuZXdsaW5lLXNlcGFyYXRlZCBmaWVsZHMgYW5kIGJvZHkgaGFzaGluZy5cbiAqXG4gKiBLZXkgZGlmZmVyZW5jZXMgZnJvbSB2Mi92MzpcbiAqIC0gU2VwYXJhdG9yOiBuZXdsaW5lIChcXG4pIGluc3RlYWQgb2YgcGlwZSAofClcbiAqIC0gQm9keTogU0hBMjU2IGhhc2ggb2YgcmF3IGJ5dGVzIGluc3RlYWQgb2YgYWN0dWFsIGJvZHkgY29udGVudFxuICogLSBUaW1lc3RhbXA6IHNlY29uZHMgaW5zdGVhZCBvZiBtaWxsaXNlY29uZHNcbiAqIC0gTmV3IGZpZWxkOiBhdXRoUmVxdWVzdElkIGZvciByZXF1ZXN0IHRyYWNraW5nXG4gKiAtIFRyYWlsaW5nIG5ld2xpbmUgaW4gcHJlaW1hZ2VcbiAqIC0gU3VwcG9ydCBmb3IgeC1vcmlnaW5hbC0qIGhlYWRlcnMgKHByb3h5IHNjZW5hcmlvcylcbiAqL1xuXG5pbXBvcnQgeyB0aW1pbmdTYWZlRXF1YWwgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHtcbiAgY3JlYXRlSG1hY1dpdGhTaGEyNTYsXG4gIHNoYTI1NkhleCxcbiAgbm9ybWFsaXplTWV0aG9kLFxuICBnZXRUaW1lc3RhbXBTZWMsXG4gIGV4dHJhY3RQYXRoV2l0aFF1ZXJ5LFxuICB0eXBlIEhhc2hhYmxlRGF0YSxcbn0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7XG4gIENhbGN1bGF0ZVY0UHJlaW1hZ2VPcHRpb25zLFxuICBDYWxjdWxhdGVWNFJlcXVlc3RIbWFjT3B0aW9ucyxcbiAgQ2FsY3VsYXRlVjRSZXF1ZXN0SGVhZGVyc09wdGlvbnMsXG4gIFY0UmVxdWVzdEhlYWRlcnMsXG4gIFZlcmlmeVY0UmVzcG9uc2VPcHRpb25zLFxuICBWZXJpZnlWNFJlc3BvbnNlSW5mbyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogQnVpbGQgY2Fub25pY2FsIHByZWltYWdlIGZvciB2NCBhdXRoZW50aWNhdGlvbi5cbiAqXG4gKiBUaGUgcHJlaW1hZ2UgaXMgY29uc3RydWN0ZWQgYXMgbmV3bGluZS1zZXBhcmF0ZWQgdmFsdWVzIHdpdGggYSB0cmFpbGluZyBuZXdsaW5lOlxuICogYGBgXG4gKiB7dGltZXN0YW1wU2VjfVxuICoge01FVEhPRH1cbiAqIHtwYXRoV2l0aFF1ZXJ5fVxuICoge2JvZHlIYXNoSGV4fVxuICoge2F1dGhSZXF1ZXN0SWR9XG4gKiBgYGBcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIG5vcm1hbGl6ZXMgdGhlIEhUVFAgbWV0aG9kIHRvIHVwcGVyY2FzZSBhbmQgaGFuZGxlcyB0aGVcbiAqIGxlZ2FjeSAnZGVsJyBtZXRob2QgY29udmVyc2lvbiB0byAnREVMRVRFJy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBwcmVpbWFnZSBjb21wb25lbnRzXG4gKiBAcmV0dXJucyBOZXdsaW5lLXNlcGFyYXRlZCBjYW5vbmljYWwgcHJlaW1hZ2Ugc3RyaW5nIHdpdGggdHJhaWxpbmcgbmV3bGluZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBwcmVpbWFnZSA9IGNhbGN1bGF0ZVY0UHJlaW1hZ2Uoe1xuICogICB0aW1lc3RhbXBTZWM6IDE3NjExMDAwMDAsXG4gKiAgIG1ldGhvZDogJ3Bvc3QnLFxuICogICBwYXRoV2l0aFF1ZXJ5OiAnL3YyL3dhbGxldHMvdHJhbnNmZXI/Zm9vPWJhcicsXG4gKiAgIGJvZHlIYXNoSGV4OiAnMGQ1ZTNiN2E4ZjljMWQyZTNmNGE1YjZjN2Q4ZTlmMGExYjJjM2Q0ZTVmNmE3YjhjOWQwZTFmMmEzYjRjNWQ2ZScsXG4gKiAgIGF1dGhSZXF1ZXN0SWQ6ICcxYjdhMWQyYi03YTJmLTRlNGItYTFmOC1jMmE1YTBmODRlM2UnLFxuICogfSk7XG4gKlxuICogLy8gUmVzdWx0OlxuICogLy8gXCIxNzYxMTAwMDAwXFxuUE9TVFxcbi92Mi93YWxsZXRzL3RyYW5zZmVyP2Zvbz1iYXJcXG4wZDVlM2IuLi5kNmVcXG4xYjdhMWQyYi03YTJmLTRlNGItYTFmOC1jMmE1YTBmODRlM2VcXG5cIlxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVWNFByZWltYWdlKHtcbiAgdGltZXN0YW1wU2VjLFxuICBtZXRob2QsXG4gIHBhdGhXaXRoUXVlcnksXG4gIGJvZHlIYXNoSGV4LFxuICBhdXRoUmVxdWVzdElkLFxufTogQ2FsY3VsYXRlVjRQcmVpbWFnZU9wdGlvbnMpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkTWV0aG9kID0gbm9ybWFsaXplTWV0aG9kKG1ldGhvZCk7XG5cbiAgLy8gQnVpbGQgbmV3bGluZS1zZXBhcmF0ZWQgcHJlaW1hZ2Ugd2l0aCB0cmFpbGluZyBuZXdsaW5lXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBbdGltZXN0YW1wU2VjLnRvU3RyaW5nKCksIG5vcm1hbGl6ZWRNZXRob2QsIHBhdGhXaXRoUXVlcnksIGJvZHlIYXNoSGV4LCBhdXRoUmVxdWVzdElkXTtcblxuICByZXR1cm4gY29tcG9uZW50cy5qb2luKCdcXG4nKSArICdcXG4nO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBTSEEyNTYgaGFzaCBvZiBib2R5IGFuZCByZXR1cm4gYXMgbG93ZXJjYXNlIGhleCBzdHJpbmcuXG4gKlxuICogVGhpcyBpcyB1c2VkIHRvIGNvbXB1dGUgdGhlIGJvZHlIYXNoSGV4IGZpZWxkIGZvciB2NCBhdXRoZW50aWNhdGlvbi5cbiAqIFRoZSBoYXNoIGlzIGNvbXB1dGVkIG92ZXIgdGhlIHJhdyBieXRlcyBvZiB0aGUgcmVxdWVzdCBib2R5LCBlbnN1cmluZ1xuICogdGhhdCB0aGUgZXhhY3QgYnl0ZXMgc2VudCBvdmVyIHRoZSB3aXJlIGFyZSB1c2VkIGZvciBzaWduYXR1cmUgY2FsY3VsYXRpb24uXG4gKlxuICogQWNjZXB0cyBjb21tb24gYnl0ZSByZXByZXNlbnRhdGlvbnMgZm9yIE5vZGUuanMgYW5kIGJyb3dzZXIgZW52aXJvbm1lbnRzLFxuICogaW5jbHVkaW5nIFVpbnQ4QXJyYXkgYW5kIEFycmF5QnVmZmVyIGZvciBGZXRjaCBBUEkgY29tcGF0aWJpbGl0eS5cbiAqXG4gKiBAcGFyYW0gYm9keSAtIFJhdyByZXF1ZXN0IGJvZHkgKHN0cmluZywgQnVmZmVyLCBVaW50OEFycmF5LCBvciBBcnJheUJ1ZmZlcilcbiAqIEByZXR1cm5zIExvd2VyY2FzZSBoZXggU0hBMjU2IGhhc2ggKDY0IGNoYXJhY3RlcnMpXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIE5vZGUuanMgd2l0aCBCdWZmZXJcbiAqIGNvbnN0IGhhc2gxID0gY2FsY3VsYXRlQm9keUhhc2goQnVmZmVyLmZyb20oJ3tcImFkZHJlc3NcIjpcInRiMXEuLi5cIixcImFtb3VudFwiOjEwMDAwMH0nKSk7XG4gKlxuICogLy8gQnJvd3NlciB3aXRoIFVpbnQ4QXJyYXlcbiAqIGNvbnN0IGhhc2gyID0gY2FsY3VsYXRlQm9keUhhc2gobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCd7XCJhZGRyZXNzXCI6XCJ0YjFxLi4uXCJ9JykpO1xuICpcbiAqIC8vIEJyb3dzZXIgd2l0aCBBcnJheUJ1ZmZlclxuICogY29uc3QgaGFzaDMgPSBjYWxjdWxhdGVCb2R5SGFzaChhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcbiAqXG4gKiAvLyBBbGwgcmV0dXJuOiAnMGQ1ZTNiN2E4Zi4uLicgKDY0IGNoYXJhY3RlciBoZXggc3RyaW5nKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVCb2R5SGFzaChib2R5OiBIYXNoYWJsZURhdGEpOiBzdHJpbmcge1xuICByZXR1cm4gc2hhMjU2SGV4KGJvZHkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgSE1BQy1TSEEyNTYgc2lnbmF0dXJlIGZvciBhIHY0IEhUVFAgcmVxdWVzdC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uOlxuICogMS4gQnVpbGRzIHRoZSBjYW5vbmljYWwgcHJlaW1hZ2UgZnJvbSB0aGUgcHJvdmlkZWQgb3B0aW9uc1xuICogMi4gQ29tcHV0ZXMgSE1BQy1TSEEyNTYgb2YgdGhlIHByZWltYWdlIHVzaW5nIHRoZSByYXcgYWNjZXNzIHRva2VuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBSZXF1ZXN0IHBhcmFtZXRlcnMgYW5kIHJhdyBhY2Nlc3MgdG9rZW5cbiAqIEByZXR1cm5zIExvd2VyY2FzZSBoZXggSE1BQy1TSEEyNTYgc2lnbmF0dXJlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGhtYWMgPSBjYWxjdWxhdGVWNFJlcXVlc3RIbWFjKHtcbiAqICAgdGltZXN0YW1wU2VjOiAxNzYxMTAwMDAwLFxuICogICBtZXRob2Q6ICdQT1NUJyxcbiAqICAgcGF0aFdpdGhRdWVyeTogJy92Mi93YWxsZXRzL3RyYW5zZmVyJyxcbiAqICAgYm9keUhhc2hIZXg6ICcwZDVlM2IuLi4nLFxuICogICBhdXRoUmVxdWVzdElkOiAnMWI3YTFkMmItN2EyZi00ZTRiLWExZjgtYzJhNWEwZjg0ZTNlJyxcbiAqICAgcmF3VG9rZW46ICd5b3VyLXRva2VuJyxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVWNFJlcXVlc3RIbWFjKHtcbiAgdGltZXN0YW1wU2VjLFxuICBtZXRob2QsXG4gIHBhdGhXaXRoUXVlcnksXG4gIGJvZHlIYXNoSGV4LFxuICBhdXRoUmVxdWVzdElkLFxuICByYXdUb2tlbixcbn06IENhbGN1bGF0ZVY0UmVxdWVzdEhtYWNPcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3QgcHJlaW1hZ2UgPSBjYWxjdWxhdGVWNFByZWltYWdlKHtcbiAgICB0aW1lc3RhbXBTZWMsXG4gICAgbWV0aG9kLFxuICAgIHBhdGhXaXRoUXVlcnksXG4gICAgYm9keUhhc2hIZXgsXG4gICAgYXV0aFJlcXVlc3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIGNyZWF0ZUhtYWNXaXRoU2hhMjU2KHJhd1Rva2VuLCBwcmVpbWFnZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYWxsIGhlYWRlcnMgcmVxdWlyZWQgZm9yIHY0IGF1dGhlbnRpY2F0ZWQgcmVxdWVzdHMuXG4gKlxuICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIGZ1bmN0aW9uIHRoYXQ6XG4gKiAxLiBHZW5lcmF0ZXMgdGhlIGN1cnJlbnQgdGltZXN0YW1wIChpbiBzZWNvbmRzKVxuICogMi4gQ2FsY3VsYXRlcyB0aGUgYm9keSBoYXNoIGZyb20gcmF3IGJ5dGVzXG4gKiAzLiBDb21wdXRlcyB0aGUgSE1BQyBzaWduYXR1cmVcbiAqIDQuIFJldHVybnMgYWxsIHZhbHVlcyBuZWVkZWQgZm9yIHJlcXVlc3QgaGVhZGVyc1xuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gUmVxdWVzdCBwYXJhbWV0ZXJzIGluY2x1ZGluZyByYXcgYm9keSBhbmQgcmF3IHRva2VuXG4gKiBAcmV0dXJucyBPYmplY3QgY29udGFpbmluZyBhbGwgdjQgYXV0aGVudGljYXRpb24gaGVhZGVyIHZhbHVlc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBoZWFkZXJzID0gY2FsY3VsYXRlVjRSZXF1ZXN0SGVhZGVycyh7XG4gKiAgIG1ldGhvZDogJ1BPU1QnLFxuICogICBwYXRoV2l0aFF1ZXJ5OiAnL3YyL3dhbGxldHMvdHJhbnNmZXI/Zm9vPWJhcicsXG4gKiAgIHJhd0JvZHk6IEJ1ZmZlci5mcm9tKCd7XCJhZGRyZXNzXCI6XCJ0YjFxLi4uXCJ9JyksXG4gKiAgIHJhd1Rva2VuOiAneW91ci10b2tlbicsXG4gKiAgIGF1dGhSZXF1ZXN0SWQ6ICcxYjdhMWQyYi03YTJmLTRlNGItYTFmOC1jMmE1YTBmODRlM2UnLFxuICogfSk7XG4gKlxuICogLy8gVXNlIGhlYWRlcnMgdG8gc2V0OlxuICogLy8gLSBYLVJlcXVlc3QtVGltZXN0YW1wOiBoZWFkZXJzLnRpbWVzdGFtcFNlY1xuICogLy8gLSBYLVNpZ25hdHVyZTogaGVhZGVycy5obWFjXG4gKiAvLyAtIFgtQ29udGVudC1TSEEyNTY6IGhlYWRlcnMuYm9keUhhc2hIZXhcbiAqIC8vIC0gWC1BdXRoLVJlcXVlc3QtSWQ6IGhlYWRlcnMuYXV0aFJlcXVlc3RJZFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVWNFJlcXVlc3RIZWFkZXJzKHtcbiAgbWV0aG9kLFxuICBwYXRoV2l0aFF1ZXJ5LFxuICByYXdCb2R5LFxuICByYXdUb2tlbixcbiAgYXV0aFJlcXVlc3RJZCxcbn06IENhbGN1bGF0ZVY0UmVxdWVzdEhlYWRlcnNPcHRpb25zKTogVjRSZXF1ZXN0SGVhZGVycyB7XG4gIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGdldFRpbWVzdGFtcFNlYygpO1xuICBjb25zdCBib2R5SGFzaEhleCA9IGNhbGN1bGF0ZUJvZHlIYXNoKHJhd0JvZHkpO1xuXG4gIGNvbnN0IGhtYWMgPSBjYWxjdWxhdGVWNFJlcXVlc3RIbWFjKHtcbiAgICB0aW1lc3RhbXBTZWMsXG4gICAgbWV0aG9kLFxuICAgIHBhdGhXaXRoUXVlcnksXG4gICAgYm9keUhhc2hIZXgsXG4gICAgYXV0aFJlcXVlc3RJZCxcbiAgICByYXdUb2tlbixcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBobWFjLFxuICAgIHRpbWVzdGFtcFNlYyxcbiAgICBib2R5SGFzaEhleCxcbiAgICBhdXRoUmVxdWVzdElkLFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGNhbm9uaWNhbCBwcmVpbWFnZSBmb3IgdjQgcmVzcG9uc2UgdmVyaWZpY2F0aW9uLlxuICpcbiAqIFJlc3BvbnNlIHByZWltYWdlIGluY2x1ZGVzIHRoZSBzdGF0dXMgY29kZSBhbmQgdXNlcyB0aGUgc2FtZSBmb3JtYXQ6XG4gKiBgYGBcbiAqIHt0aW1lc3RhbXBTZWN9XG4gKiB7TUVUSE9EfVxuICoge3BhdGhXaXRoUXVlcnl9XG4gKiB7c3RhdHVzQ29kZX1cbiAqIHtib2R5SGFzaEhleH1cbiAqIHthdXRoUmVxdWVzdElkfVxuICogYGBgXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBSZXNwb25zZSB2ZXJpZmljYXRpb24gcGFyYW1ldGVyc1xuICogQHJldHVybnMgTmV3bGluZS1zZXBhcmF0ZWQgY2Fub25pY2FsIHByZWltYWdlIHN0cmluZyB3aXRoIHRyYWlsaW5nIG5ld2xpbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVY0UmVzcG9uc2VQcmVpbWFnZSh7XG4gIHRpbWVzdGFtcFNlYyxcbiAgbWV0aG9kLFxuICBwYXRoV2l0aFF1ZXJ5LFxuICBzdGF0dXNDb2RlLFxuICBib2R5SGFzaEhleCxcbiAgYXV0aFJlcXVlc3RJZCxcbn06IE9taXQ8VmVyaWZ5VjRSZXNwb25zZU9wdGlvbnMsICdobWFjJyB8ICdyYXdUb2tlbic+KTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZE1ldGhvZCA9IG5vcm1hbGl6ZU1ldGhvZChtZXRob2QpO1xuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBbXG4gICAgdGltZXN0YW1wU2VjLnRvU3RyaW5nKCksXG4gICAgbm9ybWFsaXplZE1ldGhvZCxcbiAgICBwYXRoV2l0aFF1ZXJ5LFxuICAgIHN0YXR1c0NvZGUudG9TdHJpbmcoKSxcbiAgICBib2R5SGFzaEhleCxcbiAgICBhdXRoUmVxdWVzdElkLFxuICBdO1xuXG4gIHJldHVybiBjb21wb25lbnRzLmpvaW4oJ1xcbicpICsgJ1xcbic7XG59XG5cbi8qKlxuICogVmVyaWZ5IHRoZSBITUFDIHNpZ25hdHVyZSBvZiBhIHY0IEhUVFAgcmVzcG9uc2UuXG4gKlxuICogVGhpcyBmdW5jdGlvbjpcbiAqIDEuIFJlY29uc3RydWN0cyB0aGUgY2Fub25pY2FsIHByZWltYWdlIGZyb20gcmVzcG9uc2UgZGF0YVxuICogMi4gQ2FsY3VsYXRlcyB0aGUgZXhwZWN0ZWQgSE1BQ1xuICogMy4gQ29tcGFyZXMgd2l0aCB0aGUgcmVjZWl2ZWQgSE1BQ1xuICogNC4gQ2hlY2tzIGlmIHRoZSB0aW1lc3RhbXAgaXMgd2l0aGluIHRoZSB2YWxpZGl0eSB3aW5kb3dcbiAqXG4gKiBUaGUgdmFsaWRpdHkgd2luZG93IGlzOlxuICogLSA1IG1pbnV0ZXMgYmFja3dhcmRzICh0byBhY2NvdW50IGZvciBjbG9jayBza2V3IGFuZCBuZXR3b3JrIGxhdGVuY3kpXG4gKiAtIDEgbWludXRlIGZvcndhcmRzICh0byBhY2NvdW50IGZvciBtaW5vciBjbG9jayBkaWZmZXJlbmNlcylcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFJlc3BvbnNlIGRhdGEgYW5kIHJhdyB0b2tlbiBmb3IgdmVyaWZpY2F0aW9uXG4gKiBAcmV0dXJucyBWZXJpZmljYXRpb24gcmVzdWx0IGluY2x1ZGluZyB2YWxpZGl0eSBhbmQgZGlhZ25vc3RpYyBpbmZvXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlWNFJlc3BvbnNlKHtcbiAgaG1hYyxcbiAgdGltZXN0YW1wU2VjLFxuICBtZXRob2QsXG4gIHBhdGhXaXRoUXVlcnksXG4gIGJvZHlIYXNoSGV4LFxuICBhdXRoUmVxdWVzdElkLFxuICBzdGF0dXNDb2RlLFxuICByYXdUb2tlbixcbn06IFZlcmlmeVY0UmVzcG9uc2VPcHRpb25zKTogVmVyaWZ5VjRSZXNwb25zZUluZm8ge1xuICAvLyBCdWlsZCB0aGUgcmVzcG9uc2UgcHJlaW1hZ2VcbiAgY29uc3QgcHJlaW1hZ2UgPSBjYWxjdWxhdGVWNFJlc3BvbnNlUHJlaW1hZ2Uoe1xuICAgIHRpbWVzdGFtcFNlYyxcbiAgICBtZXRob2QsXG4gICAgcGF0aFdpdGhRdWVyeSxcbiAgICBzdGF0dXNDb2RlLFxuICAgIGJvZHlIYXNoSGV4LFxuICAgIGF1dGhSZXF1ZXN0SWQsXG4gIH0pO1xuXG4gIC8vIENhbGN1bGF0ZSBleHBlY3RlZCBITUFDXG4gIGNvbnN0IGV4cGVjdGVkSG1hYyA9IGNyZWF0ZUhtYWNXaXRoU2hhMjU2KHJhd1Rva2VuLCBwcmVpbWFnZSk7XG5cbiAgLy8gVXNlIGNvbnN0YW50LXRpbWUgY29tcGFyaXNvbiB0byBwcmV2ZW50IHRpbWluZyBzaWRlLWNoYW5uZWwgYXR0YWNrc1xuICBjb25zdCBobWFjQnVmZmVyID0gQnVmZmVyLmZyb20oaG1hYywgJ2hleCcpO1xuICBjb25zdCBleHBlY3RlZEhtYWNCdWZmZXIgPSBCdWZmZXIuZnJvbShleHBlY3RlZEhtYWMsICdoZXgnKTtcbiAgY29uc3QgaXNIbWFjVmFsaWQgPVxuICAgIGhtYWNCdWZmZXIubGVuZ3RoID09PSBleHBlY3RlZEhtYWNCdWZmZXIubGVuZ3RoICYmIHRpbWluZ1NhZmVFcXVhbChobWFjQnVmZmVyLCBleHBlY3RlZEhtYWNCdWZmZXIpO1xuXG4gIC8vIENoZWNrIHRpbWVzdGFtcCB2YWxpZGl0eSB3aW5kb3dcbiAgY29uc3Qgbm93U2VjID0gZ2V0VGltZXN0YW1wU2VjKCk7XG4gIGNvbnN0IGJhY2t3YXJkVmFsaWRpdHlXaW5kb3dTZWMgPSA1ICogNjA7IC8vIDUgbWludXRlc1xuICBjb25zdCBmb3J3YXJkVmFsaWRpdHlXaW5kb3dTZWMgPSAxICogNjA7IC8vIDEgbWludXRlXG4gIGNvbnN0IGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93ID1cbiAgICB0aW1lc3RhbXBTZWMgPj0gbm93U2VjIC0gYmFja3dhcmRWYWxpZGl0eVdpbmRvd1NlYyAmJiB0aW1lc3RhbXBTZWMgPD0gbm93U2VjICsgZm9yd2FyZFZhbGlkaXR5V2luZG93U2VjO1xuXG4gIHJldHVybiB7XG4gICAgaXNWYWxpZDogaXNIbWFjVmFsaWQsXG4gICAgZXhwZWN0ZWRIbWFjLFxuICAgIHByZWltYWdlLFxuICAgIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93LFxuICAgIHZlcmlmaWNhdGlvblRpbWU6IERhdGUubm93KCksXG4gIH07XG59XG5cbi8qKlxuICogRXh0cmFjdCBwYXRoIHdpdGggcXVlcnkgZnJvbSB4LW9yaWdpbmFsLXVyaSBoZWFkZXIgb3IgcmVxdWVzdCBVUkwuXG4gKiBBbHdheXMgY2Fub25pY2FsaXplcyB0byBwYXRobmFtZSArIHNlYXJjaCB0byBoYW5kbGUgYWJzb2x1dGUgVVJMcy5cbiAqXG4gKiBAcGFyYW0geE9yaWdpbmFsVXJpIC0gVmFsdWUgb2YgeC1vcmlnaW5hbC11cmkgaGVhZGVyIChpZiBwcmVzZW50KVxuICogQHBhcmFtIHJlcXVlc3RVcmwgLSBUaGUgYWN0dWFsIHJlcXVlc3QgVVJMXG4gKiBAcmV0dXJucyBUaGUgY2Fub25pY2FsIHBhdGggd2l0aCBxdWVyeSB0byB1c2UgZm9yIHByZWltYWdlIGNhbGN1bGF0aW9uXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGF0aFdpdGhRdWVyeSh4T3JpZ2luYWxVcmk6IHN0cmluZyB8IHVuZGVmaW5lZCwgcmVxdWVzdFVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gUHJlZmVyIHgtb3JpZ2luYWwtdXJpIGlmIGF2YWlsYWJsZSAocHJveHkgc2NlbmFyaW8pXG4gIGNvbnN0IHJhd1BhdGggPSB4T3JpZ2luYWxVcmkgPz8gcmVxdWVzdFVybDtcbiAgcmV0dXJuIGV4dHJhY3RQYXRoV2l0aFF1ZXJ5KHJhd1BhdGgpO1xufVxuXG4vKipcbiAqIEdldCBtZXRob2QgZnJvbSB4LW9yaWdpbmFsLW1ldGhvZCBoZWFkZXIgb3IgYWN0dWFsIHJlcXVlc3QgbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB4T3JpZ2luYWxNZXRob2QgLSBWYWx1ZSBvZiB4LW9yaWdpbmFsLW1ldGhvZCBoZWFkZXIgKGlmIHByZXNlbnQpXG4gKiBAcGFyYW0gcmVxdWVzdE1ldGhvZCAtIFRoZSBhY3R1YWwgcmVxdWVzdCBtZXRob2RcbiAqIEByZXR1cm5zIFRoZSBtZXRob2QgdG8gdXNlIGZvciBwcmVpbWFnZSBjYWxjdWxhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWV0aG9kKHhPcmlnaW5hbE1ldGhvZDogc3RyaW5nIHwgdW5kZWZpbmVkLCByZXF1ZXN0TWV0aG9kOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBQcmVmZXIgeC1vcmlnaW5hbC1tZXRob2QgaWYgYXZhaWxhYmxlIChwcm94eSBzY2VuYXJpbylcbiAgcmV0dXJuIHhPcmlnaW5hbE1ldGhvZCA/PyByZXF1ZXN0TWV0aG9kO1xufVxuIl19
@@ -1,3 +1,5 @@
1
1
  export * from './hmac';
2
+ export * from './hmacv4';
3
+ export * from './util';
2
4
  export * from './types';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
package/dist/src/index.js CHANGED
@@ -15,5 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./hmac"), exports);
18
+ __exportStar(require("./hmacv4"), exports);
19
+ __exportStar(require("./util"), exports);
18
20
  __exportStar(require("./types"), exports);
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlDQUF1QjtBQUN2QiwwQ0FBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2htYWMnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG4iXX0=
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlDQUF1QjtBQUN2QiwyQ0FBeUI7QUFDekIseUNBQXVCO0FBQ3ZCLDBDQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vaG1hYyc7XG5leHBvcnQgKiBmcm9tICcuL2htYWN2NCc7XG5leHBvcnQgKiBmcm9tICcuL3V0aWwnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG4iXX0=
@@ -1,24 +1,24 @@
1
- export declare const supportedRequestMethods: readonly ["get", "post", "put", "del", "patch", "options"];
1
+ export declare const supportedRequestMethods: readonly ["get", "post", "put", "del", "patch", "options", "delete"];
2
2
  export type AuthVersion = 2 | 3;
3
- export interface CalculateHmacSubjectOptions {
3
+ export interface CalculateHmacSubjectOptions<T> {
4
4
  urlPath: string;
5
- text: string;
5
+ text: T;
6
6
  timestamp: number;
7
7
  method: (typeof supportedRequestMethods)[number];
8
8
  statusCode?: number;
9
9
  authVersion: AuthVersion;
10
10
  }
11
- export interface CalculateRequestHmacOptions {
11
+ export interface CalculateRequestHmacOptions<T extends string | Buffer = string> {
12
12
  url: string;
13
- text: string;
13
+ text: T;
14
14
  timestamp: number;
15
15
  token: string;
16
16
  method: (typeof supportedRequestMethods)[number];
17
17
  authVersion: AuthVersion;
18
18
  }
19
- export interface CalculateRequestHeadersOptions {
19
+ export interface CalculateRequestHeadersOptions<T extends string | Buffer = string> {
20
20
  url: string;
21
- text: string;
21
+ text: T;
22
22
  token: string;
23
23
  method: (typeof supportedRequestMethods)[number];
24
24
  authVersion: AuthVersion;
@@ -28,19 +28,69 @@ export interface RequestHeaders {
28
28
  timestamp: number;
29
29
  tokenHash: string;
30
30
  }
31
- export interface VerifyResponseOptions extends CalculateRequestHeadersOptions {
31
+ export interface VerifyResponseOptions<T extends string | Buffer = string> extends CalculateRequestHeadersOptions<T> {
32
32
  hmac: string;
33
33
  url: string;
34
- text: string;
34
+ text: T;
35
35
  timestamp: number;
36
36
  method: (typeof supportedRequestMethods)[number];
37
37
  statusCode?: number;
38
38
  authVersion: AuthVersion;
39
39
  }
40
- export interface VerifyResponseInfo {
40
+ export interface VerifyResponseInfo<T extends string | Buffer = string> {
41
41
  isValid: boolean;
42
42
  expectedHmac: string;
43
- signatureSubject: string;
43
+ signatureSubject: T;
44
+ isInResponseValidityWindow: boolean;
45
+ verificationTime: number;
46
+ }
47
+ export interface CalculateV4PreimageOptions {
48
+ timestampSec: number;
49
+ method: string;
50
+ pathWithQuery: string;
51
+ bodyHashHex: string;
52
+ authRequestId: string;
53
+ }
54
+ export interface CalculateV4RequestHmacOptions extends CalculateV4PreimageOptions {
55
+ rawToken: string;
56
+ }
57
+ import type { HashableData } from './util';
58
+ export interface CalculateV4RequestHeadersOptions {
59
+ method: string;
60
+ pathWithQuery: string;
61
+ rawBody: HashableData;
62
+ rawToken: string;
63
+ authRequestId: string;
64
+ }
65
+ /**
66
+ * Headers generated for V4 authenticated requests.
67
+ */
68
+ export interface V4RequestHeaders {
69
+ hmac: string;
70
+ timestampSec: number;
71
+ bodyHashHex: string;
72
+ authRequestId: string;
73
+ }
74
+ /**
75
+ * Options for verifying V4 response HMAC.
76
+ */
77
+ export interface VerifyV4ResponseOptions {
78
+ hmac: string;
79
+ timestampSec: number;
80
+ method: string;
81
+ pathWithQuery: string;
82
+ bodyHashHex: string;
83
+ authRequestId: string;
84
+ statusCode: number;
85
+ rawToken: string;
86
+ }
87
+ /**
88
+ * Result of V4 response HMAC verification.
89
+ */
90
+ export interface VerifyV4ResponseInfo {
91
+ isValid: boolean;
92
+ expectedHmac: string;
93
+ preimage: string;
44
94
  isInResponseValidityWindow: boolean;
45
95
  verificationTime: number;
46
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,4DAA6D,CAAC;AAElG,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,CAAC;AAEhC,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;IACjD,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,8BAA8B;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;IACjD,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,8BAA8B;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/dist/src/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.supportedRequestMethods = void 0;
4
- exports.supportedRequestMethods = ['get', 'post', 'put', 'del', 'patch', 'options'];
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQWEsUUFBQSx1QkFBdUIsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3Qgc3VwcG9ydGVkUmVxdWVzdE1ldGhvZHMgPSBbJ2dldCcsICdwb3N0JywgJ3B1dCcsICdkZWwnLCAncGF0Y2gnLCAnb3B0aW9ucyddIGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBBdXRoVmVyc2lvbiA9IDIgfCAzO1xuXG5leHBvcnQgaW50ZXJmYWNlIENhbGN1bGF0ZUhtYWNTdWJqZWN0T3B0aW9ucyB7XG4gIHVybFBhdGg6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgbWV0aG9kOiAodHlwZW9mIHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzKVtudW1iZXJdO1xuICBzdGF0dXNDb2RlPzogbnVtYmVyO1xuICBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlUmVxdWVzdEhtYWNPcHRpb25zIHtcbiAgdXJsOiBzdHJpbmc7XG4gIHRleHQ6IHN0cmluZztcbiAgdGltZXN0YW1wOiBudW1iZXI7XG4gIHRva2VuOiBzdHJpbmc7XG4gIG1ldGhvZDogKHR5cGVvZiBzdXBwb3J0ZWRSZXF1ZXN0TWV0aG9kcylbbnVtYmVyXTtcbiAgYXV0aFZlcnNpb246IEF1dGhWZXJzaW9uO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzT3B0aW9ucyB7XG4gIHVybDogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIG1ldGhvZDogKHR5cGVvZiBzdXBwb3J0ZWRSZXF1ZXN0TWV0aG9kcylbbnVtYmVyXTtcbiAgYXV0aFZlcnNpb246IEF1dGhWZXJzaW9uO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RIZWFkZXJzIHtcbiAgaG1hYzogc3RyaW5nO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgdG9rZW5IYXNoOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5UmVzcG9uc2VPcHRpb25zIGV4dGVuZHMgQ2FsY3VsYXRlUmVxdWVzdEhlYWRlcnNPcHRpb25zIHtcbiAgaG1hYzogc3RyaW5nO1xuICB1cmw6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgbWV0aG9kOiAodHlwZW9mIHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzKVtudW1iZXJdO1xuICBzdGF0dXNDb2RlPzogbnVtYmVyO1xuICBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5UmVzcG9uc2VJbmZvIHtcbiAgaXNWYWxpZDogYm9vbGVhbjtcbiAgZXhwZWN0ZWRIbWFjOiBzdHJpbmc7XG4gIHNpZ25hdHVyZVN1YmplY3Q6IHN0cmluZztcbiAgaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3c6IGJvb2xlYW47XG4gIHZlcmlmaWNhdGlvblRpbWU6IG51bWJlcjtcbn1cbiJdfQ==
4
+ exports.supportedRequestMethods = ['get', 'post', 'put', 'del', 'patch', 'options', 'delete'];
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQWEsUUFBQSx1QkFBdUIsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzID0gWydnZXQnLCAncG9zdCcsICdwdXQnLCAnZGVsJywgJ3BhdGNoJywgJ29wdGlvbnMnLCAnZGVsZXRlJ10gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIEF1dGhWZXJzaW9uID0gMiB8IDM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlSG1hY1N1YmplY3RPcHRpb25zPFQ+IHtcbiAgdXJsUGF0aDogc3RyaW5nO1xuICB0ZXh0OiBUO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgbWV0aG9kOiAodHlwZW9mIHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzKVtudW1iZXJdO1xuICBzdGF0dXNDb2RlPzogbnVtYmVyO1xuICBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlUmVxdWVzdEhtYWNPcHRpb25zPFQgZXh0ZW5kcyBzdHJpbmcgfCBCdWZmZXIgPSBzdHJpbmc+IHtcbiAgdXJsOiBzdHJpbmc7XG4gIHRleHQ6IFQ7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICB0b2tlbjogc3RyaW5nO1xuICBtZXRob2Q6ICh0eXBlb2Ygc3VwcG9ydGVkUmVxdWVzdE1ldGhvZHMpW251bWJlcl07XG4gIGF1dGhWZXJzaW9uOiBBdXRoVmVyc2lvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYWxjdWxhdGVSZXF1ZXN0SGVhZGVyc09wdGlvbnM8VCBleHRlbmRzIHN0cmluZyB8IEJ1ZmZlciA9IHN0cmluZz4ge1xuICB1cmw6IHN0cmluZztcbiAgdGV4dDogVDtcbiAgdG9rZW46IHN0cmluZztcbiAgbWV0aG9kOiAodHlwZW9mIHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzKVtudW1iZXJdO1xuICBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdEhlYWRlcnMge1xuICBobWFjOiBzdHJpbmc7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICB0b2tlbkhhc2g6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlSZXNwb25zZU9wdGlvbnM8VCBleHRlbmRzIHN0cmluZyB8IEJ1ZmZlciA9IHN0cmluZz4gZXh0ZW5kcyBDYWxjdWxhdGVSZXF1ZXN0SGVhZGVyc09wdGlvbnM8VD4ge1xuICBobWFjOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICB0ZXh0OiBUO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgbWV0aG9kOiAodHlwZW9mIHN1cHBvcnRlZFJlcXVlc3RNZXRob2RzKVtudW1iZXJdO1xuICBzdGF0dXNDb2RlPzogbnVtYmVyO1xuICBhdXRoVmVyc2lvbjogQXV0aFZlcnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5UmVzcG9uc2VJbmZvPFQgZXh0ZW5kcyBzdHJpbmcgfCBCdWZmZXIgPSBzdHJpbmc+IHtcbiAgaXNWYWxpZDogYm9vbGVhbjtcbiAgZXhwZWN0ZWRIbWFjOiBzdHJpbmc7XG4gIHNpZ25hdHVyZVN1YmplY3Q6IFQ7XG4gIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93OiBib29sZWFuO1xuICB2ZXJpZmljYXRpb25UaW1lOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlVjRQcmVpbWFnZU9wdGlvbnMge1xuICB0aW1lc3RhbXBTZWM6IG51bWJlcjtcbiAgbWV0aG9kOiBzdHJpbmc7XG4gIHBhdGhXaXRoUXVlcnk6IHN0cmluZztcbiAgYm9keUhhc2hIZXg6IHN0cmluZztcbiAgYXV0aFJlcXVlc3RJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhbGN1bGF0ZVY0UmVxdWVzdEhtYWNPcHRpb25zIGV4dGVuZHMgQ2FsY3VsYXRlVjRQcmVpbWFnZU9wdGlvbnMge1xuICByYXdUb2tlbjogc3RyaW5nO1xufVxuXG5pbXBvcnQgdHlwZSB7IEhhc2hhYmxlRGF0YSB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsY3VsYXRlVjRSZXF1ZXN0SGVhZGVyc09wdGlvbnMge1xuICBtZXRob2Q6IHN0cmluZztcbiAgcGF0aFdpdGhRdWVyeTogc3RyaW5nO1xuICByYXdCb2R5OiBIYXNoYWJsZURhdGE7XG4gIHJhd1Rva2VuOiBzdHJpbmc7XG4gIGF1dGhSZXF1ZXN0SWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBIZWFkZXJzIGdlbmVyYXRlZCBmb3IgVjQgYXV0aGVudGljYXRlZCByZXF1ZXN0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWNFJlcXVlc3RIZWFkZXJzIHtcbiAgaG1hYzogc3RyaW5nO1xuICB0aW1lc3RhbXBTZWM6IG51bWJlcjtcbiAgYm9keUhhc2hIZXg6IHN0cmluZztcbiAgYXV0aFJlcXVlc3RJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHZlcmlmeWluZyBWNCByZXNwb25zZSBITUFDLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVY0UmVzcG9uc2VPcHRpb25zIHtcbiAgaG1hYzogc3RyaW5nO1xuICB0aW1lc3RhbXBTZWM6IG51bWJlcjtcbiAgbWV0aG9kOiBzdHJpbmc7XG4gIHBhdGhXaXRoUXVlcnk6IHN0cmluZztcbiAgYm9keUhhc2hIZXg6IHN0cmluZztcbiAgYXV0aFJlcXVlc3RJZDogc3RyaW5nO1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIHJhd1Rva2VuOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIFY0IHJlc3BvbnNlIEhNQUMgdmVyaWZpY2F0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVY0UmVzcG9uc2VJbmZvIHtcbiAgaXNWYWxpZDogYm9vbGVhbjtcbiAgZXhwZWN0ZWRIbWFjOiBzdHJpbmc7XG4gIHByZWltYWdlOiBzdHJpbmc7XG4gIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93OiBib29sZWFuO1xuICB2ZXJpZmljYXRpb25UaW1lOiBudW1iZXI7XG59XG4iXX0=
@@ -0,0 +1,49 @@
1
+ import { type BinaryLike, type KeyObject } from 'crypto';
2
+ export type HashableData = string | Buffer | Uint8Array | ArrayBuffer;
3
+ /**
4
+ * Calculate SHA256 hash of data and return as lowercase hex string.
5
+ * Used for body hash calculation in v4 authentication.
6
+ *
7
+ * Accepts string, Buffer, Uint8Array, and ArrayBuffer for compatibility
8
+ * with both Node.js and browser environments.
9
+ *
10
+ * Note: ArrayBuffer is converted to Uint8Array internally since Node.js crypto
11
+ * requires TypedArray or DataView, not plain ArrayBuffer.
12
+ *
13
+ * @param data - The data to hash
14
+ * @returns Lowercase hex string of SHA256 hash
15
+ */
16
+ export declare function sha256Hex(data: HashableData): string;
17
+ /**
18
+ * Calculate HMAC-SHA256 and return as lowercase hex string.
19
+ * This is the core cryptographic primitive shared by v2/v3/v4 authentication.
20
+ *
21
+ * @param key - The secret key for HMAC
22
+ * @param message - The message to authenticate
23
+ * @returns Lowercase hex string of HMAC-SHA256
24
+ */
25
+ export declare function createHmacWithSha256(key: string | BinaryLike | KeyObject, message: string | BinaryLike): string;
26
+ /**
27
+ * Normalize HTTP method to uppercase.
28
+ * Handles legacy 'del' → 'DELETE' conversion for backward compatibility.
29
+ *
30
+ * @param method - HTTP method (case-insensitive)
31
+ * @returns Uppercase HTTP method
32
+ */
33
+ export declare function normalizeMethod(method: string): string;
34
+ /**
35
+ * Extract path with query string from a URL.
36
+ * Handles both absolute URLs and relative paths.
37
+ *
38
+ * @param urlPath - Full URL or relative path
39
+ * @returns Path with query string (e.g., '/api/v2/wallet?foo=bar')
40
+ */
41
+ export declare function extractPathWithQuery(urlPath: string): string;
42
+ /**
43
+ * Get current timestamp in seconds (Unix epoch).
44
+ * Used for v4 authentication which uses seconds instead of milliseconds.
45
+ *
46
+ * @returns Current Unix timestamp in seconds
47
+ */
48
+ export declare function getTimestampSec(): number;
49
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAKpD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAE/G;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sha256Hex = sha256Hex;
4
+ exports.createHmacWithSha256 = createHmacWithSha256;
5
+ exports.normalizeMethod = normalizeMethod;
6
+ exports.extractPathWithQuery = extractPathWithQuery;
7
+ exports.getTimestampSec = getTimestampSec;
8
+ const crypto_1 = require("crypto");
9
+ /**
10
+ * Calculate SHA256 hash of data and return as lowercase hex string.
11
+ * Used for body hash calculation in v4 authentication.
12
+ *
13
+ * Accepts string, Buffer, Uint8Array, and ArrayBuffer for compatibility
14
+ * with both Node.js and browser environments.
15
+ *
16
+ * Note: ArrayBuffer is converted to Uint8Array internally since Node.js crypto
17
+ * requires TypedArray or DataView, not plain ArrayBuffer.
18
+ *
19
+ * @param data - The data to hash
20
+ * @returns Lowercase hex string of SHA256 hash
21
+ */
22
+ function sha256Hex(data) {
23
+ const normalizedData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
24
+ return (0, crypto_1.createHash)('sha256')
25
+ .update(normalizedData)
26
+ .digest('hex');
27
+ }
28
+ /**
29
+ * Calculate HMAC-SHA256 and return as lowercase hex string.
30
+ * This is the core cryptographic primitive shared by v2/v3/v4 authentication.
31
+ *
32
+ * @param key - The secret key for HMAC
33
+ * @param message - The message to authenticate
34
+ * @returns Lowercase hex string of HMAC-SHA256
35
+ */
36
+ function createHmacWithSha256(key, message) {
37
+ return (0, crypto_1.createHmac)('sha256', key).update(message).digest('hex');
38
+ }
39
+ /**
40
+ * Normalize HTTP method to uppercase.
41
+ * Handles legacy 'del' → 'DELETE' conversion for backward compatibility.
42
+ *
43
+ * @param method - HTTP method (case-insensitive)
44
+ * @returns Uppercase HTTP method
45
+ */
46
+ function normalizeMethod(method) {
47
+ const lowerMethod = method.toLowerCase();
48
+ if (lowerMethod === 'del') {
49
+ return 'DELETE';
50
+ }
51
+ return method.toUpperCase();
52
+ }
53
+ /**
54
+ * Extract path with query string from a URL.
55
+ * Handles both absolute URLs and relative paths.
56
+ *
57
+ * @param urlPath - Full URL or relative path
58
+ * @returns Path with query string (e.g., '/api/v2/wallet?foo=bar')
59
+ */
60
+ function extractPathWithQuery(urlPath) {
61
+ try {
62
+ // Try parsing as absolute URL first
63
+ const url = new URL(urlPath);
64
+ return url.pathname + url.search;
65
+ }
66
+ catch {
67
+ try {
68
+ const url = new URL(urlPath, 'http://localhost');
69
+ return url.pathname + url.search;
70
+ }
71
+ catch {
72
+ return urlPath;
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Get current timestamp in seconds (Unix epoch).
78
+ * Used for v4 authentication which uses seconds instead of milliseconds.
79
+ *
80
+ * @returns Current Unix timestamp in seconds
81
+ */
82
+ function getTimestampSec() {
83
+ return Math.floor(Date.now() / 1000);
84
+ }
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaUJBLDhCQUtDO0FBVUQsb0RBRUM7QUFTRCwwQ0FNQztBQVNELG9EQWFDO0FBUUQsMENBRUM7QUFqRkQsbUNBQWlGO0FBSWpGOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxJQUFrQjtJQUMxQyxNQUFNLGNBQWMsR0FBRyxJQUFJLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2pGLE9BQU8sSUFBQSxtQkFBVSxFQUFDLFFBQVEsQ0FBQztTQUN4QixNQUFNLENBQUMsY0FBNEIsQ0FBQztTQUNwQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxHQUFvQyxFQUFFLE9BQTRCO0lBQ3JHLE9BQU8sSUFBQSxtQkFBVSxFQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pFLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixlQUFlLENBQUMsTUFBYztJQUM1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekMsSUFBSSxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDMUIsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQzlCLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxPQUFlO0lBQ2xELElBQUksQ0FBQztRQUNILG9DQUFvQztRQUNwQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QixPQUFPLEdBQUcsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUNuQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDakQsT0FBTyxHQUFHLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7UUFDbkMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsZUFBZTtJQUM3QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIYXNoLCBjcmVhdGVIbWFjLCB0eXBlIEJpbmFyeUxpa2UsIHR5cGUgS2V5T2JqZWN0IH0gZnJvbSAnY3J5cHRvJztcblxuZXhwb3J0IHR5cGUgSGFzaGFibGVEYXRhID0gc3RyaW5nIHwgQnVmZmVyIHwgVWludDhBcnJheSB8IEFycmF5QnVmZmVyO1xuXG4vKipcbiAqIENhbGN1bGF0ZSBTSEEyNTYgaGFzaCBvZiBkYXRhIGFuZCByZXR1cm4gYXMgbG93ZXJjYXNlIGhleCBzdHJpbmcuXG4gKiBVc2VkIGZvciBib2R5IGhhc2ggY2FsY3VsYXRpb24gaW4gdjQgYXV0aGVudGljYXRpb24uXG4gKlxuICogQWNjZXB0cyBzdHJpbmcsIEJ1ZmZlciwgVWludDhBcnJheSwgYW5kIEFycmF5QnVmZmVyIGZvciBjb21wYXRpYmlsaXR5XG4gKiB3aXRoIGJvdGggTm9kZS5qcyBhbmQgYnJvd3NlciBlbnZpcm9ubWVudHMuXG4gKlxuICogTm90ZTogQXJyYXlCdWZmZXIgaXMgY29udmVydGVkIHRvIFVpbnQ4QXJyYXkgaW50ZXJuYWxseSBzaW5jZSBOb2RlLmpzIGNyeXB0b1xuICogcmVxdWlyZXMgVHlwZWRBcnJheSBvciBEYXRhVmlldywgbm90IHBsYWluIEFycmF5QnVmZmVyLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGRhdGEgdG8gaGFzaFxuICogQHJldHVybnMgTG93ZXJjYXNlIGhleCBzdHJpbmcgb2YgU0hBMjU2IGhhc2hcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNoYTI1NkhleChkYXRhOiBIYXNoYWJsZURhdGEpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkRGF0YSA9IGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciA/IG5ldyBVaW50OEFycmF5KGRhdGEpIDogZGF0YTtcbiAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgLnVwZGF0ZShub3JtYWxpemVkRGF0YSBhcyBCaW5hcnlMaWtlKVxuICAgIC5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBITUFDLVNIQTI1NiBhbmQgcmV0dXJuIGFzIGxvd2VyY2FzZSBoZXggc3RyaW5nLlxuICogVGhpcyBpcyB0aGUgY29yZSBjcnlwdG9ncmFwaGljIHByaW1pdGl2ZSBzaGFyZWQgYnkgdjIvdjMvdjQgYXV0aGVudGljYXRpb24uXG4gKlxuICogQHBhcmFtIGtleSAtIFRoZSBzZWNyZXQga2V5IGZvciBITUFDXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGF1dGhlbnRpY2F0ZVxuICogQHJldHVybnMgTG93ZXJjYXNlIGhleCBzdHJpbmcgb2YgSE1BQy1TSEEyNTZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhtYWNXaXRoU2hhMjU2KGtleTogc3RyaW5nIHwgQmluYXJ5TGlrZSB8IEtleU9iamVjdCwgbWVzc2FnZTogc3RyaW5nIHwgQmluYXJ5TGlrZSk6IHN0cmluZyB7XG4gIHJldHVybiBjcmVhdGVIbWFjKCdzaGEyNTYnLCBrZXkpLnVwZGF0ZShtZXNzYWdlKS5kaWdlc3QoJ2hleCcpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBIVFRQIG1ldGhvZCB0byB1cHBlcmNhc2UuXG4gKiBIYW5kbGVzIGxlZ2FjeSAnZGVsJyDihpIgJ0RFTEVURScgY29udmVyc2lvbiBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbiAqXG4gKiBAcGFyYW0gbWV0aG9kIC0gSFRUUCBtZXRob2QgKGNhc2UtaW5zZW5zaXRpdmUpXG4gKiBAcmV0dXJucyBVcHBlcmNhc2UgSFRUUCBtZXRob2RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZU1ldGhvZChtZXRob2Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGxvd2VyTWV0aG9kID0gbWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChsb3dlck1ldGhvZCA9PT0gJ2RlbCcpIHtcbiAgICByZXR1cm4gJ0RFTEVURSc7XG4gIH1cbiAgcmV0dXJuIG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEV4dHJhY3QgcGF0aCB3aXRoIHF1ZXJ5IHN0cmluZyBmcm9tIGEgVVJMLlxuICogSGFuZGxlcyBib3RoIGFic29sdXRlIFVSTHMgYW5kIHJlbGF0aXZlIHBhdGhzLlxuICpcbiAqIEBwYXJhbSB1cmxQYXRoIC0gRnVsbCBVUkwgb3IgcmVsYXRpdmUgcGF0aFxuICogQHJldHVybnMgUGF0aCB3aXRoIHF1ZXJ5IHN0cmluZyAoZS5nLiwgJy9hcGkvdjIvd2FsbGV0P2Zvbz1iYXInKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFBhdGhXaXRoUXVlcnkodXJsUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgdHJ5IHtcbiAgICAvLyBUcnkgcGFyc2luZyBhcyBhYnNvbHV0ZSBVUkwgZmlyc3RcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHVybFBhdGgpO1xuICAgIHJldHVybiB1cmwucGF0aG5hbWUgKyB1cmwuc2VhcmNoO1xuICB9IGNhdGNoIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJsID0gbmV3IFVSTCh1cmxQYXRoLCAnaHR0cDovL2xvY2FsaG9zdCcpO1xuICAgICAgcmV0dXJuIHVybC5wYXRobmFtZSArIHVybC5zZWFyY2g7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdXJsUGF0aDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgY3VycmVudCB0aW1lc3RhbXAgaW4gc2Vjb25kcyAoVW5peCBlcG9jaCkuXG4gKiBVc2VkIGZvciB2NCBhdXRoZW50aWNhdGlvbiB3aGljaCB1c2VzIHNlY29uZHMgaW5zdGVhZCBvZiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHJldHVybnMgQ3VycmVudCBVbml4IHRpbWVzdGFtcCBpbiBzZWNvbmRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaW1lc3RhbXBTZWMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xufVxuIl19
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@bitgo-beta/sdk-hmac",
3
- "version": "1.0.1-beta.97",
3
+ "version": "1.0.1-beta.970",
4
4
  "description": "HMAC module for the BitGo SDK",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "yarn tsc --build --incremental --verbose .",
9
9
  "fmt": "prettier --write .",
10
- "check-fmt": "prettier --check .",
10
+ "check-fmt": "prettier --check '**/*.{ts,js,json}'",
11
11
  "clean": "rm -r ./dist",
12
12
  "lint": "eslint --quiet .",
13
13
  "test": "npm run coverage",
@@ -16,7 +16,7 @@
16
16
  "prepare": "npm run build"
17
17
  },
18
18
  "dependencies": {
19
- "@bitgo-beta/sjcl": "1.0.2-beta.969"
19
+ "@bitgo-beta/sjcl": "1.0.2-beta.1842"
20
20
  },
21
21
  "devDependencies": {
22
22
  "chai": "^4.3.6",
@@ -46,5 +46,5 @@
46
46
  ".ts"
47
47
  ]
48
48
  },
49
- "gitHead": "c8b2277e85fcd4da3e31b82ea8e3c0ac1e98ed80"
49
+ "gitHead": "025735cf19973e1aeb7e13be2aea92a9a2f32657"
50
50
  }