diff --git a/express-basic-auth.d.ts b/express-basic-auth.d.ts index 3bbe755..38d6fda 100644 --- a/express-basic-auth.d.ts +++ b/express-basic-auth.d.ts @@ -1,6 +1,6 @@ /// -import { Request, RequestHandler } from 'express' +import { Request, RequestHandler, Response } from 'express' /** * This is the middleware builder. @@ -16,14 +16,14 @@ declare function expressBasicAuth(options: expressBasicAuth.BasicAuthMiddlewareO declare namespace expressBasicAuth { /** * Time safe string comparison function to protect against timing attacks. - * + * * It is important to provide the arguments in the correct order, as the runtime * depends only on the `userInput` argument. Switching the order would expose the `secret` * to timing attacks. - * + * * @param userInput The user input to be compared * @param secret The secret value the user input should be compared with - * + * * @returns true if `userInput` matches `secret`, false if not */ export function safeCompare(userInput: string, secret: string): boolean @@ -46,7 +46,15 @@ declare namespace expressBasicAuth { * }) */ export interface IBasicAuthedRequest extends Request { - auth: { user: string, password: string } + auth?: { user: string, password: string } + } + + export interface IUnauthorizeOptions { + challenge: boolean; + getResponseBody: any; + req: IBasicAuthedRequest; + realm: any; + res: Response; } type Authorizer = (username: string, password: string) => boolean @@ -140,7 +148,7 @@ declare namespace expressBasicAuth { * function authorizer(username, password, authorize) { * if(username.startsWith('A') && password.startsWith('secret')) * return authorize(null, true) - * + * * return authorize(null, false) * } */ diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..e26a57a --- /dev/null +++ b/index.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/index.d.ts.map b/index.d.ts.map new file mode 100644 index 0000000..82335e7 --- /dev/null +++ b/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/index.js b/index.js index e24980e..ec93b6c 100644 --- a/index.js +++ b/index.js @@ -1,98 +1,108 @@ -const auth = require('basic-auth') -const assert = require('assert') -const timingSafeEqual = require('crypto').timingSafeEqual - -// Credits for the actual algorithm go to github/@Bruce17 -// Thanks to github/@hraban for making me implement this -function safeCompare(userInput, secret) { - const userInputLength = Buffer.byteLength(userInput) - const secretLength = Buffer.byteLength(secret) - - const userInputBuffer = Buffer.alloc(userInputLength, 0, 'utf8') - userInputBuffer.write(userInput) - const secretBuffer = Buffer.alloc(userInputLength, 0, 'utf8') - secretBuffer.write(secret) - - return !!(timingSafeEqual(userInputBuffer, secretBuffer) & userInputLength === secretLength) -} - -function ensureFunction(option, defaultValue) { - if(option == undefined) - return function() { return defaultValue } - - if(typeof option != 'function') - return function() { return option } - - return option -} - +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const assert_1 = __importDefault(require("assert")); +const basic_auth_1 = __importDefault(require("basic-auth")); +const crypto_1 = require("crypto"); +buildMiddleware.safeCompare = safeCompare; +module.exports = buildMiddleware; function buildMiddleware(options) { - var challenge = options.challenge != undefined ? !!options.challenge : false - var users = options.users || {} - var authorizer = options.authorizer || staticUsersAuthorizer - var isAsync = options.authorizeAsync != undefined ? !!options.authorizeAsync : false - var getResponseBody = ensureFunction(options.unauthorizedResponse, '') - var realm = ensureFunction(options.realm) - - assert(typeof users == 'object', 'Expected an object for the basic auth users, found ' + typeof users + ' instead') - assert(typeof authorizer == 'function', 'Expected a function for the basic auth authorizer, found ' + typeof authorizer + ' instead') - - function staticUsersAuthorizer(username, password) { - for(var i in users) - if(safeCompare(username, i) & safeCompare(password, users[i])) - return true - - return false - } - + const { challenge, authorizer, isAsync, getResponseBody, realm } = setupOptions(options); return function authMiddleware(req, res, next) { - var authentication = auth(req) - - if(!authentication) - return unauthorized() - + const unauthOpts = { + challenge, + getResponseBody, + req, + realm, + res, + }; + const authentication = basic_auth_1.default(req); + if (!authentication) { + return unauthorized(unauthOpts); + } req.auth = { user: authentication.name, password: authentication.pass + }; + if (isAsync) { + return authorizer(authentication.name, authentication.pass, (err, approved) => { + return authorizerCallback(err, approved, next, unauthOpts); + }); } - - if(isAsync) - return authorizer(authentication.name, authentication.pass, authorizerCallback) - else if(!authorizer(authentication.name, authentication.pass)) - return unauthorized() - - return next() - - function unauthorized() { - if(challenge) { - var challengeString = 'Basic' - var realmName = realm(req) - - if(realmName) - challengeString += ' realm="' + realmName + '"' - - res.set('WWW-Authenticate', challengeString) - } - - //TODO: Allow response body to be JSON (maybe autodetect?) - const response = getResponseBody(req) - - if(typeof response == 'string') - return res.status(401).send(response) - - return res.status(401).json(response) + else if (!authorizer(authentication.name, authentication.pass)) { + return unauthorized(unauthOpts); + } + return next(); + }; +} +function setupOptions(options) { + const challenge = options.challenge === true; + const users = options['users'] || {}; + const authorizer = options['authorizer'] || ((user, pass) => { return staticUsersAuthorizer(user, pass, users); }); + const isAsync = options['authorizeAsync'] === true; + const getResponseBody = ensureFunction(options.unauthorizedResponse, ''); + const realm = ensureFunction(options['realm']); + assert_1.default(typeof users === 'object', `Expected an object for the basic auth users, found ${typeof users} instead`); + assert_1.default(typeof authorizer === 'function', `Expected a function for the basic auth authorizer, found ${typeof authorizer} instead`); + return { + challenge, + users, + authorizer, + isAsync, + getResponseBody, + realm, + }; +} +function authorizerCallback(err, approved, next, options) { + assert_1.default.ifError(err); + if (approved) { + return next(); + } + return unauthorized(options); +} +function unauthorized({ challenge, getResponseBody, req, realm, res }) { + if (challenge) { + let challengeString = 'Basic'; + const realmName = realm(req); + if (realmName) { + challengeString = `${challengeString} realm="${realmName}"`; } - - function authorizerCallback(err, approved) { - assert.ifError(err) - - if(approved) - return next() - - return unauthorized() + res.set('WWW-Authenticate', challengeString); + } + const response = getResponseBody(req); + if (typeof response == 'string') { + return res.status(401).send(response); + } + return res.status(401).json(response); +} +function ensureFunction(option, defaultValue = null) { + if (option == undefined) { + return () => { return defaultValue; }; + } + if (typeof option !== 'function') { + return () => { return option; }; + } + return option; +} +function staticUsersAuthorizer(username, password, users) { + for (var currentUser in users) { + const checkUser = safeCompare(username, currentUser); + const checkPassword = safeCompare(password, users[currentUser]); + if (checkUser && checkPassword) { + return true; } } + return false; +} +function safeCompare(userInput, secret) { + const userInputLength = Buffer.byteLength(userInput); + const secretLength = Buffer.byteLength(secret); + const userInputBuffer = Buffer.alloc(userInputLength, 0, 'utf8'); + userInputBuffer.write(userInput); + const secretBuffer = Buffer.alloc(userInputLength, 0, 'utf8'); + secretBuffer.write(secret); + return !!(crypto_1.timingSafeEqual(userInputBuffer, secretBuffer) && (userInputLength === secretLength)); } - -buildMiddleware.safeCompare = safeCompare -module.exports = buildMiddleware +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/index.js.map b/index.js.map new file mode 100644 index 0000000..2ca7f63 --- /dev/null +++ b/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..7273281 --- /dev/null +++ b/index.ts @@ -0,0 +1,135 @@ +import assert from 'assert'; +import auth from 'basic-auth'; +import { timingSafeEqual } from 'crypto'; +import { NextFunction, RequestHandler, Response } from 'express'; +import { BasicAuthMiddlewareOptions, IBasicAuthedRequest, IUnauthorizeOptions } from './express-basic-auth'; + + +buildMiddleware.safeCompare = safeCompare; +module.exports = buildMiddleware; + +function buildMiddleware(options: BasicAuthMiddlewareOptions): RequestHandler { + const { challenge, + authorizer, + isAsync, + getResponseBody, + realm + } = setupOptions(options); + return function authMiddleware(req: IBasicAuthedRequest, res: Response, next: NextFunction): any { + const unauthOpts: IUnauthorizeOptions = { + challenge, + getResponseBody, + req, + realm, + res, + }; + + const authentication = auth(req); + if (!authentication) { + return unauthorized(unauthOpts); + } + + req.auth = { + user: authentication.name, + password: authentication.pass + } + + if (isAsync) { + return authorizer(authentication.name, authentication.pass, (err: Error, approved: boolean) => { + return authorizerCallback(err, approved, next, unauthOpts); + }); + } else if (!authorizer(authentication.name, authentication.pass)) { + return unauthorized(unauthOpts); + } + return next(); + } +} + +function setupOptions(options: any) { + const challenge = options.challenge === true; + const users = options['users'] || {}; // tslint:disable-line + const authorizer = options['authorizer'] || ((user: string, pass: string) => { return staticUsersAuthorizer(user, pass, users); }); + const isAsync = options['authorizeAsync'] === true; + const getResponseBody = ensureFunction(options.unauthorizedResponse, ''); + const realm = ensureFunction(options['realm']); + + assert(typeof users === 'object', `Expected an object for the basic auth users, found ${typeof users} instead`); + assert(typeof authorizer === 'function', `Expected a function for the basic auth authorizer, found ${typeof authorizer} instead`); + + return { + challenge, + users, + authorizer, + isAsync, + getResponseBody, + realm, + }; +} + +function authorizerCallback(err: any, approved: boolean, next: NextFunction, options: IUnauthorizeOptions) { + assert.ifError(err); + if (approved) { + return next(); + } + return unauthorized(options); +} + +function unauthorized({ + challenge, + getResponseBody, + req, + realm, + res +}: IUnauthorizeOptions) { + if (challenge) { + let challengeString = 'Basic' + const realmName = realm(req); + if (realmName) { + challengeString = `${challengeString} realm="${realmName}"`; + } + res.set('WWW-Authenticate', challengeString); + } + + //TODO: Allow response body to be JSON (maybe autodetect?) + const response = getResponseBody(req); + + if (typeof response == 'string') { + return res.status(401).send(response); + } + return res.status(401).json(response); +} + +function ensureFunction(option: BasicAuthMiddlewareOptions, defaultValue: any = null) { + if (option == undefined) { + return () => { return defaultValue }; + } + if (typeof option !== 'function') { + return () => { return option }; + } + return option; +} + +function staticUsersAuthorizer(username: string, password: string, users: []): boolean { + for (var currentUser in users) { + const checkUser = safeCompare(username, currentUser); + const checkPassword = safeCompare(password, users[currentUser]); + if (checkUser && checkPassword) { + return true + } + } + return false +} + +// Credits for the actual algorithm go to github/@Bruce17 +// Thanks to github/@hraban for making me implement this +function safeCompare(userInput:string , secret: string) { + const userInputLength = Buffer.byteLength(userInput) + const secretLength = Buffer.byteLength(secret) + + const userInputBuffer = Buffer.alloc(userInputLength, 0, 'utf8') + userInputBuffer.write(userInput) + const secretBuffer = Buffer.alloc(userInputLength, 0, 'utf8') + secretBuffer.write(secret) + + return !!(timingSafeEqual(userInputBuffer, secretBuffer) && (userInputLength === secretLength)) // tslint:disable-line +} diff --git a/package-lock.json b/package-lock.json index d59af23..3896fc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,10 +4,25 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/assert": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/assert/-/assert-1.4.3.tgz", + "integrity": "sha512-491hfOvNr0+BGOHT2m36xJ+LK68IuOshvxV0VIrKOnzBDL11WlDa3PwO+drTYkwCdfzJRN9REcDPZVVcrx1ucw==", + "dev": true + }, + "@types/basic-auth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/basic-auth/-/basic-auth-1.1.2.tgz", + "integrity": "sha512-NzkkcC+gkkILWaBi3+/z/3do6Ybk6TWeTqV5zCVXmG2KaBoT5YqlJvfqP44HCyDA+Cu58pp7uKAxy/G58se/TA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/body-parser": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", - "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", + "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", "dev": true, "requires": { "@types/connect": "*", @@ -23,16 +38,10 @@ "@types/node": "*" } }, - "@types/events": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, "@types/express": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", - "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", + "integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==", "dev": true, "requires": { "@types/body-parser": "*", @@ -41,38 +50,37 @@ } }, "@types/express-serve-static-core": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz", - "integrity": "sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==", + "version": "4.16.10", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.10.tgz", + "integrity": "sha512-gM6evDj0OvTILTRKilh9T5dTaGpv1oYiFcJAfgSejuMJgGJUsD9hKEU2lB4aiTNy4WwChxRnjfYFuBQsULzsJw==", "dev": true, "requires": { - "@types/events": "*", "@types/node": "*", "@types/range-parser": "*" } }, "@types/mime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", - "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", "dev": true }, "@types/node": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz", - "integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==", + "version": "12.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz", + "integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==", "dev": true }, "@types/range-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.2.tgz", - "integrity": "sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, "@types/serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", "dev": true, "requires": { "@types/express-serve-static-core": "*", @@ -80,13 +88,30 @@ } }, "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + } } }, "array-flatten": { @@ -116,21 +141,29 @@ } }, "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { - "bytes": "3.0.0", + "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } } }, "brace-expansion": { @@ -150,9 +183,9 @@ "dev": true }, "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, "combined-stream": { @@ -183,10 +216,13 @@ "dev": true }, "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } }, "content-type": { "version": "1.0.4", @@ -195,9 +231,9 @@ "dev": true }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, "cookie-signature": { @@ -282,41 +318,49 @@ "dev": true }, "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { - "accepts": "~1.3.5", + "accepts": "~1.3.7", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", "content-type": "~1.0.4", - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.1.1", + "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } } }, "extend": { @@ -326,17 +370,17 @@ "dev": true }, "finalhandler": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, @@ -408,21 +452,22 @@ "dev": true }, "http-errors": { - "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" } }, "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -445,9 +490,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", "dev": true }, "isarray": { @@ -556,9 +601,9 @@ "dev": true }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "on-finished": { @@ -580,9 +625,9 @@ } }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "path-is-absolute": { @@ -604,13 +649,13 @@ "dev": true }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "dev": true, "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" + "ipaddr.js": "1.9.0" } }, "qs": { @@ -620,20 +665,20 @@ "dev": true }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, @@ -664,9 +709,9 @@ "dev": true }, "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", @@ -676,30 +721,44 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" + "parseurl": "~1.3.3", + "send": "0.17.1" } }, "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, "should": { @@ -757,9 +816,9 @@ "dev": true }, "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, "string_decoder": { @@ -825,20 +884,43 @@ "has-flag": "^3.0.0" } }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + } } }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", "dev": true }, "unpipe": { diff --git a/package.json b/package.json index ef57536..2296373 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "types": "express-basic-auth.d.ts", "scripts": { "check-dts": "tsc express-basic-auth.d.ts", + "build": "tsc", "test": "mocha test.js && npm run check-dts" }, "repository": { @@ -30,11 +31,14 @@ "basic-auth": "^2.0.1" }, "devDependencies": { - "@types/express": "^4.16.0", - "express": "^4.16.4", + "@types/assert": "^1.4.3", + "@types/basic-auth": "^1.1.2", + "@types/express": "^4.17.1", + "@types/node": "^12.11.7", + "express": "^4.17.1", "mocha": "^5.2.0", "should": "^11.2.1", "supertest": "^3.3.0", - "typescript": "^2.9.2" + "typescript": "^3.6.4" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..82927f0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,59 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ + "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./index.js", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* Enable strict null checks. */ + "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +}