larvituser 0.19.1 → 0.20.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/index.js DELETED
@@ -1,956 +0,0 @@
1
- 'use strict';
2
-
3
- const topLogPrefix = 'larvituser: index.js: ',
4
- DataWriter = require(__dirname + '/dataWriter.js'),
5
- Intercom = require('larvitamintercom'),
6
- uuidLib = require('uuid'),
7
- Helpers = require(__dirname + '/helpers.js'),
8
- LUtils = require('larvitutils'),
9
- bcrypt = require('bcryptjs'),
10
- async = require('async');
11
-
12
- function User(options, cb) {
13
- const logPrefix = topLogPrefix + 'User() - ',
14
- that = this;
15
-
16
- if (typeof cb !== 'function') {
17
- cb = function () {};
18
- }
19
-
20
- that.options = options || {};
21
-
22
- if ( ! options.log) {
23
- const tmpLUtils = new LUtils();
24
- options.log = new tmpLUtils.Log();
25
- }
26
-
27
- that.options = options;
28
-
29
- for (const key of Object.keys(options)) {
30
- that[key] = options[key];
31
- }
32
-
33
- that.lUtils = new LUtils({'log': that.log});
34
-
35
- if ( ! that.db) {
36
- const err = new Error('Required option db is missing');
37
- that.log.error(logPrefix + err.message);
38
- throw err;
39
- }
40
-
41
- if ( ! that.exchangeName) {
42
- that.exchangeName = 'larvituser';
43
- }
44
-
45
- if ( ! that.mode) {
46
- that.log.info(logPrefix + 'No "mode" option given, defaulting to "noSync"');
47
- that.mode = 'noSync';
48
- } else if (['noSync', 'master', 'slave'].indexOf(that.mode) === - 1) {
49
- const err = new Error('Invalid "mode" option given: "' + that.mode + '"');
50
- that.log.error(logPrefix + err.message);
51
- throw err;
52
- }
53
-
54
- if ( ! that.intercom) {
55
- that.log.info(logPrefix + 'No "intercom" option given, defaulting to "loopback interface"');
56
- that.intercom = new Intercom('loopback interface');
57
- }
58
-
59
- that.dataWriter = new DataWriter({
60
- 'exchangeName': that.exchangeName,
61
- 'intercom': that.intercom,
62
- 'mode': that.mode,
63
- 'log': that.log,
64
- 'db': that.db,
65
- 'amsync': that.options.amsync,
66
- }, function (err) {
67
- if (err) return cb(err);
68
-
69
- that.helpers = new Helpers({
70
- 'dataWriter': that.dataWriter,
71
- 'log': that.log,
72
- 'db': that.db
73
- });
74
-
75
- cb();
76
- });
77
- };
78
-
79
- /**
80
- * Add a single user field to database
81
- *
82
- * @param str userUuid
83
- * @param str fieldName
84
- * @param str fieldValue
85
- * @param func cb(err)
86
- */
87
- User.prototype.addUserDataField = function addUserDataField(userUuid, fieldName, fieldValue, cb) {
88
- const fields = {},
89
- that = this;
90
-
91
- fields[fieldName] = fieldValue;
92
-
93
- that.addUserDataFields(userUuid, fields, cb);
94
- };
95
-
96
- /**
97
- * Add user fields
98
- *
99
- * @param str userUuid
100
- * @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']}
101
- * @param func cb(err)
102
- */
103
- User.prototype.addUserDataFields = function addUserDataFields(userUuid, fields, cb) {
104
- const options = {'exchange': this.exchangeName},
105
- sendObj = {},
106
- that = this;
107
-
108
- // do not want to broadcast msg on queue for no reason
109
- if ( ! fields || Object.keys(fields).length === 0) return cb();
110
-
111
- sendObj.action = 'addUserDataFields';
112
- sendObj.params = {};
113
- sendObj.params.userUuid = userUuid;
114
- sendObj.params.fields = fields;
115
-
116
- that.intercom.send(sendObj, options, function (err, msgUuid) {
117
- if (err) return cb(err);
118
-
119
- that.dataWriter.emitter.once(msgUuid, cb);
120
- });
121
- };
122
-
123
- /**Analyze Optimize Check Repair Truncate Drop * Checks a password for validity
124
- *
125
- * @param str password - plain text password
126
- * @param str hash - hash to check password against
127
- * @param func cb(err, res) res is boolean
128
- */
129
- User.prototype.checkPassword = function checkPassword(password, hash, cb) {
130
- const logPrefix = topLogPrefix + 'checkPassword() - ',
131
- that = this;
132
-
133
- password = password.trim();
134
-
135
- bcrypt.compare(password, hash, function (err, result) {
136
- if (err) {
137
- that.log.error(logPrefix + err.message);
138
- }
139
-
140
- cb(err, result);
141
- });
142
- };
143
-
144
- /**
145
- * Creates a new user (and adds to it to db)
146
- *
147
- * @param str username
148
- * @param str password (plain text) or false for no password (user will not be able to login at all)
149
- * @param obj fields - key, value pairs, where value can be an array of values
150
- * @param uuid custom uuid - if not supplied a random will be generated
151
- * @param func cb(err, user) - user being an instance of the new user
152
- */
153
- User.prototype.create = function create(username, password, userData, uuid, cb) {
154
- const logPrefix = topLogPrefix + 'create() - ',
155
- tasks = [],
156
- that = this;
157
-
158
- let hashedPassword;
159
-
160
- if (typeof uuid === 'function') {
161
- cb = uuid;
162
- uuid = uuidLib.v1();
163
- } else if (typeof userData === 'function') {
164
- userData = undefined;
165
- uuid = uuidLib.v1();
166
- cb = userData;
167
- }
168
-
169
- if (cb === undefined) {
170
- cb = function () {};
171
- }
172
-
173
- if (uuid === undefined) {
174
- uuid = uuidLib.v1();
175
- }
176
-
177
- username = username.trim();
178
-
179
- if (password) {
180
- password = password.trim();
181
- }
182
-
183
- if (username.length === 0) {
184
- const err = new Error('Trying to create user with empty username');
185
- that.log.warn(logPrefix + err.message);
186
- return cb(err);
187
- }
188
-
189
- // Check for username availability
190
- tasks.push(function (cb) {
191
- that.usernameAvailable(username, function (err, result) {
192
- if (err) return cb(err);
193
-
194
- if (result === true) {
195
- that.log.debug(logPrefix + 'Username available: "' + username + '"');
196
- cb();
197
- } else {
198
- const err = new Error('Trying to create user with taken username: "' + username + '"');
199
-
200
- that.log.info(logPrefix + err.message);
201
- cb(err);
202
- }
203
- });
204
- });
205
-
206
- // Hash Password
207
- tasks.push(function (cb) {
208
- if (password === false) {
209
- that.log.debug(logPrefix + 'Password set to empty string for no-login, username: "' + username + '"');
210
- hashedPassword = '';
211
- return cb();
212
- }
213
-
214
- that.hashPassword(password, function (err, hash) {
215
- if (err) return cb(err);
216
-
217
- hashedPassword = hash;
218
- that.log.debug(logPrefix + 'Password hashed, username: "' + username + '"');
219
- cb();
220
- });
221
- });
222
-
223
- // Create all fields
224
- tasks.push(function (cb) {
225
- const tasks = [];
226
-
227
- for (const fieldName of Object.keys(userData)) {
228
- tasks.push(function (cb) {
229
- that.helpers.getFieldUuid(fieldName, cb);
230
- });
231
- }
232
-
233
- async.parallel(tasks, cb);
234
- });
235
-
236
- // Write new user via queue
237
- tasks.push(function (cb) {
238
- const options = {'exchange': that.exchangeName},
239
- sendObj = {};
240
-
241
- sendObj.action = 'create';
242
- sendObj.params = {};
243
- sendObj.params.uuid = uuid;
244
- sendObj.params.username = username;
245
- sendObj.params.password = hashedPassword;
246
- sendObj.params.fields = userData;
247
-
248
- that.intercom.send(sendObj, options, function (err, msgUuid) {
249
- if (err) return cb(err);
250
-
251
- that.dataWriter.emitter.once(msgUuid, cb);
252
- });
253
- });
254
-
255
- async.series(tasks, function (err) {
256
- if (err) return cb(err);
257
-
258
- that.fromUuid(uuid, function (err, user) {
259
- if (err) {
260
- that.log.error(logPrefix + err.message);
261
- return cb(err);
262
- }
263
-
264
- cb(null, user);
265
- });
266
- });
267
- };
268
-
269
- /**
270
- * Create a user object from a field
271
- * IMPORTANT! Only fetches first matching user!
272
- *
273
- * @param str fieldName
274
- * @param str fieldValue
275
- * @param func cb(err, user) - "user" being a new user object or boolean false on failed search
276
- */
277
- User.prototype.fromField = function fromField(fieldName, fieldValue, cb) {
278
- const dbFields = [fieldName.trim(), fieldValue.trim()],
279
- that = this,
280
- sql = 'SELECT uud.userUuid\n' +
281
- 'FROM user_users_data uud\n' +
282
- ' JOIN user_data_fields udf ON udf.uuid = uud.fieldUuid\n' +
283
- 'WHERE udf.name = ? AND uud.data = ?\n' +
284
- 'LIMIT 1';
285
-
286
- that.dataWriter.ready(function (err) {
287
- if (err) return cb(err);
288
- that.db.query(sql, dbFields, function (err, rows) {
289
- if (err) return cb(err);
290
-
291
- if (rows.length === 0) return cb(null, false);
292
-
293
- that.fromUuid(that.lUtils.formatUuid(rows[0].userUuid), cb);
294
- });
295
- });
296
- };
297
-
298
- /**
299
- * Create a user object from fields
300
- * IMPORTANT! Only fetches first matching user that matches all fields!
301
- *
302
- * @param obj fields - {'fieldName': 'fieldValue', 'fieldName2': 'fieldValue2'}
303
- * @param func cb(err, user) - "user" being a new user object or boolean false on failed search
304
- */
305
- User.prototype.fromFields = function fromFields(fields, cb) {
306
- const dbFields = [],
307
- that = this;
308
-
309
- let sql = 'SELECT uuid FROM user_users u\nWHERE\n 1 + 1\n';
310
-
311
- for (const fieldName of Object.keys(fields)) {
312
- sql += ' AND uuid IN (SELECT userUuid FROM user_users_data WHERE data = ? AND fieldUuid = (SELECT uuid FROM user_data_fields WHERE name = ?))\n';
313
- dbFields.push(fields[fieldName].trim());
314
- dbFields.push(fieldName.trim());
315
- }
316
-
317
- sql += 'LIMIT 1';
318
-
319
- that.dataWriter.ready(function (err) {
320
- if (err) return cb(err);
321
- that.db.query(sql, dbFields, function (err, rows) {
322
- if (err) return cb(err);
323
-
324
- if (rows.length === 0) return cb(null, false);
325
-
326
- that.fromUuid(that.lUtils.formatUuid(rows[0].uuid), cb);
327
- });
328
- });
329
- };
330
-
331
- /**
332
- * Create a user object from username and password
333
- *
334
- * @param str username
335
- * @param str password
336
- * @param func cb(err, user) - "user" being a new user object or boolean false on failed login
337
- */
338
- User.prototype.fromUserAndPass = function fromUserAndPass(username, password, cb) {
339
- const logPrefix = topLogPrefix + 'fromUserAndPass() - ',
340
- tasks = [],
341
- that = this;
342
-
343
- let hashedPassword,
344
- userUuid,
345
- userObj;
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
-
350
- username = username.trim();
351
- password = password.trim();
352
-
353
- tasks.push(function (cb) {
354
- that.dataWriter.ready(cb);
355
- });
356
-
357
- tasks.push(function (cb) {
358
- const dbFields = [username],
359
- sql = 'SELECT uuid, password FROM user_users WHERE username = ?';
360
-
361
- that.db.query(sql, dbFields, function (err, rows) {
362
- if (err) return cb(err);
363
-
364
- if (rows.length === 0) {
365
- userObj = false;
366
- return cb();
367
- }
368
-
369
- hashedPassword = rows[0].password;
370
- userUuid = rows[0].uuid;
371
- cb();
372
- });
373
- });
374
-
375
- tasks.push(function (cb) {
376
- if ( ! hashedPassword) return cb();
377
-
378
- that.checkPassword(password, hashedPassword, function (err, res) {
379
- if (err) {
380
- that.log.error(logPrefix + err.message);
381
- return cb(err);
382
- }
383
-
384
- if (res === false) {
385
- userObj = false;
386
- return cb();
387
- }
388
-
389
- that.fromUuid(that.lUtils.formatUuid(userUuid), function (err, result) {
390
- userObj = result;
391
- if (err) userObj = false;
392
- cb(err);
393
- });
394
- });
395
- });
396
-
397
- async.series(tasks, function (err) {
398
- cb(err, userObj);
399
- });
400
- };
401
-
402
- /**
403
- * Create a user object from username
404
- *
405
- * @param str username
406
- * @param func cb(err, user) - "user" being a new user object
407
- */
408
- User.prototype.fromUsername = function fromUsername(username, cb) {
409
- const logPrefix = topLogPrefix + 'fromUsername() - ',
410
- dbFields = [],
411
- that = this,
412
- sql = 'SELECT uuid FROM user_users WHERE username = ?';
413
-
414
- username = username.trim();
415
- dbFields.push(username);
416
-
417
- that.dataWriter.ready(function (err) {
418
- if (err) return cb(err);
419
-
420
- that.db.query(sql, dbFields, function (err, rows) {
421
- if (err) return cb(err);
422
-
423
- if (rows.length === 0) {
424
- that.log.debug(logPrefix + 'No user found for username: "' + username + '"');
425
- return cb(null, false);
426
- }
427
-
428
- // Use fromUuid() to get the user instance
429
- that.fromUuid(that.lUtils.formatUuid(rows[0].uuid), cb);
430
- });
431
- });
432
- };
433
-
434
- /**
435
- * Instanciate user object from user id
436
- *
437
- * @param int userUuid
438
- * @param func cb(err, userObj) - userObj will be false if no user is found
439
- */
440
- User.prototype.fromUuid = function fromUuid(userUuid, cb) {
441
- const userUuidBuf = this.lUtils.uuidToBuffer(userUuid),
442
- logPrefix = topLogPrefix + 'fromUuid() - ',
443
- returnObj = new UserBase(this),
444
- dbFields = [userUuidBuf],
445
- that = this,
446
- sql = 'SELECT\n' +
447
- ' u.uuid,\n' +
448
- ' u.username,\n' +
449
- ' u.password,\n' +
450
- ' uf.uuid AS fieldUuid,\n' +
451
- ' uf.name AS fieldName,\n' +
452
- ' ud.data AS fieldData\n' +
453
- 'FROM\n' +
454
- ' user_users u\n' +
455
- ' LEFT JOIN user_users_data ud ON ud.userUuid = u.uuid\n' +
456
- ' LEFT JOIN user_data_fields uf ON uf.uuid = ud.fieldUuid\n' +
457
- 'WHERE u.uuid = ?';
458
-
459
- if ( ! userUuidBuf) {
460
- const err = new Error('Invalid userUuid');
461
- that.log.warn(logPrefix + err.message);
462
- return cb(err);
463
- }
464
-
465
- that.dataWriter.ready(function (err) {
466
- if (err) return cb(err);
467
-
468
- that.db.query(sql, dbFields, function (err, rows) {
469
- if (err) return cb(err);
470
-
471
- if (rows.length === 0) {
472
- const err = new Error('No user found for userUuid: "' + userUuid + '"');
473
- that.log.debug(logPrefix + err.message);
474
- return cb(null, false);
475
- }
476
-
477
- returnObj.uuid = that.lUtils.formatUuid(rows[0].uuid);
478
- returnObj.username = rows[0].username;
479
-
480
- if (rows[0].password === '') {
481
- returnObj.passwordIsFalse = true;
482
- } else {
483
- returnObj.passwordIsFalse = false;
484
- }
485
-
486
- for (let i = 0; rows[i] !== undefined; i ++) {
487
- const row = rows[i];
488
-
489
- if (row.fieldUuid) {
490
- if (returnObj.fields[row.fieldName] === undefined) {
491
- returnObj.fields[row.fieldName] = [];
492
- }
493
-
494
- returnObj.fields[row.fieldName].push(row.fieldData);
495
- }
496
- }
497
-
498
- cb(null, returnObj);
499
- });
500
- });
501
- };
502
-
503
- /**
504
- * Get field data for a user
505
- *
506
- * @param str userUuid
507
- * @param str fieldName
508
- * @param func cb(err, data) - data is always an array of data (or empty array)
509
- */
510
- User.prototype.getFieldData = function getFieldData(userUuid, fieldName, cb) {
511
- const logPrefix = topLogPrefix + 'getFieldData() - ',
512
- that = this;
513
-
514
- that.helpers.getFieldUuid(fieldName, function (err, fieldUuid) {
515
- const userUuidBuffer = that.lUtils.uuidToBuffer(userUuid),
516
- fieldUuidBuffer = that.lUtils.uuidToBuffer(fieldUuid),
517
- dbFields = [userUuidBuffer, fieldUuidBuffer],
518
- sql = 'SELECT data FROM user_users_data WHERE userUuid = ? AND fieldUuid = ?';
519
-
520
- if (err) return cb(err);
521
-
522
- if (userUuidBuffer === false) {
523
- const err = new Error('Invalid user uuid');
524
- that.log.verbose(logPrefix + err.message);
525
- return cb(err);
526
- }
527
-
528
- if (fieldUuidBuffer === false) {
529
- const err = new Error('Invalid field uuid');
530
- that.log.verbose(logPrefix + err.message);
531
- return cb(err);
532
- }
533
-
534
- that.db.query(sql, dbFields, function (err, rows) {
535
- const data = [];
536
-
537
- if (err) return cb(err);
538
-
539
- for (let i = 0; rows[i] !== undefined; i ++) {
540
- data.push(rows[i].data);
541
- }
542
-
543
- cb(null, data);
544
- });
545
- });
546
- };
547
-
548
- /**
549
- * Hashes a new password
550
- *
551
- * @param str password
552
- * @param func cb(err, hash)
553
- */
554
- User.prototype.hashPassword = function hashPassword(password, cb) {
555
- const logPrefix = topLogPrefix + 'hashPassword() - ',
556
- that = this;
557
-
558
- if ( ! password) {
559
- password = '';
560
- }
561
-
562
- password = password.trim();
563
-
564
- bcrypt.hash(password, 10, function (err, hash) {
565
- if (err) {
566
- that.log.error(logPrefix + err.message);
567
- }
568
-
569
- cb(err, hash);
570
- });
571
- };
572
-
573
- /**
574
- * Replace all fields
575
- * IMPORTANT!!! Will clear all data not given in the fields parameter
576
- *
577
- * @param str userUuid
578
- * @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']}
579
- * @param func cb(err)
580
- */
581
- User.prototype.replaceUserFields = function replaceUserFields(uuid, fields, cb) {
582
- const options = {'exchange': this.dataWriter.exchangeName},
583
- sendObj = {},
584
- that = this;
585
-
586
- that.fromUuid(uuid, function (err, user) {
587
- if (err) return cb(err);
588
-
589
- sendObj.action = 'replaceFields';
590
- sendObj.params = {};
591
- sendObj.params.username = user.username;
592
- sendObj.params.userUuid = uuid;
593
- sendObj.params.fields = fields;
594
-
595
- that.intercom.send(sendObj, options, function (err, msgUuid) {
596
- if (err) return cb(err);
597
-
598
- that.dataWriter.emitter.once(msgUuid, cb);
599
- });
600
- });
601
- };
602
-
603
- /**
604
- * Remove a user
605
- *
606
- * @param uuid userUuid
607
- * @param func cb(err)
608
- */
609
- User.prototype.rmUser = function rmUser(userUuid, cb) {
610
- const options = {'exchange': this.dataWriter.exchangeName},
611
- sendObj = {},
612
- that = this;
613
-
614
- sendObj.action = 'rmUser';
615
- sendObj.params = {};
616
- sendObj.params.userUuid = userUuid;
617
-
618
- that.intercom.send(sendObj, options, function (err, msgUuid) {
619
- if (err) return cb(err);
620
-
621
- that.dataWriter.emitter.once(msgUuid, cb);
622
- });
623
- };
624
-
625
- /**
626
- * Remove a user field
627
- *
628
- * @param uuid userUuid
629
- * @param str fieldName
630
- * @param func cb(err)
631
- */
632
- User.prototype.rmUserField = function rmUserField(userUuid, fieldName, cb) {
633
- const options = {'exchange': this.dataWriter.exchangeName},
634
- sendObj = {},
635
- that = this;
636
-
637
- sendObj.action = 'rmUserField';
638
- sendObj.params = {};
639
- sendObj.params.userUuid = userUuid;
640
- sendObj.params.fieldName = fieldName;
641
-
642
- that.intercom.send(sendObj, options, function (err, msgUuid) {
643
- if (err) return cb(err);
644
-
645
- that.dataWriter.emitter.once(msgUuid, cb);
646
- });
647
- };
648
-
649
- /**
650
- * Set password for a user
651
- *
652
- * @param str userUuid
653
- * @param str newPassword (plain text) or false for no valid password (user will not be able to login at all)
654
- * @param func cb(err)
655
- */
656
- User.prototype.setPassword = function setPassword(userUuid, newPassword, cb) {
657
- const tasks = [],
658
- that = this;
659
-
660
- let hashedPassword;
661
-
662
- tasks.push(function (cb) {
663
- if (newPassword) {
664
- that.hashPassword(newPassword.trim(), function (err, hash) {
665
- hashedPassword = hash;
666
- cb(err);
667
- });
668
- } else {
669
- hashedPassword = false;
670
- cb();
671
- }
672
- });
673
-
674
- tasks.push(function (cb) {
675
- const options = {'exchange': that.dataWriter.exchangeName},
676
- sendObj = {};
677
-
678
- sendObj.action = 'setPassword';
679
- sendObj.params = {};
680
- sendObj.params.userUuid = userUuid;
681
- sendObj.params.password = hashedPassword;
682
-
683
- that.intercom.send(sendObj, options, function (err, msgUuid) {
684
- if (err) return cb(err);
685
-
686
- that.dataWriter.emitter.once(msgUuid, cb);
687
- });
688
- });
689
-
690
- async.series(tasks, cb);
691
- };
692
-
693
- /**
694
- * Set the username for a user
695
- *
696
- * @param str userUuid
697
- * @param str newusername
698
- * @param fucn cb(err)
699
- */
700
- User.prototype.setUsername = function setUsername(userUuid, newUsername, cb) {
701
- const userUuidBuf = this.lUtils.uuidToBuffer(userUuid),
702
- logPrefix = topLogPrefix + 'setUsername() - ',
703
- that = this;
704
-
705
- newUsername = newUsername.trim();
706
-
707
- if ( ! newUsername) {
708
- const err = new Error('No new username supplied');
709
- that.log.warn(logPrefix + err.message);
710
- return cb(err);
711
- }
712
-
713
- if (userUuidBuf === false) {
714
- const err = new Error('Invalid user uuid');
715
- that.log.warn(logPrefix + err.message);
716
- return cb(err);
717
- }
718
-
719
- that.dataWriter.ready(function (err) {
720
- if (err) return cb(err);
721
-
722
- that.db.query('SELECT uuid FROM user_users WHERE username = ? AND uuid != ?', [newUsername, userUuidBuf], function (err, rows) {
723
- const options = {'exchange': that.dataWriter.exchangeName},
724
- sendObj = {};
725
-
726
- if (err) return cb(err);
727
-
728
- if (rows.length && that.lUtils.formatUuid(rows[0].uuid) !== userUuid) {
729
- const err = new Error('Username is already taken');
730
- return cb(err);
731
- }
732
-
733
- sendObj.action = 'setUsername';
734
- sendObj.params = {};
735
- sendObj.params.userUuid = userUuid;
736
- sendObj.params.username = newUsername;
737
-
738
- that.intercom.send(sendObj, options, function (err, msgUuid) {
739
- if (err) return cb(err);
740
-
741
- that.dataWriter.emitter.once(msgUuid, cb);
742
- });
743
- });
744
- });
745
- };
746
-
747
- /**
748
- * Checks if a unsername is available
749
- *
750
- * @param str username
751
- * @param func cb(err, result) - result is a bolean
752
- */
753
- User.prototype.usernameAvailable = function usernameAvailable(username, cb) {
754
- const that = this;
755
-
756
- let isAvailable;
757
-
758
- username = username.trim();
759
-
760
- that.dataWriter.ready(function (err) {
761
- if (err) return cb(err);
762
-
763
- that.db.query('SELECT uuid FROM user_users WHERE username = ?', [username], function (err, rows) {
764
- if (err) return cb(err);
765
-
766
- if (rows.length === 0) {
767
- isAvailable = true;
768
- } else {
769
- isAvailable = false;
770
- }
771
-
772
- cb(null, isAvailable);
773
- });
774
- });
775
- };
776
-
777
- function UserBase(userInstance) {
778
- const that = this;
779
-
780
- that.fields = {};
781
-
782
- that.userInstance = userInstance;
783
- that.log = that.userInstance.log;
784
- }
785
-
786
- /**
787
- * Add a field with value
788
- *
789
- * @param str name
790
- * @param str value
791
- * @param func cb(err)
792
- */
793
- UserBase.prototype.addField = function addField(name, value, cb) {
794
- const logPrefix = topLogPrefix + 'UserBase.addField() - ',
795
- that = this;
796
-
797
- if (that.uuid === undefined) {
798
- const err = new Error('Cannot add field; no user loaded');
799
- that.log.verbose(logPrefix + err.message);
800
- return cb(err);
801
- }
802
-
803
- that.userInstance.addUserDataField(that.uuid, name, value, function (err) {
804
- if (err) return cb(err);
805
-
806
- if (that.fields[name] === undefined) {
807
- that.fields[name] = [];
808
- }
809
-
810
- that.fields[name].push(value);
811
- cb();
812
- });
813
- };
814
-
815
- /**
816
- * Adds one or more fields with values to the user object. Does not overwrite existing values. It is possible to add the same value multiple times
817
- *
818
- * @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']}
819
- * @param func cb(err)
820
- */
821
- UserBase.prototype.addFields = function addFields(fields, cb) {
822
- const logPrefix = topLogPrefix + 'UserBase.addFields() - ',
823
- that = this;
824
-
825
- if (that.uuid === undefined) {
826
- const err = new Error('Cannot add field; no user loaded');
827
- that.log.verbose(logPrefix + err.message);
828
- return cb(err);
829
- }
830
-
831
- that.userInstance.addUserDataFields(that.uuid, fields, function (err) {
832
- if (err) return cb(err);
833
-
834
- for (let key in fields) {
835
- if (that.fields[key] === undefined) {
836
- that[key] = fields[key];
837
- } else {
838
- for (let value of fields[key]) {
839
- that.fields[key].push(value);
840
- }
841
- }
842
- }
843
-
844
- cb();
845
- });
846
- };
847
-
848
- /**
849
- * Replace all fields
850
- * IMPORTANT!!! Will clear all data not given in the fields parameter
851
- *
852
- * @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']}
853
- * @param func cb(err)
854
- */
855
- UserBase.prototype.replaceFields = function replaceFields(fields, cb) {
856
- const logPrefix = topLogPrefix + 'UserBase.replaceFields() - ',
857
- that = this;
858
-
859
- if (that.uuid === undefined) {
860
- const err = new Error('Cannot replace fields; no user loaded');
861
- that.log.verbose(logPrefix + err.message);
862
- return cb(err);
863
- }
864
-
865
- that.userInstance.replaceUserFields(that.uuid, fields, function (err) {
866
- if (err) return cb(err);
867
-
868
- // Reload everything
869
- that.userInstance.fromUuid(that.uuid, function (err, user) {
870
- if (err) return cb(err);
871
-
872
- that.fields = user.fields;
873
- cb();
874
- });
875
- });
876
- };
877
-
878
- UserBase.prototype.rm = function rm(cb) {
879
- const logPrefix = topLogPrefix + 'UserBase.rm() - ',
880
- that = this;
881
-
882
- if (that.uuid === undefined) {
883
- const err = new Error('Cannot remove field; no user loaded');
884
- that.log.verbose(logPrefix + err.message);
885
- return cb(err);
886
- }
887
-
888
- that.userInstance.rmUser(that.uuid, function (err) {
889
- if (err) return cb(err);
890
-
891
- delete that.uuid;
892
- delete that.username;
893
-
894
- that.fields = {};
895
-
896
- cb();
897
- });
898
- };
899
-
900
- /**
901
- * Remove a field from this user
902
- *
903
- * @param str name
904
- * @param func cb(err)
905
- */
906
- UserBase.prototype.rmField = function rmField(name, cb) {
907
- const logPrefix = topLogPrefix + 'UserBase.rmField() - ',
908
- that = this;
909
-
910
- if (that.uuid === undefined) {
911
- const err = new Error('Cannot remove field; no user loaded');
912
- that.log.verbose(logPrefix + err.message);
913
- return cb(err);
914
- }
915
-
916
- that.userInstance.rmUserField(that.uuid, name, function (err) {
917
- if (err) return cb(err);
918
-
919
- delete that.fields[name];
920
- cb();
921
- });
922
- };
923
-
924
- UserBase.prototype.setPassword = function (newPassword, cb) {
925
- const logPrefix = topLogPrefix + 'UserBase.setPassword() - ',
926
- that = this;
927
-
928
- if (that.uuid === undefined) {
929
- const err = new Error('Cannot set password; no user loaded');
930
- that.log.verbose(logPrefix + err.message);
931
- return cb(err);
932
- }
933
-
934
- that.userInstance.setPassword(that.uuid, newPassword, cb);
935
- };
936
-
937
- UserBase.prototype.setUsername = function (newUsername, cb) {
938
- const logPrefix = topLogPrefix + 'UserBase.setUsername() - ',
939
- that = this;
940
-
941
- if (that.uuid === undefined) {
942
- const err = new Error('Cannot set username; no user loaded');
943
- that.log.verbose(logPrefix + err.message);
944
- return cb(err);
945
- }
946
-
947
- that.userInstance.setUsername(that.uuid, newUsername, function (err) {
948
- if (err) return cb(err);
949
-
950
- that.username = newUsername;
951
- cb();
952
- });
953
- };
954
-
955
- exports = module.exports = User;
956
- exports.Users = require(__dirname + '/users.js');