Skip to content

Commit

Permalink
Merge pull request #35 from lob/MI-471/dependency-upgrades
Browse files Browse the repository at this point in the history
MI-471: Upgrade Hapi and other vulnerable deps
  • Loading branch information
kevinpjones authored Sep 16, 2024
2 parents 9e441de + 9b1b1a4 commit cdbbcd7
Show file tree
Hide file tree
Showing 20 changed files with 4,299 additions and 9,333 deletions.
15 changes: 11 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
{
extends: "lob",
globals: {
expect: false
"env": {
"node": true,
"es6": true
},
rules: {
"parserOptions": {
"ecmaVersion": 2020
},
"extends": "lob",
"globals": {
"expect": false
},
"rules": {
"no-extra-parens": 0
}
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [12, 14, 16]
node-version: [18, 20]

services:
redis:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ node_modules

# SQLite databases
*.sqlite3

.idea/

.nyc_output/
.DS_Store
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.14.0
20.15.0
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### 5.0.0 (2024-09-16)

* Update to use [@hapi/hapi](https://www.npmjs.com/package/@hapi/hapi) package, replaces deprecated [hapi](https://www.npmjs.com/package/hapi) package in peer dependencies.

#### BREAKING CHANGES

* Dropped support for deprecated [hapi](https://www.npmjs.com/package/hapi) package

### 4.3.0 (2019-07-24)

##### Chores
Expand Down
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@


services:
redis:
image: redis:7
ports:
- "6379:6379"
volumes:
- redis_data:/data


volumes:
redis_data:
35 changes: 17 additions & 18 deletions lib/counter.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
'use strict';

const Bluebird = require('bluebird');

const RADIX = 10;

exports.count = (Model, request, Redis, key, ttlFn) => {
return Bluebird.resolve()
.then(() => {
if (typeof Model.prototype.filter === 'function') {
return new Model().filter(request.query.filter, request.auth.credentials).count('*');
}
return new Model().count('*');
})
.then((count) => {
return parseInt(count, RADIX);
})
.tap((count) => {
if (Redis) {
const seconds = ttlFn(count);
return Redis.setAsync(key, count, 'EX', seconds);
}
});
return Promise.resolve()
.then(() => {
if (typeof Model.prototype.filter === 'function') {
return new Model().filter(request.query.filter, request.auth.credentials).count('*');
}
return new Model().count('*');
})
.then((count) => {
return parseInt(count, RADIX);
})
.then(async (count) => {
if (Redis) {
const seconds = ttlFn(count);
await Redis.set(key, count, { EX: seconds });
}
return count;
});
};
77 changes: 41 additions & 36 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,65 @@
'use strict';

const Bluebird = require('bluebird');
const Joi = require('joi');

const ApproximateCountValidator = require('./validators/approximate-count');
const Counter = require('./counter');
const Key = require('./key');
const TotalCountValidator = require('./validators/total-count');

exports.register = (server, options, next) => {
/** @typedef {import('@hapi/hapi').Server} Server } */

/** @typedef {import('redis').RedisClientType} RedisClient } */

server.ext('onPreResponse', (request, reply) => {
/**
* Registers the events routes.
* @param {Server} server
* @param {{ ttl: number?, redisClient: RedisClient?, uniqueKey: Function? }} options
*/
function register (server, options) {

server.ext('onPreResponse', (request, h) => {

const settings = request.route.settings.plugins.totalCount;
const includeApproximate = !settings || !settings.include || settings.include.indexOf('approximate') !== -1;
const includeTotal = !settings || !settings.include || settings.include.indexOf('total') !== -1;
const approximateCountValid = includeApproximate ? !Joi.validate(request, ApproximateCountValidator, { allowUnknown: true }).error : false;
const totalCountValid = includeTotal ? !Joi.validate(request, TotalCountValidator, { allowUnknown: true }).error : false;
const approximateCountValid = includeApproximate ? !ApproximateCountValidator.validate(request, { allowUnknown: true }).error : false;
const totalCountValid = includeTotal ? !TotalCountValidator.validate(request, { allowUnknown: true }).error : false;

if (!settings || !settings.model || (!approximateCountValid && !totalCountValid)) {
return reply.continue();
return h.continue;
}

const Model = settings.model;
const Redis = options.redisClient;
const ttl = options.ttl;
const key = Key.generate(Model, request, options.uniqueKey);

return Bluebird.resolve()
.then(() => {
if (Redis && approximateCountValid) {
return Redis.getAsync(key);
}
})
.then((cachedCount) => {
if (cachedCount) {
return parseInt(cachedCount);
}

return Counter.count(Model, request, Redis, key, ttl);
})
.then((count) => {
if (approximateCountValid) {
request.response.source.approximate_count = count;
} else {
request.response.source.total_count = count;
}
return reply.continue();
})
.catch((err) => reply(err));
});
return Promise.resolve()
.then(() => {
if (Redis && approximateCountValid) {
return Redis.get(key);
}
})
.then((cachedCount) => {
if (cachedCount) {
return parseInt(cachedCount);
}

next();

};
return Counter.count(Model, request, Redis, key, ttl);
})
.then((count) => {
if (approximateCountValid) {
request.response.source.approximate_count = count;
} else {
request.response.source.total_count = count;
}
return h.continue;
}).catch((err) => {
throw err;
});
});
}

exports.register.attributes = {
pkg: require('../package.json')
exports.plugin = {
pkg: require('../package.json'),
register
};
11 changes: 11 additions & 0 deletions lib/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

const ObjectHash = require('object-hash');

/** @typedef {import('bookshelf').Model} Model */

/** @typedef {import('@hapi/hapi').Request} Request */

/**
* Generates a cache key for the approximate count value.
* @param {Model} Model
* @param {Request} request
* @param {Function?} uniqueKeyFn
* @returns {String} The cache key
*/
exports.generate = (Model, request, uniqueKeyFn) => {
const tableName = Model.prototype.tableName;
let filterHash = '';
Expand Down
4 changes: 2 additions & 2 deletions lib/validators/approximate-count.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

const Joi = require('joi');

module.exports = {
module.exports = Joi.object({
query: Joi.object().keys({
include: Joi.array().items(Joi.string().valid('approximate_count').required(), Joi.any()).required()
}),
response: Joi.object().keys({
source: Joi.object().required()
})
};
});
5 changes: 3 additions & 2 deletions lib/validators/total-count.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

const Joi = require('joi');

module.exports = {
module.exports = Joi.object({
query: Joi.object().keys({
include: Joi.array().items(Joi.string().valid('total_count').required(), Joi.any()).required()
}),
response: Joi.object().keys({
source: Joi.object().required()
})
};
});

Loading

0 comments on commit cdbbcd7

Please sign in to comment.