UNPKG

flexbiz-server

Version:

Flexible Server

41 lines (40 loc) 16.1 kB
const Tokens=require("./tokens"),StaticPool=require("../libs/WorkerStaticPool"),emailService=require("../libs/email"),path=require("path"),validator=require("validator"),{isSupperAdmin,generatePasswordHash,encrypt}=require("../libs/utils"),EXP_TIME=144E5,underscore=require("underscore"),redis=require("redis"),request=require("request"),{onAfterCommit}=require("../libs/sessionContext"),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},so_luong_db:Number,is_system_admin:Boolean,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$$);$id_app_par$$=await global.getModel("participant").findOne({id_app:$id_app_par$$,email:this.email}).lean();if(!$id_app_par$$)return Logger.info("[user] participant kh\u00f4ng t\u1ed3n t\u1ea1i",this.email),!1;if($id_app_par$$.password===$password$jscomp$2_s2$$)return!0;Logger.info("[user]M\u1eadt kh\u1ea9u kh\u00f4ng kh\u1edbp", $id_app_par$$.password,$password$jscomp$2_s2$$);return!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().then($rs$$=>{if(!$rs$$)return $reject$$(Error("Can't find information"));$resolve$$($fields$$?$rs$$[$fields$$]:$rs$$)}).catch($e$$=>{$reject$$($e$$)})}):null; User.findByToken=async($token$$,$ip_now$$,$fn$$,$options$$={check_service_token:!1})=>{const $usersAdmin$$=global.configs.admins;if(!$token$$||$token$$==="undefined")return $fn$$("Token kh\u00f4ng c\u00f3 gi\u00e1 tr\u1ecb");let $_token$$;if($token$$===global.configs.public_token)$_token$$={email:"public"};else if($_token$$=await Tokens.findOne({token:$token$$}),!$_token$$)return $fn$$("Token kh\u00f4ng t\u1ed3n t\u1ea1i");if($_token$$.email!=="public"){if($_token$$.ip&&$_token$$.ip.split(":").pop()!== $ip_now$$.split(":").pop())return $fn$$("\u0110\u1ecba ch\u1ec9 IP n\u00e0y kh\u00f4ng \u0111\u01b0\u1ee3c ph\u00e9p s\u1eed d\u1ee5ng token n\u00e0y");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 \u0111\u00e3 h\u1ebft h\u1ea1n")}if($_token$$.service&&$options$$.check_service_token&&$_token$$.service==="facebook"&&!await checkFacebookToken($token$$))return Logger.error("This facebook access token is not valid", $_token$$),$fn$$("This facebook access token is not valid");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().then(function($user$$){$user$$?$resove$$($user$$):$reject$$(`User ${$_token$$.email} kh\u00f4ng t\u1ed3n t\u1ea1i`)}).catch($error$$=>{$reject$$($error$$)})})})})).then(async $user$$=>{$user$$.current_user= $user$$.email;$user$$.token=$token$$;if($user$$.status===!1)return $fn$$(`User ${$user$$.email} \u0111\u00e3 b\u1ecb kho\u00e1`);$user$$.admin=underscore.contains($usersAdmin$$,$user$$.email)||isSupperAdmin($user$$.email.toLowerCase())||$user$$.is_system_admin;if($_token$$.email!=="public"&&$_token$$._id){const $now$$=new Date;if(!$_token$$.last_access||$now$$-(new Date($_token$$.last_access)).getTime()>3E5)global.getModel("token").updateOne({_id:$_token$$._id},{last_access:$now$$}).catch($err$$=> Logger.error("Update last_access failed",$err$$)),$_token$$.last_access=$now$$}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$$&& Logger.error($error$$)})}}; User.socketSendTo=async($email$$,$event_name$$,$msg$$)=>{$email$$&&$event_name$$&&(global.socketContainer.socketIO?($email$$=$email$$.toLowerCase(),setImmediate(async()=>{try{Logger.info("[user] [socketSendTo] send msg ",{email:$email$$,event_name:$event_name$$,msg:$msg$$}),global.socketContainer.socketIO.to($email$$).emit($event_name$$,$msg$$),global.socketContainer.socketIO.to($email$$).emit("allevents",{event:$event_name$$,msg:$msg$$})}catch($e$$){Logger.error("[user] [socketSendTo] error send msg ",{email:$email$$, event_name:$event_name$$,msg:$msg$$},$e$$)}})):User.socketSendToOtherServer($email$$,$event_name$$,$msg$$,"socket"))};User.isOnline=async $email$$=>{try{return global.socketContainer.socketIO?[...(await global.socketContainer.socketIO.in($email$$).allSockets())].length>0?!0:!1:!1}catch($e$$){return Logger.error($e$$),!1}};const channel_update_system="updatesystem"; User.socketSendToOtherServer=async($data$jscomp$1_email$$,$event_name$$,$msg$$,$channel$$=channel_update_system)=>{global.clientRedis?($data$jscomp$1_email$$={event:$event_name$$,email:$data$jscomp$1_email$$,data:$msg$$,from_server_port:global.configs?.port},Logger.warn(`[user] [socketSendToOtherServer] [${global.configs?.port}] g\u1eedi s\u1ef1 ki\u1ec7n t\u1edbi k\u00eanh`,$channel$$,$data$jscomp$1_email$$),await global.clientRedis.publish($channel$$,JSON.stringify($data$jscomp$1_email$$))):Logger.warn(`[user] [socketSendToOtherServer] [${global.configs?.port}] kh\u00f4ng th\u1ec3 g\u1eedi s\u1ef1 ki\u1ec7n t\u1edbi k\u00eanh`, $channel$$,"do kh\u00f4ng c\u00f3 clientRedis tr\u00ean server")}; User.initClientSockets=()=>{setTimeout(()=>{const $subscriber$$=redis.createClient();$subscriber$$.on("error",$err$$=>{Logger.error(`[user] [initClientSockets] [${global.configs?.port}] Redis subscriber error:`,$err$$)});$subscriber$$.on("connect",()=>{$subscriber$$.subscribe(channel_update_system,($err$$,$count$$)=>{if($err$$)return Logger.error(`[user] [initClientSockets] [${global.configs?.port}] Failed to subscribe to channel '${channel_update_system}':`,$err$$);Logger.info(`[user] [initClientSockets] [${global.configs?.port}] \u0110\u00e3 subscribe th\u00e0nh c\u00f4ng v\u00e0o channel "${channel_update_system}". C\u00f3 ${$count$$} subscriber.`)}); $subscriber$$.subscribe("socket",($err$$,$count$$)=>{if($err$$)return Logger.error(`[user] [initClientSockets] [${global.configs?.port}] Failed to subscribe to channel 'socket':`,$err$$);Logger.info(`[user] [initClientSockets] [${global.configs?.port}] \u0110\u00e3 subscribe th\u00e0nh c\u00f4ng v\u00e0o channel "socket". C\u00f3 ${$count$$} subscriber.`)})});$subscriber$$.on("message",async($subscribedChannel$$,$msg$$)=>{try{if($msg$$=JSON.parse($msg$$),$msg$$?.from_server_port!=global.configs?.port){if($subscribedChannel$$=== channel_update_system&&$msg$$?.email==="system")if($msg$$.event=="listinfo_updated"&&($msg$$.data||{}).listinfo_id){let $obj$$=await global.getModel("listinfo").findOne({_id:($msg$$.data||{}).listinfo_id}).lean();$obj$$&&global.getModel("listinfo").createController(global.routerAPI,$obj$$)}else Logger.info(`[user] [initClientSockets] [${global.configs?.port}] don't handle msg from system`,$msg$$);$subscribedChannel$$==="socket"&&global.socketContainer.socketIO&&User.socketSendTo($msg$$.email,$msg$$.event, $msg$$.data)}}catch($e$$){Logger.error(`[user] [initClientSockets] [${global.configs?.port}]`,$e$$,$subscribedChannel$$,$msg$$)}})},1)}; User.initSocket=$server$$=>{setTimeout(()=>{Logger.info("[user] [initSocket] 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("join-flow",$flowInstanceId$$=>{$socket$$.join($flowInstanceId$$);Logger.info(`[user] [initSocket] Client ${$socket$$.id} joined flow ${$flowInstanceId$$}`)});$socket$$.on("login",async $msg$$=>{if($msg$$.token){var $_token$$=await Tokens.findOne({token:$msg$$.token}).lean();if($_token$$){$socket$$.auth=!0;$socket$$.join($_token$$.email);let $clientIO$$=await global.socketContainer.loadConnectionId();$clientIO$$[$socket$$.id]= {token:$msg$$.token,email:$_token$$.email};global.socketContainer.saveConnectionId($clientIO$$);$msg$$.id_app?global.alertNotification($_token$$.email,$msg$$.id_app):$_token$$.id_apps&&$_token$$.id_apps.length>0?$_token$$.id_apps.forEach($id_app$$=>{global.alertNotification($_token$$.email,$id_app$$)}):global.alertNotification($_token$$.email,$_token$$.only_id_app);global.alertMessage($_token$$.email,$msg$$.id_app);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$$)});$socket$$.on("answer",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"answer",$msg$$)});$socket$$.on("candidate",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"candidate",$msg$$)});$socket$$.on("leave",function($msg$$){$msg$$.from=$_token$$.email;User.socketSendTo($msg$$.to,"leave",$msg$$)})}else global.socketContainer.socketIO.to($socket$$.id).emit("login", {user:$msg$$.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$$=>$pwString$$.length>5&&/[A-Z]+/.test($pwString$$)&&/[a-z]+/.test($pwString$$)&&/[0-9]+/.test($pwString$$); User.teststrengthPin=$pin$$=>$pin$$.length===4&&/^-?\d+$/.test($pin$$); User.emitEvent=async function($email$$,$event$$,$_data$$,$push$$){onAfterCommit(async()=>{if($email$$){if(typeof $_data$$==="object"){var $data$$=Object.assign({},$_data$$);$data$$.__event=$event$$}else $data$$=$_data$$;if($data$$.body&&($data$$.body.indexOf("{")==0||$data$$.body.indexOf("[")==0))try{var $file_obj_send$$=JSON.parse($data$$.body);$file_obj_send$$.data&&($file_obj_send$$.data.indexOf("data:image")>=0?$data$$.body="Image":$data$$.body="File")}catch($e$$){Logger.error("Kh\u00f4ng th\u1ec3 parse data", $data$$.body,$e$$)}if($data$$.email_content&&!$data$$.not_send_email&&$data$$.title){var $encrypted_unsub_link_unsub_unsub$$;$data$$.allow_unsubcribe!=0&&$data$$.id_app&&($encrypted_unsub_link_unsub_unsub$$=await global.getModel("subscribe").findOne({id_app:$data$$.id_app,email:$email$$,unsubcribe:!0}).lean());$encrypted_unsub_link_unsub_unsub$$||($file_obj_send$$={...$data$$},$file_obj_send$$.id_app&&($encrypted_unsub_link_unsub_unsub$$=encrypt({id_app:$data$$.id_app,email:$email$$}),$encrypted_unsub_link_unsub_unsub$$= `${configs.api_url}/public/unsubscribe/${$encrypted_unsub_link_unsub_unsub$$}`,$data$$.allow_unsubcribe!=0&&($file_obj_send$$.email_content=`${$file_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="${$encrypted_unsub_link_unsub_unsub$$}">vui l\u00f2ng b\u1ea5m v\u00e0o \u0111\u00e2y</a>.</div> </p> `)),User.sendEmailTo($email$$.toLowerCase(),$file_obj_send$$))}delete $data$$.email_content;delete $data$$.rq_approve;delete $data$$.app_info;$data$$.body&&$data$$.body.length>512&&($data$$.body=$data$$.body.substring(0,512));$data$$.title&&$data$$.title.length>512&&($data$$.title=$data$$.title.substring(0,512));User.socketSendTo($email$$.toLowerCase(),$event$$,$data$$);setImmediate(()=>{if(($data$$.title||$data$$.body)&&$push$$!=0)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}},()=>{})}catch($e$$){Logger.error($e$$)}})}})};module.exports=User;