f19e590541600427dac6ccb214db409a1db79327
[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
8 module.exports = function(sequelize, DataTypes) {
9   var User = sequelize.define('User', {
10     name: {
11       type: DataTypes.STRING,
12       unique: true,
13       validate: {
14         notEmpty: true,
15         is: /^[A-Za-z0-9\.\_]+$/i
16       },
17       set: function(name) {
18         this.setDataValue('name', name);
19         this.setDataValue('defaultuser', name);
20       }
21     },
22     fullname: {
23       type: DataTypes.STRING,
24       allowNull: false,
25       unique: true
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     smsPause: {
140       type: DataTypes.BOOLEAN,
141       defaultValue: false
142     },
143     openchannelPause: {
144       type: DataTypes.BOOLEAN,
145       defaultValue: false
146     },
147     pauseType: {
148       type: DataTypes.STRING,
149       defaultValue: 'Default Pause'
150     },
151     lastPauseAt: {
152       type: DataTypes.DATE
153     },
154     chatCapacity: {
155       type: DataTypes.INTEGER,
156       defaultValue: 0
157     },
158     mailCapacity: {
159       type: DataTypes.INTEGER,
160       defaultValue: 0
161     },
162     faxCapacity: {
163       type: DataTypes.INTEGER,
164       defaultValue: 0
165     },
166     smsCapacity: {
167       type: DataTypes.INTEGER,
168       defaultValue: 0
169     },
170     openchannelCapacity: {
171       type: DataTypes.INTEGER,
172       defaultValue: 0
173     },
174     phoneBarAutoAnswer: {
175       type: DataTypes.BOOLEAN,
176       defaultValue: false
177     },
178     phoneBarEnableSettings: {
179       type: DataTypes.BOOLEAN,
180       defaultValue: true
181     },
182     phoneBarUnconditionalNumber: {
183       type: DataTypes.STRING,
184       get: function() {
185         if (this.getDataValue('phoneBarUnconditional')) {
186           return this.getDataValue('phoneBarUnconditionalNumber');
187         }
188         return null;
189       }
190     },
191     phoneBarNoReplyNumber: {
192       type: DataTypes.STRING,
193       get: function() {
194         if (this.getDataValue('phoneBarNoReply')) {
195           return this.getDataValue('phoneBarNoReplyNumber');
196         }
197         return null;
198       }
199     },
200     phoneBarBusyNumber: {
201       type: DataTypes.STRING,
202       get: function() {
203         if (this.getDataValue('phoneBarBusy')) {
204           return this.getDataValue('phoneBarBusyNumber');
205         }
206         return null;
207       }
208     },
209     phoneBarUnconditional: {
210       type: DataTypes.BOOLEAN,
211       defaultValue: false
212     },
213     phoneBarNoReply: {
214       type: DataTypes.BOOLEAN,
215       defaultValue: false
216     },
217     phoneBarBusy: {
218       type: DataTypes.BOOLEAN,
219       defaultValue: false
220     },
221     phoneBarListenPort: {
222       type: DataTypes.INTEGER(5),
223       defaultValue: 5060
224     },
225     phoneBarECTail: {
226       type: DataTypes.INTEGER(5),
227       defaultValue: 200
228     },
229     phoneBarExpires: {
230       type: DataTypes.INTEGER(5),
231       defaultValue: 120
232     },
233     phoneBarNameServer: {
234       type: DataTypes.STRING,
235       allowNull: true
236     },
237     phoneBarStunServer: {
238       type: DataTypes.STRING,
239       allowNull: true
240     },
241     phoneBarVADEnabled: {
242       type: DataTypes.BOOLEAN,
243       defaultValue: false
244     },
245     phoneBarNoUDP: {
246       type: DataTypes.BOOLEAN,
247       defaultValue: false
248     },
249     phoneBarNoTCP: {
250       type: DataTypes.BOOLEAN,
251       defaultValue: true
252     },
253     phoneBarLogLevel: {
254       type: DataTypes.INTEGER(5),
255       defaultValue: 1
256     },
257     phoneBarPublishEnabled: {
258       type: DataTypes.BOOLEAN,
259       defaultValue: false
260     },
261     phoneBarRemoteControl: {
262       type: DataTypes.BOOLEAN,
263       defaultValue: false
264     },
265     phoneBarRemoteControlPort: {
266       type: DataTypes.INTEGER,
267       defaultValue: 9888
268     },
269     chanspy: {
270       type: DataTypes.BOOLEAN,
271       defaultValue: false
272     },
273     description: {
274       type: DataTypes.STRING,
275       allowNull: true,
276     },
277     host: {
278       type: DataTypes.STRING,
279       allowNull: true,
280       defaultValue: 'dynamic'
281     },
282     ipaddr: { //REALTIME ASTERISK
283       type: DataTypes.STRING,
284       allowNull: true,
285     },
286     port: { //REALTIME ASTERISK
287       type: DataTypes.INTEGER(5),
288       allowNull: true,
289     },
290     regseconds: { //REALTIME ASTERISK
291       type: DataTypes.INTEGER(11),
292       allowNull: true,
293     },
294     fullcontact: { //REALTIME ASTERISK
295       type: DataTypes.STRING,
296       allowNull: true,
297     },
298     regserver: { //REALTIME ASTERISK
299       type: DataTypes.STRING,
300       allowNull: true,
301     },
302     useragent: { //REALTIME ASTERISK
303       type: DataTypes.STRING,
304       allowNull: true,
305     },
306     lastms: { //REALTIME ASTERISK
307       type: DataTypes.INTEGER(11),
308       allowNull: true,
309     },
310     type: {
311       type: DataTypes.ENUM('friend', 'user', 'peer'),
312       allowNull: true,
313       defaultValue: 'friend'
314     },
315     context: {
316       type: DataTypes.STRING,
317       allowNull: true,
318       defaultValue: 'from-sip'
319     },
320     callingpres: {
321       type: DataTypes.ENUM('ALLOWED_NOT_SCREENED',
322         'ALLOWED_PASSED_SCREEN', 'ALLOWED_FAILED_SCREEN', 'ALLOWED',
323         'PROHIB_NOT_SCREENED', 'PROHIB_PASSED_SCREEN',
324         'PROHIB_FAILED_SCREEN', 'PROHIB'),
325       allowNull: true,
326     },
327     deny: {
328       type: DataTypes.STRING,
329       allowNull: true,
330     },
331     permit: {
332       type: DataTypes.STRING,
333       allowNull: true,
334     },
335     secret: {
336       type: DataTypes.STRING,
337       allowNull: true,
338     },
339     md5secret: {
340       type: DataTypes.STRING,
341       allowNull: true,
342     },
343     remotesecret: {
344       type: DataTypes.STRING,
345       allowNull: true,
346     },
347     transport: {
348       type: DataTypes.STRING,
349       allowNull: true,
350       defaultValue: 'udp'
351     },
352     dtmfmode: {
353       type: DataTypes.ENUM('rfc2833', 'info', 'shortinfo', 'inband',
354         'auto'),
355       allowNull: true,
356       defaultValue: 'rfc2833'
357     },
358     directmedia: {
359       type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'outgoing'),
360       allowNull: true,
361       defaultValue: 'no'
362     },
363     directrtpsetup: {
364       type: DataTypes.ENUM('yes', 'no'),
365       allowNull: true,
366       defaultValue: 'no'
367     },
368     directmediapermit: {
369       type: DataTypes.STRING,
370       allowNull: true,
371     },
372     directmediadeny: {
373       type: DataTypes.STRING,
374       allowNull: true,
375     },
376     nat: {
377       type: DataTypes.STRING,
378       allowNull: true,
379       defaultValue: 'force_rport,comedia'
380     },
381     callgroup: {
382       type: DataTypes.STRING,
383       allowNull: true,
384     },
385     namedcallgroup: { //We are in named call groups engineering,sales,netgroup,protgroup
386       type: DataTypes.STRING,
387       allowNull: true,
388     },
389     pickupgroup: {
390       type: DataTypes.STRING,
391       allowNull: true,
392     },
393     namedpickupgroup: { //We can do call pick-p for named call group sales
394       type: DataTypes.STRING,
395       allowNull: true,
396     },
397     language: {
398       type: DataTypes.STRING,
399       allowNull: true,
400       defaultValue: 'en'
401     },
402     tonezone: {
403       type: DataTypes.STRING,
404       allowNull: true
405     },
406     disallow: {
407       type: DataTypes.STRING,
408       allowNull: true,
409       defaultValue: 'all'
410     },
411     allow: {
412       type: DataTypes.STRING,
413       allowNull: true,
414       defaultValue: 'alaw;ulaw;gsm'
415     },
416     autoframing: {
417       type: DataTypes.ENUM('yes', 'no'),
418       allowNull: true,
419     },
420     insecure: {
421       type: DataTypes.STRING,
422       allowNull: true,
423       defaultValue: 'port,invite'
424     },
425     trustrpid: {
426       type: DataTypes.ENUM('yes', 'no'),
427       allowNull: true,
428       defaultValue: 'no'
429     },
430     trust_id_outbound: {
431       type: DataTypes.ENUM('yes', 'no'),
432       allowNull: true,
433       defaultValue: 'no'
434     },
435     progressinband: {
436       type: DataTypes.ENUM('yes', 'no', 'never'),
437       allowNull: true,
438     },
439     promiscredir: {
440       type: DataTypes.ENUM('yes', 'no'),
441       allowNull: true,
442     },
443     useclientcode: {
444       type: DataTypes.ENUM('yes', 'no'),
445       allowNull: true,
446     },
447     accountcode: {
448       type: DataTypes.INTEGER(11),
449       allowNull: true,
450     },
451     setvar: {
452       type: DataTypes.STRING,
453       allowNull: true,
454     },
455     callerid: {
456       type: DataTypes.STRING,
457       allowNull: true,
458       defaultValue: '"" <>'
459     },
460     amaflags: {
461       type: DataTypes.STRING,
462       allowNull: true,
463     },
464     callcounter: {
465       type: DataTypes.ENUM('yes', 'no'),
466       allowNull: true,
467       defaultValue: 'yes'
468     },
469     busylevel: {
470       type: DataTypes.INTEGER(11),
471       allowNull: true,
472     },
473     allowoverlap: {
474       type: DataTypes.ENUM('yes', 'no'),
475       allowNull: true,
476     },
477     allowsubscribe: {
478       type: DataTypes.ENUM('yes', 'no'),
479       allowNull: true,
480     },
481     allowtransfer: {
482       type: DataTypes.ENUM('yes', 'no'),
483       allowNull: true,
484     },
485     ignoresdpversion: {
486       type: DataTypes.ENUM('yes', 'no'),
487       allowNull: true,
488     },
489     subscribecontext: {
490       type: DataTypes.STRING,
491       allowNull: true,
492     },
493     template: {
494       type: DataTypes.STRING,
495       allowNull: true,
496     },
497     videosupport: {
498       type: DataTypes.ENUM('yes', 'no', 'always'),
499       allowNull: true,
500       defaultValue: 'no'
501     },
502     maxcallbitrate: {
503       type: DataTypes.INTEGER(11),
504       allowNull: true,
505     },
506     rfc2833compensate: {
507       type: DataTypes.ENUM('yes', 'no'),
508       allowNull: true,
509     },
510     mailbox: {
511       type: DataTypes.STRING,
512       allowNull: true,
513     },
514     session_timers: {
515       type: DataTypes.ENUM('accept', 'refuse', 'originate'),
516       allowNull: true,
517     },
518     session_expires: {
519       type: DataTypes.INTEGER(11),
520       allowNull: true,
521     },
522     session_minse: {
523       type: DataTypes.INTEGER(11),
524       allowNull: true,
525     },
526     session_refresher: {
527       type: DataTypes.ENUM('uac', 'uas'),
528       allowNull: true,
529       defaultValue: 'uas'
530     },
531     t38pt_usertpsource: {
532       type: DataTypes.STRING,
533       allowNull: true,
534     },
535     regexten: {
536       type: DataTypes.STRING,
537       allowNull: true,
538     },
539     fromdomain: {
540       type: DataTypes.STRING,
541       allowNull: true,
542     },
543     fromuser: {
544       type: DataTypes.STRING,
545       allowNull: true,
546     },
547     qualify: {
548       type: DataTypes.ENUM('yes', 'no'),
549       allowNull: true,
550       defaultValue: 'yes'
551     },
552     keepalive: {
553       type: DataTypes.INTEGER(11),
554       allowNull: true,
555     },
556     defaultip: {
557       type: DataTypes.STRING,
558       allowNull: true,
559     },
560     defaultuser: {
561       type: DataTypes.STRING,
562       allowNull: true,
563     },
564     rtptimeout: { // Terminate call if 60 seconds of no RTP or RTCP activity on the audio channel  when we're not on hold.
565       type: DataTypes.INTEGER(11),
566       allowNull: true,
567     },
568     rtpholdtimeout: { // Terminate call if 300 seconds of no RTP or RTCP activity on the audio channel when we're on hold (must be > rtptimeout)
569       type: DataTypes.INTEGER(11),
570       allowNull: true,
571     },
572     rtpkeepalive: { // Send keepalives in the RTP stream to keep NAT open (default is off - zero)
573       type: DataTypes.INTEGER(11),
574       allowNull: true,
575     },
576     sendrpid: {
577       type: DataTypes.ENUM('yes', 'no'),
578       allowNull: true,
579       defaultValue: 'no'
580     },
581     outboundproxy: {
582       type: DataTypes.STRING,
583       allowNull: true,
584     },
585     callbackextension: {
586       type: DataTypes.STRING,
587       allowNull: true,
588     },
589     timert1: {
590       type: DataTypes.INTEGER(11),
591       allowNull: true,
592     },
593     timerb: {
594       type: DataTypes.INTEGER(11),
595       allowNull: true,
596     },
597     qualifyfreq: {
598       type: DataTypes.INTEGER(11),
599       allowNull: true,
600     },
601     contactpermit: {
602       type: DataTypes.STRING,
603       allowNull: true,
604     },
605     contactdeny: {
606       type: DataTypes.STRING,
607       allowNull: true,
608     },
609     contactacl: {
610       type: DataTypes.STRING,
611       allowNull: true,
612     },
613     unsolicited_mailbox: {
614       type: DataTypes.STRING,
615       allowNull: true,
616     },
617     use_q850_reason: {
618       type: DataTypes.STRING,
619       allowNull: true,
620     },
621     maxforwards: {
622       type: DataTypes.INTEGER(11),
623       allowNull: true,
624     },
625     encryption: {
626       type: DataTypes.ENUM('yes', 'no'),
627       allowNull: true,
628       defaultValue: 'no'
629     },
630     avpf: {
631       type: DataTypes.ENUM('yes', 'no'),
632       allowNull: true
633     },
634     force_avp: {
635       type: DataTypes.ENUM('yes', 'no'),
636       allowNull: true
637     },
638     icesupport: {
639       type: DataTypes.ENUM('yes', 'no'),
640       allowNull: true
641     },
642     dtlsenable: {
643       type: DataTypes.ENUM('yes', 'no'),
644       allowNull: true
645     },
646     dtlsverify: {
647       type: DataTypes.ENUM('yes', 'no', 'fingerprint', 'certificate'),
648       allowNull: true
649     },
650     dtlsrekey: {
651       type: DataTypes.INTEGER(11),
652       allowNull: true,
653     },
654     dtlscertfile: {
655       type: DataTypes.STRING,
656       allowNull: true,
657     },
658     dtlsprivatekey: {
659       type: DataTypes.STRING,
660       allowNull: true,
661     },
662     dtlscipher: {
663       type: DataTypes.STRING,
664       allowNull: true,
665     },
666     dtlscafile: {
667       type: DataTypes.STRING,
668       allowNull: true,
669     },
670     dtlscapath: {
671       type: DataTypes.STRING,
672       allowNull: true,
673     },
674     dtlssetup: {
675       type: DataTypes.ENUM('active', 'passive', 'actpass'),
676       allowNull: true
677     },
678     dtlsfingerprint: {
679       type: DataTypes.STRING,
680       allowNull: true,
681     },
682     usereqphone: { //This provider requires ";user=phone" on URI
683       type: DataTypes.ENUM('yes', 'no'),
684       allowNull: true,
685       defaultValue: 'no'
686     },
687     recordonfeature: { //Feature to use when INFO with Record: on is received.
688       type: DataTypes.STRING,
689       allowNull: true,
690     },
691     recordofffeature: { //Feature to use when INFO with Record: off is received.
692       type: DataTypes.STRING,
693       allowNull: true,
694     },
695     call_limit: {
696       type: DataTypes.INTEGER(11),
697       allowNull: true,
698       defaultValue: 10
699     },
700     registertrying: { //Send a 100 Trying when the device registers.
701       type: DataTypes.ENUM('yes', 'no'),
702       allowNull: true,
703     },
704     subscribemwi: { //Only send notifications if this phone subscribes for mailbox notification
705       type: DataTypes.ENUM('yes', 'no'),
706       allowNull: true,
707     },
708     vmexten: { // dialplan extension to reach mailbox. defaults to global vmexten which defaults to "asterisk"
709       type: DataTypes.STRING,
710       allowNull: true,
711     },
712     mohinterpret: { // This option specifies a preference for which music on hold class this channel should listen to when put on hold
713       type: DataTypes.STRING,
714       allowNull: true,
715     },
716     mohsuggest: { //  This option specifies which music on hold class to suggest to the peer channel when this channel places the peer on hold.
717       type: DataTypes.STRING,
718       allowNull: true,
719     },
720     parkinglot: {
721       type: DataTypes.STRING,
722       allowNull: true,
723     },
724     canreinvite: {
725       type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'update,nonat'),
726       allowNull: true,
727       defaultValue: 'no'
728     },
729     loginInPause: {
730       type: DataTypes.BOOLEAN,
731       defaultValue: false
732     },
733     resetPasswordToken: {
734       type: DataTypes.STRING
735     },
736     resetPasswordExpires: {
737       type: DataTypes.DATE
738     },
739     phoneBarEnableRecording: {
740       type: DataTypes.BOOLEAN,
741       defaultValue: true
742     }
743   }, {
744     tableName: 'users',
745     instanceMethods: {
746       /**
747        * Authenticate - check if the passwords are the same
748        *
749        * @param {String} plainText
750        *        {function} callBack
751        * @api public
752        */
753       authenticate: function(plainText) {
754         return this.encryptPassword(plainText) === this.password;
755       },
756       /**
757        * Make salt
758        *
759        * @return {String}
760        * @api public
761        */
762       makeSalt: function() {
763         return crypto.randomBytes(16).toString('base64');
764       },
765       /**
766        * Encrypt password
767        *
768        * @param {String} password
769        * @return {String}
770        * @api public
771        */
772       encryptPassword: function(password) {
773         if (!password || !this.salt) return '';
774         var salt = new Buffer(this.salt, 'base64');
775         return crypto.pbkdf2Sync(password, salt, 10000, 64).toString(
776           'base64');
777       },
778       /**
779        * md5 password
780        *
781        * @param {String} password
782        * @return {String}
783        * @api public
784        */
785       md5Password: function(password) {
786         if (!password) return '';
787         return md5(password);
788       }
789     },
790     associate: function(models) {
791       // BELOGNS TO MANY
792       User.hasMany(models.ChatMessage);
793       User.hasMany(models.MailMessage);
794       User.hasMany(models.Contact);
795       User.hasMany(models.Action);
796       User.belongsToMany(models.Module, {
797         through: models.UserHasModule,
798         required: false
799       });
800       User.belongsToMany(models.Channel, {
801         through: 'user_has_channels'
802       });
803       User.belongsToMany(models.MailRoom, {
804         through: 'user_has_mail_rooms'
805       });
806       User.belongsToMany(models.SmsRoom, {
807         through: 'user_has_sms_rooms'
808       });
809       User.belongsToMany(models.OpenchannelRoom, {
810         through: 'user_has_openchannel_rooms'
811       });
812       User.belongsToMany(models.FaxRoom, {
813         through: 'user_has_fax_rooms'
814       });
815       User.belongsToMany(models.Team, {
816         through: models.UserHasTeam
817       });
818       User.belongsToMany(models.VoiceQueue, {
819         through: models.UserHasVoiceQueue,
820         required: false
821       });
822       User.belongsToMany(models.VoiceQueue, {
823         through: models.UserHasVoiceQueuePermit,
824         as: 'PVoiceQueues'
825       });
826       User.belongsToMany(models.MailQueue, {
827         through: models.UserHasMailQueue,
828         required: false
829       });
830       User.belongsToMany(models.SmsQueue, {
831         through: models.UserHasSmsQueue,
832         required: false
833       });
834       User.belongsToMany(models.SmsQueue, {
835         through: models.UserHasSmsQueuePermit,
836         as: 'PSmsQueues'
837       });
838       User.belongsToMany(models.OpenchannelQueue, {
839         through: models.UserHasOpenchannelQueue,
840         required: false
841       });
842       User.belongsToMany(models.OpenchannelQueue, {
843         through: models.UserHasOpenchannelQueuePermit,
844         as: 'POpenchannelQueues'
845       });
846       User.belongsToMany(models.MailQueue, {
847         through: models.UserHasMailQueuePermit,
848         as: 'PMailQueues'
849       });
850       User.belongsToMany(models.FaxQueue, {
851         through: models.UserHasFaxQueue,
852         required: false
853       });
854       User.belongsToMany(models.FaxQueue, {
855         through: models.UserHasFaxQueuePermit,
856         as: 'PFaxQueues'
857       });
858       User.belongsToMany(models.ChatQueue, {
859         through: models.UserHasChatQueue,
860         required: false
861       });
862       User.belongsToMany(models.ChatQueue, {
863         through: models.UserHasChatQueuePermit,
864         as: 'PChatQueues'
865       });
866       User.belongsToMany(models.ChatRoom, {
867         through: models.UserHasChatRoom
868       });
869       User.belongsToMany(models.List, {
870         through: models.UserHasList
871       });
872       User.hasMany(models.VoiceExtension, {
873         foreignKey: 'UserId',
874         as: 'UserExtensions',
875         onDelete: 'cascade',
876         hooks: true
877       });
878
879       // SCOPES MANAGEMENT
880       User.addScope('all', {
881         attributes: ['id',
882           'name',
883           'email',
884           'internal',
885           'fullname',
886           'role',
887           'online',
888           'userpic',
889           'accountcode',
890           'transport',
891           'host',
892           'role',
893           'nat',
894           'type',
895           'allow',
896           'lastLoginAt',
897           'ipaddr',
898           'fullcontact',
899           'port',
900           'lastms',
901           'description'
902         ]
903       });
904
905       // SCOPES MANAGEMENT
906       User.addScope('user', {
907         where: {
908           role: {
909             $in: ['admin', 'user']
910           },
911         },
912         attributes: ['id',
913           'name',
914           'email',
915           'internal',
916           'fullname',
917           'role',
918           'userpic',
919           'accountcode',
920           'transport',
921           'host',
922           'role',
923           'nat',
924           'type',
925           'allow',
926           'lastLoginAt',
927           'ipaddr',
928           'fullcontact',
929           'port',
930           'lastms',
931           'description',
932         ]
933       });
934       User.addScope('agent', {
935         where: {
936           role: 'agent'
937         },
938         attributes: ['id',
939           'name',
940           'email',
941           'internal',
942           'fullname',
943           'role',
944           'userpic',
945           'accountcode',
946           'transport',
947           'host',
948           'nat',
949           'type',
950           'allow',
951           'chatCapacity',
952           'mailCapacity',
953           'faxCapacity',
954           'smsCapacity',
955           'openchannelCapacity',
956           'online',
957           'lastLoginAt',
958           'phoneBarAutoAnswer',
959           'phoneBarEnableSettings',
960           'phoneBarUnconditional',
961           'phoneBarNoReply',
962           'phoneBarBusy',
963           'phoneBarUnconditionalNumber',
964           'phoneBarNoReplyNumber',
965           'phoneBarBusyNumber',
966           'phoneBarListenPort',
967           'phoneBarExpires',
968           'phoneBarRemoteControl',
969           'phoneBarRemoteControlPort',
970           'phoneBarEnableRecording',
971           'chanspy',
972           'voicePause',
973           'mailPause',
974           'faxPause',
975           'chatPause',
976           'smsPause',
977           'openchannelPause',
978           'pauseType',
979           'lastPauseAt',
980           'status',
981           'statusAt',
982           'queueStatus',
983           'queueStatusAt',
984           'lastQueue',
985           'useragent',
986           'ipaddr',
987           'fullcontact',
988           'port',
989           'lastms',
990           'description',
991           'loginInPause'
992         ]
993       });
994       User.addScope('telephone', {
995         where: {
996           role: 'telephone'
997         }
998       });
999       User.addScope('queues', {
1000         include: [{
1001           model: models.VoiceQueue,
1002           required: false
1003         }, {
1004           model: models.ChatQueue,
1005           required: false
1006         }, {
1007           model: models.MailQueue,
1008           required: false
1009         }, {
1010           model: models.FaxQueue,
1011           required: false
1012         }, {
1013           model: models.SmsQueue,
1014           required: false
1015         }, {
1016           model: models.OpenchannelQueue,
1017           required: false
1018         }]
1019       });
1020
1021       User.addScope('checkPauseStatus', function(query) {
1022         var scope = {
1023           where: {}
1024         };
1025         if (query.voicePause) {
1026           scope.where.voicePause = (query.voicePause === 'true') ?
1027             true : false;
1028           delete query.voicePause;
1029         } else if (query.faxPause) {
1030           scope.where.faxPause = (query.faxPause === 'true') ? true :
1031             false;
1032           delete query.faxPause;
1033         } else if (query.chatPause) {
1034           scope.where.chatPause = (query.chatPause === 'true') ?
1035             true : false;
1036           delete query.chatPause;
1037         } else if (query.mailPause) {
1038           scope.where.mailPause = (query.mailPause === 'true') ?
1039             true : false;
1040           delete query.mailPause;
1041         } else if (query.smsPause) {
1042           scope.where.smsPause = (query.smsPause === 'true') ?
1043             true : false;
1044           delete query.smsPause;
1045         } else if (query.openchannelPause) {
1046           scope.where.openchannelPause = (query.openchannelPause === 'true') ?
1047             true : false;
1048           delete query.openchannelPause;
1049         }
1050         return scope;
1051       });
1052       User.addScope('checkOnlineStatus', function(query) {
1053         var scope = {
1054           where: {}
1055         };
1056         if (query.online) {
1057           scope.where.online = (query.online === 'true') ? true :
1058             false;
1059           delete query.online;
1060         }
1061         return scope;
1062       });
1063       User.addScope('checkSipStatus', function(query) {
1064         var scope = {
1065           where: {}
1066         };
1067         if (query.status) {
1068           scope.where.status = query.status;
1069           delete query.status;
1070         }
1071         return scope;
1072       });
1073       User.addScope('checkQueueStatus', function(query) {
1074         var scope = {
1075           where: {}
1076         };
1077         if (query.queueStatus) {
1078           scope.where.queueStatus = query.queueStatus;
1079           delete query.queueStatus;
1080         }
1081         return scope;
1082       });
1083
1084       User.addScope('me', function(userId) {
1085         var scope = {
1086           where: {
1087             id: userId
1088           },
1089           attributes: ['id', 'fullname', 'name', 'email', 'role', 'userpic', 'lastLoginAt', 'voicePause',
1090             'mailPause',
1091             'chatPause',
1092             'faxPause',
1093             'smsPause',
1094             'openchannelPause',
1095             'lastPauseAt',
1096             'pauseType',
1097             'phoneBarRemoteControl',
1098             'phoneBarRemoteControlPort',
1099             'loginInPause'
1100           ],
1101           include: [{
1102             model: models.Module,
1103             include: [{
1104               model: models.Module,
1105               as: 'SubModules',
1106               required: false,
1107               include: [{
1108                 all: true
1109               }]
1110             }]
1111           }, {
1112             model: models.VoiceQueue,
1113             as: 'PVoiceQueues'
1114           }, {
1115             model: models.ChatQueue,
1116             as: 'PChatQueues'
1117           }, {
1118             model: models.MailQueue,
1119             as: 'PMailQueues'
1120           }, {
1121             model: models.FaxQueue,
1122             as: 'PFaxQueues'
1123           }, {
1124             model: models.SmsQueue,
1125             as: 'PSmsQueues'
1126           }]
1127         };
1128         return scope;
1129       });
1130     }
1131   });
1132
1133   return User;
1134 }