Skip to content

Commit 05c6741

Browse files
committed
MI-471: Upgrade Hapi and other vulnerable deps
1 parent 9e441de commit 05c6741

18 files changed

+4281
-9323
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212

1313
strategy:
1414
matrix:
15-
node-version: [12, 14, 16]
15+
node-version: [18, 20]
1616

1717
services:
1818
redis:

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,8 @@ node_modules
3434

3535
# SQLite databases
3636
*.sqlite3
37+
38+
.idea/
39+
40+
.nyc_output/
41+
.DS_Store

.node-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
16.14.0
1+
20.15.0

docker-compose.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
services:
4+
redis:
5+
image: redis:7
6+
ports:
7+
- "6379:6379"
8+
volumes:
9+
- redis_data:/data
10+
11+
12+
volumes:
13+
redis_data:

lib/counter.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
'use strict';
22

3-
const Bluebird = require('bluebird');
4-
53
const RADIX = 10;
64

75
exports.count = (Model, request, Redis, key, ttlFn) => {
8-
return Bluebird.resolve()
9-
.then(() => {
10-
if (typeof Model.prototype.filter === 'function') {
11-
return new Model().filter(request.query.filter, request.auth.credentials).count('*');
12-
}
13-
return new Model().count('*');
14-
})
15-
.then((count) => {
16-
return parseInt(count, RADIX);
17-
})
18-
.tap((count) => {
19-
if (Redis) {
20-
const seconds = ttlFn(count);
21-
return Redis.setAsync(key, count, 'EX', seconds);
22-
}
23-
});
6+
return Promise.resolve()
7+
.then(() => {
8+
if (typeof Model.prototype.filter === 'function') {
9+
return new Model().filter(request.query.filter, request.auth.credentials).count('*');
10+
}
11+
return new Model().count('*');
12+
})
13+
.then((count) => {
14+
return parseInt(count, RADIX);
15+
})
16+
.then(async (count) => {
17+
if (Redis) {
18+
const seconds = ttlFn(count);
19+
await Redis.set(key, count, {EX: seconds});
20+
}
21+
return count;
22+
});
2423
};

lib/index.js

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,67 @@
11
'use strict';
22

3-
const Bluebird = require('bluebird');
43
const Joi = require('joi');
54

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

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

13-
server.ext('onPreResponse', (request, reply) => {
12+
/** @typedef {import('redis').RedisClientType} RedisClient } */
13+
14+
/**
15+
* Registers the events routes.
16+
* @param {Server} server
17+
* @param {{ ttl: number?, redisClient: RedisClient?, uniqueKey: Function? }} options
18+
*/
19+
function register (server, options) {
20+
21+
server.ext('onPreResponse', (request, h) => {
1422

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

2129
if (!settings || !settings.model || (!approximateCountValid && !totalCountValid)) {
22-
return reply.continue();
30+
return h.continue;
2331
}
2432

2533
const Model = settings.model;
2634
const Redis = options.redisClient;
2735
const ttl = options.ttl;
2836
const key = Key.generate(Model, request, options.uniqueKey);
2937

30-
return Bluebird.resolve()
31-
.then(() => {
32-
if (Redis && approximateCountValid) {
33-
return Redis.getAsync(key);
34-
}
35-
})
36-
.then((cachedCount) => {
37-
if (cachedCount) {
38-
return parseInt(cachedCount);
39-
}
40-
41-
return Counter.count(Model, request, Redis, key, ttl);
42-
})
43-
.then((count) => {
44-
if (approximateCountValid) {
45-
request.response.source.approximate_count = count;
46-
} else {
47-
request.response.source.total_count = count;
48-
}
49-
return reply.continue();
50-
})
51-
.catch((err) => reply(err));
52-
});
53-
54-
next();
38+
return Promise.resolve()
39+
.then(() => {
40+
if (Redis && approximateCountValid) {
41+
return Redis.get(key);
42+
}
43+
})
44+
.then((cachedCount) => {
45+
if (cachedCount) {
46+
return parseInt(cachedCount);
47+
}
5548

56-
};
49+
return Counter.count(Model, request, Redis, key, ttl);
50+
})
51+
.then((count) => {
52+
if (approximateCountValid) {
53+
request.response.source.approximate_count = count;
54+
} else {
55+
request.response.source.total_count = count;
56+
}
57+
return h.continue;
58+
}).catch(err => {
59+
throw err;
60+
});
61+
});
62+
}
5763

58-
exports.register.attributes = {
59-
pkg: require('../package.json')
64+
exports.plugin = {
65+
pkg: require('../package.json'),
66+
register
6067
};

lib/key.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

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

5+
/** @typedef {import('bookshelf').Model} Model */
6+
7+
/** @typedef {import('@hapi/hapi').Request} Request */
8+
9+
/**
10+
* Generates a cache key for the approximate count value.
11+
* @param {Model} Model
12+
* @param {Request} request
13+
* @param {Function?} uniqueKeyFn
14+
* @returns {String} The cache key
15+
*/
516
exports.generate = (Model, request, uniqueKeyFn) => {
617
const tableName = Model.prototype.tableName;
718
let filterHash = '';

lib/validators/approximate-count.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
const Joi = require('joi');
44

5-
module.exports = {
5+
module.exports = Joi.object({
66
query: Joi.object().keys({
77
include: Joi.array().items(Joi.string().valid('approximate_count').required(), Joi.any()).required()
88
}),
99
response: Joi.object().keys({
1010
source: Joi.object().required()
1111
})
12-
};
12+
});

lib/validators/total-count.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
const Joi = require('joi');
44

5-
module.exports = {
5+
module.exports = Joi.object({
66
query: Joi.object().keys({
77
include: Joi.array().items(Joi.string().valid('total_count').required(), Joi.any()).required()
88
}),
99
response: Joi.object().keys({
1010
source: Joi.object().required()
1111
})
12-
};
12+
});
13+

0 commit comments

Comments
 (0)