Built motion from commit d415888.|0.0.73
[motion.git] / server / models / user.js
1 'use strict';
2
3 var crypto = require('crypto');
4 var md5 = require('md5');
5 var _ = require('lodash');
6 var moment = require('moment');
7 var VoiceQueue = require('.').VoiceQueue;
8
9 module.exports = function(sequelize, DataTypes) {
10   var User = sequelize.define('User', {
11     name: {
12       type: DataTypes.STRING,
13       unique: true,
14       validate: {
15         notEmpty: true,
16         is: /^[A-Za-z0-9\.\_]+$/i
17       },
18       set: function(name) {
19         this.setDataValue('name', name);
20         this.setDataValue('defaultuser', name);
21       }
22     },
23     fullname: {
24       type: DataTypes.STRING,
25       allowNull: false,
26     },
27     email: {
28       type: DataTypes.STRING,
29       unique: true,
30       isEmail: true,
31       set: function(email) {
32         if (email) {
33           this.setDataValue('email', email.toLowerCase());
34         }
35       },
36       defaultValue: null
37     },
38     role: {
39       type: DataTypes.ENUM('admin', 'user', 'agent', 'telephone')
40     },
41     password: {
42       type: DataTypes.STRING,
43       allowNull: false,
44       validate: {
45         notEmpty: true
46       },
47       set: function(password) {
48         this.salt = this.makeSalt();
49         this.setDataValue('password', this.encryptPassword(password));
50         this.setDataValue('md5secret', this.md5Password(this.name + ':asterisk:' + password));
51       }
52     },
53     provider: {
54       type: DataTypes.STRING,
55       defaultValue: 'local'
56     },
57     internal: {
58       type: DataTypes.INTEGER(11),
59       unique: true,
60       set: function(internal) {
61         this.setDataValue('internal', internal);
62         this.setDataValue('accountcode', internal);
63       }
64     },
65     salt: {
66       type: DataTypes.STRING
67     },
68     phone: {
69       type: DataTypes.STRING
70     },
71     mobile: {
72       type: DataTypes.STRING
73     },
74     address: {
75       type: DataTypes.STRING
76     },
77     zipcode: {
78       type: DataTypes.STRING
79     },
80     userpic: {
81       type: DataTypes.STRING
82     },
83     city: {
84       type: DataTypes.STRING
85     },
86     country: {
87       type: DataTypes.STRING
88     },
89     online: {
90       type: DataTypes.BOOLEAN,
91       defaultValue: false
92     },
93     lastLoginAt: {
94       type: DataTypes.DATE
95     },
96     status: {
97       type: DataTypes.STRING,
98       defaultValue: 'UNKNOWN'
99     },
100     statusAt: {
101       type: DataTypes.DATE
102     },
103     queueStatus: {
104       type: DataTypes.STRING,
105       defaultValue: 'complete'
106     },
107     queueStatusAt: {
108       type: DataTypes.DATE
109     },
110     lastQueue: {
111       type: DataTypes.STRING
112     },
113     voicePause: {
114       type: DataTypes.BOOLEAN,
115       defaultValue: false,
116       set: function(voicePause) {
117         this.setDataValue('voicePause', voicePause);
118         if (voicePause) {
119           this.setDataValue('queueStatus', 'paused');
120           this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
121         } else {
122           this.setDataValue('queueStatus', 'complete');
123           this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
124         }
125       }
126     },
127     chatPause: {
128       type: DataTypes.BOOLEAN,
129       defaultValue: false
130     },
131     mailPause: {
132       type: DataTypes.BOOLEAN,
133       defaultValue: false
134     },
135     faxPause: {
136       type: DataTypes.BOOLEAN,
137       defaultValue: false
138     },
139     pauseType: {
140       type: DataTypes.STRING,
141       defaultValue: 'Default Pause'
142     },
143     lastPauseAt: {
144       type: DataTypes.DATE
145     },
146     chatCapacity: {
147       type: DataTypes.INTEGER,
148       defaultValue: 0
149     },
150     mailCapacity: {
151       type: DataTypes.INTEGER,
152       defaultValue: 0
153     },
154     faxCapacity: {
155       type: DataTypes.INTEGER,
156       defaultValue: 0
157     },
158     phoneBarAutoAnswer: {
159       type: DataTypes.BOOLEAN,
160       defaultValue: false
161     },
162     phoneBarEnableSettings: {
163       type: DataTypes.BOOLEAN,
164       defaultValue: true
165     },
166     phoneBarUnconditionalNumber: {
167       type: DataTypes.STRING,
168       get: function() {
169         if (this.getDataValue('phoneBarUnconditional')) {
170           return this.getDataValue('phoneBarUnconditionalNumber');
171         }
172         return null;
173       }
174     },
175     phoneBarNoReplyNumber: {
176       type: DataTypes.STRING,
177       get: function() {
178         if (this.getDataValue('phoneBarNoReply')) {
179           return this.getDataValue('phoneBarNoReplyNumber');
180         }
181         return null;
182       }
183     },
184     phoneBarBusyNumber: {
185       type: DataTypes.STRING,
186       get: function() {
187         if (this.getDataValue('phoneBarBusy')) {
188           return this.getDataValue('phoneBarBusyNumber');
189         }
190         return null;
191       }
192     },
193     phoneBarUnconditional: {
194       type: DataTypes.BOOLEAN,
195       defaultValue: false
196     },
197     phoneBarNoReply: {
198       type: DataTypes.BOOLEAN,
199       defaultValue: false
200     },
201     phoneBarBusy: {
202       type: DataTypes.BOOLEAN,
203       defaultValue: false
204     },
205     phoneBarListenPort: {
206       type: DataTypes.INTEGER(5),
207       defaultValue: 5060
208     },
209     phoneBarECTail: {
210       type: DataTypes.INTEGER(5),
211       defaultValue: 200
212     },
213     phoneBarExpires: {
214       type: DataTypes.INTEGER(5),
215       defaultValue: 3600
216     },
217     phoneBarNameServer: {
218       type: DataTypes.STRING,
219       allowNull: true
220     },
221     phoneBarStunServer: {
222       type: DataTypes.STRING,
223       allowNull: true
224     },
225     phoneBarVADEnabled: {
226       type: DataTypes.BOOLEAN,
227       defaultValue: true
228     },
229     phoneBarNoUDP: {
230       type: DataTypes.BOOLEAN,
231       defaultValue: false
232     },
233     phoneBarNoTCP: {
234       type: DataTypes.BOOLEAN,
235       defaultValue: true
236     },
237     phoneBarLogLevel: {
238       type: DataTypes.INTEGER(5),
239       defaultValue: 1
240     },
241     phoneBarPublishEnabled: {
242       type: DataTypes.BOOLEAN,
243       defaultValue: false
244     },
245     chanspy: {
246       type: DataTypes.BOOLEAN,
247       defaultValue: false
248     },
249     description: {
250       type: DataTypes.STRING,
251       allowNull: true,
252     },
253     ipaddr: { //REALTIME ASTERISK
254       type: DataTypes.STRING,
255       allowNull: true,
256     },
257     port: { //REALTIME ASTERISK
258       type: DataTypes.INTEGER(5),
259       allowNull: true,
260     },
261     regseconds: { //REALTIME ASTERISK
262       type: DataTypes.INTEGER(11),
263       allowNull: true,
264     },
265     fullcontact: { //REALTIME ASTERISK
266       type: DataTypes.STRING,
267       allowNull: true,
268     },
269     regserver: { //REALTIME ASTERISK
270       type: DataTypes.STRING,
271       allowNull: true,
272     },
273     useragent: { //REALTIME ASTERISK
274       type: DataTypes.STRING,
275       allowNull: true,
276     },
277     lastms: { //REALTIME ASTERISK
278       type: DataTypes.INTEGER(11),
279       allowNull: true,
280     },
281     type: {
282       type: DataTypes.ENUM('friend', 'user', 'peer'),
283       allowNull: true,
284       defaultValue: 'friend'
285     },
286     context: {
287       type: DataTypes.STRING,
288       allowNull: true,
289       defaultValue: 'from-sip'
290     },
291     callingpres: {
292       type: DataTypes.ENUM('ALLOWED_NOT_SCREENED',
293         'ALLOWED_PASSED_SCREEN', 'ALLOWED_FAILED_SCREEN', 'ALLOWED',
294         'PROHIB_NOT_SCREENED', 'PROHIB_PASSED_SCREEN',
295         'PROHIB_FAILED_SCREEN', 'PROHIB'),
296       allowNull: true,
297     },
298     permit: {
299       type: DataTypes.STRING,
300       allowNull: true,
301     },
302     deny: {
303       type: DataTypes.STRING,
304       allowNull: true,
305     },
306     secret: {
307       type: DataTypes.STRING,
308       allowNull: true,
309     },
310     md5secret: {
311       type: DataTypes.STRING,
312       allowNull: true,
313     },
314     remotesecret: {
315       type: DataTypes.STRING,
316       allowNull: true,
317     },
318     transport: {
319       type: DataTypes.STRING,
320       allowNull: true,
321       defaultValue: 'udp'
322     },
323     dtmfmode: {
324       type: DataTypes.ENUM('rfc2833', 'info', 'shortinfo', 'inband',
325         'auto'),
326       allowNull: true,
327       defaultValue: 'rfc2833'
328     },
329     directmedia: {
330       type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'outgoing'),
331       allowNull: true,
332       defaultValue: 'no'
333     },
334     directrtpsetup: {
335       type: DataTypes.ENUM('yes', 'no'),
336       allowNull: true,
337       defaultValue: 'no'
338     },
339     directmediapermit: {
340       type: DataTypes.STRING,
341       allowNull: true,
342     },
343     directmediadeny: {
344       type: DataTypes.STRING,
345       allowNull: true,
346     },
347     nat: {
348       type: DataTypes.STRING,
349       allowNull: true,
350       defaultValue: 'force_rport,comedia'
351     },
352     callgroup: {
353       type: DataTypes.STRING,
354       allowNull: true,
355     },
356     namedcallgroup: { //We are in named call groups engineering,sales,netgroup,protgroup
357       type: DataTypes.STRING,
358       allowNull: true,
359     },
360     pickupgroup: {
361       type: DataTypes.STRING,
362       allowNull: true,
363     },
364     namedpickupgroup: { //We can do call pick-p for named call group sales
365       type: DataTypes.STRING,
366       allowNull: true,
367     },
368     language: {
369       type: DataTypes.STRING,
370       allowNull: true,
371       defaultValue: 'en'
372     },
373     tonezone: {
374       type: DataTypes.STRING,
375       allowNull: true
376     },
377     allow: {
378       type: DataTypes.STRING,
379       allowNull: true,
380       defaultValue: 'alaw;ulaw;gsm'
381     },
382     disallow: {
383       type: DataTypes.STRING,
384       allowNull: true,
385       defaultValue: null
386     },
387     autoframing: {
388       type: DataTypes.ENUM('yes', 'no'),
389       allowNull: true,
390     },
391     insecure: {
392       type: DataTypes.STRING,
393       allowNull: true,
394       defaultValue: 'port,invite'
395     },
396     trustrpid: {
397       type: DataTypes.ENUM('yes', 'no'),
398       allowNull: true,
399       defaultValue: 'no'
400     },
401     trust_id_outbound: {
402       type: DataTypes.ENUM('yes', 'no'),
403       allowNull: true,
404       defaultValue: 'no'
405     },
406     progressinband: {
407       type: DataTypes.ENUM('yes', 'no', 'never'),
408       allowNull: true,
409     },
410     promiscredir: {
411       type: DataTypes.ENUM('yes', 'no'),
412       allowNull: true,
413     },
414     useclientcode: {
415       type: DataTypes.ENUM('yes', 'no'),
416       allowNull: true,
417     },
418     accountcode: {
419       type: DataTypes.INTEGER(11),
420       allowNull: true,
421     },
422     setvar: {
423       type: DataTypes.STRING,
424       allowNull: true,
425     },
426     callerid: {
427       type: DataTypes.STRING,
428       allowNull: true,
429       defaultValue: '"" <>'
430     },
431     amaflags: {
432       type: DataTypes.STRING,
433       allowNull: true,
434     },
435     callcounter: {
436       type: DataTypes.ENUM('yes', 'no'),
437       allowNull: true,
438       defaultValue: 'yes'
439     },
440     busylevel: {
441       type: DataTypes.INTEGER(11),
442       allowNull: true,
443     },
444     allowoverlap: {
445       type: DataTypes.ENUM('yes', 'no'),
446       allowNull: true,
447     },
448     allowsubscribe: {
449       type: DataTypes.ENUM('yes', 'no'),
450       allowNull: true,
451     },
452     allowtransfer: {
453       type: DataTypes.ENUM('yes', 'no'),
454       allowNull: true,
455     },
456     ignoresdpversion: {
457       type: DataTypes.ENUM('yes', 'no'),
458       allowNull: true,
459     },
460     subscribecontext: {
461       type: DataTypes.STRING,
462       allowNull: true,
463     },
464     template: {
465       type: DataTypes.STRING,
466       allowNull: true,
467     },
468     videosupport: {
469       type: DataTypes.ENUM('yes', 'no', 'always'),
470       allowNull: true,
471       defaultValue: 'no'
472     },
473     maxcallbitrate: {
474       type: DataTypes.INTEGER(11),
475       allowNull: true,
476     },
477     rfc2833compensate: {
478       type: DataTypes.ENUM('yes', 'no'),
479       allowNull: true,
480     },
481     mailbox: {
482       type: DataTypes.STRING,
483       allowNull: true,
484     },
485     session_timers: {
486       type: DataTypes.ENUM('accept', 'refuse', 'originate'),
487       allowNull: true,
488     },
489     session_expires: {
490       type: DataTypes.INTEGER(11),
491       allowNull: true,
492     },
493     session_minse: {
494       type: DataTypes.INTEGER(11),
495       allowNull: true,
496     },
497     session_refresher: {
498       type: DataTypes.ENUM('uac', 'uas'),
499       allowNull: true,
500       defaultValue: 'uas'
501     },
502     t38pt_usertpsource: {
503       type: DataTypes.STRING,
504       allowNull: true,
505     },
506     regexten: {
507       type: DataTypes.STRING,
508       allowNull: true,
509     },
510     fromdomain: {
511       type: DataTypes.STRING,
512       allowNull: true,
513     },
514     fromuser: {
515       type: DataTypes.STRING,
516       allowNull: true,
517     },
518     host: {
519       type: DataTypes.STRING,
520       allowNull: true,
521       defaultValue: 'dynamic'
522     },
523     qualify: {
524       type: DataTypes.ENUM('yes', 'no'),
525       allowNull: true,
526       defaultValue: 'yes'
527     },
528     keepalive: {
529       type: DataTypes.INTEGER(11),
530       allowNull: true,
531     },
532     defaultip: {
533       type: DataTypes.STRING,
534       allowNull: true,
535     },
536     defaultuser: {
537       type: DataTypes.STRING,
538       allowNull: true,
539     },
540     rtptimeout: { // Terminate call if 60 seconds of no RTP or RTCP activity on the audio channel  when we're not on hold.
541       type: DataTypes.INTEGER(11),
542       allowNull: true,
543     },
544     rtpholdtimeout: { // Terminate call if 300 seconds of no RTP or RTCP activity on the audio channel when we're on hold (must be > rtptimeout)
545       type: DataTypes.INTEGER(11),
546       allowNull: true,
547     },
548     rtpkeepalive: { // Send keepalives in the RTP stream to keep NAT open (default is off - zero)
549       type: DataTypes.INTEGER(11),
550       allowNull: true,
551     },
552     sendrpid: {
553       type: DataTypes.ENUM('yes', 'no'),
554       allowNull: true,
555       defaultValue: 'no'
556     },
557     outboundproxy: {
558       type: DataTypes.STRING,
559       allowNull: true,
560     },
561     callbackextension: {
562       type: DataTypes.STRING,
563       allowNull: true,
564     },
565     timert1: {
566       type: DataTypes.INTEGER(11),
567       allowNull: true,
568     },
569     timerb: {
570       type: DataTypes.INTEGER(11),
571       allowNull: true,
572     },
573     qualifyfreq: {
574       type: DataTypes.INTEGER(11),
575       allowNull: true,
576     },
577     contactpermit: {
578       type: DataTypes.STRING,
579       allowNull: true,
580     },
581     contactdeny: {
582       type: DataTypes.STRING,
583       allowNull: true,
584     },
585     contactacl: {
586       type: DataTypes.STRING,
587       allowNull: true,
588     },
589     unsolicited_mailbox: {
590       type: DataTypes.STRING,
591       allowNull: true,
592     },
593     use_q850_reason: {
594       type: DataTypes.STRING,
595       allowNull: true,
596     },
597     maxforwards: {
598       type: DataTypes.INTEGER(11),
599       allowNull: true,
600     },
601     encryption: {
602       type: DataTypes.ENUM('yes', 'no'),
603       allowNull: true,
604       defaultValue: 'no'
605     },
606     avpf: {
607       type: DataTypes.ENUM('yes', 'no'),
608       allowNull: true
609     },
610     force_avp: {
611       type: DataTypes.ENUM('yes', 'no'),
612       allowNull: true
613     },
614     icesupport: {
615       type: DataTypes.ENUM('yes', 'no'),
616       allowNull: true
617     },
618     dtlsenable: {
619       type: DataTypes.ENUM('yes', 'no'),
620       allowNull: true
621     },
622     dtlsverify: {
623       type: DataTypes.ENUM('yes', 'no', 'fingerprint', 'certificate'),
624       allowNull: true
625     },
626     dtlsrekey: {
627       type: DataTypes.INTEGER(11),
628       allowNull: true,
629     },
630     dtlscertfile: {
631       type: DataTypes.STRING,
632       allowNull: true,
633     },
634     dtlsprivatekey: {
635       type: DataTypes.STRING,
636       allowNull: true,
637     },
638     dtlscipher: {
639       type: DataTypes.STRING,
640       allowNull: true,
641     },
642     dtlscafile: {
643       type: DataTypes.STRING,
644       allowNull: true,
645     },
646     dtlscapath: {
647       type: DataTypes.STRING,
648       allowNull: true,
649     },
650     dtlssetup: {
651       type: DataTypes.ENUM('active', 'passive', 'actpass'),
652       allowNull: true
653     },
654     dtlsfingerprint: {
655       type: DataTypes.STRING,
656       allowNull: true,
657     },
658     usereqphone: { //This provider requires ";user=phone" on URI
659       type: DataTypes.ENUM('yes', 'no'),
660       allowNull: true,
661       defaultValue: 'no'
662     },
663     recordonfeature: { //Feature to use when INFO with Record: on is received.
664       type: DataTypes.STRING,
665       allowNull: true,
666     },
667     recordofffeature: { //Feature to use when INFO with Record: off is received.
668       type: DataTypes.STRING,
669       allowNull: true,
670     },
671     call_limit: {
672       type: DataTypes.INTEGER(11),
673       allowNull: true,
674       defaultValue: null
675     },
676     registertrying: { //Send a 100 Trying when the device registers.
677       type: DataTypes.ENUM('yes', 'no'),
678       allowNull: true,
679     },
680     subscribemwi: { //Only send notifications if this phone subscribes for mailbox notification
681       type: DataTypes.ENUM('yes', 'no'),
682       allowNull: true,
683     },
684     vmexten: { // dialplan extension to reach mailbox. defaults to global vmexten which defaults to "asterisk"
685       type: DataTypes.STRING,
686       allowNull: true,
687     },
688     mohinterpret: { // This option specifies a preference for which music on hold class this channel should listen to when put on hold
689       type: DataTypes.STRING,
690       allowNull: true,
691     },
692     mohsuggest: { //  This option specifies which music on hold class to suggest to the peer channel when this channel places the peer on hold.
693       type: DataTypes.STRING,
694       allowNull: true,
695     },
696     parkinglot: {
697       type: DataTypes.STRING,
698       allowNull: true,
699     },
700     canreinvite: {
701       type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'update,nonat'),
702       allowNull: true,
703       defaultValue: 'no'
704     },
705   }, {
706     tableName: 'users',
707     instanceMethods: {
708       /**
709        * Authenticate - check if the passwords are the same
710        *
711        * @param {String} plainText
712        *        {function} callBack
713        * @api public
714        */
715       authenticate: function(plainText) {
716         return this.encryptPassword(plainText) === this.password;
717       },
718       /**
719        * Make salt
720        *
721        * @return {String}
722        * @api public
723        */
724       makeSalt: function() {
725         return crypto.randomBytes(16).toString('base64');
726       },
727       /**
728        * Encrypt password
729        *
730        * @param {String} password
731        * @return {String}
732        * @api public
733        */
734       encryptPassword: function(password) {
735         if (!password || !this.salt) return '';
736         var salt = new Buffer(this.salt, 'base64');
737         return crypto.pbkdf2Sync(password, salt, 10000, 64).toString(
738           'base64');
739       },
740       /**
741        * md5 password
742        *
743        * @param {String} password
744        * @return {String}
745        * @api public
746        */
747       md5Password: function(password) {
748         if (!password) return '';
749         return md5(password);
750       }
751     },
752     associate: function(models) {
753       // BELOGNS TO MANY
754       User.hasMany(models.ChatMessage);
755       User.hasMany(models.MailMessage);
756       User.hasMany(models.Contact);
757       User.hasMany(models.Action);
758       User.belongsToMany(models.Module, {
759         through: 'user_has_modules'
760       });
761       User.belongsToMany(models.Channel, {
762         through: 'user_has_channels'
763       });
764       User.belongsToMany(models.MailRoom, {
765         through: 'user_has_mail_rooms'
766       });
767       User.belongsToMany(models.Team, {
768         through: models.UserHasTeam
769       });
770       User.belongsToMany(models.ChatRoom, {
771         through: models.UserHasChatRoom
772       });
773       User.belongsToMany(models.MailQueue, {
774         through: models.UserHasMailQueue,
775         required: false
776       });
777       User.belongsToMany(models.FaxQueue, {
778         through: models.UserHasFaxQueue,
779         required: false
780       });
781       User.belongsToMany(models.ChatQueue, {
782         through: models.UserHasChatQueue,
783         required: false
784       });
785       User.belongsToMany(models.VoiceQueue, {
786         through: models.UserHasVoiceQueue,
787         required: false
788       });
789       User.belongsToMany(models.List, {
790         through: models.UserHasList
791       });
792       User.hasMany(models.VoiceExtension, {
793         foreignKey: 'UserId',
794         as: 'UserExtensions',
795         onDelete: 'cascade',
796         hooks: true
797       });
798
799       // SCOPES MANAGEMENT
800       User.addScope('user', {
801         where: {
802           role: {
803             $in: ['admin', 'user']
804           },
805         }
806       });
807       User.addScope('queues', {
808         include: [models.VoiceQueue, models.ChatQueue, models.MailQueue, models.FaxQueue]
809       });
810       User.addScope('telephone', {
811         where: {
812           role: 'telephone'
813         }
814       });
815       User.addScope('checkPauseStatus', function(query) {
816         var scope = {
817           where: {}
818         };
819         if (query.voicePause) {
820           scope.where.voicePause = (query.voicePause === 'true') ? true : false;
821           delete query.voicePause;
822         } else if (query.faxPause) {
823           scope.where.faxPause = (query.faxPause === 'true') ? true : false;
824           delete query.faxPause;
825         } else if (query.chatPause) {
826           scope.where.chatPause = (query.chatPause === 'true') ? true : false;
827           delete query.chatPause;
828         } else if (query.mailPause) {
829           scope.where.mailPause = (query.mailPause === 'true') ? true : false;
830           delete query.mailPause;
831         }
832         return scope;
833       });
834       User.addScope('checkOnlineStatus', function(query) {
835         var scope = {
836           where: {}
837         };
838         if (query.online) {
839           scope.where.online = (query.online === 'true') ? true : false;
840           delete query.online;
841         }
842         return scope;
843       });
844       User.addScope('checkSipStatus', function(query) {
845         var scope = {
846           where: {}
847         };
848         if (query.status) {
849           scope.where.status = query.status;
850           delete query.status;
851         }
852         return scope;
853       });
854       User.addScope('checkQueueStatus', function(query) {
855         var scope = {
856           where: {}
857         };
858         if (query.queueStatus) {
859           scope.where.queueStatus = query.queueStatus;
860           delete query.queueStatus;
861         }
862         return scope;
863       });
864       User.addScope('agent', {
865         where: {
866           role: 'agent'
867         },
868         attributes: ['id',
869           'name',
870           'email',
871           'internal',
872           'fullname',
873           'accountcode',
874           'transport',
875           'host',
876           'nat',
877           'type',
878           'allow',
879           'chatCapacity',
880           'mailCapacity',
881           'faxCapacity',
882           'online',
883           'lastLoginAt',
884           'phoneBarAutoAnswer',
885           'phoneBarEnableSettings',
886           'phoneBarUnconditional',
887           'phoneBarNoReply',
888           'phoneBarBusy',
889           'phoneBarUnconditionalNumber',
890           'phoneBarNoReplyNumber',
891           'phoneBarBusyNumber',
892           'phoneBarListenPort',
893           'chanspy',
894           'voicePause',
895           'mailPause',
896           'faxPause',
897           'chatPause',
898           'pauseType',
899           'lastPauseAt',
900           'status',
901           'statusAt',
902           'queueStatus',
903           'queueStatusAt',
904           'lastQueue',
905           'useragent',
906           'ipaddr',
907           'fullcontact',
908           'port',
909           'lastms',
910           'description'
911         ]
912       });
913     }
914   });
915
916   return User;
917 }