-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathlisteners_users.js
More file actions
96 lines (86 loc) · 3.76 KB
/
listeners_users.js
File metadata and controls
96 lines (86 loc) · 3.76 KB
1
2
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const auth = require('./auth')
const util = require('./util.js')
const debug = require('debug')('expressa')
module.exports = async function(api) {
const loginCollections = (await util.getLoginCollections(api)).map((coll) => coll._id)
api.addCollectionListener(['post', 'put'], loginCollections, async function updatePassword(req, collection, data) {
if (req.method === 'PUT') {
if (!data.password) {
const oldData = await api.db[collection].get(data._id)
data.password = oldData.password // preserve password if not explicitly set
}
}
if (!auth.isHashed(data.password)) {
debug('hashing and replacing password in the user document.')
data.password = auth.createHash(data.password)
data.meta.password_last_updated_at = new Date().toISOString()
}
})
api.addCollectionListener('post', loginCollections, async function roleCreateCheck(req, collection, data) {
if (!data.roles) {
data.roles = []
}
// user special case to allow first user to be admin
if (collection === 'users') {
const hasUsers = (await api.db.users.find({}, 0, 1)).length === 1
if (!hasUsers && !data.roles.includes('Admin')) {
throw new util.ApiError(400, 'first user must have role Admin')
}
if (hasUsers && data.roles.length > 0 && !req.hasPermission('users: modify roles')) {
throw new util.ApiError(400, 'insufficient permissions to create user with roles')
}
}
else {
if (data.roles.length > 0 && !req.hasPermission(`${collection}: modify roles`)) {
throw new util.ApiError(400, `insufficient permissions to create ${collection} with roles`)
}
}
})
api.addLateCollectionListener('put', loginCollections, async function roleChangeCheck(req, collection, data) {
if (!req.hasPermission(`${collection}: modify roles`)) {
const oldData = await api.db[collection].get(data._id)
data.roles = oldData.roles
}
})
api.addCollectionListenerWithPriority(['get', 'changed', 'deleted'], loginCollections, 100, function hidePasswordHashes(req, collection, data) {
if (!req.hasPermission(`${collection}: view hashed passwords`)) {
debug(`deleting password because "${collection}: view hashed passwords"-permission is not set`)
delete data.password
}
})
api.addCollectionListener(['post', 'put'], loginCollections, async function userEmailLowerCase(req, collection, data) {
if (data.email) {
data.email = data.email.toLowerCase()
}
})
api.addCollectionListener('post', loginCollections, async function userUniquenessCheck(req, collection, data) {
if (data.email) {
const result = await api.db[collection].find({email: data.email})
if (result.length > 0) {
throw new util.ApiError(409, 'This email is already registered.')
}
}
})
/* Mantain users-roles reference */
api.addCollectionListener('changed', 'role', async function addRoleToUserSchema(req, collection, data) {
for (const coll of loginCollections) {
const doc = await api.db.collection.get(coll)
if (!doc.schema.properties.roles.items.enum.includes(data._id)) {
doc.schema.properties.roles.items.enum.push(data._id)
await api.db.collection.update(coll, doc)
await api.notify('changed', req, 'collection', doc)
}
}
})
api.addCollectionListener('deleted', 'role', async function removeRoleToUserSchema(req, collection, data) {
for (const coll of loginCollections) {
const doc = await api.db.collection.get(coll)
const roles = doc.schema.properties.roles.items.enum
if (roles.includes(data._id)) {
roles.splice(roles.indexOf(data._id), 1)
await api.db.collection.update(coll, doc)
await api.notify('changed', req, 'collection', doc)
}
}
})
}