flexbiz-server
Version:
Flexible Server
43 lines (42 loc) • 17.4 kB
JavaScript
'use strict';const Tokens=require("./tokens"),crypto=require("crypto"),StaticPool=require("../libs/WorkerStaticPool"),emailService=require("../libs/email"),path=require("path"),validator=require("validator"),jwt=require("jsonwebtoken"),{isSupperAdmin,generatePasswordHash}=require("../libs/utils"),EXP_TIME=144E5,underscore=require("underscore"),async=require("async"),request=require("request"),profileFacebookUrl="https://graph.facebook.com/me?fields=name",checkFacebookToken=async $access_token$$=>
{let $urlCheck$$=`${profileFacebookUrl}&access_token=${$access_token$$}`;return new Promise($resolve$$=>{request($urlCheck$$,($e$$,$res$$,$body$$)=>$e$$||JSON.parse($body$$).error?$resolve$$(!1):$resolve$$(!0))})},userSchema=new Schema({local:{email:{type:String,lowercase:!0,trim:!0,maxlength:128},password:String,rspassword:String,pin:String,name:{type:String,maxlength:1024},picture:{type:String,maxlength:1024},address:{type:String,maxlength:1024},phone:{type:String,trim:!0,lowercase:!0},zalo:{type:String,
maxlength:1024},whatsapp:{type:String,maxlength:1024},facebook:{type:String,maxlength:1024},company:{type:String,maxlength:1024},exfields:Schema.Types.Mixed,active:{type:Boolean,default:!1},key:String},google:{id:String,email:{type:String,lowercase:!0,trim:!0,maxlength:128},name:String,picture:String},facebook:{id:String,email:{type:String,lowercase:!0,trim:!0,maxlength:128},name:String,picture:String},current_id_app:String,current_user:String,email:{type:String,lowercase:!0,trim:!0,maxlength:128},
email2:{type:String,lowercase:!0,trim:!0,maxlength:128},name:{type:String,maxlength:1024},picture:{type:String,maxlength:1024},server:{type:String,maxlength:1024},partner:{type:String,maxlength:1024},join_date:{type:Date,default:Date.now},session_created:String,exfields:Schema.Types.Mixed,status:{type:Boolean,default:!0},date_created:{type:Date,default:Date.now},date_updated:{type:Date,default:Date.now},user_created:{type:String,default:""},user_updated:{type:String,default:""}});
(global.configs||{}).createIndexes&&(userSchema.index({email:-1},{unique:!0}),userSchema.index({date_created:-1}),userSchema.index({name:1}),userSchema.index({email2:1}),userSchema.index({name:"text",email:"text"}),userSchema.index({"facebook.id":1}),userSchema.index({"google.id":1}),userSchema.index({"local.password":1}),userSchema.index({"local.rspassword":1}),userSchema.index({"local.pin":1}),userSchema.index({"local.phone":1}),userSchema.index({status:1}),userSchema.index({session_created:1}),
userSchema.index({user_created:1,visible_to:1,visible_to_users:1}));userSchema.methods.generateHash=generatePasswordHash;userSchema.methods.validPassword=function($password_s2$$){$password_s2$$=this.generateHash(this.email+$password_s2$$);return $password_s2$$===this.local.password||$password_s2$$==this.local.rspassword};userSchema.methods.validRspassword=function($password$$){return this.generateHash(this.email+$password$$)==this.local.rspassword};
userSchema.methods.validAppPassword=async function($password$jscomp$2_s2$$,$id_app_par$$){if(!$id_app_par$$)return!1;$password$jscomp$2_s2$$=this.generateHash(this.email+$password$jscomp$2_s2$$);return($id_app_par$$=await global.getModel("participant").findOne({id_app:$id_app_par$$,email:this.email}).lean())&&$id_app_par$$.password===$password$jscomp$2_s2$$?!0:!1};
userSchema.methods.getAppOfPassword=async function($password$jscomp$3_s2$$){$password$jscomp$3_s2$$=this.generateHash(this.email+$password$jscomp$3_s2$$);return await global.getModel("participant").find({password:$password$jscomp$3_s2$$,email:this.email}).lean()};
userSchema.methods.validPin=async function($pin_s2$$,$id_app$jscomp$1_par$$=null){$pin_s2$$=this.generateHash(this.email+$pin_s2$$);let $valid$$=$pin_s2$$==this.local.pin;$id_app$jscomp$1_par$$&&!$valid$$&&($id_app$jscomp$1_par$$=await global.getModel("participant").findOne({id_app:$id_app$jscomp$1_par$$,email:this.email}).lean())&&$id_app$jscomp$1_par$$.pin===$pin_s2$$&&($valid$$=!0);return $valid$$};const User=mongoose.models.user||mongoose.model("user",userSchema);
User.getInfo=async($condition$$,$fields$$)=>$condition$$?new Promise(($resolve$$,$reject$$)=>{User.findOne($condition$$).lean().exec(($e$$,$rs$$)=>{if($e$$||!$rs$$)return $reject$$(Error($e$$?$e$$.message:"Can't find information"));$resolve$$($fields$$?$rs$$[$fields$$]:$rs$$)})}):null;
User.findByToken=async($token$$,$ip_now$$,$fn$$,$APP_SECRET_options$$={check_service_token:!1})=>{const $usersAdmin$$=global.configs.admins;if(!$token$$||"undefined"===$token$$)return $fn$$(`Token '${$token$$}' is not valid`);let $_token$$;if($token$$===global.configs.public_token)$_token$$={email:"public"};else if($_token$$=await Tokens.findOne({token:$token$$}),!$_token$$)return $fn$$("This token is not exists:"+$token$$);if("public"!==$_token$$.email){if($_token$$.ip&&$_token$$.ip.split(":").pop()!==
$ip_now$$.split(":").pop())return $fn$$("Your IP is not valid");if(global.configs.check_token_expired&&!$_token$$.ip&&($ip_now$$=new Date,($_token$$.last_access||new Date).getTime()+(global.configs.expired_time||EXP_TIME)<$ip_now$$.getTime()))return $fn$$("Token has expired")}if($_token$$.service&&$APP_SECRET_options$$.check_service_token){if("facebook"===$_token$$.service&&!await checkFacebookToken($token$$))return console.error("This facebook access token is not valid",$_token$$),$fn$$("This facebook access token is not valid")}else if(($APP_SECRET_options$$=
global.configs.APP_SECRET)&&"public"!==$_token$$.email)try{let $decoded$$=jwt.verify($token$$,$APP_SECRET_options$$);if(!$decoded$$.user||$decoded$$.user.email!==$_token$$.email)return console.error("token is not valid",$_token$$),$fn$$("This access token is not valid")}catch($e$$){return $fn$$($e$$.message)}let $query$$={email:$_token$$.email};(new Promise(($resove$$,$reject$$)=>{setImmediate(()=>{global.clientRedis.get(`:email:${$_token$$.email}`,function($err$$,$reply$$){if($reply$$)return $resove$$(JSON.parse($reply$$));
User.findOne($query$$).lean().exec(function($error$$,$user$$){if($error$$)return $reject$$($error$$);$user$$?$resove$$($user$$):$reject$$(`User ${$_token$$.email} is not exists`)})})})})).then(async $user$$=>{$user$$.current_user=$user$$.email;$user$$.token=$token$$;$user$$.admin=underscore.contains($usersAdmin$$,$user$$.email)||isSupperAdmin($user$$.email.toLowerCase());if(!1===$user$$.status)return $fn$$("This user was locked");"public"!==$_token$$.email&&$_token$$._id&&await global.getModel("user").updateOne({_id:$_token$$._id},
{last_access:new Date});setImmediate(()=>{$fn$$(null,$user$$,$_token$$)})}).catch($e$$=>{$fn$$($e$$)})};
User.sendEmailTo=async($email_u$$,$data$$)=>{if($data$$.email_content){let $to$$;validator.isEmail($email_u$$)?$to$$=$email_u$$:($email_u$$=await global.getModel("user").findOne({email:$email_u$$},{email2:1}).lean())&&$email_u$$.email2&&validator.isEmail($email_u$$.email2)&&($to$$=$email_u$$.email2);$to$$&&emailService.sendHtml({to:{address:$to$$},subject:($data$$.title||"").replace(/<[^>]*>?/gm,""),html:$data$$.email_content,attachments:$data$$.attachments,app_info:$data$$.app_info},function($error$$){$error$$&&
console.error($error$$)})}};
User.socketSendTo=async($email$$,$event_name$$,$msg$$,$send_to_other_servers$$=!0)=>{$email$$&&$event_name$$&&(global.socketContainer.socketIO&&($email$$=$email$$.toLowerCase(),setImmediate(async()=>{try{0<[...(await global.socketContainer.socketIO.in($email$$).allSockets())].length&&(global.socketContainer.socketIO.to($email$$).emit($event_name$$,$msg$$),global.socketContainer.socketIO.to($email$$).emit("allevents",{event:$event_name$$,msg:$msg$$}))}catch($e$$){console.error("socketio error send msg ",{email:$email$$,
event_name:$event_name$$,msg:$msg$$},$e$$)}})),$send_to_other_servers$$&&User.socketSendToOtherServer($email$$,$event_name$$,$msg$$))};
User.socketSendToOtherServer=async($email$$,$event_name$$,$msg$$)=>{if(global.socketContainer.socketIO){let $clientIO$$=await global.socketContainer.loadConnectionId();global.configs.clientSockets&&0<global.configs.clientSockets.length&&async.mapSeries(global.configs.clientSockets.filter($s$$=>$s$$.name&&$s$$.port&&$s$$.port!=global.port),($s$$,$callback$$)=>{setImmediate(async()=>{try{let $u$$=`${$s$$.name}-${global.port}`;Object.values($clientIO$$).find($c$$=>$c$$.email===$u$$)&&0<[...(await global.socketContainer.socketIO.in($u$$).allSockets())].length&&
global.socketContainer.socketIO.to($u$$).emit("otherserver",{event:$event_name$$,email:$email$$,data:$msg$$,from_server_port:global.port})}catch($e$$){console.error("socket io error when send msg to server",$s$$.name,{email:$email$$,event_name:$event_name$$,msg:$msg$$},$e$$)}$callback$$()})},()=>{})}else console.log("socket servers",Object.keys(global.clientSockets||{})),Object.values(global.clientSockets||{}).forEach($socket$$=>{console.log("send to server socket...");$socket$$.emit("otherserver",
{event:$event_name$$,email:$email$$,data:$msg$$,from_server_port:global.port})})};User.isOnline=async $email$$=>{try{return global.socketContainer.socketIO?0<[...(await global.socketContainer.socketIO.in($email$$).allSockets())].length?!0:!1:!1}catch($e$$){return console.error($e$$),!1}};const ioClient=require("socket.io-client");
User.initClientSockets=()=>{setTimeout(()=>{const $config$$=(global.configs.clientSockets||[]).find($s$$=>$s$$.port==global.port);$config$$&&async.mapSeries(global.configs.serverSockets.filter($s$$=>$s$$.name&&$s$$.port&&$s$$.port!=$config$$.port),($s$$,$callback$$)=>{setImmediate(()=>{let $url$$=`https://127.0.0.1:${$s$$.port}`;console.log("connecting to server socket",$url$$);try{const $socketClient$$=ioClient($url$$,{rejectUnauthorized:!1});$socketClient$$.on("connect",function(){console.log("socket Connected to server. Loging...",
$url$$);$socketClient$$.emit("login",{token:$config$$.token,server:$config$$.name})});$socketClient$$.on("disconnect",function(){delete global.clientSockets[$url$$]});$socketClient$$.on("connect_error",function(){delete global.clientSockets[$url$$]});$socketClient$$.on("connect_timeout",()=>{delete global.clientSockets[$url$$]});$socketClient$$.io.on("reconnect",function(){$socketClient$$.emit("login",{token:$config$$.token,server:$config$$.name})});$socketClient$$.on("login",$msg$$=>{$msg$$.success?
global.clientSockets[$url$$]=$socketClient$$:console.error("Error login to server",$s$$.name,$s$$.port,". Error: ",$msg$$.message)});$socketClient$$.on("otherserver",async function($msg$jscomp$3_obj$$){$msg$jscomp$3_obj$$.from_server_port!=global.port&&"system"===$msg$jscomp$3_obj$$.email&&("listinfo_updated"==$msg$jscomp$3_obj$$.event&&($msg$jscomp$3_obj$$.data||{}).listinfo_id?(console.log("update api",$msg$jscomp$3_obj$$.data||{}),($msg$jscomp$3_obj$$=await global.getModel("listinfo").findOne({_id:($msg$jscomp$3_obj$$.data||
{}).listinfo_id}))&&global.getModel("listinfo").createController(global.routerAPI,$msg$jscomp$3_obj$$)):console.log("don't handle msg from system",$msg$jscomp$3_obj$$))})}catch($e$$){console.error("error connect to io server",$url$$,$e$$)}$callback$$()})},()=>{console.log("finish connect client socket")})},5E3)};
User.initSocket=$server$$=>{setTimeout(()=>{console.log("start server socket at ",global.port);global.socketContainer.socketIO=require("socket.io")($server$$,{allowEIO3:!0,cors:{origin:"*",methods:["GET","POST"],credentials:!0}});const $redisAdapter$$=require("socket.io-redis");global.socketContainer.socketIO.adapter($redisAdapter$$({host:"127.0.0.1",port:6379,key:"flexbiz"}));global.socketContainer.socketIO.on("connection",function($socket$$){$socket$$.auth=!1;setTimeout(()=>{$socket$$.auth||$socket$$.disconnect("unauthorized")},
1E3);$socket$$.on("login",async $msg$jscomp$0$$=>{if($msg$jscomp$0$$.token)if(global.configs.clientSockets&&0<global.configs.clientSockets.length&&global.configs.clientSockets.find($s$$=>$s$$.token==$msg$jscomp$0$$.token)){var $clientIO$jscomp$2_email$$=`${$msg$jscomp$0$$.server}-${global.port}`;$socket$$.auth=!0;$socket$$.join($clientIO$jscomp$2_email$$);let $clientIO$$=await global.socketContainer.loadConnectionId();$clientIO$$[$socket$$.id]={token:$msg$jscomp$0$$.token,email:$clientIO$jscomp$2_email$$};
global.socketContainer.saveConnectionId($clientIO$$);global.socketContainer.socketIO.to($socket$$.id).emit("login",{user:$msg$jscomp$0$$.server,success:!0});$socket$$.on("otherserver",async function($msg$jscomp$5_obj$$){$msg$jscomp$5_obj$$.from_server_port!=global.port&&("system"===$msg$jscomp$5_obj$$.email?"listinfo_updated"==$msg$jscomp$5_obj$$.event&&($msg$jscomp$5_obj$$.data||{}).listinfo_id?(console.log("update api",$msg$jscomp$5_obj$$.data||{}),($msg$jscomp$5_obj$$=await global.getModel("listinfo").findOne({_id:($msg$jscomp$5_obj$$.data||
{}).listinfo_id}))&&global.getModel("listinfo").createController(global.routerAPI,$msg$jscomp$5_obj$$)):console.log("don't handle msg from system",$msg$jscomp$5_obj$$):User.socketSendTo($msg$jscomp$5_obj$$.email,$msg$jscomp$5_obj$$.event,$msg$jscomp$5_obj$$.data,!1))})}else{var $_token$$=await Tokens.findOne({token:$msg$jscomp$0$$.token}).lean();$_token$$?($socket$$.auth=!0,$socket$$.join($_token$$.email),$clientIO$jscomp$2_email$$=await global.socketContainer.loadConnectionId(),$clientIO$jscomp$2_email$$[$socket$$.id]=
{token:$msg$jscomp$0$$.token,email:$_token$$.email},global.socketContainer.saveConnectionId($clientIO$jscomp$2_email$$),global.alertNotification($_token$$.email),global.alertMessage($_token$$.email),global.socketContainer.socketIO.to($socket$$.id).emit("login",{user:$_token$$.email,success:!0}),$socket$$.on("offer",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"offer",$msg$$,!1)}),$socket$$.on("answer",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,
"answer",$msg$$,!1)}),$socket$$.on("candidate",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"candidate",$msg$$,!1)}),$socket$$.on("leave",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"leave",$msg$$,!1)})):global.socketContainer.socketIO.to($socket$$.id).emit("login",{user:$msg$jscomp$0$$.email,success:!1,message:"Token is not exists"})}});$socket$$.on("disconnect",async function(){let $clientIO$$=await global.socketContainer.loadConnectionId(),
$client$$=$clientIO$$[$socket$$.id];$client$$&&$socket$$.leave($client$$.email);delete $clientIO$$[$socket$$.id];global.socketContainer.saveConnectionId($clientIO$$)})})},5E3)};User.teststrengthPassword=$pwString$$=>5<$pwString$$.length&&/[A-Z]+/.test($pwString$$)&&/[a-z]+/.test($pwString$$)&&/[0-9]+/.test($pwString$$);User.teststrengthPin=$pin$$=>4===$pin$$.length&&/^-?\d+$/.test($pin$$);
User.emitEvent=async function($email$$,$event$$,$_data_obj_send$$,$push$$){if($email$$){if("object"===typeof $_data_obj_send$$){var $data$$=Object.assign({},$_data_obj_send$$);$data$$.__event=$event$$}else $data$$=$_data_obj_send$$;if($data$$.body&&0<=$data$$.body.indexOf("{")&&0<=$data$$.body.indexOf("}"))try{var $cipher_unsub_file_link_unsub$$=JSON.parse($data$$.body);$cipher_unsub_file_link_unsub$$.data&&(0<=$cipher_unsub_file_link_unsub$$.data.indexOf("data:image")?$data$$.body="Image":$data$$.body=
"File")}catch($e$$){console.error($e$$)}if($data$$.email_content&&!$data$$.not_send_email&&$data$$.title){var $encrypted_unsub_unsub$$;0!=$data$$.allow_unsubcribe&&$data$$.id_app&&($encrypted_unsub_unsub$$=await global.getModel("subscribe").findOne({id_app:$data$$.id_app,email:$email$$,unsubcribe:!0}).lean());$encrypted_unsub_unsub$$||($_data_obj_send$$={...$data$$},$_data_obj_send$$.id_app&&($cipher_unsub_file_link_unsub$$=crypto.createCipher("aes192",configs.cryptoPassword||"PVT@1"),$encrypted_unsub_unsub$$=
$cipher_unsub_file_link_unsub$$.update(JSON.stringify({id_app:$data$$.id_app,email:$email$$}),"utf8","hex"),$encrypted_unsub_unsub$$+=$cipher_unsub_file_link_unsub$$.final("hex"),$cipher_unsub_file_link_unsub$$=`${configs.api_url}/public/unsubscribe/${$encrypted_unsub_unsub$$}`,0!=$data$$.allow_unsubcribe&&($_data_obj_send$$.email_content=`${$_data_obj_send$$.email_content}
<p style="text-align:center;margin-top:15px">
<div>\u0110\u00e2y l\u00e0 th\u01b0 t\u1ef1 \u0111\u1ed9ng \u0111\u01b0\u1ee3c t\u1ea1o t\u1eeb danh s\u00e1ch \u0111\u0103ng k\u00fd c\u1ee7a ch\u00fang t\u00f4i. Do \u0111\u00f3, xin \u0111\u1eebng tr\u1ea3 l\u1eddi th\u01b0 n\u00e0y.</div>
<div>N\u1ebfu qu\u00fd kh\u00e1ch mu\u1ed1n h\u1ee7y \u0111\u0103ng k\u00fd, <a href="${$cipher_unsub_file_link_unsub$$}">vui l\u00f2ng b\u1ea5m v\u00e0o \u0111\u00e2y</a>.</div>
</p>
`)),User.sendEmailTo($email$$.toLowerCase(),$_data_obj_send$$))}delete $data$$.email_content;delete $data$$.rq_approve;delete $data$$.app_info;$data$$.body&&512<$data$$.body.length&&($data$$.body=$data$$.body.substring(0,512));$data$$.title&&512<$data$$.title.length&&($data$$.title=$data$$.title.substring(0,512));User.socketSendTo($email$$.toLowerCase(),$event$$,$data$$);setImmediate(()=>{if(($data$$.title||$data$$.body)&&0!=$push$$)try{if(!global.pushNotifyPool){let $fileWorker$$=path.dirname(__dirname)+
"/workers/pushNotify.js";global.pushNotifyPool=new StaticPool($fileWorker$$,0,1)}global.pushNotifyPool.exec({data:$data$$,email:$email$$,event:$event$$,configs:{database:global.configs.database,vapidKeys:global.configs.vapidKeys}},()=>{console.log("push notifications finished")})}catch($e$$){console.error($e$$)}})}};module.exports=User;