-var _0xb5b7=["\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","\x55\x4E\x4B\x4E\x4F\x57\x4E","\x63\x6F\x6D\x70\x6C\x65\x74\x65","\x76\x6F\x69\x63\x65\x50\x61\x75\x73\x65","\x71\x75\x65\x75\x65\x53\x74\x61\x74\x75\x73","\x70\x61\x75\x73\x65\x64","\x71\x75\x65\x75\x65\x53\x74\x61\x74\x75\x73\x41\x74","\x59\x59\x59\x59\x2D\x4D\x4D\x2D\x44\x44\x20\x48\x48\x3A\x6D\x6D\x3A\x73\x73","\x66\x6F\x72\x6D\x61\x74","\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","\x6F\x75\x74\x67\x6F\x69\x6E\x67","\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\x70\x64\x61\x74\x65\x2C\x6E\x6F\x6E\x61\x74","\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\x46\x61\x78\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","\x43\x68\x61\x74\x51\x75\x65\x75\x65","\x4D\x61\x69\x6C\x51\x75\x65\x75\x65","\x46\x61\x78\x51\x75\x65\x75\x65","\x63\x68\x65\x63\x6B\x50\x61\x75\x73\x65\x53\x74\x61\x74\x75\x73","\x77\x68\x65\x72\x65","\x74\x72\x75\x65","\x66\x61\x78\x50\x61\x75\x73\x65","\x63\x68\x61\x74\x50\x61\x75\x73\x65","\x6D\x61\x69\x6C\x50\x61\x75\x73\x65","\x63\x68\x65\x63\x6B\x4F\x6E\x6C\x69\x6E\x65\x53\x74\x61\x74\x75\x73","\x6F\x6E\x6C\x69\x6E\x65","\x63\x68\x65\x63\x6B\x53\x69\x70\x53\x74\x61\x74\x75\x73","\x73\x74\x61\x74\x75\x73","\x63\x68\x65\x63\x6B\x51\x75\x65\x75\x65\x53\x74\x61\x74\x75\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","\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","\x70\x68\x6F\x6E\x65\x42\x61\x72\x50\x6F\x72\x74","\x63\x68\x61\x6E\x73\x70\x79","\x70\x61\x75\x73\x65\x54\x79\x70\x65","\x6C\x61\x73\x74\x50\x61\x75\x73\x65\x41\x74","\x73\x74\x61\x74\x75\x73\x41\x74","\x6C\x61\x73\x74\x51\x75\x65\x75\x65","\x75\x73\x65\x72\x61\x67\x65\x6E\x74","\x69\x70\x61\x64\x64\x72","\x66\x75\x6C\x6C\x63\x6F\x6E\x74\x61\x63\x74","\x70\x6F\x72\x74","\x6C\x61\x73\x74\x6D\x73","\x64\x65\x73\x63\x72\x69\x70\x74\x69\x6F\x6E","\x64\x65\x66\x69\x6E\x65"];_0xb5b7[0];var crypto=require(_0xb5b7[1]);var md5=require(_0xb5b7[2]);var _=require(_0xb5b7[3]);var moment=require(_0xb5b7[4]);var VoiceQueue=require(_0xb5b7[6])[_0xb5b7[5]];module[_0xb5b7[7]]=function(_0xa627x6,_0xa627x7){var _0xa627x8=_0xa627x6[_0xb5b7[150]](_0xb5b7[8],{name:{type:_0xa627x7[_0xb5b7[9]],unique:true,validate:{notEmpty:true,is:/^[A-Za-z0-9\.\_]+$/i},set:function(_0xa627x9){this[_0xb5b7[11]](_0xb5b7[10],_0xa627x9);this[_0xb5b7[11]](_0xb5b7[12],_0xa627x9)}},fullname:{type:_0xa627x7[_0xb5b7[9]],allowNull:false},email:{type:_0xa627x7[_0xb5b7[9]],unique:true,set:function(_0xa627xa){if(_0xa627xa){this[_0xb5b7[11]](_0xb5b7[13],_0xa627xa[_0xb5b7[14]]())}},defaultValue:null},role:{type:_0xa627x7.ENUM(_0xb5b7[15],_0xb5b7[16],_0xb5b7[17],_0xb5b7[18])},password:{type:_0xa627x7[_0xb5b7[9]],allowNull:false,validate:{notEmpty:true},set:function(_0xa627xb){this[_0xb5b7[19]]=this[_0xb5b7[20]]();this[_0xb5b7[11]](_0xb5b7[21],this[_0xb5b7[22]](_0xa627xb));this[_0xb5b7[11]](_0xb5b7[23],this[_0xb5b7[25]](this[_0xb5b7[10]]+_0xb5b7[24]+_0xa627xb))}},provider:{type:_0xa627x7[_0xb5b7[9]],defaultValue:_0xb5b7[26]},internal:{type:_0xa627x7.INTEGER(11),unique:true,set:function(_0xa627xc){this[_0xb5b7[11]](_0xb5b7[27],_0xa627xc);this[_0xb5b7[11]](_0xb5b7[28],_0xa627xc)}},salt:{type:_0xa627x7[_0xb5b7[9]]},phone:{type:_0xa627x7[_0xb5b7[9]]},mobile:{type:_0xa627x7[_0xb5b7[9]]},address:{type:_0xa627x7[_0xb5b7[9]]},zipcode:{type:_0xa627x7[_0xb5b7[9]]},userpic:{type:_0xa627x7[_0xb5b7[9]]},city:{type:_0xa627x7[_0xb5b7[9]]},country:{type:_0xa627x7[_0xb5b7[9]]},online:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},lastLoginAt:{type:_0xa627x7[_0xb5b7[30]]},status:{type:_0xa627x7[_0xb5b7[9]],defaultValue:_0xb5b7[31]},statusAt:{type:_0xa627x7[_0xb5b7[30]]},queueStatus:{type:_0xa627x7[_0xb5b7[9]],defaultValue:_0xb5b7[32]},queueStatusAt:{type:_0xa627x7[_0xb5b7[30]]},lastQueue:{type:_0xa627x7[_0xb5b7[9]]},voicePause:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false,set:function(_0xa627xd){this[_0xb5b7[11]](_0xb5b7[33],_0xa627xd);if(_0xa627xd){this[_0xb5b7[11]](_0xb5b7[34],_0xb5b7[35]);this[_0xb5b7[11]](_0xb5b7[36],moment()[_0xb5b7[38]](_0xb5b7[37]))}else {this[_0xb5b7[11]](_0xb5b7[34],_0xb5b7[32]);this[_0xb5b7[11]](_0xb5b7[36],moment()[_0xb5b7[38]](_0xb5b7[37]))}}},chatPause:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},mailPause:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},faxPause:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},pauseType:{type:_0xa627x7[_0xb5b7[9]],defaultValue:_0xb5b7[39]},lastPauseAt:{type:_0xa627x7[_0xb5b7[30]]},chatCapacity:{type:_0xa627x7[_0xb5b7[40]],defaultValue:0},mailCapacity:{type:_0xa627x7[_0xb5b7[40]],defaultValue:0},faxCapacity:{type:_0xa627x7[_0xb5b7[40]],defaultValue:0},phoneBarAutoAnswer:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},phoneBarEnableSettings:{type:_0xa627x7[_0xb5b7[29]],defaultValue:true},phoneBarUnconditionalNumber:{type:_0xa627x7[_0xb5b7[9]],get:function(){if(this[_0xb5b7[42]](_0xb5b7[41])){return this[_0xb5b7[42]](_0xb5b7[43])};return null}},phoneBarNoReplyNumber:{type:_0xa627x7[_0xb5b7[9]],get:function(){if(this[_0xb5b7[42]](_0xb5b7[44])){return this[_0xb5b7[42]](_0xb5b7[45])};return null}},phoneBarBusyNumber:{type:_0xa627x7[_0xb5b7[9]],get:function(){if(this[_0xb5b7[42]](_0xb5b7[46])){return this[_0xb5b7[42]](_0xb5b7[47])};return null}},phoneBarUnconditional:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},phoneBarNoReply:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},phoneBarBusy:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},phoneBarPort:{type:_0xa627x7.INTEGER(5),allowNull:true,defaultValue:5060},chanspy:{type:_0xa627x7[_0xb5b7[29]],defaultValue:false},description:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},ipaddr:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},port:{type:_0xa627x7.INTEGER(5),allowNull:true},regseconds:{type:_0xa627x7.INTEGER(11),allowNull:true},fullcontact:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},regserver:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},useragent:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},lastms:{type:_0xa627x7.INTEGER(11),allowNull:true},type:{type:_0xa627x7.ENUM(_0xb5b7[48],_0xb5b7[16],_0xb5b7[49]),allowNull:true,defaultValue:_0xb5b7[48]},context:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[50]},callingpres:{type:_0xa627x7.ENUM(_0xb5b7[51],_0xb5b7[52],_0xb5b7[53],_0xb5b7[54],_0xb5b7[55],_0xb5b7[56],_0xb5b7[57],_0xb5b7[58]),allowNull:true},permit:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},deny:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},secret:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},md5secret:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},remotesecret:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},transport:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[59]},dtmfmode:{type:_0xa627x7.ENUM(_0xb5b7[60],_0xb5b7[61],_0xb5b7[62],_0xb5b7[63],_0xb5b7[64]),allowNull:true,defaultValue:_0xb5b7[60]},directmedia:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66],_0xb5b7[67],_0xb5b7[68],_0xb5b7[69]),allowNull:true,defaultValue:_0xb5b7[66]},directrtpsetup:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},directmediapermit:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},directmediadeny:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},nat:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[70]},callgroup:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},namedcallgroup:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},pickupgroup:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},namedpickupgroup:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},language:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[71]},tonezone:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},allow:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[72]},disallow:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:null},autoframing:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},insecure:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[73]},trustrpid:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},trust_id_outbound:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},progressinband:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66],_0xb5b7[74]),allowNull:true},promiscredir:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},useclientcode:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},accountcode:{type:_0xa627x7.INTEGER(11),allowNull:true},setvar:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},callerid:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[75]},amaflags:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},callcounter:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[65]},busylevel:{type:_0xa627x7.INTEGER(11),allowNull:true},allowoverlap:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},allowsubscribe:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},allowtransfer:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},ignoresdpversion:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},subscribecontext:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},template:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},videosupport:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66],_0xb5b7[76]),allowNull:true,defaultValue:_0xb5b7[66]},maxcallbitrate:{type:_0xa627x7.INTEGER(11),allowNull:true},rfc2833compensate:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},mailbox:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},session_timers:{type:_0xa627x7.ENUM(_0xb5b7[77],_0xb5b7[78],_0xb5b7[79]),allowNull:true},session_expires:{type:_0xa627x7.INTEGER(11),allowNull:true},session_minse:{type:_0xa627x7.INTEGER(11),allowNull:true},session_refresher:{type:_0xa627x7.ENUM(_0xb5b7[80],_0xb5b7[81]),allowNull:true,defaultValue:_0xb5b7[81]},t38pt_usertpsource:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},regexten:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},fromdomain:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},fromuser:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},host:{type:_0xa627x7[_0xb5b7[9]],allowNull:true,defaultValue:_0xb5b7[82]},qualify:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[65]},keepalive:{type:_0xa627x7.INTEGER(11),allowNull:true},defaultip:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},defaultuser:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},rtptimeout:{type:_0xa627x7.INTEGER(11),allowNull:true},rtpholdtimeout:{type:_0xa627x7.INTEGER(11),allowNull:true},rtpkeepalive:{type:_0xa627x7.INTEGER(11),allowNull:true},sendrpid:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},outboundproxy:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},callbackextension:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},timert1:{type:_0xa627x7.INTEGER(11),allowNull:true},timerb:{type:_0xa627x7.INTEGER(11),allowNull:true},qualifyfreq:{type:_0xa627x7.INTEGER(11),allowNull:true},contactpermit:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},contactdeny:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},contactacl:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},unsolicited_mailbox:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},use_q850_reason:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},maxforwards:{type:_0xa627x7.INTEGER(11),allowNull:true},encryption:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},avpf:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},force_avp:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},icesupport:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},dtlsenable:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},dtlsverify:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66],_0xb5b7[83],_0xb5b7[84]),allowNull:true},dtlsrekey:{type:_0xa627x7.INTEGER(11),allowNull:true},dtlscertfile:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},dtlsprivatekey:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},dtlscipher:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},dtlscafile:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},dtlscapath:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},dtlssetup:{type:_0xa627x7.ENUM(_0xb5b7[85],_0xb5b7[86],_0xb5b7[87]),allowNull:true},dtlsfingerprint:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},usereqphone:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true,defaultValue:_0xb5b7[66]},recordonfeature:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},recordofffeature:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},call_limit:{type:_0xa627x7.INTEGER(11),allowNull:true,defaultValue:null},registertrying:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},subscribemwi:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66]),allowNull:true},vmexten:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},mohinterpret:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},mohsuggest:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},parkinglot:{type:_0xa627x7[_0xb5b7[9]],allowNull:true},canreinvite:{type:_0xa627x7.ENUM(_0xb5b7[65],_0xb5b7[66],_0xb5b7[67],_0xb5b7[68],_0xb5b7[88]),allowNull:true,defaultValue:_0xb5b7[66]}},{tableName:_0xb5b7[89],instanceMethods:{authenticate:function(_0xa627xe){return this[_0xb5b7[22]](_0xa627xe)===this[_0xb5b7[21]]},makeSalt:function(){return crypto[_0xb5b7[91]](16).toString(_0xb5b7[90])},encryptPassword:function(_0xa627xb){if(!_0xa627xb||!this[_0xb5b7[19]]){return _0xb5b7[92]};var _0xa627xf= new Buffer(this[_0xb5b7[19]],_0xb5b7[90]);return crypto[_0xb5b7[93]](_0xa627xb,_0xa627xf,10000,64).toString(_0xb5b7[90])},md5Password:function(_0xa627xb){if(!_0xa627xb){return _0xb5b7[92]};return md5(_0xa627xb)}},associate:function(_0xa627x10){_0xa627x8[_0xb5b7[94]](_0xa627x10.ChatMessage);_0xa627x8[_0xb5b7[94]](_0xa627x10.MailMessage);_0xa627x8[_0xb5b7[94]](_0xa627x10.Contact);_0xa627x8[_0xb5b7[94]](_0xa627x10.Action);_0xa627x8[_0xb5b7[96]](_0xa627x10.Module,{through:_0xb5b7[95]});_0xa627x8[_0xb5b7[96]](_0xa627x10.Channel,{through:_0xb5b7[97]});_0xa627x8[_0xb5b7[96]](_0xa627x10.MailRoom,{through:_0xb5b7[98]});_0xa627x8[_0xb5b7[96]](_0xa627x10.Team,{through:_0xa627x10[_0xb5b7[99]]});_0xa627x8[_0xb5b7[96]](_0xa627x10.ChatRoom,{through:_0xa627x10[_0xb5b7[100]]});_0xa627x8[_0xb5b7[96]](_0xa627x10.MailQueue,{through:_0xa627x10[_0xb5b7[101]],required:false});_0xa627x8[_0xb5b7[96]](_0xa627x10.FaxQueue,{through:_0xa627x10[_0xb5b7[102]],required:false});_0xa627x8[_0xb5b7[96]](_0xa627x10.ChatQueue,{through:_0xa627x10[_0xb5b7[103]],required:false});_0xa627x8[_0xb5b7[96]](_0xa627x10.VoiceQueue,{through:_0xa627x10[_0xb5b7[104]],required:false});_0xa627x8[_0xb5b7[96]](_0xa627x10.Service,{through:_0xa627x10[_0xb5b7[105]]});_0xa627x8[_0xb5b7[94]](_0xa627x10.VoiceExtension,{foreignKey:_0xb5b7[106],as:_0xb5b7[107],onDelete:_0xb5b7[108],hooks:true});_0xa627x8[_0xb5b7[109]](_0xb5b7[16],{where:{role:{$in:[_0xb5b7[15],_0xb5b7[16]]}}});_0xa627x8[_0xb5b7[109]](_0xb5b7[110],{include:[_0xa627x10[_0xb5b7[5]],_0xa627x10[_0xb5b7[111]],_0xa627x10[_0xb5b7[112]],_0xa627x10[_0xb5b7[113]]]});_0xa627x8[_0xb5b7[109]](_0xb5b7[18],{where:{role:_0xb5b7[18]}});_0xa627x8[_0xb5b7[109]](_0xb5b7[114],function(_0xa627x11){var _0xa627x12={where:{}};if(_0xa627x11[_0xb5b7[33]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[33]]=(_0xa627x11[_0xb5b7[33]]===_0xb5b7[116])?true:false;delete _0xa627x11[_0xb5b7[33]]}else {if(_0xa627x11[_0xb5b7[117]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[117]]=(_0xa627x11[_0xb5b7[117]]===_0xb5b7[116])?true:false;delete _0xa627x11[_0xb5b7[117]]}else {if(_0xa627x11[_0xb5b7[118]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[118]]=(_0xa627x11[_0xb5b7[118]]===_0xb5b7[116])?true:false;delete _0xa627x11[_0xb5b7[118]]}else {if(_0xa627x11[_0xb5b7[119]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[119]]=(_0xa627x11[_0xb5b7[119]]===_0xb5b7[116])?true:false;delete _0xa627x11[_0xb5b7[119]]}}}};return _0xa627x12});_0xa627x8[_0xb5b7[109]](_0xb5b7[120],function(_0xa627x11){var _0xa627x12={where:{}};if(_0xa627x11[_0xb5b7[121]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[121]]=(_0xa627x11[_0xb5b7[121]]===_0xb5b7[116])?true:false;delete _0xa627x11[_0xb5b7[121]]};return _0xa627x12});_0xa627x8[_0xb5b7[109]](_0xb5b7[122],function(_0xa627x11){var _0xa627x12={where:{}};if(_0xa627x11[_0xb5b7[123]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[123]]=_0xa627x11[_0xb5b7[123]];delete _0xa627x11[_0xb5b7[123]]};return _0xa627x12});_0xa627x8[_0xb5b7[109]](_0xb5b7[124],function(_0xa627x11){var _0xa627x12={where:{}};if(_0xa627x11[_0xb5b7[34]]){_0xa627x12[_0xb5b7[115]][_0xb5b7[34]]=_0xa627x11[_0xb5b7[34]];delete _0xa627x11[_0xb5b7[34]]};return _0xa627x12});_0xa627x8[_0xb5b7[109]](_0xb5b7[17],{where:{role:_0xb5b7[17]},attributes:[_0xb5b7[125],_0xb5b7[10],_0xb5b7[13],_0xb5b7[27],_0xb5b7[126],_0xb5b7[28],_0xb5b7[127],_0xb5b7[128],_0xb5b7[129],_0xb5b7[130],_0xb5b7[131],_0xb5b7[132],_0xb5b7[133],_0xb5b7[134],_0xb5b7[121],_0xb5b7[135],_0xb5b7[136],_0xb5b7[137],_0xb5b7[41],_0xb5b7[44],_0xb5b7[46],_0xb5b7[43],_0xb5b7[45],_0xb5b7[47],_0xb5b7[138],_0xb5b7[139],_0xb5b7[33],_0xb5b7[119],_0xb5b7[117],_0xb5b7[118],_0xb5b7[140],_0xb5b7[141],_0xb5b7[123],_0xb5b7[142],_0xb5b7[34],_0xb5b7[36],_0xb5b7[143],_0xb5b7[144],_0xb5b7[145],_0xb5b7[146],_0xb5b7[147],_0xb5b7[148],_0xb5b7[149]]})}});return _0xa627x8}
\ 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: true,
+ 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,
+ unique: true
+ },
+ email: {
+ type: DataTypes.STRING,
+ unique: true,
+ 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: true,
+ 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,
+ },
+ permit: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ },
+ deny: {
+ 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: 'alaw;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: false
+ }
+ }, {
+ tableName: 'users',
+ 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.Channel, {
+ through: 'user_has_channels'
+ });
+ User.belongsToMany(models.MailRoom, {
+ through: 'user_has_mail_rooms'
+ });
+ 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'
+ ]
+ });
+
+ // 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',
+ ]
+ });
+ 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'
+ ]
+ });
+ User.addScope('telephone', {
+ where: {
+ role: 'telephone'
+ }
+ });
+ User.addScope('queues', {
+ include: [models.VoiceQueue, models.ChatQueue, models.MailQueue,
+ models.FaxQueue, models.SmsQueue, models.OpenchannelQueue
+ ]
+ });
+
+ 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) {
+ var scope = {
+ where: {}
+ };
+ if (query.queueStatus) {
+ scope.where.queueStatus = query.queueStatus;
+ 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'
+ ],
+ include: [{
+ model: models.Module,
+ include: [{
+ model: models.Module,
+ as: 'SubModules',
+ required: false,
+ include: [{
+ all: true
+ }]
+ }]
+ }, {
+ model: models.VoiceQueue,
+ as: 'PVoiceQueues'
+ }, {
+ model: models.ChatQueue,
+ as: 'PChatQueues'
+ }, {
+ model: models.MailQueue,
+ as: 'PMailQueues'
+ }, {
+ model: models.FaxQueue,
+ as: 'PFaxQueues'
+ }, {
+ model: models.SmsQueue,
+ as: 'PSmsQueues'
+ }]
+ };
+ return scope;
+ });
+ }
+ });
+
+ return User;
+}