Built motion from commit 945d615.|1.0.13
[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     showWebBar: {
744       type: DataTypes.BOOLEAN,
745       defaultValue: false
746     },
747     phoneBarShowOmniDesktop: {
748       type: DataTypes.BOOLEAN,
749       defaultValue: true
750     }
751   }, {
752     tableName: 'users',
753     instanceMethods: {
754       /**
755        * Authenticate - check if the passwords are the same
756        *
757        * @param {String} plainText
758        *        {function} callBack
759        * @api public
760        */
761       authenticate: function(plainText) {
762         return this.encryptPassword(plainText) === this.password;
763       },
764       /**
765        * Make salt
766        *
767        * @return {String}
768        * @api public
769        */
770       makeSalt: function() {
771         return crypto.randomBytes(16).toString('base64');
772       },
773       /**
774        * Encrypt password
775        *
776        * @param {String} password
777        * @return {String}
778        * @api public
779        */
780       encryptPassword: function(password) {
781         if (!password || !this.salt) return '';
782         var salt = new Buffer(this.salt, 'base64');
783         return crypto.pbkdf2Sync(password, salt, 10000, 64).toString(
784           'base64');
785       },
786       /**
787        * md5 password
788        *
789        * @param {String} password
790        * @return {String}
791        * @api public
792        */
793       md5Password: function(password) {
794         if (!password) return '';
795         return md5(password);
796       }
797     },
798     associate: function(models) {
799       // BELOGNS TO MANY
800       User.hasMany(models.ChatMessage);
801       User.hasMany(models.MailMessage);
802       User.hasMany(models.Contact);
803       User.hasMany(models.Action);
804       User.belongsToMany(models.Module, {
805         through: models.UserHasModule,
806         required: false
807       });
808       User.belongsToMany(models.Channel, {
809         through: 'user_has_channels'
810       });
811       User.belongsToMany(models.MailRoom, {
812         through: 'user_has_mail_rooms'
813       });
814       User.belongsToMany(models.SmsRoom, {
815         through: 'user_has_sms_rooms'
816       });
817       User.belongsToMany(models.OpenchannelRoom, {
818         through: 'user_has_openchannel_rooms'
819       });
820       User.belongsToMany(models.FaxRoom, {
821         through: 'user_has_fax_rooms'
822       });
823       User.belongsToMany(models.Team, {
824         through: models.UserHasTeam
825       });
826       User.belongsToMany(models.VoiceQueue, {
827         through: models.UserHasVoiceQueue,
828         required: false
829       });
830       User.belongsToMany(models.VoiceQueue, {
831         through: models.UserHasVoiceQueuePermit,
832         as: 'PVoiceQueues'
833       });
834       User.belongsToMany(models.MailQueue, {
835         through: models.UserHasMailQueue,
836         required: false
837       });
838       User.belongsToMany(models.SmsQueue, {
839         through: models.UserHasSmsQueue,
840         required: false
841       });
842       User.belongsToMany(models.SmsQueue, {
843         through: models.UserHasSmsQueuePermit,
844         as: 'PSmsQueues'
845       });
846       User.belongsToMany(models.OpenchannelQueue, {
847         through: models.UserHasOpenchannelQueue,
848         required: false
849       });
850       User.belongsToMany(models.OpenchannelQueue, {
851         through: models.UserHasOpenchannelQueuePermit,
852         as: 'POpenchannelQueues'
853       });
854       User.belongsToMany(models.MailQueue, {
855         through: models.UserHasMailQueuePermit,
856         as: 'PMailQueues'
857       });
858       User.belongsToMany(models.FaxQueue, {
859         through: models.UserHasFaxQueue,
860         required: false
861       });
862       User.belongsToMany(models.FaxQueue, {
863         through: models.UserHasFaxQueuePermit,
864         as: 'PFaxQueues'
865       });
866       User.belongsToMany(models.ChatQueue, {
867         through: models.UserHasChatQueue,
868         required: false
869       });
870       User.belongsToMany(models.ChatQueue, {
871         through: models.UserHasChatQueuePermit,
872         as: 'PChatQueues'
873       });
874       User.belongsToMany(models.ChatRoom, {
875         through: models.UserHasChatRoom
876       });
877       User.belongsToMany(models.List, {
878         through: models.UserHasList
879       });
880       User.hasMany(models.VoiceExtension, {
881         foreignKey: 'UserId',
882         as: 'UserExtensions',
883         onDelete: 'cascade',
884         hooks: true
885       });
886
887       // SCOPES MANAGEMENT
888       User.addScope('all', {
889         attributes: ['id',
890           'name',
891           'email',
892           'internal',
893           'fullname',
894           'role',
895           'online',
896           'userpic',
897           'accountcode',
898           'transport',
899           'host',
900           'role',
901           'nat',
902           'type',
903           'allow',
904           'lastLoginAt',
905           'ipaddr',
906           'fullcontact',
907           'port',
908           'lastms',
909           'description',
910           'callgroup',
911           'pickupgroup'
912         ]
913       });
914
915       // SCOPES MANAGEMENT
916       User.addScope('user', {
917         where: {
918           role: {
919             $in: ['admin', 'user']
920           },
921         },
922         attributes: ['id',
923           'name',
924           'email',
925           'internal',
926           'fullname',
927           'role',
928           'userpic',
929           'accountcode',
930           'transport',
931           'host',
932           'role',
933           'nat',
934           'type',
935           'allow',
936           'lastLoginAt',
937           'ipaddr',
938           'fullcontact',
939           'port',
940           'lastms',
941           'description',
942           'callgroup',
943           'pickupgroup'
944         ]
945       });
946       User.addScope('agent', {
947         where: {
948           role: 'agent'
949         },
950         attributes: ['id',
951           'name',
952           'email',
953           'internal',
954           'fullname',
955           'role',
956           'userpic',
957           'accountcode',
958           'transport',
959           'host',
960           'nat',
961           'type',
962           'allow',
963           'chatCapacity',
964           'mailCapacity',
965           'faxCapacity',
966           'smsCapacity',
967           'openchannelCapacity',
968           'online',
969           'lastLoginAt',
970           'phoneBarAutoAnswer',
971           'phoneBarEnableSettings',
972           'phoneBarUnconditional',
973           'phoneBarNoReply',
974           'phoneBarBusy',
975           'phoneBarUnconditionalNumber',
976           'phoneBarNoReplyNumber',
977           'phoneBarBusyNumber',
978           'phoneBarListenPort',
979           'phoneBarExpires',
980           'phoneBarRemoteControl',
981           'phoneBarRemoteControlPort',
982           'phoneBarEnableRecording',
983           'chanspy',
984           'voicePause',
985           'mailPause',
986           'faxPause',
987           'chatPause',
988           'smsPause',
989           'openchannelPause',
990           'pauseType',
991           'lastPauseAt',
992           'status',
993           'statusAt',
994           'queueStatus',
995           'queueStatusAt',
996           'lastQueue',
997           'useragent',
998           'ipaddr',
999           'fullcontact',
1000           'port',
1001           'lastms',
1002           'description',
1003           'loginInPause',
1004           'showWebBar',
1005           'callgroup',
1006           'pickupgroup',
1007           'phoneBarShowOmniDesktop'
1008         ]
1009       });
1010       User.addScope('telephone', {
1011         where: {
1012           role: 'telephone'
1013         }
1014       });
1015       User.addScope('queues', {
1016         include: [{
1017           model: models.VoiceQueue,
1018           required: false
1019         }, {
1020           model: models.ChatQueue,
1021           required: false
1022         }, {
1023           model: models.MailQueue,
1024           required: false
1025         }, {
1026           model: models.FaxQueue,
1027           required: false
1028         }, {
1029           model: models.SmsQueue,
1030           required: false
1031         }, {
1032           model: models.OpenchannelQueue,
1033           required: false
1034         }]
1035       });
1036
1037       User.addScope('checkPauseStatus', function(query) {
1038         var scope = {
1039           where: {}
1040         };
1041         if (query.voicePause) {
1042           scope.where.voicePause = (query.voicePause === 'true') ?
1043             true : false;
1044           delete query.voicePause;
1045         } else if (query.faxPause) {
1046           scope.where.faxPause = (query.faxPause === 'true') ? true :
1047             false;
1048           delete query.faxPause;
1049         } else if (query.chatPause) {
1050           scope.where.chatPause = (query.chatPause === 'true') ?
1051             true : false;
1052           delete query.chatPause;
1053         } else if (query.mailPause) {
1054           scope.where.mailPause = (query.mailPause === 'true') ?
1055             true : false;
1056           delete query.mailPause;
1057         } else if (query.smsPause) {
1058           scope.where.smsPause = (query.smsPause === 'true') ?
1059             true : false;
1060           delete query.smsPause;
1061         } else if (query.openchannelPause) {
1062           scope.where.openchannelPause = (query.openchannelPause === 'true') ?
1063             true : false;
1064           delete query.openchannelPause;
1065         }
1066         return scope;
1067       });
1068       User.addScope('checkOnlineStatus', function(query) {
1069         var scope = {
1070           where: {}
1071         };
1072         if (query.online) {
1073           scope.where.online = (query.online === 'true') ? true :
1074             false;
1075           delete query.online;
1076         }
1077         return scope;
1078       });
1079       User.addScope('checkSipStatus', function(query) {
1080         var scope = {
1081           where: {}
1082         };
1083         if (query.status) {
1084           scope.where.status = query.status;
1085           delete query.status;
1086         }
1087         return scope;
1088       });
1089       User.addScope('checkQueueStatus', function(query) {
1090         var scope = {
1091           where: {}
1092         };
1093         if (query.queueStatus) {
1094           scope.where.queueStatus = query.queueStatus;
1095           delete query.queueStatus;
1096         }
1097         return scope;
1098       });
1099
1100       User.addScope('me', function(userId) {
1101         var scope = {
1102           where: {
1103             id: userId
1104           },
1105           attributes: ['id', 'fullname', 'name', 'email', 'role', 'userpic', 'lastLoginAt', 'voicePause',
1106             'mailPause',
1107             'chatPause',
1108             'faxPause',
1109             'smsPause',
1110             'openchannelPause',
1111             'lastPauseAt',
1112             'pauseType',
1113             'phoneBarRemoteControl',
1114             'phoneBarRemoteControlPort',
1115             'loginInPause',
1116             'showWebBar'
1117           ],
1118           include: [{
1119             model: models.Module,
1120             include: [{
1121               model: models.Module,
1122               as: 'SubModules',
1123               required: false,
1124               include: [{
1125                 all: true
1126               }]
1127             }]
1128           }, {
1129             model: models.VoiceQueue,
1130             as: 'PVoiceQueues'
1131           }, {
1132             model: models.ChatQueue,
1133             as: 'PChatQueues'
1134           }, {
1135             model: models.MailQueue,
1136             as: 'PMailQueues'
1137           }, {
1138             model: models.FaxQueue,
1139             as: 'PFaxQueues'
1140           }, {
1141             model: models.SmsQueue,
1142             as: 'PSmsQueues'
1143           }]
1144         };
1145         return scope;
1146       });
1147     }
1148   });
1149
1150   return User;
1151 }