expressa 2.0.5 → 2.0.7
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.
- package/auth/index.js +50 -47
- package/controllers/collections.js +1 -3
- package/db/file.js +2 -4
- package/db/memory.js +2 -4
- package/index.js +0 -2
- package/listeners_users.js +1 -1
- package/package.json +1 -1
- package/util.js +10 -0
package/auth/index.js
CHANGED
|
@@ -1,47 +1,50 @@
|
|
|
1
|
-
const bcrypt = require('bcryptjs')
|
|
2
|
-
const handler = require('./jwt')
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
req.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
1
|
+
const bcrypt = require('bcryptjs')
|
|
2
|
+
const handler = require('./jwt')
|
|
3
|
+
|
|
4
|
+
exports.isHashed = function (string) {
|
|
5
|
+
return string && string.length === 60 && string[0] === '$'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
exports.createHash = function (password) {
|
|
9
|
+
const salt = bcrypt.genSaltSync(10)
|
|
10
|
+
return bcrypt.hashSync(password, salt)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
exports.isValidPassword = function (password, hashedPassword) {
|
|
14
|
+
return bcrypt.compareSync(password, hashedPassword)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.doLogin = handler.doLogin
|
|
18
|
+
|
|
19
|
+
exports.middleware = async function authMiddleware(req, res, next) {
|
|
20
|
+
req.query = req.query || {}
|
|
21
|
+
const token = req.query['token'] || req.headers['x-access-token']
|
|
22
|
+
delete req.query['token']
|
|
23
|
+
delete req.headers['x-access-token']
|
|
24
|
+
let payload
|
|
25
|
+
try {
|
|
26
|
+
payload = await handler.isLoggedIn(token, req.getSetting('jwt_secret'))
|
|
27
|
+
}
|
|
28
|
+
catch(e) {
|
|
29
|
+
req.uerror = e.message
|
|
30
|
+
}
|
|
31
|
+
if (payload) {
|
|
32
|
+
let user
|
|
33
|
+
try {
|
|
34
|
+
user = await req.db[payload.collection].get(payload._id)
|
|
35
|
+
} catch (e) {
|
|
36
|
+
req.uerror = 'user no longer exists'
|
|
37
|
+
}
|
|
38
|
+
if (user) {
|
|
39
|
+
if (req.getSetting('jwt_expire_on_password_change') && user.meta.password_last_updated_at !== payload.timestamp) {
|
|
40
|
+
req.uerror = 'jwt expired'
|
|
41
|
+
}
|
|
42
|
+
if (!req.uerror) {
|
|
43
|
+
req.uid = payload._id
|
|
44
|
+
req.ucollection = payload.collection
|
|
45
|
+
req.user = user
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
next()
|
|
50
|
+
}
|
|
@@ -14,13 +14,11 @@ async function validateDocumentOwner(req, doc) {
|
|
|
14
14
|
if (!doc.meta.owner_collection) {
|
|
15
15
|
throw new util.ApiError(417, 'no owner_collection for owner found')
|
|
16
16
|
}
|
|
17
|
-
if (doc._id
|
|
17
|
+
if (!(doc._id === doc.meta.owner && req.params.collection === doc.meta.owner_collection)) {
|
|
18
18
|
const count = await req.db[doc.meta.owner_collection].count({ _id: doc.meta.owner }, undefined, 1)
|
|
19
19
|
if (!count) {
|
|
20
20
|
throw new util.ApiError(417, 'invalid owner')
|
|
21
21
|
}
|
|
22
|
-
} else if (req.params.collection !== doc.meta.owner_collection) {
|
|
23
|
-
throw new util.ApiError(417, 'invalid owner collection')
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
24
|
|
package/db/file.js
CHANGED
|
@@ -5,8 +5,6 @@ Store.prototype.allAsync = promisify(Store.prototype.all)
|
|
|
5
5
|
Store.prototype.getAsync = promisify(Store.prototype.get)
|
|
6
6
|
Store.prototype.saveAsync = promisify(Store.prototype.save)
|
|
7
7
|
|
|
8
|
-
const sift = require('sift')
|
|
9
|
-
|
|
10
8
|
const util = require('../util')
|
|
11
9
|
|
|
12
10
|
module.exports = function (settings, collection) {
|
|
@@ -25,7 +23,7 @@ module.exports = function (settings, collection) {
|
|
|
25
23
|
const arr = Object.keys(data).map(function (id) {
|
|
26
24
|
return data[id]
|
|
27
25
|
})
|
|
28
|
-
let matches =
|
|
26
|
+
let matches = util.mongoSearch(arr, query)
|
|
29
27
|
if (orderby) {
|
|
30
28
|
matches = util.orderBy(matches, orderby)
|
|
31
29
|
}
|
|
@@ -96,7 +94,7 @@ module.exports = function (settings, collection) {
|
|
|
96
94
|
updateWithQuery: async function (query, update, options) {
|
|
97
95
|
const data = await store.allAsync()
|
|
98
96
|
const arr = Object.keys(data).map((id) => ({ _id: id, ...data[id]}) )
|
|
99
|
-
const matches =
|
|
97
|
+
const matches = util.mongoSearch(arr, query)
|
|
100
98
|
const promises = matches.map((doc) => {
|
|
101
99
|
util.mongoUpdate(doc, update)
|
|
102
100
|
return store.saveAsync(doc._id, doc)
|
package/db/memory.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/* eslint no-unused-vars: ["error", { "args": "none" }] */
|
|
2
|
-
const sift = require('sift')
|
|
3
|
-
|
|
4
2
|
const util = require('../util')
|
|
5
3
|
|
|
6
4
|
module.exports = function (settings, collection) {
|
|
@@ -14,7 +12,7 @@ module.exports = function (settings, collection) {
|
|
|
14
12
|
},
|
|
15
13
|
find: async function (query, offset, limit, orderby, fields) {
|
|
16
14
|
const arr = Object.values(store)
|
|
17
|
-
let matches =
|
|
15
|
+
let matches = util.mongoSearch(arr, query)
|
|
18
16
|
if (orderby) {
|
|
19
17
|
matches = util.orderBy(matches, orderby)
|
|
20
18
|
}
|
|
@@ -61,7 +59,7 @@ module.exports = function (settings, collection) {
|
|
|
61
59
|
// https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/
|
|
62
60
|
updateWithQuery: async function (query, update, options) {
|
|
63
61
|
const arr = Object.keys(store).map((id) => ({ _id: id, ...store[id]}) )
|
|
64
|
-
const matches =
|
|
62
|
+
const matches = util.mongoSearch(arr, query)
|
|
65
63
|
matches.forEach((doc) => {
|
|
66
64
|
util.mongoUpdate(doc, update)
|
|
67
65
|
store[doc._id] = doc
|
package/index.js
CHANGED
package/listeners_users.js
CHANGED
|
@@ -13,7 +13,7 @@ module.exports = async function(api) {
|
|
|
13
13
|
data.password = oldData.password // preserve password if not explicitly set
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
if (
|
|
16
|
+
if (!auth.isHashed(data.password)) {
|
|
17
17
|
debug('hashing and replacing password in the user document.')
|
|
18
18
|
data.password = auth.createHash(data.password)
|
|
19
19
|
data.meta.password_last_updated_at = new Date().toISOString()
|
package/package.json
CHANGED
package/util.js
CHANGED
|
@@ -6,6 +6,8 @@ const pg = require('pg')
|
|
|
6
6
|
const pgPools = {}
|
|
7
7
|
const dot = require('dot-object')
|
|
8
8
|
const mongoQuery = require('mongo-query')
|
|
9
|
+
const sift = require('sift')
|
|
10
|
+
const auth = require('./auth/index')
|
|
9
11
|
const Ajv = require('ajv')
|
|
10
12
|
const ajv = new Ajv({
|
|
11
13
|
allErrors: true,
|
|
@@ -152,6 +154,10 @@ exports.mongoProject = function(record, projection) {
|
|
|
152
154
|
return result
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
exports.mongoSearch = function(docs, query) {
|
|
158
|
+
return sift(query || {}, docs)
|
|
159
|
+
}
|
|
160
|
+
|
|
155
161
|
exports.mongoUpdate = function(doc, update) {
|
|
156
162
|
return mongoQuery(doc, {}, update)
|
|
157
163
|
}
|
|
@@ -423,3 +429,7 @@ exports.createPagePagination = function createPagePagination (pageData, page, pa
|
|
|
423
429
|
exports.getDatabaseOffset = function getDatabaseOffset(page, itemsPerPage) {
|
|
424
430
|
return (page - 1) * itemsPerPage
|
|
425
431
|
}
|
|
432
|
+
|
|
433
|
+
exports.createHash = auth.createHash
|
|
434
|
+
exports.isHashed = auth.isHashed
|
|
435
|
+
exports.doLogin = auth.doLogin
|