simple-hmac-auth
Advanced tools
Comparing version 3.3.5 to 4.0.0
@@ -16,2 +16,3 @@ "use strict"; | ||
'authorization', | ||
'timestamp', | ||
'date', | ||
@@ -31,3 +32,3 @@ 'content-length', | ||
function canonicalize(method, uri, queryString = '', headers, data) { | ||
// Hash the method, the path, aplhabetically sorted headers, alphabetically sorted GET parameters, and body data | ||
// Hash the method, the path, alphabetically sorted headers, alphabetically sorted GET parameters, and body data | ||
method = method.toUpperCase(); | ||
@@ -56,3 +57,3 @@ if (queryString === undefined || queryString === null) { | ||
headerKeys.sort(); | ||
// Create a string of all headers, arranged alphabetically, seperated by newlines | ||
// Create a string of all headers, arranged alphabetically, separated by newlines | ||
let headerString = ''; | ||
@@ -76,3 +77,3 @@ for (const [index, key] of headerKeys.entries()) { | ||
Alphabetically sorted query string with individually escaped keys and values + \n | ||
Alphabetically sorted headers with lower case keys, seperated by newlines + \n | ||
Alphabetically sorted headers with lower case keys, separated by newlines + \n | ||
Hash of body, or hash of blank string if body is empty | ||
@@ -79,0 +80,0 @@ |
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import http from 'http'; | ||
@@ -12,2 +13,3 @@ import https from 'https'; | ||
algorithm?: string; | ||
useDateHeader?: boolean; | ||
headers?: { | ||
@@ -14,0 +16,0 @@ [key: string]: string; |
@@ -78,2 +78,5 @@ "use strict"; | ||
} | ||
if (typeof validatedSettings.useDateHeader !== 'boolean') { | ||
validatedSettings.useDateHeader = false; | ||
} | ||
if (typeof validatedSettings.headers !== 'object') { | ||
@@ -172,3 +175,8 @@ validatedSettings.headers = {}; | ||
headers.authorization = `api-key ${apiKey}`; | ||
headers.date = new Date().toUTCString(); | ||
if (this._settings.useDateHeader === true) { | ||
headers.date = new Date().toUTCString(); | ||
} | ||
else { | ||
headers.timestamp = new Date().toUTCString(); | ||
} | ||
// Sort query keys alphabetically | ||
@@ -231,4 +239,4 @@ const keys = Object.keys(query).sort(); | ||
const { algorithm } = this._settings; | ||
const canonical = canonicalize_1.default(method, path, queryString, headers, bodyData); | ||
const signature = sign_1.sign(canonical, secret, algorithm); | ||
const canonical = (0, canonicalize_1.default)(method, path, queryString, headers, bodyData); | ||
const signature = (0, sign_1.sign)(canonical, secret, algorithm); | ||
// Populate the HTTP authorization header | ||
@@ -235,0 +243,0 @@ headers.signature = `simple-hmac-auth ${algorithm} ${signature}`; |
@@ -57,2 +57,3 @@ "use strict"; | ||
async authenticate(request, data) { | ||
var _a; | ||
// Let's just assume the worst until we have reason to believe otherwise | ||
@@ -94,11 +95,12 @@ request.authenticated = false; | ||
} | ||
if (request.headers.date === undefined) { | ||
throw new AuthError_1.default(`Missing timestamp. Please timestamp all incoming requests by including 'date' header.`, `DATE_HEADER_MISSING`); | ||
const timestamp = (_a = request.headers.date) !== null && _a !== void 0 ? _a : request.headers.timestamp; | ||
if (timestamp === undefined) { | ||
throw new AuthError_1.default(`Missing timestamp. Please timestamp all incoming requests by including either the 'date' or 'timestamp' header.`, `DATE_HEADER_MISSING`); | ||
} | ||
// First, confirm that the 'date' header is recent enough | ||
const requestTime = new Date(request.headers.date); | ||
const requestTime = new Date(timestamp); | ||
const now = new Date(); | ||
// If this request was made over [60] seconds ago, ignore it | ||
if ((now.getTime() / 1000) - (requestTime.getTime() / 1000) > (this.options.permittedTimestampSkew / 1000)) { | ||
const error = new AuthError_1.default(`Timestamp is too old. Recieved: "${request.headers.date}" current time: "${now.toUTCString()}"`, `DATE_HEADER_INVALID`); | ||
const error = new AuthError_1.default(`Timestamp is too old. Received: "${request.headers.date}" current time: "${now.toUTCString()}"`, `DATE_HEADER_INVALID`); | ||
error.time = now.toUTCString(); | ||
@@ -132,4 +134,4 @@ throw error; | ||
} | ||
const canonical = canonicalize_1.default(request.method, requestURL.pathname, requestURL.query, headers, data); | ||
const calculatedSignature = sign_1.sign(canonical, secret, algorithm); | ||
const canonical = (0, canonicalize_1.default)(request.method, requestURL.pathname, requestURL.query, headers, data); | ||
const calculatedSignature = (0, sign_1.sign)(canonical, secret, algorithm); | ||
request.signature = calculatedSignature; | ||
@@ -136,0 +138,0 @@ request.signatureExpected = calculatedSignature; |
{ | ||
"name": "simple-hmac-auth", | ||
"version": "3.3.5", | ||
"version": "4.0.0", | ||
"description": "Library designed to make building APIs that use HMAC signatures simple.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -38,5 +38,5 @@ # simple-hmac-auth | ||
Each request requires three headers: `date`, `authorization` and `signature`. If the HTTP request contains a body, the `content-length` and `content-type` headers are also required. | ||
Each request requires three headers: `authorization`, `signature` and either `date` or `timestamp`. If the HTTP request contains a body, the `content-length` and `content-type` headers are also required. | ||
The `date` header is a standard [RFC-822 (updated in RFC-1123)](https://tools.ietf.org/html/rfc822#section-5) date, as per [RFC-7231](https://tools.ietf.org/html/rfc7231#section-7.1.1.2). | ||
The `date` header is a standard [RFC-822 (updated in RFC-1123)](https://tools.ietf.org/html/rfc822#section-5) date, as per [RFC-7231](https://tools.ietf.org/html/rfc7231#section-7.1.1.2). Because it [cannot be programmatically set inside of a browser](https://fetch.spec.whatwg.org/#forbidden-header-name), the `timestamp` header may be substituted instead. | ||
@@ -43,0 +43,0 @@ The `authorization` header is a standard as per [RFC-2617](https://tools.ietf.org/html/rfc2617#section-3.2.2) that, confusingly, is designed for authentication and not authorization. It should contain a string representation of the client's API key. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
57112
954