larvituser 0.18.0 → 0.19.1
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/dataWriter.js +1 -0
- package/index.js +4 -3
- package/package.json +2 -2
- package/test/00test.js +22 -0
- package/users.js +5 -4
- package/controllers/adminUsers/edit.js +0 -180
- package/controllers/adminUsers/list.js +0 -47
- package/public/tmpl/adminUsers/edit.tmpl +0 -71
- package/public/tmpl/adminUsers/list.tmpl +0 -22
package/dataWriter.js
CHANGED
|
@@ -247,6 +247,7 @@ DataWriter.prototype.create = function create(params, deliveryTag, msgUuid, cb)
|
|
|
247
247
|
if (results.affectedRows === 0) {
|
|
248
248
|
const err = new Error('No user created, duplicate key on uuid: "' + params.uuid + '" or username: "' + params.username + '"');
|
|
249
249
|
that.log.warn(logPrefix + err.message);
|
|
250
|
+
that.emitter.emit(msgUuid, err);
|
|
250
251
|
return cb(err);
|
|
251
252
|
}
|
|
252
253
|
|
package/index.js
CHANGED
|
@@ -62,9 +62,7 @@ function User(options, cb) {
|
|
|
62
62
|
'mode': that.mode,
|
|
63
63
|
'log': that.log,
|
|
64
64
|
'db': that.db,
|
|
65
|
-
'
|
|
66
|
-
'amsync_minPort': that.options.amsync_minPort || null,
|
|
67
|
-
'amsync_maxPort': that.options.amsync_maxPort || null
|
|
65
|
+
'amsync': that.options.amsync,
|
|
68
66
|
}, function (err) {
|
|
69
67
|
if (err) return cb(err);
|
|
70
68
|
|
|
@@ -346,6 +344,9 @@ User.prototype.fromUserAndPass = function fromUserAndPass(username, password, cb
|
|
|
346
344
|
userUuid,
|
|
347
345
|
userObj;
|
|
348
346
|
|
|
347
|
+
if (typeof username !== 'string') return cb(new Error('Username must be a string'), false);
|
|
348
|
+
if (typeof password !== 'string') return cb(new Error('Password must be a string'), false);
|
|
349
|
+
|
|
349
350
|
username = username.trim();
|
|
350
351
|
password = password.trim();
|
|
351
352
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "larvituser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Mikael 'Lilleman' Göransson",
|
|
6
6
|
"email": "lilleman@larvit.se",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"description": "User module for node.js",
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"freeport": "1.0.5",
|
|
22
|
-
"mocha": "6.
|
|
22
|
+
"mocha": "6.2.2",
|
|
23
23
|
"mocha-eslint": "5.0.0"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
package/test/00test.js
CHANGED
|
@@ -53,6 +53,11 @@ before(function (done) {
|
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
+
// Clear DB
|
|
57
|
+
tasks.push(function (cb) {
|
|
58
|
+
db.removeAllTables(cb);
|
|
59
|
+
});
|
|
60
|
+
|
|
56
61
|
// Check for empty db
|
|
57
62
|
tasks.push(function (cb) {
|
|
58
63
|
db.query('SHOW TABLES', function (err, rows) {
|
|
@@ -202,6 +207,23 @@ describe('User', function () {
|
|
|
202
207
|
});
|
|
203
208
|
});
|
|
204
209
|
|
|
210
|
+
it('should fail to log in user if username is an array', function (done) {
|
|
211
|
+
userLib.fromUserAndPass(['lill', 'eman'], 'foobar', function (err, user) {
|
|
212
|
+
assert(err.message === 'Username must be a string', 'Error should be "Username must be a string"');
|
|
213
|
+
assert(user === false, 'user should be false');
|
|
214
|
+
done();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
it('should fail to log in user if password is an array', function (done) {
|
|
220
|
+
userLib.fromUserAndPass('lilleman', ['foo', 'bar'], function (err, user) {
|
|
221
|
+
assert(err.message === 'Password must be a string', 'Error should be "Password must be a string"');
|
|
222
|
+
assert(user === false, 'user should be false');
|
|
223
|
+
done();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
205
227
|
it('should log in user by field', function (done) {
|
|
206
228
|
userLib.fromField('firstname', 'migal', function (err, user) {
|
|
207
229
|
if (err) throw err;
|
package/users.js
CHANGED
|
@@ -138,7 +138,9 @@ Users.prototype.get = function (cb) {
|
|
|
138
138
|
if (err) return cb(err);
|
|
139
139
|
|
|
140
140
|
let sql = 'SELECT user_users.uuid as uuid, user_users.username as username',
|
|
141
|
-
allowedSortables = ['uuid', 'username']
|
|
141
|
+
allowedSortables = ['uuid', 'username'],
|
|
142
|
+
mainDbFields = dbFields.slice(0);
|
|
143
|
+
|
|
142
144
|
|
|
143
145
|
if (that.returnFields !== undefined && ! Array.isArray(that.returnFields)) {
|
|
144
146
|
that.returnFields = [that.returnFields];
|
|
@@ -154,7 +156,7 @@ Users.prototype.get = function (cb) {
|
|
|
154
156
|
sql += ', group_concat(user_users_data.data) as ' + dbCon.escapeId(that.order.by) + ' FROM user_users ';
|
|
155
157
|
sql += 'LEFT JOIN user_users_data on (user_users_data.fieldUuid = (SELECT uuid FROM user_data_fields WHERE name = ?) AND user_users_data.userUuid = user_users.uuid) ';
|
|
156
158
|
sql += 'WHERE 1 ';
|
|
157
|
-
|
|
159
|
+
mainDbFields.unshift(that.order.by);
|
|
158
160
|
} else {
|
|
159
161
|
sql += ' FROM user_users WHERE 1 ';
|
|
160
162
|
}
|
|
@@ -185,7 +187,7 @@ Users.prototype.get = function (cb) {
|
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
|
|
188
|
-
dbCon.query(sql,
|
|
190
|
+
dbCon.query(sql, mainDbFields, function (err, rows) {
|
|
189
191
|
dbCon.release();
|
|
190
192
|
if (err) return cb(err);
|
|
191
193
|
|
|
@@ -267,7 +269,6 @@ Users.prototype.get = function (cb) {
|
|
|
267
269
|
if (err) return cb(err);
|
|
268
270
|
|
|
269
271
|
totalElements = rows[0].totalElements;
|
|
270
|
-
|
|
271
272
|
cb(err);
|
|
272
273
|
});
|
|
273
274
|
});
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const userLib = require('larvituser'),
|
|
4
|
-
async = require('async');
|
|
5
|
-
|
|
6
|
-
exports.run = function (req, res, cb) {
|
|
7
|
-
const tasks = [],
|
|
8
|
-
data = {'global': res.globalData};
|
|
9
|
-
|
|
10
|
-
data.global.errors = [];
|
|
11
|
-
|
|
12
|
-
// Make sure the user have the correct rights
|
|
13
|
-
// This is set in larvitadmingui controllerGlobal
|
|
14
|
-
if ( ! res.adminRights) {
|
|
15
|
-
cb(new Error('Invalid rights'), req, res, {});
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
data.global.menuControllerName = 'adminUsers';
|
|
20
|
-
|
|
21
|
-
if (data.global.formFields.save !== undefined) {
|
|
22
|
-
const userFields = {};
|
|
23
|
-
|
|
24
|
-
let newPassword,
|
|
25
|
-
user;
|
|
26
|
-
|
|
27
|
-
if (data.global.formFields.disableLogin === 'yes') {
|
|
28
|
-
newPassword = false;
|
|
29
|
-
} else {
|
|
30
|
-
newPassword = data.global.formFields.password.trim();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Format userFields
|
|
34
|
-
for (let i = 0; data.global.formFields.fieldName[i] !== undefined; i ++) {
|
|
35
|
-
const fieldName = data.global.formFields.fieldName[i],
|
|
36
|
-
fieldValue = data.global.formFields.fieldValue[i];
|
|
37
|
-
|
|
38
|
-
if (fieldValue !== '' && fieldValue !== undefined) {
|
|
39
|
-
if (userFields[fieldName] === undefined) {
|
|
40
|
-
userFields[fieldName] = [];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
userFields[fieldName].push(fieldValue);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Create user if it did not exist
|
|
48
|
-
if (data.global.urlParsed.query.uuid === undefined) {
|
|
49
|
-
|
|
50
|
-
// Check so username is not taken
|
|
51
|
-
tasks.push(function (cb) {
|
|
52
|
-
userLib.usernameAvailable(data.global.formFields.username.trim(), function (err, result) {
|
|
53
|
-
if (err) return cb(err);
|
|
54
|
-
|
|
55
|
-
if (result !== true) {
|
|
56
|
-
const err = new Error('Username is taken by another user');
|
|
57
|
-
data.global.errors.push(err.message);
|
|
58
|
-
return cb(err);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
cb(err);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Create the user
|
|
66
|
-
tasks.push(function (cb) {
|
|
67
|
-
if (data.global.errors.length) return cb();
|
|
68
|
-
|
|
69
|
-
userLib.create(data.global.formFields.username, newPassword, userFields, function (err, result) {
|
|
70
|
-
user = result;
|
|
71
|
-
cb(err);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
} else {
|
|
75
|
-
tasks.push(function (cb) {
|
|
76
|
-
userLib.fromUuid(data.global.urlParsed.query.uuid, function (err, result) {
|
|
77
|
-
user = result;
|
|
78
|
-
cb(err);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Update username
|
|
84
|
-
tasks.push(function (cb) {
|
|
85
|
-
if ( ! user) {
|
|
86
|
-
throw new Error('No user set');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
data.global.formFields.username = data.global.formFields.username.trim();
|
|
90
|
-
|
|
91
|
-
if (data.global.formFields.username === user.username) return cb();
|
|
92
|
-
|
|
93
|
-
userLib.usernameAvailable(data.global.formFields.username, function (err, result) {
|
|
94
|
-
if (err) return cb(err);
|
|
95
|
-
|
|
96
|
-
if (result !== true) {
|
|
97
|
-
data.global.errors.push('Username is taken by another user');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
cb(err);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
tasks.push(function (cb) {
|
|
105
|
-
if (data.global.formFields.username === user.username) return cb();
|
|
106
|
-
|
|
107
|
-
if (data.global.errors.length) return cb();
|
|
108
|
-
|
|
109
|
-
user.setUsername(data.global.formFields.username.trim(), cb);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// Update password
|
|
113
|
-
if (newPassword !== '' || newPassword === false) {
|
|
114
|
-
tasks.push(function (cb) {
|
|
115
|
-
if (data.global.errors.length) return cb();
|
|
116
|
-
|
|
117
|
-
user.setPassword(newPassword, cb);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Replace user fields
|
|
122
|
-
tasks.push(function (cb) {
|
|
123
|
-
if (data.global.errors.length) return cb();
|
|
124
|
-
|
|
125
|
-
user.replaceFields(userFields, cb);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
tasks.push(function (cb) {
|
|
129
|
-
if (data.global.errors.length) return cb();
|
|
130
|
-
|
|
131
|
-
if (data.global.urlParsed.query.uuid === undefined) {
|
|
132
|
-
req.session.data.nextCallData = {'global': {'messages': ['New user created']}};
|
|
133
|
-
res.statusCode = 302;
|
|
134
|
-
res.setHeader('Location', '/adminUsers/edit?uuid=' + user.uuid);
|
|
135
|
-
} else {
|
|
136
|
-
data.global.messages = ['Saved'];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
cb();
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (data.global.formFields.rmUser !== undefined) {
|
|
144
|
-
tasks.push(function (cb) {
|
|
145
|
-
userLib.rmUser(data.global.urlParsed.query.uuid, function (err) {
|
|
146
|
-
if (err) return cb(err);
|
|
147
|
-
|
|
148
|
-
req.session.data.nextCallData = {'global': {'messages': ['User "' + data.global.urlParsed.query.uuid + '" erased']}};
|
|
149
|
-
res.statusCode = 302;
|
|
150
|
-
res.setHeader('Location', '/adminUsers/list');
|
|
151
|
-
cb();
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (data.global.urlParsed.query.uuid !== undefined) {
|
|
157
|
-
tasks.push(function (cb) {
|
|
158
|
-
userLib.fromUuid(data.global.urlParsed.query.uuid, function (err, user) {
|
|
159
|
-
if (err) return cb(err);
|
|
160
|
-
|
|
161
|
-
data.user = {
|
|
162
|
-
'uuid': user.uuid,
|
|
163
|
-
'username': user.username,
|
|
164
|
-
'passwordIsFalse': user.passwordIsFalse,
|
|
165
|
-
'fields': user.fields
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
cb();
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async.series(tasks, function (err) {
|
|
174
|
-
if (err && ! data.global.errors) {
|
|
175
|
-
cb(err, req, res, data);
|
|
176
|
-
} else {
|
|
177
|
-
cb(null, req, res, data);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const userLib = require(__dirname + '/../../index.js'),
|
|
4
|
-
async = require('async');
|
|
5
|
-
|
|
6
|
-
exports.run = function (req, res, cb) {
|
|
7
|
-
const tasks = [],
|
|
8
|
-
data = {'global': res.globalData};
|
|
9
|
-
|
|
10
|
-
// Make sure the user have the correct rights
|
|
11
|
-
// This is set in larvitadmingui controllerGlobal
|
|
12
|
-
if ( ! res.adminRights) {
|
|
13
|
-
cb(new Error('Invalid rights'), req, res, {});
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
data.global.menuControllerName = 'adminUsers';
|
|
18
|
-
data.pagination = {};
|
|
19
|
-
data.pagination.urlParsed = data.global.urlParsed;
|
|
20
|
-
data.pagination.elementsPerPage = 100;
|
|
21
|
-
|
|
22
|
-
tasks.push(function (cb) {
|
|
23
|
-
const users = new userLib.Users();
|
|
24
|
-
|
|
25
|
-
//users.returnFields = ['firstname', 'lastname'];
|
|
26
|
-
users.limit = data.pagination.elementsPerPage;
|
|
27
|
-
users.offset = parseInt(data.global.urlParsed.query.offset) || 0;
|
|
28
|
-
|
|
29
|
-
if (isNaN(users.offset) || users.offset < 0) {
|
|
30
|
-
users.offset = 0;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
//if (data.global.urlParsed.query.filterStatus) {
|
|
34
|
-
// users.matchAllFields = {'status': data.global.urlParsed.query.filterStatus};
|
|
35
|
-
//}
|
|
36
|
-
|
|
37
|
-
users.get(function (err, result, totalElements) {
|
|
38
|
-
data.users = result;
|
|
39
|
-
data.pagination.totalElements = totalElements;
|
|
40
|
-
cb(err);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
async.series(tasks, function (err) {
|
|
45
|
-
cb(err, req, res, data);
|
|
46
|
-
});
|
|
47
|
-
};
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
<%= _.render('inc/head', obj) %>
|
|
2
|
-
<%= _.render('inc/pageTop', obj) %>
|
|
3
|
-
<form method="post">
|
|
4
|
-
|
|
5
|
-
<div class="row">
|
|
6
|
-
<div class="six columns">
|
|
7
|
-
<label for="uuid">Uuid</label>
|
|
8
|
-
<input class="u-full-width" type="text" name="uuid" placeholder="auto generated" readonly="readonly" value="<%= obj.global.urlParsed.query.uuid %>" />
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<div class="six columns">
|
|
12
|
-
<label for="disableLogin">
|
|
13
|
-
<input id="disableLogin" name="disableLogin" type="checkbox" value="yes" <% if (obj.user && obj.user.passwordIsFalse === true) { print('checked="checked"');} %> />
|
|
14
|
-
<span class="label-body">Disable login (will erase the password)</span>
|
|
15
|
-
</label>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<div class="row">
|
|
20
|
-
<div class="six columns">
|
|
21
|
-
<label for="username">Username</label>
|
|
22
|
-
<input class="u-full-width" type="text" name="username" value="<%= obj.user ? obj.user.username : '' %>" />
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<div class="six columns">
|
|
26
|
-
<label for="password">Password (Leave empty to not change the password)</label>
|
|
27
|
-
<input class="u-full-width" type="password" name="password" />
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<h2>Fields</h2>
|
|
32
|
-
<% if (obj.user) { %>
|
|
33
|
-
<% _.forEach(obj.user.fields, function (fieldValues, fieldName) { %>
|
|
34
|
-
<% if ( ! (fieldValues instanceof Array)) { fieldValues = [fieldValues]; } %>
|
|
35
|
-
<% for (var i = 0; fieldValues[i] !== undefined; i ++) { %>
|
|
36
|
-
<div class="row">
|
|
37
|
-
<div class="six columns">
|
|
38
|
-
<label for="fieldName[]">Field Name</label>
|
|
39
|
-
<input class="u-full-width" type="text" name="fieldName[]" value="<%= fieldName %>" />
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
<div class="six columns">
|
|
43
|
-
<label for="fieldValue[]">Field Value</label>
|
|
44
|
-
<input class="u-full-width" type="text" name="fieldValue[]" value="<%= fieldValues[i] %>" />
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
<% }; %>
|
|
48
|
-
<% }); %>
|
|
49
|
-
<% }; %>
|
|
50
|
-
|
|
51
|
-
<div class="row">
|
|
52
|
-
<div class="six columns">
|
|
53
|
-
<label for="fieldName[]">Field Name</label>
|
|
54
|
-
<input class="u-full-width" type="text" name="fieldName[]" value="" />
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<div class="six columns">
|
|
58
|
-
<label for="fieldValue[]">Field Value</label>
|
|
59
|
-
<input class="u-full-width" type="text" name="fieldValue[]" value="" />
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<div class="controls clearfix">
|
|
64
|
-
<button type="submit" name="save" class="button right inv">Save</button>
|
|
65
|
-
<a class="button left" href="/adminUsers/list">Cancel</a>
|
|
66
|
-
<% if (global.urlParsed.query.uuid) { %>
|
|
67
|
-
<button type="submit" name="rmUser" class="button left warning" value="true">Delete user</button>
|
|
68
|
-
<% } %>
|
|
69
|
-
</div>
|
|
70
|
-
</form>
|
|
71
|
-
<%= _.render('inc/pageBottom', obj) %>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<%= _.render('inc/head', obj) %>
|
|
2
|
-
<%= _.render('inc/pageTop', obj) %>
|
|
3
|
-
<form method="post">
|
|
4
|
-
<table>
|
|
5
|
-
<thead>
|
|
6
|
-
<tr>
|
|
7
|
-
<th>UUID</th>
|
|
8
|
-
<th>Username</th>
|
|
9
|
-
</tr>
|
|
10
|
-
</thead>
|
|
11
|
-
<tbody>
|
|
12
|
-
<% _.forEach(obj.users, function (user) { %>
|
|
13
|
-
<tr>
|
|
14
|
-
<td><a href="/adminUsers/edit?uuid=<%= user.uuid %>"><%= user.uuid %></a></td>
|
|
15
|
-
<td><%= user.username %></td>
|
|
16
|
-
</tr>
|
|
17
|
-
<% }); %>
|
|
18
|
-
</tbody>
|
|
19
|
-
</table>
|
|
20
|
-
</form>
|
|
21
|
-
<%= _.render('inc/pagination', obj.pagination) %>
|
|
22
|
-
<%= _.render('inc/pageBottom', obj) %>
|