-var _0x5f42=["\x75\x73\x65\x20\x73\x74\x72\x69\x63\x74","\x63\x72\x79\x70\x74\x6F","\x6D\x64\x35","\x6C\x6F\x64\x61\x73\x68","\x6D\x6F\x6D\x65\x6E\x74","\x56\x6F\x69\x63\x65\x51\x75\x65\x75\x65","\x2E","\x65\x78\x70\x6F\x72\x74\x73","\x55\x73\x65\x72","\x53\x54\x52\x49\x4E\x47","\x6E\x61\x6D\x65","\x73\x65\x74\x44\x61\x74\x61\x56\x61\x6C\x75\x65","\x64\x65\x66\x61\x75\x6C\x74\x75\x73\x65\x72","\x65\x6D\x61\x69\x6C","\x74\x6F\x4C\x6F\x77\x65\x72\x43\x61\x73\x65","\x61\x64\x6D\x69\x6E","\x75\x73\x65\x72","\x61\x67\x65\x6E\x74","\x74\x65\x6C\x65\x70\x68\x6F\x6E\x65","\x73\x61\x6C\x74","\x6D\x61\x6B\x65\x53\x61\x6C\x74","\x70\x61\x73\x73\x77\x6F\x72\x64","\x65\x6E\x63\x72\x79\x70\x74\x50\x61\x73\x73\x77\x6F\x72\x64","\x6D\x64\x35\x73\x65\x63\x72\x65\x74","\x3A\x61\x73\x74\x65\x72\x69\x73\x6B\x3A","\x6D\x64\x35\x50\x61\x73\x73\x77\x6F\x72\x64","\x6C\x6F\x63\x61\x6C","\x69\x6E\x74\x65\x72\x6E\x61\x6C","\x61\x63\x63\x6F\x75\x6E\x74\x63\x6F\x64\x65","\x42\x4F\x4F\x4C\x45\x41\x4E","\x44\x41\x54\x45","\x44\x65\x66\x61\x75\x6C\x74\x20\x50\x61\x75\x73\x65","\x49\x4E\x54\x45\x47\x45\x52","\x70\x68\x6F\x6E\x65\x42\x61\x72\x55\x6E\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x61\x6C","\x67\x65\x74\x44\x61\x74\x61\x56\x61\x6C\x75\x65","\x70\x68\x6F\x6E\x65\x42\x61\x72\x55\x6E\x63\x6F\x6E\x64\x69\x74\x69\x6F\x6E\x61\x6C\x4E\x75\x6D\x62\x65\x72","\x70\x68\x6F\x6E\x65\x42\x61\x72\x4E\x6F\x52\x65\x70\x6C\x79","\x70\x68\x6F\x6E\x65\x42\x61\x72\x4E\x6F\x52\x65\x70\x6C\x79\x4E\x75\x6D\x62\x65\x72","\x70\x68\x6F\x6E\x65\x42\x61\x72\x42\x75\x73\x79","\x70\x68\x6F\x6E\x65\x42\x61\x72\x42\x75\x73\x79\x4E\x75\x6D\x62\x65\x72","\x66\x72\x69\x65\x6E\x64","\x70\x65\x65\x72","\x66\x72\x6F\x6D\x2D\x73\x69\x70","\x41\x4C\x4C\x4F\x57\x45\x44\x5F\x4E\x4F\x54\x5F\x53\x43\x52\x45\x45\x4E\x45\x44","\x41\x4C\x4C\x4F\x57\x45\x44\x5F\x50\x41\x53\x53\x45\x44\x5F\x53\x43\x52\x45\x45\x4E","\x41\x4C\x4C\x4F\x57\x45\x44\x5F\x46\x41\x49\x4C\x45\x44\x5F\x53\x43\x52\x45\x45\x4E","\x41\x4C\x4C\x4F\x57\x45\x44","\x50\x52\x4F\x48\x49\x42\x5F\x4E\x4F\x54\x5F\x53\x43\x52\x45\x45\x4E\x45\x44","\x50\x52\x4F\x48\x49\x42\x5F\x50\x41\x53\x53\x45\x44\x5F\x53\x43\x52\x45\x45\x4E","\x50\x52\x4F\x48\x49\x42\x5F\x46\x41\x49\x4C\x45\x44\x5F\x53\x43\x52\x45\x45\x4E","\x50\x52\x4F\x48\x49\x42","\x75\x64\x70","\x72\x66\x63\x32\x38\x33\x33","\x69\x6E\x66\x6F","\x73\x68\x6F\x72\x74\x69\x6E\x66\x6F","\x69\x6E\x62\x61\x6E\x64","\x61\x75\x74\x6F","\x79\x65\x73","\x6E\x6F","\x6E\x6F\x6E\x61\x74","\x75\x70\x64\x61\x74\x65","\x66\x6F\x72\x63\x65\x5F\x72\x70\x6F\x72\x74\x2C\x63\x6F\x6D\x65\x64\x69\x61","\x65\x6E","\x61\x6C\x61\x77\x3B\x75\x6C\x61\x77\x3B\x67\x73\x6D","\x70\x6F\x72\x74\x2C\x69\x6E\x76\x69\x74\x65","\x6E\x65\x76\x65\x72","\x22\x22\x20\x3C\x3E","\x61\x6C\x77\x61\x79\x73","\x61\x63\x63\x65\x70\x74","\x72\x65\x66\x75\x73\x65","\x6F\x72\x69\x67\x69\x6E\x61\x74\x65","\x75\x61\x63","\x75\x61\x73","\x64\x79\x6E\x61\x6D\x69\x63","\x66\x69\x6E\x67\x65\x72\x70\x72\x69\x6E\x74","\x63\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65","\x61\x63\x74\x69\x76\x65","\x70\x61\x73\x73\x69\x76\x65","\x61\x63\x74\x70\x61\x73\x73","\x75\x73\x65\x72\x73","\x62\x61\x73\x65\x36\x34","\x72\x61\x6E\x64\x6F\x6D\x42\x79\x74\x65\x73","","\x70\x62\x6B\x64\x66\x32\x53\x79\x6E\x63","\x68\x61\x73\x4D\x61\x6E\x79","\x75\x73\x65\x72\x5F\x68\x61\x73\x5F\x6D\x6F\x64\x75\x6C\x65\x73","\x62\x65\x6C\x6F\x6E\x67\x73\x54\x6F\x4D\x61\x6E\x79","\x75\x73\x65\x72\x5F\x68\x61\x73\x5F\x63\x68\x61\x6E\x6E\x65\x6C\x73","\x75\x73\x65\x72\x5F\x68\x61\x73\x5F\x6D\x61\x69\x6C\x5F\x72\x6F\x6F\x6D\x73","\x55\x73\x65\x72\x48\x61\x73\x54\x65\x61\x6D","\x55\x73\x65\x72\x48\x61\x73\x43\x68\x61\x74\x52\x6F\x6F\x6D","\x55\x73\x65\x72\x48\x61\x73\x4D\x61\x69\x6C\x51\x75\x65\x75\x65","\x55\x73\x65\x72\x48\x61\x73\x43\x68\x61\x74\x51\x75\x65\x75\x65","\x55\x73\x65\x72\x48\x61\x73\x56\x6F\x69\x63\x65\x51\x75\x65\x75\x65","\x55\x73\x65\x72\x48\x61\x73\x53\x65\x72\x76\x69\x63\x65","\x55\x73\x65\x72\x49\x64","\x55\x73\x65\x72\x45\x78\x74\x65\x6E\x73\x69\x6F\x6E\x73","\x63\x61\x73\x63\x61\x64\x65","\x61\x64\x64\x53\x63\x6F\x70\x65","\x71\x75\x65\x75\x65\x73","\x69\x64","\x66\x75\x6C\x6C\x6E\x61\x6D\x65","\x74\x72\x61\x6E\x73\x70\x6F\x72\x74","\x68\x6F\x73\x74","\x6E\x61\x74","\x74\x79\x70\x65","\x61\x6C\x6C\x6F\x77","\x63\x68\x61\x74\x43\x61\x70\x61\x63\x69\x74\x79","\x6D\x61\x69\x6C\x43\x61\x70\x61\x63\x69\x74\x79","\x66\x61\x78\x43\x61\x70\x61\x63\x69\x74\x79","\x6F\x6E\x6C\x69\x6E\x65","\x6C\x61\x73\x74\x4C\x6F\x67\x69\x6E\x41\x74","\x70\x68\x6F\x6E\x65\x42\x61\x72\x41\x75\x74\x6F\x41\x6E\x73\x77\x65\x72","\x70\x68\x6F\x6E\x65\x42\x61\x72\x45\x6E\x61\x62\x6C\x65\x53\x65\x74\x74\x69\x6E\x67\x73","\x63\x68\x61\x6E\x73\x70\x79","\x76\x6F\x69\x63\x65\x50\x61\x75\x73\x65","\x6D\x61\x69\x6C\x50\x61\x75\x73\x65","\x66\x61\x78\x50\x61\x75\x73\x65","\x63\x68\x61\x74\x50\x61\x75\x73\x65","\x70\x61\x75\x73\x65\x54\x79\x70\x65","\x6C\x61\x73\x74\x50\x61\x75\x73\x65\x41\x74","\x64\x65\x66\x69\x6E\x65"];_0x5f42[0];var crypto=require(_0x5f42[1]);var md5=require(_0x5f42[2]);var _=require(_0x5f42[3]);var moment=require(_0x5f42[4]);var VoiceQueue=require(_0x5f42[6])[_0x5f42[5]];module[_0x5f42[7]]=function(_0xb583x6,_0xb583x7){var _0xb583x8=_0xb583x6[_0x5f42[121]](_0x5f42[8],{name:{type:_0xb583x7[_0x5f42[9]],unique:true,validate:{notEmpty:true,is:/^[A-Za-z0-9\.\_]+$/i},set:function(_0xb583x9){this[_0x5f42[11]](_0x5f42[10],_0xb583x9);this[_0x5f42[11]](_0x5f42[12],_0xb583x9)}},fullname:{type:_0xb583x7[_0x5f42[9]],allowNull:false},email:{type:_0xb583x7[_0x5f42[9]],unique:true,set:function(_0xb583xa){if(_0xb583xa){this[_0x5f42[11]](_0x5f42[13],_0xb583xa[_0x5f42[14]]())}},defaultValue:null},role:{type:_0xb583x7.ENUM(_0x5f42[15],_0x5f42[16],_0x5f42[17],_0x5f42[18])},password:{type:_0xb583x7[_0x5f42[9]],allowNull:false,validate:{notEmpty:true},set:function(_0xb583xb){this[_0x5f42[19]]=this[_0x5f42[20]]();this[_0x5f42[11]](_0x5f42[21],this[_0x5f42[22]](_0xb583xb));this[_0x5f42[11]](_0x5f42[23],this[_0x5f42[25]](this[_0x5f42[10]]+_0x5f42[24]+_0xb583xb))}},provider:{type:_0xb583x7[_0x5f42[9]],defaultValue:_0x5f42[26]},internal:{type:_0xb583x7.INTEGER(11),unique:true,set:function(_0xb583xc){this[_0x5f42[11]](_0x5f42[27],_0xb583xc);this[_0x5f42[11]](_0x5f42[28],_0xb583xc)}},salt:{type:_0xb583x7[_0x5f42[9]]},phone:{type:_0xb583x7[_0x5f42[9]]},mobile:{type:_0xb583x7[_0x5f42[9]]},address:{type:_0xb583x7[_0x5f42[9]]},zipcode:{type:_0xb583x7[_0x5f42[9]]},userpic:{type:_0xb583x7[_0x5f42[9]]},city:{type:_0xb583x7[_0x5f42[9]]},country:{type:_0xb583x7[_0x5f42[9]]},online:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},lastLoginAt:{type:_0xb583x7[_0x5f42[30]]},lastPauseAt:{type:_0xb583x7[_0x5f42[30]]},voicePause:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},chatPause:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},mailPause:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},faxPause:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},pauseType:{type:_0xb583x7[_0x5f42[9]],defaultValue:_0x5f42[31]},chatCapacity:{type:_0xb583x7[_0x5f42[32]],defaultValue:1000},mailCapacity:{type:_0xb583x7[_0x5f42[32]],defaultValue:1000},faxCapacity:{type:_0xb583x7[_0x5f42[32]],defaultValue:1000},phoneBarAutoAnswer:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},phoneBarEnableSettings:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},phoneBarUnconditionalNumber:{type:_0xb583x7[_0x5f42[9]],get:function(){if(this[_0x5f42[34]](_0x5f42[33])){return this[_0x5f42[34]](_0x5f42[35])};return null}},phoneBarNoReplyNumber:{type:_0xb583x7[_0x5f42[9]],get:function(){if(this[_0x5f42[34]](_0x5f42[36])){return this[_0x5f42[34]](_0x5f42[37])};return null}},phoneBarBusyNumber:{type:_0xb583x7[_0x5f42[9]],get:function(){if(this[_0x5f42[34]](_0x5f42[38])){return this[_0x5f42[34]](_0x5f42[39])};return null}},phoneBarUnconditional:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},phoneBarNoReply:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},phoneBarBusy:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},phoneBarPort:{type:_0xb583x7.INTEGER(5),allowNull:true},chanspy:{type:_0xb583x7[_0x5f42[29]],defaultValue:false},description:{type:_0xb583x7[_0x5f42[9]],allowNull:true},ipaddr:{type:_0xb583x7[_0x5f42[9]],allowNull:true},port:{type:_0xb583x7.INTEGER(5),allowNull:true},regseconds:{type:_0xb583x7.INTEGER(11),allowNull:true},fullcontact:{type:_0xb583x7[_0x5f42[9]],allowNull:true},regserver:{type:_0xb583x7[_0x5f42[9]],allowNull:true},useragent:{type:_0xb583x7[_0x5f42[9]],allowNull:true},lastms:{type:_0xb583x7.INTEGER(11),allowNull:true},type:{type:_0xb583x7.ENUM(_0x5f42[40],_0x5f42[16],_0x5f42[41]),allowNull:true,defaultValue:_0x5f42[40]},context:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[42]},callingpres:{type:_0xb583x7.ENUM(_0x5f42[43],_0x5f42[44],_0x5f42[45],_0x5f42[46],_0x5f42[47],_0x5f42[48],_0x5f42[49],_0x5f42[50]),allowNull:true},permit:{type:_0xb583x7[_0x5f42[9]],allowNull:true},deny:{type:_0xb583x7[_0x5f42[9]],allowNull:true},secret:{type:_0xb583x7[_0x5f42[9]],allowNull:true},md5secret:{type:_0xb583x7[_0x5f42[9]],allowNull:true},remotesecret:{type:_0xb583x7[_0x5f42[9]],allowNull:true},transport:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[51]},dtmfmode:{type:_0xb583x7.ENUM(_0x5f42[52],_0x5f42[53],_0x5f42[54],_0x5f42[55],_0x5f42[56]),allowNull:true,defaultValue:_0x5f42[52]},directmedia:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58],_0x5f42[59],_0x5f42[60]),allowNull:true,defaultValue:_0x5f42[58]},nat:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[61]},callgroup:{type:_0xb583x7[_0x5f42[9]],allowNull:true},namedcallgroup:{type:_0xb583x7[_0x5f42[9]],allowNull:true},pickupgroup:{type:_0xb583x7[_0x5f42[9]],allowNull:true},namedpickupgroup:{type:_0xb583x7[_0x5f42[9]],allowNull:true},language:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[62]},tonezone:{type:_0xb583x7[_0x5f42[9]],allowNull:true},allow:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[63]},disallow:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:null},autoframing:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},insecure:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[64]},trustrpid:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[58]},trust_id_outbound:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[58]},progressinband:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58],_0x5f42[65]),allowNull:true},promiscredir:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},useclientcode:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},accountcode:{type:_0xb583x7.INTEGER(11),allowNull:true},setvar:{type:_0xb583x7[_0x5f42[9]],allowNull:true},callerid:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[66]},amaflags:{type:_0xb583x7[_0x5f42[9]],allowNull:true},callcounter:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[57]},busylevel:{type:_0xb583x7.INTEGER(11),allowNull:true},allowoverlap:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},allowsubscribe:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},allowtransfer:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},ignoresdpversion:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},subscribecontext:{type:_0xb583x7[_0x5f42[9]],allowNull:true},template:{type:_0xb583x7[_0x5f42[9]],allowNull:true},videosupport:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58],_0x5f42[67]),allowNull:true,defaultValue:_0x5f42[58]},maxcallbitrate:{type:_0xb583x7.INTEGER(11),allowNull:true},rfc2833compensate:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},mailbox:{type:_0xb583x7[_0x5f42[9]],allowNull:true},session_timers:{type:_0xb583x7.ENUM(_0x5f42[68],_0x5f42[69],_0x5f42[70]),allowNull:true},session_expires:{type:_0xb583x7.INTEGER(11),allowNull:true},session_minse:{type:_0xb583x7.INTEGER(11),allowNull:true},session_refresher:{type:_0xb583x7.ENUM(_0x5f42[71],_0x5f42[72]),allowNull:true,defaultValue:_0x5f42[72]},t38pt_usertpsource:{type:_0xb583x7[_0x5f42[9]],allowNull:true},regexten:{type:_0xb583x7[_0x5f42[9]],allowNull:true},fromdomain:{type:_0xb583x7[_0x5f42[9]],allowNull:true},fromuser:{type:_0xb583x7[_0x5f42[9]],allowNull:true},host:{type:_0xb583x7[_0x5f42[9]],allowNull:true,defaultValue:_0x5f42[73]},qualify:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[57]},keepalive:{type:_0xb583x7.INTEGER(11),allowNull:true},defaultip:{type:_0xb583x7[_0x5f42[9]],allowNull:true},defaultuser:{type:_0xb583x7[_0x5f42[9]],allowNull:true},rtptimeout:{type:_0xb583x7.INTEGER(11),allowNull:true},rtpholdtimeout:{type:_0xb583x7.INTEGER(11),allowNull:true},rtpkeepalive:{type:_0xb583x7.INTEGER(11),allowNull:true},sendrpid:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[58]},outboundproxy:{type:_0xb583x7[_0x5f42[9]],allowNull:true},callbackextension:{type:_0xb583x7[_0x5f42[9]],allowNull:true},timert1:{type:_0xb583x7.INTEGER(11),allowNull:true},timerb:{type:_0xb583x7.INTEGER(11),allowNull:true},qualifyfreq:{type:_0xb583x7.INTEGER(11),allowNull:true},contactpermit:{type:_0xb583x7[_0x5f42[9]],allowNull:true},contactdeny:{type:_0xb583x7[_0x5f42[9]],allowNull:true},contactacl:{type:_0xb583x7[_0x5f42[9]],allowNull:true},directmediapermit:{type:_0xb583x7[_0x5f42[9]],allowNull:true},directmediadeny:{type:_0xb583x7[_0x5f42[9]],allowNull:true},unsolicited_mailbox:{type:_0xb583x7[_0x5f42[9]],allowNull:true},use_q850_reason:{type:_0xb583x7[_0x5f42[9]],allowNull:true},maxforwards:{type:_0xb583x7.INTEGER(11),allowNull:true},encryption:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[58]},avpf:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},force_avp:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},icesupport:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},dtlsenable:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},dtlsverify:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58],_0x5f42[74],_0x5f42[75]),allowNull:true},dtlsrekey:{type:_0xb583x7.INTEGER(11),allowNull:true},dtlscertfile:{type:_0xb583x7[_0x5f42[9]],allowNull:true},dtlsprivatekey:{type:_0xb583x7[_0x5f42[9]],allowNull:true},dtlscipher:{type:_0xb583x7[_0x5f42[9]],allowNull:true},dtlscafile:{type:_0xb583x7[_0x5f42[9]],allowNull:true},dtlscapath:{type:_0xb583x7[_0x5f42[9]],allowNull:true},dtlssetup:{type:_0xb583x7.ENUM(_0x5f42[76],_0x5f42[77],_0x5f42[78]),allowNull:true},dtlsfingerprint:{type:_0xb583x7[_0x5f42[9]],allowNull:true},usereqphone:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true,defaultValue:_0x5f42[58]},recordonfeature:{type:_0xb583x7[_0x5f42[9]],allowNull:true},recordofffeature:{type:_0xb583x7[_0x5f42[9]],allowNull:true},call_limit:{type:_0xb583x7.INTEGER(11),allowNull:true,defaultValue:null},registertrying:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},subscribemwi:{type:_0xb583x7.ENUM(_0x5f42[57],_0x5f42[58]),allowNull:true},vmexten:{type:_0xb583x7[_0x5f42[9]],allowNull:true},mohinterpret:{type:_0xb583x7[_0x5f42[9]],allowNull:true},mohsuggest:{type:_0xb583x7[_0x5f42[9]],allowNull:true},parkinglot:{type:_0xb583x7[_0x5f42[9]],allowNull:true}},{tableName:_0x5f42[79],instanceMethods:{authenticate:function(_0xb583xd){return this[_0x5f42[22]](_0xb583xd)===this[_0x5f42[21]]},makeSalt:function(){return crypto[_0x5f42[81]](16).toString(_0x5f42[80])},encryptPassword:function(_0xb583xb){if(!_0xb583xb||!this[_0x5f42[19]]){return _0x5f42[82]};var _0xb583xe= new Buffer(this[_0x5f42[19]],_0x5f42[80]);return crypto[_0x5f42[83]](_0xb583xb,_0xb583xe,10000,64).toString(_0x5f42[80])},md5Password:function(_0xb583xb){if(!_0xb583xb){return _0x5f42[82]};return md5(_0xb583xb)}},associate:function(_0xb583xf){_0xb583x8[_0x5f42[84]](_0xb583xf.ChatMessage);_0xb583x8[_0x5f42[84]](_0xb583xf.Contact);_0xb583x8[_0x5f42[84]](_0xb583xf.Action);_0xb583x8[_0x5f42[86]](_0xb583xf.Module,{through:_0x5f42[85]});_0xb583x8[_0x5f42[86]](_0xb583xf.Channel,{through:_0x5f42[87]});_0xb583x8[_0x5f42[86]](_0xb583xf.MailRoom,{through:_0x5f42[88]});_0xb583x8[_0x5f42[86]](_0xb583xf.Team,{through:_0xb583xf[_0x5f42[89]]});_0xb583x8[_0x5f42[86]](_0xb583xf.ChatRoom,{through:_0xb583xf[_0x5f42[90]]});_0xb583x8[_0x5f42[86]](_0xb583xf.MailQueue,{through:_0xb583xf[_0x5f42[91]]});_0xb583x8[_0x5f42[86]](_0xb583xf.ChatQueue,{through:_0xb583xf[_0x5f42[92]]});_0xb583x8[_0x5f42[86]](_0xb583xf.VoiceQueue,{through:_0xb583xf[_0x5f42[93]],required:false});_0xb583x8[_0x5f42[86]](_0xb583xf.Service,{through:_0xb583xf[_0x5f42[94]]});_0xb583x8[_0x5f42[84]](_0xb583xf.VoiceExtension,{foreignKey:_0x5f42[95],as:_0x5f42[96],onDelete:_0x5f42[97],hooks:true});_0xb583x8[_0x5f42[98]](_0x5f42[16],{where:{role:{$in:[_0x5f42[15],_0x5f42[16]]}}});_0xb583x8[_0x5f42[98]](_0x5f42[99],{include:[_0xb583xf[_0x5f42[5]]]});_0xb583x8[_0x5f42[98]](_0x5f42[18],{where:{role:_0x5f42[18]}});_0xb583x8[_0x5f42[98]](_0x5f42[17],{where:{role:_0x5f42[17]},attributes:[_0x5f42[100],_0x5f42[10],_0x5f42[13],_0x5f42[27],_0x5f42[101],_0x5f42[28],_0x5f42[102],_0x5f42[103],_0x5f42[104],_0x5f42[105],_0x5f42[106],_0x5f42[107],_0x5f42[108],_0x5f42[109],_0x5f42[110],_0x5f42[111],_0x5f42[112],_0x5f42[113],_0x5f42[33],_0x5f42[36],_0x5f42[38],_0x5f42[35],_0x5f42[37],_0x5f42[39],_0x5f42[114],_0x5f42[115],_0x5f42[116],_0x5f42[117],_0x5f42[118],_0x5f42[119],_0x5f42[120]]})}});return _0xb583x8}
\ No newline at end of file
+'use strict';
+
+var crypto = require('crypto');
+var md5 = require('md5');
+var _ = require('lodash');
+var moment = require('moment');
+
+module.exports = function(sequelize, DataTypes) {
+ var User = sequelize.define('User', {
+ name: {
+ type: DataTypes.STRING,
+ unique: 'name',
+ validate: {
+ notEmpty: true,
+ is: /^[A-Za-z0-9\.\_]+$/i
+ },
+ set: function(name) {
+ this.setDataValue('name', name);
+ this.setDataValue('defaultuser', name);
+ }
+ },
+ fullname: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ },
+ email: {
+ type: DataTypes.STRING,
+ unique: 'email',
+ isEmail: true,
+ set: function(email) {
+ if (email) {
+ this.setDataValue('email', email.toLowerCase());
+ }
+ },
+ defaultValue: null
+ },
+ role: {
+ type: DataTypes.ENUM('admin', 'user', 'agent', 'telephone')
+ },
+ password: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ validate: {
+ notEmpty: true
+ },
+ set: function(password) {
+ this.salt = this.makeSalt();
+ this.setDataValue('password', this.encryptPassword(password));
+ this.setDataValue('md5secret', this.md5Password(this.name + ':asterisk:' + password));
+ }
+ },
+ provider: {
+ type: DataTypes.STRING,
+ defaultValue: 'local'
+ },
+ internal: {
+ type: DataTypes.INTEGER(11),
+ unique: 'internal',
+ set: function(internal) {
+ this.setDataValue('internal', internal);
+ this.setDataValue('accountcode', internal);
+ }
+ },
+ salt: {
+ type: DataTypes.STRING
+ },
+ phone: {
+ type: DataTypes.STRING
+ },
+ mobile: {
+ type: DataTypes.STRING
+ },
+ address: {
+ type: DataTypes.STRING
+ },
+ zipcode: {
+ type: DataTypes.STRING
+ },
+ userpic: {
+ type: DataTypes.STRING
+ },
+ city: {
+ type: DataTypes.STRING
+ },
+ country: {
+ type: DataTypes.STRING
+ },
+ online: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ lastLoginAt: {
+ type: DataTypes.DATE
+ },
+ status: {
+ type: DataTypes.STRING,
+ defaultValue: 'UNKNOWN'
+ },
+ statusAt: {
+ type: DataTypes.DATE
+ },
+ queueStatus: {
+ type: DataTypes.STRING,
+ defaultValue: 'complete'
+ },
+ queueStatusAt: {
+ type: DataTypes.DATE
+ },
+ lastQueue: {
+ type: DataTypes.STRING
+ },
+ voicePause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false,
+ // set: function(voicePause) {
+ // this.setDataValue('voicePause', voicePause);
+ // if (voicePause) {
+ // this.setDataValue('queueStatus', 'paused');
+ // this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
+ // } else {
+ // this.setDataValue('queueStatus', 'complete');
+ // this.setDataValue('queueStatusAt', moment().format("YYYY-MM-DD HH:mm:ss"));
+ // }
+ // }
+ },
+ chatPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ mailPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ faxPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ smsPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ openchannelPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ pauseType: {
+ type: DataTypes.STRING,
+ defaultValue: 'Default Pause'
+ },
+ lastPauseAt: {
+ type: DataTypes.DATE
+ },
+ chatCapacity: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ },
+ mailCapacity: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ },
+ faxCapacity: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ },
+ smsCapacity: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ },
+ openchannelCapacity: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ },
+ phoneBarAutoAnswer: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarEnableSettings: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ phoneBarUnconditionalNumber: {
+ type: DataTypes.STRING,
+ get: function() {
+ if (this.getDataValue('phoneBarUnconditional')) {
+ return this.getDataValue('phoneBarUnconditionalNumber');
+ }
+ return null;
+ }
+ },
+ phoneBarNoReplyNumber: {
+ type: DataTypes.STRING,
+ get: function() {
+ if (this.getDataValue('phoneBarNoReply')) {
+ return this.getDataValue('phoneBarNoReplyNumber');
+ }
+ return null;
+ }
+ },
+ phoneBarBusyNumber: {
+ type: DataTypes.STRING,
+ get: function() {
+ if (this.getDataValue('phoneBarBusy')) {
+ return this.getDataValue('phoneBarBusyNumber');
+ }
+ return null;
+ }
+ },
+ phoneBarUnconditional: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarNoReply: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarBusy: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarListenPort: {
+ type: DataTypes.INTEGER(5),
+ defaultValue: 5060
+ },
+ phoneBarECTail: {
+ type: DataTypes.INTEGER(5),
+ defaultValue: 200
+ },
+ phoneBarExpires: {
+ type: DataTypes.INTEGER(5),
+ defaultValue: 120
+ },
+ phoneBarNameServer: {
+ type: DataTypes.STRING,
+ allowNull: true
+ },
+ phoneBarStunServer: {
+ type: DataTypes.STRING,
+ allowNull: true
+ },
+ phoneBarVADEnabled: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarNoUDP: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarNoTCP: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ phoneBarLogLevel: {
+ type: DataTypes.INTEGER(5),
+ defaultValue: 1
+ },
+ phoneBarPublishEnabled: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarRemoteControl: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarRemoteControlPort: {
+ type: DataTypes.INTEGER,
+ defaultValue: 9888
+ },
+ chanspy: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ description: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ host: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'dynamic'
+ },
+ ipaddr: { //REALTIME ASTERISK
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ port: { //REALTIME ASTERISK
+ type: DataTypes.INTEGER(5),
+ allowNull: true,
+ },
+ regseconds: { //REALTIME ASTERISK
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ fullcontact: { //REALTIME ASTERISK
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ regserver: { //REALTIME ASTERISK
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ useragent: { //REALTIME ASTERISK
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ lastms: { //REALTIME ASTERISK
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ type: {
+ type: DataTypes.ENUM('friend', 'user', 'peer'),
+ allowNull: true,
+ defaultValue: 'friend'
+ },
+ context: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'from-sip'
+ },
+ callingpres: {
+ type: DataTypes.ENUM('ALLOWED_NOT_SCREENED',
+ 'ALLOWED_PASSED_SCREEN', 'ALLOWED_FAILED_SCREEN', 'ALLOWED',
+ 'PROHIB_NOT_SCREENED', 'PROHIB_PASSED_SCREEN',
+ 'PROHIB_FAILED_SCREEN', 'PROHIB'),
+ allowNull: true,
+ },
+ deny: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ permit: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ secret: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ md5secret: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ remotesecret: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ transport: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'udp'
+ },
+ dtmfmode: {
+ type: DataTypes.ENUM('rfc2833', 'info', 'shortinfo', 'inband',
+ 'auto'),
+ allowNull: true,
+ defaultValue: 'rfc2833'
+ },
+ directmedia: {
+ type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'outgoing'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ directrtpsetup: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ directmediapermit: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ directmediadeny: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ nat: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'force_rport,comedia'
+ },
+ callgroup: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ namedcallgroup: { //We are in named call groups engineering,sales,netgroup,protgroup
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ pickupgroup: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ namedpickupgroup: { //We can do call pick-p for named call group sales
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ language: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'en'
+ },
+ tonezone: {
+ type: DataTypes.STRING,
+ allowNull: true
+ },
+ disallow: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'all'
+ },
+ allow: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'ulaw;gsm'
+ },
+ autoframing: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ insecure: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: 'port,invite'
+ },
+ trustrpid: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ trust_id_outbound: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ progressinband: {
+ type: DataTypes.ENUM('yes', 'no', 'never'),
+ allowNull: true,
+ },
+ promiscredir: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ useclientcode: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ accountcode: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ setvar: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ callerid: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: '"" <>'
+ },
+ amaflags: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ callcounter: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'yes'
+ },
+ busylevel: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ allowoverlap: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ allowsubscribe: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ allowtransfer: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ ignoresdpversion: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ subscribecontext: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ template: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ videosupport: {
+ type: DataTypes.ENUM('yes', 'no', 'always'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ maxcallbitrate: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ rfc2833compensate: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ mailbox: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ session_timers: {
+ type: DataTypes.ENUM('accept', 'refuse', 'originate'),
+ allowNull: true,
+ },
+ session_expires: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ session_minse: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ session_refresher: {
+ type: DataTypes.ENUM('uac', 'uas'),
+ allowNull: true,
+ defaultValue: 'uas'
+ },
+ t38pt_usertpsource: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ regexten: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ fromdomain: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ fromuser: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ qualify: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'yes'
+ },
+ keepalive: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ defaultip: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ defaultuser: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ rtptimeout: { // Terminate call if 60 seconds of no RTP or RTCP activity on the audio channel when we're not on hold.
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ rtpholdtimeout: { // Terminate call if 300 seconds of no RTP or RTCP activity on the audio channel when we're on hold (must be > rtptimeout)
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ rtpkeepalive: { // Send keepalives in the RTP stream to keep NAT open (default is off - zero)
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ sendrpid: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ outboundproxy: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ callbackextension: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ timert1: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ timerb: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ qualifyfreq: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ contactpermit: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ contactdeny: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ contactacl: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ unsolicited_mailbox: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ use_q850_reason: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ maxforwards: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ encryption: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ avpf: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true
+ },
+ force_avp: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true
+ },
+ icesupport: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true
+ },
+ dtlsenable: {
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true
+ },
+ dtlsverify: {
+ type: DataTypes.ENUM('yes', 'no', 'fingerprint', 'certificate'),
+ allowNull: true
+ },
+ dtlsrekey: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ },
+ dtlscertfile: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ dtlsprivatekey: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ dtlscipher: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ dtlscafile: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ dtlscapath: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ dtlssetup: {
+ type: DataTypes.ENUM('active', 'passive', 'actpass'),
+ allowNull: true
+ },
+ dtlsfingerprint: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ usereqphone: { //This provider requires ";user=phone" on URI
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ recordonfeature: { //Feature to use when INFO with Record: on is received.
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ recordofffeature: { //Feature to use when INFO with Record: off is received.
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ call_limit: {
+ type: DataTypes.INTEGER(11),
+ allowNull: true,
+ defaultValue: 10
+ },
+ registertrying: { //Send a 100 Trying when the device registers.
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ subscribemwi: { //Only send notifications if this phone subscribes for mailbox notification
+ type: DataTypes.ENUM('yes', 'no'),
+ allowNull: true,
+ },
+ vmexten: { // dialplan extension to reach mailbox. defaults to global vmexten which defaults to "asterisk"
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ mohinterpret: { // This option specifies a preference for which music on hold class this channel should listen to when put on hold
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ mohsuggest: { // This option specifies which music on hold class to suggest to the peer channel when this channel places the peer on hold.
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ parkinglot: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ canreinvite: {
+ type: DataTypes.ENUM('yes', 'no', 'nonat', 'update', 'update,nonat'),
+ allowNull: true,
+ defaultValue: 'no'
+ },
+ loginInPause: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ resetPasswordToken: {
+ type: DataTypes.STRING
+ },
+ resetPasswordExpires: {
+ type: DataTypes.DATE
+ },
+ phoneBarEnableRecording: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ showWebBar: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarShowOmniDesktop: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ phoneBarRingInUse: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phoneBarDnd: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ phoneBarUnansweredCallBadge: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: true
+ },
+ phonebarEnableDtmfTone: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
+ phonebarAutoAnswerDelay: {
+ type: DataTypes.INTEGER,
+ defaultValue: 0
+ }
+ }, {
+ tableName: 'users',
+ charset: 'utf8',
+ collate: 'utf8_bin',
+ instanceMethods: {
+ /**
+ * Authenticate - check if the passwords are the same
+ *
+ * @param {String} plainText
+ * {function} callBack
+ * @api public
+ */
+ authenticate: function(plainText) {
+ return this.encryptPassword(plainText) === this.password;
+ },
+ /**
+ * Make salt
+ *
+ * @return {String}
+ * @api public
+ */
+ makeSalt: function() {
+ return crypto.randomBytes(16).toString('base64');
+ },
+ /**
+ * Encrypt password
+ *
+ * @param {String} password
+ * @return {String}
+ * @api public
+ */
+ encryptPassword: function(password) {
+ if (!password || !this.salt) return '';
+ var salt = new Buffer(this.salt, 'base64');
+ return crypto.pbkdf2Sync(password, salt, 10000, 64).toString(
+ 'base64');
+ },
+ /**
+ * md5 password
+ *
+ * @param {String} password
+ * @return {String}
+ * @api public
+ */
+ md5Password: function(password) {
+ if (!password) return '';
+ return md5(password);
+ }
+ },
+ associate: function(models) {
+ // BELOGNS TO MANY
+ User.hasMany(models.ChatMessage);
+ User.hasMany(models.MailMessage);
+ User.hasMany(models.Contact);
+ User.hasMany(models.Action);
+ User.belongsToMany(models.Module, {
+ through: models.UserHasModule,
+ required: false
+ });
+ User.belongsToMany(models.MailRoom, {
+ through: models.UserHasMailRoom,
+ });
+ User.belongsToMany(models.Channel, {
+ through: 'user_has_channels'
+ });
+ User.belongsToMany(models.SmsRoom, {
+ through: 'user_has_sms_rooms'
+ });
+ User.belongsToMany(models.OpenchannelRoom, {
+ through: 'user_has_openchannel_rooms'
+ });
+ User.belongsToMany(models.FaxRoom, {
+ through: 'user_has_fax_rooms'
+ });
+ User.belongsToMany(models.Team, {
+ through: models.UserHasTeam
+ });
+ User.belongsToMany(models.VoiceQueue, {
+ through: models.UserHasVoiceQueue,
+ required: false
+ });
+ User.belongsToMany(models.VoiceQueue, {
+ through: models.UserHasVoiceQueuePermit,
+ as: 'PVoiceQueues'
+ });
+ User.belongsToMany(models.MailQueue, {
+ through: models.UserHasMailQueue,
+ required: false
+ });
+ User.belongsToMany(models.SmsQueue, {
+ through: models.UserHasSmsQueue,
+ required: false
+ });
+ User.belongsToMany(models.SmsQueue, {
+ through: models.UserHasSmsQueuePermit,
+ as: 'PSmsQueues'
+ });
+ User.belongsToMany(models.OpenchannelQueue, {
+ through: models.UserHasOpenchannelQueue,
+ required: false
+ });
+ User.belongsToMany(models.OpenchannelQueue, {
+ through: models.UserHasOpenchannelQueuePermit,
+ as: 'POpenchannelQueues'
+ });
+ User.belongsToMany(models.MailQueue, {
+ through: models.UserHasMailQueuePermit,
+ as: 'PMailQueues'
+ });
+ User.belongsToMany(models.FaxQueue, {
+ through: models.UserHasFaxQueue,
+ required: false
+ });
+ User.belongsToMany(models.FaxQueue, {
+ through: models.UserHasFaxQueuePermit,
+ as: 'PFaxQueues'
+ });
+ User.belongsToMany(models.ChatQueue, {
+ through: models.UserHasChatQueue,
+ required: false
+ });
+ User.belongsToMany(models.ChatQueue, {
+ through: models.UserHasChatQueuePermit,
+ as: 'PChatQueues'
+ });
+ User.belongsToMany(models.ChatRoom, {
+ through: models.UserHasChatRoom
+ });
+ User.belongsToMany(models.List, {
+ through: models.UserHasList
+ });
+ User.hasMany(models.VoiceExtension, {
+ foreignKey: 'UserId',
+ as: 'UserExtensions',
+ onDelete: 'cascade',
+ hooks: true
+ });
+
+ // SCOPES MANAGEMENT
+ User.addScope('all', {
+ attributes: ['id',
+ 'name',
+ 'email',
+ 'internal',
+ 'fullname',
+ 'role',
+ 'online',
+ 'userpic',
+ 'accountcode',
+ 'transport',
+ 'host',
+ 'role',
+ 'nat',
+ 'type',
+ 'allow',
+ 'lastLoginAt',
+ 'ipaddr',
+ 'fullcontact',
+ 'port',
+ 'lastms',
+ 'description',
+ 'callgroup',
+ 'pickupgroup'
+ ]
+ });
+
+ // SCOPES MANAGEMENT
+ User.addScope('user', {
+ where: {
+ role: {
+ $in: ['admin', 'user']
+ },
+ },
+ attributes: ['id',
+ 'name',
+ 'email',
+ 'internal',
+ 'fullname',
+ 'role',
+ 'userpic',
+ 'accountcode',
+ 'transport',
+ 'host',
+ 'role',
+ 'nat',
+ 'type',
+ 'allow',
+ 'lastLoginAt',
+ 'ipaddr',
+ 'fullcontact',
+ 'port',
+ 'lastms',
+ 'description',
+ 'callgroup',
+ 'pickupgroup'
+ ]
+ });
+ User.addScope('agent', {
+ where: {
+ role: 'agent'
+ },
+ attributes: ['id',
+ 'name',
+ 'email',
+ 'internal',
+ 'fullname',
+ 'role',
+ 'userpic',
+ 'accountcode',
+ 'transport',
+ 'host',
+ 'nat',
+ 'type',
+ 'allow',
+ 'chatCapacity',
+ 'mailCapacity',
+ 'faxCapacity',
+ 'smsCapacity',
+ 'openchannelCapacity',
+ 'online',
+ 'lastLoginAt',
+ 'phoneBarAutoAnswer',
+ 'phoneBarEnableSettings',
+ 'phoneBarUnconditional',
+ 'phoneBarNoReply',
+ 'phoneBarBusy',
+ 'phoneBarUnconditionalNumber',
+ 'phoneBarNoReplyNumber',
+ 'phoneBarBusyNumber',
+ 'phoneBarListenPort',
+ 'phoneBarExpires',
+ 'phoneBarRemoteControl',
+ 'phoneBarRemoteControlPort',
+ 'phoneBarEnableRecording',
+ 'chanspy',
+ 'voicePause',
+ 'mailPause',
+ 'faxPause',
+ 'chatPause',
+ 'smsPause',
+ 'openchannelPause',
+ 'pauseType',
+ 'lastPauseAt',
+ 'status',
+ 'statusAt',
+ 'queueStatus',
+ 'queueStatusAt',
+ 'lastQueue',
+ 'useragent',
+ 'ipaddr',
+ 'fullcontact',
+ 'port',
+ 'lastms',
+ 'description',
+ 'loginInPause',
+ 'showWebBar',
+ 'callgroup',
+ 'pickupgroup',
+ 'phoneBarShowOmniDesktop',
+ 'phoneBarRingInUse',
+ 'phoneBarDnd',
+ 'phoneBarUnansweredCallBadge',
+ 'phone',
+ 'mobile',
+ 'phonebarEnableDtmfTone',
+ 'phonebarAutoAnswerDelay'
+ ]
+ });
+ User.addScope('telephone', {
+ where: {
+ role: 'telephone'
+ }
+ });
+ User.addScope('queues', {
+ include: [{
+ model: models.VoiceQueue,
+ required: false
+ }, {
+ model: models.ChatQueue,
+ required: false
+ }, {
+ model: models.MailQueue,
+ required: false
+ }, {
+ model: models.FaxQueue,
+ required: false
+ }, {
+ model: models.SmsQueue,
+ required: false
+ }, {
+ model: models.OpenchannelQueue,
+ required: false
+ }]
+ });
+
+ User.addScope('checkPauseStatus', function(query) {
+ var scope = {
+ where: {}
+ };
+ if (query.voicePause) {
+ scope.where.voicePause = (query.voicePause === 'true') ?
+ true : false;
+ delete query.voicePause;
+ } else if (query.faxPause) {
+ scope.where.faxPause = (query.faxPause === 'true') ? true :
+ false;
+ delete query.faxPause;
+ } else if (query.chatPause) {
+ scope.where.chatPause = (query.chatPause === 'true') ?
+ true : false;
+ delete query.chatPause;
+ } else if (query.mailPause) {
+ scope.where.mailPause = (query.mailPause === 'true') ?
+ true : false;
+ delete query.mailPause;
+ } else if (query.smsPause) {
+ scope.where.smsPause = (query.smsPause === 'true') ?
+ true : false;
+ delete query.smsPause;
+ } else if (query.openchannelPause) {
+ scope.where.openchannelPause = (query.openchannelPause === 'true') ?
+ true : false;
+ delete query.openchannelPause;
+ }
+ return scope;
+ });
+ User.addScope('checkOnlineStatus', function(query) {
+ var scope = {
+ where: {}
+ };
+ if (query.online) {
+ scope.where.online = (query.online === 'true') ? true :
+ false;
+ delete query.online;
+ }
+ return scope;
+ });
+ User.addScope('checkSipStatus', function(query) {
+ var scope = {
+ where: {}
+ };
+ if (query.status) {
+ scope.where.status = query.status;
+ delete query.status;
+ }
+ return scope;
+ });
+ User.addScope('checkQueueStatus', function(query) { //to be executed before checkOnlineStatus
+ var scope = {
+ where: {}
+ };
+ if (query.queueStatus) {
+ if (query.queueStatus === 'paused') {
+ scope.where.voicePause = true;
+ } else {
+ scope.where.queueStatus = query.queueStatus;
+ scope.where.voicePause = false;
+ query.online = 'true';
+ }
+ delete query.queueStatus;
+ }
+ return scope;
+ });
+
+ User.addScope('me', function(userId) {
+ var scope = {
+ where: {
+ id: userId
+ },
+ attributes: ['id', 'fullname', 'name', 'email', 'role', 'userpic', 'lastLoginAt', 'voicePause',
+ 'mailPause',
+ 'chatPause',
+ 'faxPause',
+ 'smsPause',
+ 'openchannelPause',
+ 'lastPauseAt',
+ 'pauseType',
+ 'phoneBarRemoteControl',
+ 'phoneBarRemoteControlPort',
+ 'loginInPause',
+ 'showWebBar',
+ 'phonebarEnableDtmfTone',
+ 'phonebarAutoAnswerDelay'
+ ],
+ include: [{
+ model: models.Module,
+ attributes: ['id', 'path'],
+ include: [{
+ model: models.Module,
+ attributes: ['id', 'path'],
+ as: 'SubModules',
+ required: false,
+ include: [{
+ model: models.Module,
+ attributes: ['id', 'path'],
+ as: 'SubModules'
+ }]
+ }]
+ }]
+ };
+ return scope;
+ });
+ }
+ });
+
+ return User;
+}