3 var crypto = require('crypto');
4 var md5 = require('md5');
5 var _ = require('lodash');
6 var moment = require('moment');
8 module.exports = function(sequelize, DataTypes) {
9 var User = sequelize.define('User', {
11 type: DataTypes.STRING,
15 is: /^[A-Za-z0-9\.\_]+$/i
18 this.setDataValue('name', name);
19 this.setDataValue('defaultuser', name);
23 type: DataTypes.STRING,
28 type: DataTypes.STRING,
31 set: function(email) {
33 this.setDataValue('email', email.toLowerCase());
39 type: DataTypes.ENUM('admin', 'user', 'agent', 'telephone')
42 type: DataTypes.STRING,
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));
54 type: DataTypes.STRING,
58 type: DataTypes.INTEGER(11),
60 set: function(internal) {
61 this.setDataValue('internal', internal);
62 this.setDataValue('accountcode', internal);
66 type: DataTypes.STRING
69 type: DataTypes.STRING
72 type: DataTypes.STRING
75 type: DataTypes.STRING
78 type: DataTypes.STRING
81 type: DataTypes.STRING
84 type: DataTypes.STRING
87 type: DataTypes.STRING
90 type: DataTypes.BOOLEAN,
97 type: DataTypes.STRING,
98 defaultValue: 'UNKNOWN'
104 type: DataTypes.STRING,
105 defaultValue: 'complete'
111 type: DataTypes.STRING
114 type: DataTypes.BOOLEAN,
116 // set: function(voicePause) {
117 // this.setDataValue('voicePause', voicePause);
119 // this.setDataValue('queueStatus', 'paused');
120 // this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
122 // this.setDataValue('queueStatus', 'complete');
123 // this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
128 type: DataTypes.BOOLEAN,
132 type: DataTypes.BOOLEAN,
136 type: DataTypes.BOOLEAN,
140 type: DataTypes.BOOLEAN,
144 type: DataTypes.BOOLEAN,
148 type: DataTypes.STRING,
149 defaultValue: 'Default Pause'
155 type: DataTypes.INTEGER,
159 type: DataTypes.INTEGER,
163 type: DataTypes.INTEGER,
167 type: DataTypes.INTEGER,
170 openchannelCapacity: {
171 type: DataTypes.INTEGER,
174 phoneBarAutoAnswer: {
175 type: DataTypes.BOOLEAN,
178 phoneBarEnableSettings: {
179 type: DataTypes.BOOLEAN,
182 phoneBarUnconditionalNumber: {
183 type: DataTypes.STRING,
185 if (this.getDataValue('phoneBarUnconditional')) {
186 return this.getDataValue('phoneBarUnconditionalNumber');
191 phoneBarNoReplyNumber: {
192 type: DataTypes.STRING,
194 if (this.getDataValue('phoneBarNoReply')) {
195 return this.getDataValue('phoneBarNoReplyNumber');
200 phoneBarBusyNumber: {
201 type: DataTypes.STRING,
203 if (this.getDataValue('phoneBarBusy')) {
204 return this.getDataValue('phoneBarBusyNumber');
209 phoneBarUnconditional: {
210 type: DataTypes.BOOLEAN,
214 type: DataTypes.BOOLEAN,
218 type: DataTypes.BOOLEAN,
221 phoneBarListenPort: {
222 type: DataTypes.INTEGER(5),
226 type: DataTypes.INTEGER(5),
230 type: DataTypes.INTEGER(5),
233 phoneBarNameServer: {
234 type: DataTypes.STRING,
237 phoneBarStunServer: {
238 type: DataTypes.STRING,
241 phoneBarVADEnabled: {
242 type: DataTypes.BOOLEAN,
246 type: DataTypes.BOOLEAN,
250 type: DataTypes.BOOLEAN,
254 type: DataTypes.INTEGER(5),
257 phoneBarPublishEnabled: {
258 type: DataTypes.BOOLEAN,
261 phoneBarRemoteControl: {
262 type: DataTypes.BOOLEAN,
265 phoneBarRemoteControlPort: {
266 type: DataTypes.INTEGER,
270 type: DataTypes.BOOLEAN,
274 type: DataTypes.STRING,
278 type: DataTypes.STRING,
280 defaultValue: 'dynamic'
282 ipaddr: { //REALTIME ASTERISK
283 type: DataTypes.STRING,
286 port: { //REALTIME ASTERISK
287 type: DataTypes.INTEGER(5),
290 regseconds: { //REALTIME ASTERISK
291 type: DataTypes.INTEGER(11),
294 fullcontact: { //REALTIME ASTERISK
295 type: DataTypes.STRING,
298 regserver: { //REALTIME ASTERISK
299 type: DataTypes.STRING,
302 useragent: { //REALTIME ASTERISK
303 type: DataTypes.STRING,
306 lastms: { //REALTIME ASTERISK
307 type: DataTypes.INTEGER(11),
311 type: DataTypes.ENUM('friend', 'user', 'peer'),
313 defaultValue: 'friend'
316 type: DataTypes.STRING,
318 defaultValue: 'from-sip'
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'),
328 type: DataTypes.STRING,
332 type: DataTypes.STRING,
336 type: DataTypes.STRING,
340 type: DataTypes.STRING,
344 type: DataTypes.STRING,
348 type: DataTypes.STRING,
353 type: DataTypes.ENUM('rfc2833', 'info', 'shortinfo', 'inband',
356 defaultValue: 'rfc2833'
359 type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'outgoing'),
364 type: DataTypes.ENUM('yes', 'no'),
369 type: DataTypes.STRING,
373 type: DataTypes.STRING,
377 type: DataTypes.STRING,
379 defaultValue: 'force_rport,comedia'
382 type: DataTypes.STRING,
385 namedcallgroup: { //We are in named call groups engineering,sales,netgroup,protgroup
386 type: DataTypes.STRING,
390 type: DataTypes.STRING,
393 namedpickupgroup: { //We can do call pick-p for named call group sales
394 type: DataTypes.STRING,
398 type: DataTypes.STRING,
403 type: DataTypes.STRING,
407 type: DataTypes.STRING,
412 type: DataTypes.STRING,
414 defaultValue: 'alaw;ulaw;gsm'
417 type: DataTypes.ENUM('yes', 'no'),
421 type: DataTypes.STRING,
423 defaultValue: 'port,invite'
426 type: DataTypes.ENUM('yes', 'no'),
431 type: DataTypes.ENUM('yes', 'no'),
436 type: DataTypes.ENUM('yes', 'no', 'never'),
440 type: DataTypes.ENUM('yes', 'no'),
444 type: DataTypes.ENUM('yes', 'no'),
448 type: DataTypes.INTEGER(11),
452 type: DataTypes.STRING,
456 type: DataTypes.STRING,
458 defaultValue: '"" <>'
461 type: DataTypes.STRING,
465 type: DataTypes.ENUM('yes', 'no'),
470 type: DataTypes.INTEGER(11),
474 type: DataTypes.ENUM('yes', 'no'),
478 type: DataTypes.ENUM('yes', 'no'),
482 type: DataTypes.ENUM('yes', 'no'),
486 type: DataTypes.ENUM('yes', 'no'),
490 type: DataTypes.STRING,
494 type: DataTypes.STRING,
498 type: DataTypes.ENUM('yes', 'no', 'always'),
503 type: DataTypes.INTEGER(11),
507 type: DataTypes.ENUM('yes', 'no'),
511 type: DataTypes.STRING,
515 type: DataTypes.ENUM('accept', 'refuse', 'originate'),
519 type: DataTypes.INTEGER(11),
523 type: DataTypes.INTEGER(11),
527 type: DataTypes.ENUM('uac', 'uas'),
531 t38pt_usertpsource: {
532 type: DataTypes.STRING,
536 type: DataTypes.STRING,
540 type: DataTypes.STRING,
544 type: DataTypes.STRING,
548 type: DataTypes.ENUM('yes', 'no'),
553 type: DataTypes.INTEGER(11),
557 type: DataTypes.STRING,
561 type: DataTypes.STRING,
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),
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),
572 rtpkeepalive: { // Send keepalives in the RTP stream to keep NAT open (default is off - zero)
573 type: DataTypes.INTEGER(11),
577 type: DataTypes.ENUM('yes', 'no'),
582 type: DataTypes.STRING,
586 type: DataTypes.STRING,
590 type: DataTypes.INTEGER(11),
594 type: DataTypes.INTEGER(11),
598 type: DataTypes.INTEGER(11),
602 type: DataTypes.STRING,
606 type: DataTypes.STRING,
610 type: DataTypes.STRING,
613 unsolicited_mailbox: {
614 type: DataTypes.STRING,
618 type: DataTypes.STRING,
622 type: DataTypes.INTEGER(11),
626 type: DataTypes.ENUM('yes', 'no'),
631 type: DataTypes.ENUM('yes', 'no'),
635 type: DataTypes.ENUM('yes', 'no'),
639 type: DataTypes.ENUM('yes', 'no'),
643 type: DataTypes.ENUM('yes', 'no'),
647 type: DataTypes.ENUM('yes', 'no', 'fingerprint', 'certificate'),
651 type: DataTypes.INTEGER(11),
655 type: DataTypes.STRING,
659 type: DataTypes.STRING,
663 type: DataTypes.STRING,
667 type: DataTypes.STRING,
671 type: DataTypes.STRING,
675 type: DataTypes.ENUM('active', 'passive', 'actpass'),
679 type: DataTypes.STRING,
682 usereqphone: { //This provider requires ";user=phone" on URI
683 type: DataTypes.ENUM('yes', 'no'),
687 recordonfeature: { //Feature to use when INFO with Record: on is received.
688 type: DataTypes.STRING,
691 recordofffeature: { //Feature to use when INFO with Record: off is received.
692 type: DataTypes.STRING,
696 type: DataTypes.INTEGER(11),
700 registertrying: { //Send a 100 Trying when the device registers.
701 type: DataTypes.ENUM('yes', 'no'),
704 subscribemwi: { //Only send notifications if this phone subscribes for mailbox notification
705 type: DataTypes.ENUM('yes', 'no'),
708 vmexten: { // dialplan extension to reach mailbox. defaults to global vmexten which defaults to "asterisk"
709 type: DataTypes.STRING,
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,
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,
721 type: DataTypes.STRING,
725 type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'update,nonat'),
730 type: DataTypes.BOOLEAN,
733 resetPasswordToken: {
734 type: DataTypes.STRING
736 resetPasswordExpires: {
739 phoneBarEnableRecording: {
740 type: DataTypes.BOOLEAN,
744 type: DataTypes.BOOLEAN,
747 phoneBarShowOmniDesktop: {
748 type: DataTypes.BOOLEAN,
755 * Authenticate - check if the passwords are the same
757 * @param {String} plainText
758 * {function} callBack
761 authenticate: function(plainText) {
762 return this.encryptPassword(plainText) === this.password;
770 makeSalt: function() {
771 return crypto.randomBytes(16).toString('base64');
776 * @param {String} password
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(
789 * @param {String} password
793 md5Password: function(password) {
794 if (!password) return '';
795 return md5(password);
798 associate: function(models) {
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,
808 User.belongsToMany(models.Channel, {
809 through: 'user_has_channels'
811 User.belongsToMany(models.MailRoom, {
812 through: 'user_has_mail_rooms'
814 User.belongsToMany(models.SmsRoom, {
815 through: 'user_has_sms_rooms'
817 User.belongsToMany(models.OpenchannelRoom, {
818 through: 'user_has_openchannel_rooms'
820 User.belongsToMany(models.FaxRoom, {
821 through: 'user_has_fax_rooms'
823 User.belongsToMany(models.Team, {
824 through: models.UserHasTeam
826 User.belongsToMany(models.VoiceQueue, {
827 through: models.UserHasVoiceQueue,
830 User.belongsToMany(models.VoiceQueue, {
831 through: models.UserHasVoiceQueuePermit,
834 User.belongsToMany(models.MailQueue, {
835 through: models.UserHasMailQueue,
838 User.belongsToMany(models.SmsQueue, {
839 through: models.UserHasSmsQueue,
842 User.belongsToMany(models.SmsQueue, {
843 through: models.UserHasSmsQueuePermit,
846 User.belongsToMany(models.OpenchannelQueue, {
847 through: models.UserHasOpenchannelQueue,
850 User.belongsToMany(models.OpenchannelQueue, {
851 through: models.UserHasOpenchannelQueuePermit,
852 as: 'POpenchannelQueues'
854 User.belongsToMany(models.MailQueue, {
855 through: models.UserHasMailQueuePermit,
858 User.belongsToMany(models.FaxQueue, {
859 through: models.UserHasFaxQueue,
862 User.belongsToMany(models.FaxQueue, {
863 through: models.UserHasFaxQueuePermit,
866 User.belongsToMany(models.ChatQueue, {
867 through: models.UserHasChatQueue,
870 User.belongsToMany(models.ChatQueue, {
871 through: models.UserHasChatQueuePermit,
874 User.belongsToMany(models.ChatRoom, {
875 through: models.UserHasChatRoom
877 User.belongsToMany(models.List, {
878 through: models.UserHasList
880 User.hasMany(models.VoiceExtension, {
881 foreignKey: 'UserId',
882 as: 'UserExtensions',
888 User.addScope('all', {
916 User.addScope('user', {
919 $in: ['admin', 'user']
946 User.addScope('agent', {
967 'openchannelCapacity',
970 'phoneBarAutoAnswer',
971 'phoneBarEnableSettings',
972 'phoneBarUnconditional',
975 'phoneBarUnconditionalNumber',
976 'phoneBarNoReplyNumber',
977 'phoneBarBusyNumber',
978 'phoneBarListenPort',
980 'phoneBarRemoteControl',
981 'phoneBarRemoteControlPort',
982 'phoneBarEnableRecording',
1007 'phoneBarShowOmniDesktop'
1010 User.addScope('telephone', {
1015 User.addScope('queues', {
1017 model: models.VoiceQueue,
1020 model: models.ChatQueue,
1023 model: models.MailQueue,
1026 model: models.FaxQueue,
1029 model: models.SmsQueue,
1032 model: models.OpenchannelQueue,
1037 User.addScope('checkPauseStatus', function(query) {
1041 if (query.voicePause) {
1042 scope.where.voicePause = (query.voicePause === 'true') ?
1044 delete query.voicePause;
1045 } else if (query.faxPause) {
1046 scope.where.faxPause = (query.faxPause === 'true') ? true :
1048 delete query.faxPause;
1049 } else if (query.chatPause) {
1050 scope.where.chatPause = (query.chatPause === 'true') ?
1052 delete query.chatPause;
1053 } else if (query.mailPause) {
1054 scope.where.mailPause = (query.mailPause === 'true') ?
1056 delete query.mailPause;
1057 } else if (query.smsPause) {
1058 scope.where.smsPause = (query.smsPause === 'true') ?
1060 delete query.smsPause;
1061 } else if (query.openchannelPause) {
1062 scope.where.openchannelPause = (query.openchannelPause === 'true') ?
1064 delete query.openchannelPause;
1068 User.addScope('checkOnlineStatus', function(query) {
1073 scope.where.online = (query.online === 'true') ? true :
1075 delete query.online;
1079 User.addScope('checkSipStatus', function(query) {
1084 scope.where.status = query.status;
1085 delete query.status;
1089 User.addScope('checkQueueStatus', function(query) {
1093 if (query.queueStatus) {
1094 scope.where.queueStatus = query.queueStatus;
1095 delete query.queueStatus;
1100 User.addScope('me', function(userId) {
1105 attributes: ['id', 'fullname', 'name', 'email', 'role', 'userpic', 'lastLoginAt', 'voicePause',
1113 'phoneBarRemoteControl',
1114 'phoneBarRemoteControlPort',
1119 model: models.Module,
1121 model: models.Module,
1129 model: models.VoiceQueue,
1132 model: models.ChatQueue,
1135 model: models.MailQueue,
1138 model: models.FaxQueue,
1141 model: models.SmsQueue,