node-edge
Version:
node-edge is a tcp communication library for edge computing using local area networking.
7 lines • 68 kB
JavaScript
/**!
* node-edge.js
* v1.5.9
*
* Copyright(c) 2022 Ed Alegrid
*/
"use strict";const fs=require("node:fs"),os=require("node:os"),net=require("node:net"),{Buffer:Buffer}=require("node:buffer"),dgram=require("node:dgram"),{execFileSync:execFileSync}=require("child_process"),{randomBytes:randomBytes,createECDH:createECDH,pbkdf2Sync:pbkdf2Sync,hkdfSync:hkdfSync,scryptSync:scryptSync,createCipheriv:createCipheriv,createDecipheriv:createDecipheriv,createHmac:createHmac,createHash:createHash}=require("node:crypto"),EventEmitter=require("node:events");class MyEmitter extends EventEmitter{}const edgeEmitter=new MyEmitter,processArgs=process.argv.slice(2);var edt=!1;"-edge-test"===processArgs[0]&&(edt=!0);function config(e){e.debug&&(edt=!0)}const dm=(()=>{let e="m2mConfig/neLog",t=" Date \t\t\t\t\t\t\t\t\t\t\t\tEvent";function r(r,i){fs.mkdir("m2mConfig/",(n=>{try{if(n)throw n;r?fs.writeFileSync(r,t):fs.writeFileSync(e,t);i&&i()}catch(n){"EEXIST"===n.code||dm.logEvent("Edge initLog error:",n.message)}}))}r();function i(e,i,n,o,s,c,l,a,d,p){try{s||(s="");c||(c="");l||(l="");a||(a="");d||(d="");p||(p="");!function(e,i,n,o,s,c,l,a,d,p){fs.open(e,"r",((r,i)=>{r&&"ENOENT"===r.code&&fs.writeFileSync(e,t);try{fs.appendFileSync(e,"\n"+n+" "+o+" "+s+" "+c+" "+l+" "+a+" "+d+" "+p)}catch(r){throw r}}));fs.stat(e,((u,g)=>{u&&"ENOENT"===u.code&&r();if(g&&g.size>i)try{fs.writeFileSync(e,t);fs.appendFileSync(e,"\n"+n+" "+o+" "+s+" "+c+" "+l+" "+a+" "+d+" "+p)}catch(u){throw u}}))}(e,i,n,o,s,c,l,a,d,p)}catch(e){throw e}}return{logData:function(e,t,r,n,o,s,c,l){i(e,35e3,new Date,t,r,n,o,s,c,l)},logEvent:function(t,r,n,o,s,c,l){let a=new Date;i(e,35e3,a,t,r,n,o,s,c,l)},eventLogHeader:t}})();function removeDuplicateInArray(e){return[...new Set(e)]}function getRandomIntInclusive(e,t){e=Math.ceil(e);t=Math.floor(t);return Math.floor(Math.random()*(t-e+1)+e)}function validateData(e){try{"object"==typeof e?e=Buffer.isBuffer(e)?e.toString():JSON.stringify([e]):"number"==typeof e&&(e=e.toString());if("string"!=typeof e){console.log("\nEdge validateData error: invalid input data",e+"\n");throw new Error("invalid input data - not a string")}return e}catch(e){dm.logEvent("Edge validateData error:",e.message)}}function encodeData(e,t,r){try{return"object"==typeof e?r?Buffer.from(JSON.stringify(e)).toString(t):"obj"+Buffer.from(JSON.stringify(e)).toString(t):r?Buffer.from(""+e).toString(t):"str"+Buffer.from(""+e).toString(t)}catch(e){dm.logEvent("Edge encodeData error:",e.message);throw"Edge encodeData error: "+e.message}}function decodeData(e,t,r){r||(e=e.slice(3));if(!Buffer.isBuffer(Buffer.from(e))){dm.logEvent("Edge decodeData error: data is not buffer");throw"Edge decodeData error: data is not a buffer"}e=e.toString();try{return JSON.parse(Buffer.from(e,t).toString())}catch(r){return Buffer.from(e,t).toString()}}const uni_enc="base64",uni_dig="sha256",uni_ecdh_curve="prime256v1",uni_ivlen=16,uni_keylen=16,uni_algo="aes-128-gcm";function edgeEncrypt(e,t,r,i,n){if(!e||!t)return;if(t.ciphertext)return;const o=r;let s=null,c=null;try{const r=randomBytes(i),l=Buffer.from(r.toString("utf8"),"hex"),a=createHmac("sha256",e);a.update(t);const d=a.digest("hex"),p=createCipheriv(o,e,r,{authTagLength:16});p.setAAD(l,{plaintextLength:Buffer.byteLength(t)});s=p.update(t,"utf8","hex");p.final();c=p.getAuthTag();let u={ciphertext:s,iv:r.toString("hex"),tag:c.toString("hex"),sign:d};return n?n(u):u}catch(e){dm.logEvent("Edge edgeEncrypt error:",e.message)}}function edgeDecrypt(e,t,r,i){if(!e||!t)return;const n=r;try{const r=t,o=r.ciphertext,s=Buffer.from(r.iv,"hex"),c=Buffer.from(r.tag,"hex"),l=Buffer.from(s.toString(),"hex"),a=createDecipheriv(n,e,s,{authTagLength:16});a.setAuthTag(c);a.setAAD(l,{plaintextLength:o.length});const d=a.update(o,"hex","utf8");a.final();const p=createHmac("sha256",e);p.update(d);const u=p.digest("hex");if(r.sign!==u)throw"invalid hmac";return i?i(d):d}catch(e){dm.logEvent("Edge edgeDecrypt error:",e.message);return"Edge edgeDecrypt invalid data: "+e.message}}function getRestartStatus(){return!("start"!==process.env.npm_lifecycle_event&&!process.env.npm_package_nodemonConfig_restartable)}function restartEp(){if(getRestartStatus()){dm.logEvent("Edge endpoint restarted");setTimeout((()=>fs.writeFileSync("node_modules/m2m/mon","enable-auto-restart")),100)}}function setSecureEdge(){return JSON.parse(Buffer.from(fs.readFileSync("m2mConfig/scfg/sconfig","utf8"),"base64").toString())}var edgeId=null;function EdgeInfo(){let e={};try{e.nodeEdgeV=require("../package.json").version;"linux"===os.platform()?e.npmv=execFileSync("npm",["-v"]):"win32"===os.platform()?e.npmv=execFileSync("npm -v",{shell:!0}):e.npmv=execFileSync("npm",["-v"]);e.isContainer=function(){return!(process.pid.toString().length>3)}}catch(e){dm.logEvent("Edge system info error:",e.message)}return e}const edgeInfo=EdgeInfo();var bPath="m2mConfig/sec/",ctkPath=bPath+"client/actn",stkPath=bPath+"server/actn",encodedAccessTkn=null,systemInfo=null,EdgeGlobalServer=null;function removeLinebreaks(e){try{return e.replace(/[\r\n]+/gm,"")}catch(e){dm.logEvent("Edge removeLinebreaks error:",e.message)}}function getFileAccTkn(e){let t=null,r=null,i=null;try{"server"===e?t=stkPath:"client"===e&&(t=ctkPath);r=fs.readFileSync(t,"utf8");r=removeLinebreaks(r)}catch(e){"ENOENT"===e.code||dm.logEvent("Edge getFileAccTkn error:",e.message)}if(!r)return i;try{return JSON.parse(Buffer.from(r,"hex").toString())}catch(e){i=Buffer.from(r).toString("hex");dm.logEvent("Edge getFileAccTkn JSON.parse(Buffer.from(rTk) error:",e.message);return null}}var accessEdgepoint=null;function accessEdgeEndpoint(){function e(e){let t=null;try{t=Buffer.from(JSON.stringify(e.payload)).toString("hex");e.tkPath?fs.writeFileSync(e.tkPath,t):fs.writeFileSync(stkPath,t)}catch(e){if("ENOENT"!==e.code){dm.logEvent("Edge setServerAccessTkn fs.mkdirSync error:",e.message);throw e}fs.mkdirSync(bPath+"/server");fs.writeFileSync(stkPath,t)}try{let t=getFileAccTkn("server");e.fileTkn=t.tkn;!function(e){try{const t=decodeData(encodedAccessTkn,"hex");t.sfileTkn=e;encodedAccessTkn=encodeData(t,"hex");e.tkn?serverTopicStore[0].fileTkn=e.tkn:serverTopicStore[0].fileTkn=null}catch(e){dm.logEvent("Edge serverTknUpdate error:",e.message);throw e}}(t)}catch(e){dm.logEvent("Edge setServerAccessTkn getFileAccTkn error:",e.message);throw e}}function t(e){let t=!1,r=null,i=null,n=null,o=null;try{r=e.payload;o=Buffer.from(JSON.stringify([r])).toString("hex");i=fs.readFileSync(ctkPath,"utf8")}catch(t){if("ENOENT"!==t.code){dm.logEvent("Edge setClientAccessTkn - tk/firstTk/rTk error:",t.message);throw t}fs.mkdirSync(e.dirPath+"/client");fs.writeFileSync(ctkPath,o);i=fs.readFileSync(ctkPath,"utf8")}try{n=JSON.parse(Buffer.from(i,"hex").toString());if(!n){r=e.payload;o=Buffer.from(JSON.stringify([r])).toString("hex");n=fs.writeFileSync(ctkPath,o)}if(Array.isArray(n)){n.forEach((e=>{if(e.port===r.port&&e.ip===r.ip){e.tkn=r.tkn;t=!0}else if(e.path===r.path){e.tkn=r.tkn;t=!0}}));t||n.push(r)}}catch(e){dm.logEvent("Edge setClientAccessTkn - JSON.parse error:",e.message)}finally{try{var s=Buffer.from(JSON.stringify(n)).toString("hex");e.tkPath?fs.writeFileSync(e.tkPath,s):fs.writeFileSync(ctkPath,s);let t=getFileAccTkn("client");e.fileTkn=r.tkn;!function(e,t){try{const r=decodeData(encodedAccessTkn,"hex");r.cfileTkn=t;encodedAccessTkn=encodeData(r,"hex");clientTopicStore.forEach((t=>{(t.port===e.port&&t.host===e.ip||t.path===e.path)&&(t.fileTkn=e.tkn)}))}catch(e){dm.logEvent("Edge clientTknUpdate error:",e.message);throw e}}(r,t)}catch(e){dm.logEvent("Edge setClientAccessTkn - Buffer.from/fs.writeFileSync/others error:",e.message)}}}function r(r){r.removeServerFileAccessTkn?e(r):r.removeClientFileAccessTkn&&t(r)}return{accessEdge:function(i,n){"server"===i.dst?i.server=!0:"client"===i.dst?i.client=!0:"user"!==i.dst&&"edge"!==i.dst||(i.user=!0);if("v-ep"===i._pid)return function(e){if(!encodedAccessTkn)try{let t={},r=createHash("sha256"),i=createHash("sha256"),n=randomBytes(8).toString(),o=randomBytes(8).toString();if(e&&"object"==typeof e&&e.id){e.systemInfo&&(systemInfo=e.systemInfo);if(e.aid){r.update(e.aid);t.resin=n+r.digest("utf8")+o}edgeId=e.id;if(e.did){i.update(e.did);t.resbin=i.digest("utf8")}systemInfo&&systemInfo.ip&&(t.ip=systemInfo.ip);t.sfileTkn=getFileAccTkn("server");t.cfileTkn=getFileAccTkn("client");encodedAccessTkn=encodeData(t,"hex");return!0}}catch(e){console.log("Edge authenticateEdge error:",e.message);dm.logEvent("Edge authenticateEdge error:",e.message)}}(i);if((i.setSecureEdge||i.setInsecureEdge)&&i.edge)return restartEpClientServer(i);if(i.edgeResources)i.result=function(e){let t={};t.systemInfo=systemInfo;t.clientTopicStore=clientTopicStore;t.serverTopicStore=serverTopicStore;return t}();else if(i.setServerFileAccessTkn)i.result=e(i);else if(i.setClientFileAccessTkn)i.result=t(i);else if(i.removeServerFileAccessTkn)i.result=r(i);else if(i.removeClientFileAccessTkn)i.result=r(i);else if(i.ers||i.restart||"orchestrate-ep-restart"===i._pid){if(EdgeGlobalServer){if("udp4"===EdgeGlobalServer.type||"udp6"===EdgeGlobalServer.type)return;try{EdgeGlobalServer.close()}catch(e){dm.logEvent("Edge accessEdge error:",e.message)}}return}setTimeout((()=>n.emit("ws-emit-send",i)),1e3)}}}let timeout=null,delay=12e4;function accessNode(){clearTimeout(timeout);timeout=setTimeout((()=>{accessEdgepoint=null}),delay);accessEdgepoint||(accessEdgepoint=accessEdgeEndpoint());return accessEdgepoint.accessEdge}var clientMethod={},epName="node-edge-",waitContainer=[],clientTopicStore=[],oneClientInstanceStore=[],restartDataStore=[],clientPublishDataStore=[];try{clientMethod.kex=epName+"pk::ex";clientMethod.rdy=epName+"server:open-ready";clientMethod.sub=epName+"subscribe";clientMethod.unsub=epName+"unsubscribe";clientMethod.read=epName+"read";clientMethod.write=epName+"write";clientMethod.get=epName+"get";clientMethod.post=epName+"post";clientMethod.getResources=epName+"get-resources";clientMethod.getSubscribers=epName+"get-subscribers";clientMethod.clientExit=epName+"client-exit";clientMethod.serverExit=epName+"server-exit";clientMethod.hrn=randomBytes(8).toString();clientMethod.trn=randomBytes(8).toString();clientMethod.rbl=32}catch(e){dm.logEvent("Edge clientMethod - add properties error:",e.message)}var clientInsecureEnc="base64";function restart(e,t,r){getEndpointAddress(e);t.method===clientMethod.read?e.read(t.arg,t.cb):t.method===clientMethod.write?e.write(t.arg,t.cb):t.method===clientMethod.sub&&e.subscribe(t.arg,t.cb);!r||"udp4"!==e.option.type&&"udp6"!==e.option.type||restartDataStore.forEach((r=>{r.ciid!==e.ciid&&r.ciid!==t.ciid||(r.read?r.read(r.arg,r.cb):r.write?r.write(r.arg,r.cb):r.subscribe&&r.subscribe(r.arg,r.cb))}))}function restartClient(e,t,r,i){let n=null;try{if(e.wait){let n=getEndpointAddress(e);edgeEmitter.emit("client-error"+t.ciid,e.option.type+" server "+n+" is down")||console.log(e.option.type,"edge client - server",n,"is down. Waiting to connect when the server is up ...");if(r&&(t.topic===clientMethod.rdy||t.topic===clientMethod.kex)){dm.logEvent(e.option.type,n,"Edge client on(close):",""+r);edgeEmitter.emit("client-ready"+t.ciid,!1)}if(i&&(t.topic===clientMethod.rdy||t.topic===clientMethod.kex)){dm.logEvent(e.option.type,n,"Edge client on(error):",i.message);edgeEmitter.emit("client-ready"+t.ciid,!1);edgeEmitter.emit("client-error"+t.ciid,i.message)||console.log(e.option.type,n,"Edge client on(error):",i.message)}e.wait=!1;e.connectError=!0}let o=!1;waitContainer.forEach((e=>{e.topic===t.topic&&e.ciid===t.ciid&&(o=!0)}));if(!1===o){let r=setInterval((()=>{restart(e,t,i)}),1e4);n={topic:t.topic,mid:t.mid,method:t.method,ciid:t.ciid,interval:r,type:e.option.type};waitContainer.push(n)}}catch(e){dm.logEvent("Edge restartClient error:",e.message)}}function decryptClientRcvdData(e,t,r){let i=edgeDecrypt(e.sk,t,e.option.algo);try{if("string"!=typeof i)throw"Edge decryptClientRcvdData invalid plaintext";let e=JSON.parse(i);if(Array.isArray(e)){if(i.includes("Buffer")){t=JSON.parse(JSON.stringify(e[0]),((e,t)=>t&&"Buffer"===t.type?Buffer.from(t):t));throw"Edge decryptClientRcvdData buffer as array object"}t=e[0]}else if("boolean"==typeof e)t=Buffer.from(i);else if("object"==typeof e)t=Buffer.from(JSON.stringify(e));else{if("number"!=typeof e)throw"Edge decryptClientRcvdData invalid secure rcvd data type";t=Buffer.from(i)}}catch(r){if("invalid plaintext"===r){dm.logEvent("Edge decryptClientRcvdData - invalid plaintext error:",r.message);return}if("invalid secure rcvd data type"===r){dm.logEvent("Edge decryptClientRcvdData - invalid secure rcvd data type error:",r.message);return}let i=edgeDecrypt(e.sk,t,e.option.algo);if("string"!=typeof i)throw"Edge decryptClientRcvdData invalid secure string data";t=Buffer.from(i);dm.logEvent("Edge decryptClientRcvdData JSON.parse(rcvdPlaintext) - encrypted data is a string:",r.message)}finally{return t}}function setAccessTkn(e,t){try{const r=decodeData(encodedAccessTkn,"hex");t.resin=r.resin;if("invalid"===e.vtk)return!1;if("std"===e.vtk){t.resin=r.resin;t.vtk=e.vtk}else{e.option.tkn?t.resin=e.option.tkn:e.option.accessTkn?t.resin=e.option.accessTkn:e.fileTkn&&(t.resin=e.fileTkn);t.vtk=e.vtk}return!0}catch(e){dm.logEvent("Edge client setAccessTkn error:",e.message)}}function captureClientTopic(e,t){let r=!0;t.forEach((t=>{e===t&&(r=!1)}));r&&t.push(e)}function getEndpointAddress(e){let t=null;t=e.option.port?e.option.ip+":"+e.option.port:e.option.path;return t}function setClientPublishDataStore(e){let t=!0;clearInterval(e.clientPubInterval);clientPublishDataStore.forEach(((r,i)=>{e.topic===r.topic&&e.ciid===r.ciid&&e.mid===r.mid&&(t=!1)}));t&&clientPublishDataStore.push(e)}function startStopClientPublishDataPolling(e,t){clientPublishDataStore.forEach(((r,i)=>{e===r.ciid&&(t?clearInterval(r.clientPubInterval):r.clientPubInterval=setInterval(r.publishCallback,r.pollInterval))}))}function clientServerExitProcess(e,t,r,i,n){try{let n=getEndpointAddress(e);dm.logEvent(e.option.type,n,"server is down "+clientMethod.serverExit,i.method);if("tcp"===e.option.type||"ipc"===e.option.type)t.end();else try{t.close()}catch(t){dm.logEvent(e.option.type,n,i.method,i.topic,"Edge clientSocket.close error:",t.message)}setTimeout((()=>{restartDataStore.forEach((t=>{if(r.uid===t.ciid||r.ciid===t.ciid){dm.logEvent(e.option.type,n,"*start polling for restart (",t.method,t.topic+" ) once server is up");restartClient(e,t,"true",null);startStopClientPublishDataPolling(t.ciid,"stop")}}))}),e.delay)}catch(t){dm.logEvent(e.option.type,ep,clientMethod.serverExit+" error:",t.message)}}function unsubRestartDataStoreTopic(e,t,r){let i=getEndpointAddress(t);restartDataStore.forEach(((r,n)=>{if(e.ciid===r.ciid&&e.topic===r.topic&&e.mid===r.mid)try{restartDataStore.splice(n,1);dm.logEvent(t.option.type,i,"Edge client unsubRestartDataStoreTopic",e.topic,"- success")}catch(r){dm.logEvent(t.option.type,i,"Edge client unsubRestartDataStoreTopic",e.topic,"destroy error:",r.message);throw"unsubRestartDataStoreTopic destroy error"}}))}function clientProcessRcvdData(e,t,r,i,n,o,s,c,l){restartClearInterval(i,n,o);let a=getEndpointAddress(i);if(!Buffer.isBuffer(e)){dm.logEvent("clientConnect clientSocket.on(data) - edge.client rcvd data is not a buffer:",""+e);throw"Edge invalid edge.client rcvd data as buffer - not a buffer"}if("object"!=typeof e){dm.logEvent("clientConnect clientSocket.on(data) - edge.client rcvd data is not an object:",""+e);throw"Edge invalid edge.client rcvd object data type - not an object"}let d=null;try{d=JSON.parse(e)}catch(e){}finally{if(d&&"object"==typeof d&&d.topic===clientMethod.serverExit){"tcp"===i.option.type||i.option.type;dm.logEvent(i.option.type,a,"Edge client rcvd server exit data",d.topic);clientServerExitProcess(i,r,d,n,o);return}if(n.topic===clientMethod.kex){let t=decodeData(e,"base64");if("invalid"===t.vtk){edgeEmitter.emit("client-ready"+n.ciid,!1);let t="Edge client invalid secure server access "+a;edgeEmitter.emit("client-error"+n.ciid,t)||console.log(e.error);"tcp"!==i.option.type&&"ipc"!==i.option.type||r.end();return}if(t&&n.ciid===t.ciid){edgeEmitter.emit("client-ready"+n.ciid,!0);startStopClientPublishDataPolling(n.ciid)}}else if(n.topic===clientMethod.rdy){let t=decodeData(e,"base64");if("invalid"===t.vtk){edgeEmitter.emit("client-ready"+n.ciid,!1);let t="Edge client invalid insecure server access "+a;edgeEmitter.emit("client-error"+n.ciid,t)||console.log(e.error);startStopClientPublishDataPolling(n.ciid,"stop");"tcp"!==i.option.type&&"ipc"!==i.option.type||r.end()}else if(t.error&&"primary-insecure-invalid-connection"===t.error){edgeEmitter.emit("client-ready"+n.ciid,!1);let e="Edge client invalid insecure communication request!";edgeEmitter.emit("client-error"+n.ciid,e)||console.log(e);startStopClientPublishDataPolling(n.ciid,"stop");"tcp"!==i.option.type&&"ipc"!==i.option.type||r.end()}else if(t&&n.ciid===t.ciid){edgeEmitter.emit("client-ready"+n.ciid,!0);startStopClientPublishDataPolling(n.ciid)}}else if(n.topic!==clientMethod.kex&&n.topic!==clientMethod.rdy&&n.method!==clientMethod.sub)"tcp"===i.option.type||"ipc"===i.option.type?"publish-type-pattern"===n.type||setImmediate((()=>{r.end()})):o&&o.restart?dm.logEvent(i.option.type,a,"Edge client - *restart option "+n.method,n.topic):"publish-type-pattern"===n.type||setImmediate((()=>{r.close()}));else if(n.method===clientMethod.unsub){let t=e.toString();dm.logEvent(i.option.type,a,"Edge client "+n.method,n.topic,t,JSON.stringify(e));"true"===t&&unsubRestartDataStoreTopic(n,i)}if(d&&d.ciphertext)e=decryptClientRcvdData(i,d);else if(d&&d.data){let t=decodeData(d.data,clientInsecureEnc,!0);e=Array.isArray(t)?t[0]:t}else Array.isArray(d)&&(e=d[0]);if(e.error){if("secondary-client-invalid-access"===e.error||"primary-insecure-invalid-connection"===e.error)return;if(edgeEmitter.emit("client-error"+n.ciid,e))return;s?s(e):c&&c(e);return}s?setImmediate(s,e):c&&setImmediate(c,e)}}function restartClearInterval(e,t,r){let i=getEndpointAddress(e);waitContainer.forEach(((r,n)=>{if(r.method===t.method&&r.topic===t.topic&&r.ciid===t.ciid)try{clearInterval(r.interval);e.wait=!0;e.connectError=!1;waitContainer.splice(n,1);dm.logEvent(e.option.type,i+" Edge client restart clearInterval",r.method,r.topic)}catch(t){dm.logEvent(r.method+" "+r.topic,e.option.type,i+" waitContainer restart clearInterval error:",t.message)}}))}function clientCloseErrorEventProcess(e,t,r,i,n){try{let o=getEndpointAddress(e);if(!r||r&&!r.restart)return;if("invalid"===e.vtk){dm.logEvent(e.option.type,o,"Edge client clientSocket.on(close) clientInstance.vtk === invalid (debug)",t.topic);return}if(i&&!n);else if(!1===i&&!n&&("tcp"===e.option.type||"ipc"===e.option.type))return;e.option.restart&&r.restart&&setTimeout((()=>{n?restartClient(e,r,null,n):restartClient(e,r,!0,null)}),e.delay)}catch(t){dm.logEvent(e.option.type,ep,"Edge client clientCloseErrorEventProces error:",t.message)}}function clientConnect(t,r,i,n,o,s,c){let l=getEndpointAddress(r);"tcp"===r.option.type||"ipc"===r.option.type?t.on("data",(e=>{clientProcessRcvdData(e,null,t,r,i,n,o,s,c)})):t.on("message",((e,l)=>{clientProcessRcvdData(e,l,t,r,i,n,o,s,c)}));t.on("error",(e=>{clientCloseErrorEventProcess(r,i,n,null,e)}));t.on("close",(e=>{clientCloseErrorEventProcess(r,i,n,e,null)}));try{if(i.topic===clientMethod.kex)"tcp"===r.option.type||"ipc"===r.option.type?t.write(JSON.stringify(i)):t.send(JSON.stringify(i),r.option.port,r.option.ip);else{function a(){if(!r.sk)return;let n=edgeEncrypt(r.sk,JSON.stringify(i),r.option.algo,r.option.algo_ivlen);n.salt=r.salt;"tcp"===r.option.type||"ipc"===r.option.type?t.write(JSON.stringify(n)):"udp4"!==r.option.type&&"udp6"!==r.option.type||t.send(JSON.stringify(n),r.option.port,r.option.ip,(t=>{if(t){edgeEmitter.emit("client-error"+i.ciid,t);dm.logEvent(r.option.type,l,"Edge client clientConnect (secure) clientSocket.send error:",e.message)}}))}if(r.option.secure)setAccessTkn(r,i)&&(r.sk?a():setTimeout((()=>{a()}),200));else{function d(){let n=encodeData(i,clientInsecureEnc,!0);"tcp"===r.option.type||"ipc"===r.option.type?t.write(JSON.stringify({data:n,enc:!0})):"udp4"!==r.option.type&&"udp6"!==r.option.type||t.send(JSON.stringify({data:n,enc:!0}),r.option.port,r.option.ip,(t=>{if(t){edgeEmitter.emit("client-error"+i.ciid,t);dm.logEvent(r.option.type,l,"Edge client clientConnect (secure) clientSocket.send error:",e.message)}}))}const p=decodeData(encodedAccessTkn,"hex");i.resin=p.resin;i.ak=randomBytes(32).toString();i.topic===clientMethod.rdy?"tcp"===r.option.type||"ipc"===r.option.type?t.write(JSON.stringify(i)):"udp4"!==r.option.type&&"udp6"!==r.option.type||t.send(JSON.stringify(i),r.option.port,r.option.ip):d()}}}catch(u){dm.logEvent("Edge clientConnect - prepare and send the client payload error:",u.message)}setImmediate((()=>{try{!0===r.wait&&(i.method===clientMethod.sub?captureClientTopic(i.topic,r.subTopicStore):i.method===clientMethod.read&&i.topic!==clientMethod.rdy?captureClientTopic(i.topic,r.readTopicStore):i.method===clientMethod.write&&i.topic!==clientMethod.rdy&&i.topic!==clientMethod.kex?"client-publish"===i.type?captureClientTopic(i.topic,r.pubTopicStore):captureClientTopic(i.topic,r.writeTopicStore):i.method===clientMethod.get&&i.topic!==clientMethod.rdy?captureClientTopic(i.topic,r.httpGetTopicStore):i.method===clientMethod.post&&i.topic!==clientMethod.rdy&&captureClientTopic(i.topic,r.httpPostTopicStore))}catch(e){dm.logEvent("Edge clientConnect - capture request topic error:",e.message)}}))}function captureRestartTopic(e,t){let r=!0;restartDataStore.forEach(((t,i)=>{e.ciid===t.ciid&&e.topic===t.topic&&e.method===t.method&&(r=!1)}));r&&restartDataStore.push(t)}var cp,ch,cscb=null;function connect(e,t,r){if(!encodedAccessTkn){dm.logEvent("Edge.client invalid access");throw"Edge.client - invalid access"}cp=e;ch=t;cscb=r;let i=setSecureEdge(),n={},o={},s={},c=[],l=null;const a=randomBytes(clientMethod.rbl).toString(),d=getRandomIntInclusive(2e3,5e3);if("string"==typeof e){l=e;o={path:e};o.type="ipc";1==arguments.length||2==arguments.length&&"function"==typeof t&&(r=t)}else if("number"==typeof e)if(1==arguments.length)o={port:e,host:"127.0.0.1"};else if(2==arguments.length&&"string"==typeof t)o={port:e,host:t};else if(2==arguments.length&&"function"==typeof t){o={port:e,host:"127.0.0.1"};r=t}else 3==arguments.length&&"string"==typeof t&&"function"==typeof r&&(o={port:e,host:t});else if("object"==typeof e){2==arguments.length&&"function"==typeof t&&(r=t);o=e;if(o.path){o.type="ipc";l=e.path}else{o.ip||(o.ip="127.0.0.1");o.ip&&(o.host=o.ip)}if("aes-128-gcm"===o.algo){o.algo_keylen=16;o.algo_ivlen=16}else if("aes-192-gcm"===o.algo){o.algo_keylen=24;o.algo_ivlen=16}else if("aes-256-gcm"===o.algo){o.algo_keylen=32;o.algo_ivlen=16}else if("chacha20-poly1305"===o.algo){o.algo_keylen=32;o.algo_ivlen=12}}!o.ip&&o.host&&(o.ip=o.host);void 0===o.secure&&(o.secure=!0);void 0===o.restart&&(o.restart=!0);if(!o.algo&&o.secure){o.algo=uni_algo;o.algo_keylen=16;o.algo_ivlen=16}void 0===o.type&&(o.type="tcp");o.type;"tcp"===o.type||o.host&&(net.isIPv6(o.host)?o.type="udp6":o.type="udp4");if(i&&i.edge.secure){o.secure=!0;if("algo1"===i.edge.algo){o.algo="aes-128-gcm";o.algo_keylen=16;o.algo_ivlen=16}else if("algo2"===i.edge.algo){o.algo="aes-192-gcm";o.algo_keylen=24;o.algo_ivlen=16}else if("algo3"===i.edge.algo){o.algo="aes-256-gcm";o.algo_keylen=32;o.algo_ivlen=16}else if("algo4"===i.edge.algo){o.algo="chacha20-poly1305";o.algo_keylen=32;o.algo_ivlen=12}}s.vtk="std";s.wait=!0;s.fileTkn=null;s.delay=d;s.secureAccess=null;s.ciid=a;s.connectError=!1;s.matchClientInstance=!1;s.option=o;s.subTopicStore=[];s.pubTopicStore=[];s.readTopicStore=[];s.writeTopicStore=[];s.httpGetTopicStore=[];s.httpPostTopicStore=[];s.read=v;s.write=m;s.subscribe=f;l&&"string"==typeof l?oneClientInstanceStore.forEach((e=>{e.path===s.option.path&&(s.matchClientInstance=!0)})):oneClientInstanceStore.forEach((e=>{e.port===s.option.port&&e.host===s.option.host&&(s.matchClientInstance=!0)}));try{!1===s.matchClientInstance&&oneClientInstanceStore.push(s.option);!function(){try{const e={},t=decodeData(encodedAccessTkn,"hex");s.option.accessTkn?e.optionTkn=s.option.accessTkn:e.optionTkn=null;t.cfileTkn&&Array.isArray(t.cfileTkn)&&t.cfileTkn.forEach((t=>{if(t.ip===s.option.host&&t.port===s.option.port){e.fileTkn=t.tkn;s.fileTkn=t.tkn}else if(t.path===s.option.path){e.fileTkn=t.tkn;s.fileTkn=t.tkn}}));return e}catch(e){dm.logEvent("Edge client connect - getClientInstanceTknSources error:",e.message)}}();let e={};if(!1===s.matchClientInstance){e={ciid:a,secure:s.option.secure,secureAccess:s.vtk,subscribe:s.subTopicStore,read:s.readTopicStore,write:s.writeTopicStore,httpGet:s.httpGetTopicStore,httpPost:s.httpPostTopicStore,publish:s.pubTopicStore,optionTkn:s.option.accessTkn,fileTkn:s.fileTkn,vtk:s.vtk,container:edgeInfo.isContainer(),nodeEdgeV:edgeInfo.nodeEdgeV,npmv:edgeInfo.npmv.toString(),type:s.option.type};if(s.option.host&&s.option.port){e.address={port:s.option.port,host:s.option.host,type:s.option.type};e.host=s.option.host;e.port=s.option.port}else if(s.option.path){e.address={path:s.option.path,type:s.option.type};e.path=l}setImmediate((()=>{clientTopicStore.push(e)}))}}catch(e){dm.logEvent("Edge client connect - capture clientTopicInfo into clientTopicStore[] error:",e.message)}function p(e,t){const r=[],i=[];if(t&&!t.startsWith("/"))return e;if(t&&t.includes("?"))throw t+" - Edge client getSubTopic invalid topic attribute";for(let e=0;e<t.length;e++)("/"===t[e]||"#"===t[e])&&r.push(e);r.forEach(((e,n)=>{if(0===e&&r[n+1]){let e=t.slice(r[n],r[n+1]);i.push(e)}else if(0!==e&&r[n]&&r[n+1]){let e=t.slice(r[n],r[n+1]);i.push(e)}else{let e=t.slice(r[n],t.length);i.push(e)}}));let n=i[0].length,o=t.slice(n);e.topicKeys=i;e.baseTopic=i[0];e.rootTopic=i[0];e.subTopic=o;return e}function u(e,t){let r=null;const i=[],n=[],o={};if(!t)return;if(!t.startsWith("/"))throw new Error(new Error("path: "+t+" - invalid http path, it must begin with a slash /"),null,null);let s=t.indexOf("?",1);-1!==s&&(r=t.substring(s+1,t.length));new URLSearchParams(r).forEach(((e,t)=>{o[t]=e}));let c=t.indexOf("?");-1!==c&&(t=t.slice(0,c));for(let e=0;e<t.length;e++)"/"===t[e]&&i.push(e);i.forEach(((e,r)=>{try{if(0==e&&i[r+1]){let e=t.slice(i[r],i[r+1]);n.push(e)}else if(0!==e&&i[r]&&i[r+1]){let e=t.slice(i[r],i[r+1]);n.push(e)}else{let e=t.slice(i[r],t.length);n.push(e)}}catch(e){dm.logEvent("Edge client getSubTopic urlRoutesIndex.forEach error:",e.message)}}));e.urlPathKeys=n;e.baseUrl=n[0];e.query=o;return e}function g(e){try{let t=createHash("sha256"),r=getEndpointAddress(e),i=edgeId+e.option.type+r;t.update(i);return t.digest("utf8")}catch(e){console.log("Edge client setClientEdgeId error:",e.message)}}function f(e,t){if(!e)throw"Edge client subscriber error: missing topic name";if(!t)throw"Edge client subscriber error: missing callback function";let r=null,i=null,n=!0;try{if(!0===s.matchClientInstance)return;let l=g(s);i=randomBytes(clientMethod.rbl).toString();"object"==typeof e?r=e.topic:"string"==typeof e&&(r=e);c.forEach((e=>{if(e.topic===r&&e.ciid===a&&e.method===clientMethod.sub){i=e.mid;n=!1}}));let d={method:clientMethod.sub,topic:r,mid:i,ciid:a,date:Date.now(),epId:l,subscribe:s.subscribe,sub:!0},p={};if("object"==typeof e&&(e.interval||e.settable)){d.settable=!0;if(Number.isInteger(e.interval)){e.interval>31536e6&&(e.interval=31536e6);e.interval<1e3&&(e.interval=1e3);p["poll-interval"]=e.interval;d.eOption=encodeData(p,"base64")}}c.push(d);let u=null,f=Object.assign({},d);f.restart=restart;f.arg=e;f.type=o.type;f.cb=t;captureRestartTopic(d,f);"tcp"===o.type||"ipc"===o.type?u=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(u=dgram.createSocket(o.type));clientConnect(u,s,d,f,t)}catch(e){dm.logEvent("Edge client connect - subscribe error:",e.message)}}function h(e,t){try{if(!0===s.matchClientInstance)return;let r=g(s),i=null,n={method:clientMethod.unsub,topic:e,ciid:a,date:Date.now(),epId:r,unsub:!0};c.forEach((t=>{if(e===t.topic&&t.method===clientMethod.sub){n.mid=t.mid;t.settable&&(n.settable=t.settable)}}));"tcp"===o.type||"ipc"===o.type?i=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(i=dgram.createSocket(o.type));return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(i,s,n,null,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - unsubscribe error:",e.message)}}function m(e,t,r){let i=null,n=null,c=null,l=null,d={},u=null;try{if(!0===s.matchClientInstance)return;i=randomBytes(clientMethod.rbl).toString();if("object"==typeof e){n=e.topic;l=e.restart;e.payload&&(c=e.payload);e.pl&&(c=e.pl);"function"==typeof t&&(r=t)}else if("string"==typeof e){n=e;c=t}if("object"==typeof t&&"client-publish"===t.type){u="client-publish";c=t.data}let g=null;g=(o.secure,c);d=p({},n);d.rootTopic||(d.rootTopic=n);if("string"!=typeof n)throw"Edge client write error: invalid topic name (internal error)";let f={};f=n===clientMethod.kex?{method:clientMethod.write,topic:n,payload:c,mid:i,ciid:a,write:s.write,date:Date.now()}:{method:clientMethod.write,topic:n,payload:g,rootTopic:d.rootTopic,subTopic:d.subTopic,baseTopic:d.baseTopic,mid:i,ciid:a,write:s.write,type:u,date:Date.now()};let h=Object.assign({},f);if(l){h.restart=l;h.arg=e;h.type=o.type;h.cb=r;captureRestartTopic(f,h)}let m=null;if("tcp"===o.type||"ipc"===o.type)m=net.createConnection(o,(()=>{}));else if("udp4"===o.type||"udp6"===o.type){m=dgram.createSocket(o.type);if(f.topic===clientMethod.kex){m.connect(o.port,o.ip,(e=>{if(e){dm.logEvent("Edge client kex connect error:",e);throw"Edge client kex connect error:"+e}clientConnect(m,s,f,h,r,null,null)}));return}}return new Promise((function(e,t){r&&(e=null,t=null);clientConnect(m,s,f,h,r,e,t)}))}catch(e){dm.logEvent("Edge client connect - sendData/write error:",e.message)}}function v(e,t){let r=null,i=null,n=null,l={};try{if(!0===s.matchClientInstance)return;n=randomBytes(clientMethod.rbl).toString();if("object"==typeof e){r=e.topic;i=e.restart}else"string"==typeof e&&(r=e);c.forEach((e=>{e.topic===r&&e.method===clientMethod.sub&&(n=e.mid)}));l=p({},r);l.subTopic||(l.rootTopic=r);if("string"!=typeof r)throw"Edge client read error: invalid topic name (internal error)";let d={method:clientMethod.read,topic:r,rootTopic:l.rootTopic,subTopic:l.subTopic,baseTopic:l.baseTopic,mid:n,ciid:a,read:s.read,date:Date.now()},u=Object.assign({},d);if(i){u.restart=i;u.arg=e;u.type=o.type;u.cb=t;captureRestartTopic(d,u)}let g=null;if("tcp"===o.type||"ipc"===o.type)g=net.createConnection(o,(()=>{}));else if("udp4"===o.type||"udp6"===o.type){g=dgram.createSocket(o.type);if(d.topic===clientMethod.rdy){g.connect(o.port,o.ip,(e=>{if(e){dm.logEvent("Edge client ready connect error:",e);throw"Edge client ready connect error:"+e}clientConnect(g,s,d,u,t,null,null)}));return}}return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(g,s,d,u,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - getData error:",e.message)}}function y(e,t){let r={},i="",n=5e3;try{if(!0===s.matchClientInstance)return;let o=randomBytes(clientMethod.rbl).toString();r.topic=e;r.dataChange=!1;r.mid=o;r.ciid=a;r.date=Date.now();r.polling?n=r.polling:r.interval&&(n=r.interval);n<1e3&&(n=1e3);s.pubTopicStore.push(e);r.send=async t=>{let n=null,o=null;"object"==typeof t?t.type="client-publish":t={type:"client-publish",value:t};t=validateData(t);if(i.normalize("NFC")!==t.normalize("NFC")){i=t;r.dataChange=!0;if(s.option.secure){if(!t||!s.sk)return;{let e=edgeEncrypt(s.sk,t,s.option.algo,s.option.algo_ivlen);n={type:"client-publish",data:JSON.stringify(e)}}}else n={type:"client-publish",data:t};o=await m(e,n);if(o.topic===e&&!0===o.unsub){startStopClientPublishDataPolling(a,"stop");m(e,{unsub:!0,result:"success"})}else if(o.topic===e&&o.interval){r.pollInterval=o.interval;clearInterval(r.clientPubInterval);r.clientPubInterval=setInterval(r.publishCallback,r.pollInterval)}}else r.dataChange=!1};if(!t)throw"Edge client publish method requires a callback";t(r);function c(){t(r)}r.polling?n=r.polling:r.interval&&(n=r.interval);r.publishCallback=c;r.pollInterval=n;r.clientPubInterval=null;setClientPublishDataStore(r)}catch(l){dm.logEvent("Edge client connect - clientPublish error:",l.message)}}const E=Object.create(null);E.subscribe=f;E.sub=f;E.unsubscribe=h;E.unsub=h;E.read=v;E.write=m;E.get=function(e,t){let r=null;try{if(!0===s.matchClientInstance)return;let i=randomBytes(clientMethod.rbl).toString();"object"==typeof e?r=e.topic:"string"==typeof e&&(r=e);c.forEach((t=>{t.topic===e&&t.method===clientMethod.sub&&(i=t.mid)}));let n=null,l=u({},r),d={method:clientMethod.get,topic:r,query:l.query,baseUrl:l.baseUrl,urlPathKeys:l.urlPathKeys,mid:i,ciid:a,date:Date.now()};"tcp"===o.type||"ipc"===o.type?n=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(n=dgram.createSocket(o.type));return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(n,s,d,null,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - httpGet error:",e.message)}};E.post=function(e,t,r){let i=null,n=null;try{if(!0===s.matchClientInstance)return;let c=randomBytes(clientMethod.rbl).toString();if("object"==typeof e){if(!e.body)throw"Edge lient httpPost invalid/missing post body";i=e.topic;e.body&&(n=e.body);"function"==typeof t&&(r=t)}else if("string"==typeof e){if("function"==typeof t)throw"Edge client httpPost invalid/missing post body";i=e;n=t}let l=null;l=(o.secure,n);let d=null,p=u({},i),g={method:clientMethod.post,topic:i,body:l,query:p.query,baseUrl:p.baseUrl,urlPathKeys:p.urlPathKeys,mid:c,ciid:a,date:Date.now()};"tcp"===o.type||"ipc"===o.type?d=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(d=dgram.createSocket(o.type));return new Promise((function(e,t){r&&(e=null,t=null);clientConnect(d,s,g,null,r,e,t)}))}catch(e){dm.logEvent("Edge client connect - httpPost error:",e.message)}};E.getResources=function(e){try{if(!0===s.matchClientInstance)return;let t=null,r=randomBytes(clientMethod.rbl).toString(),i={method:clientMethod.getResources,topic:"getResources",mid:r,ciid:a,date:Date.now()};"tcp"===o.type||"ipc"===o.type?t=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(t=dgram.createSocket(o.type));return new Promise((function(r,n){e&&(r=null,n=null);clientConnect(t,s,i,null,e,r,n)}))}catch(e){dm.logEvent("Edge client connect - getResources error:",e.message)}};E.getSubscribers=function(e){try{if(!0===s.matchClientInstance)return;let t=null,r=randomBytes(clientMethod.rbl).toString(),i={method:clientMethod.getSubscribers,topic:"getSubscribers",mid:r,ciid:a,date:Date.now()};"tcp"===o.type||"ipc"===o.type?t=net.createConnection(o,(()=>{})):"udp4"!==o.type&&"udp6"!==o.type||(t=dgram.createSocket(o.type));return new Promise((function(r,n){e&&(r=null,n=null);clientConnect(t,s,i,null,e,r,n)}))}catch(e){dm.logEvent("Edge client connect - getSubsribers error:",e.message)}};E.on=function(e,t){try{if(!0===s.matchClientInstance)return;let r=getEndpointAddress(s);if("ready"===e){let i="client-"+e+a;edgeEmitter.listenerCount(i)<1&&edgeEmitter.on(i,(e=>{t&&setImmediate((()=>{t(e)}));o.port,dm.logEvent(o.type,r,"Edge client ready",""+e)}))}else if("error"===e){let r="client-"+e+a;edgeEmitter.listenerCount(r)<1&&edgeEmitter.on(r,(e=>{t&&setImmediate((()=>{t(e)}))}))}}catch(e){dm.logEvent("Edge client connect - on(topic, cb) error:",e.message)}};E.publish=y;E.pub=y;E.close=function(){setTimeout((()=>{dm.logEvent("Edge client connect - close executed");process.exit()}),3e3)};o.secure?function(){let e=getEndpointAddress(s);try{if(!encodedAccessTkn)return;if(!0===s.matchClientInstance)return;n.clientEC=createECDH("prime256v1");n.cepk=n.clientEC.generateKeys(uni_enc,"compressed");const t=createHash("sha256"),r=decodeData(encodedAccessTkn,"hex"),i={ciid:a,cepk:n.cepk,stid:r.resin};if(s.option.tkn){t.update(s.option.tkn);let e=t.digest("utf8");i.optid=clientMethod.hrn+e+clientMethod.trn}else if(s.option.accessTkn){t.update(s.option.accessTkn);let e=t.digest("utf8");i.optid=clientMethod.hrn+e+clientMethod.trn}else if(s.fileTkn){t.update(s.fileTkn);let e=t.digest("utf8");i.fiid=clientMethod.hrn+e+clientMethod.trn}if(s.option.secure&&s.option.algo){i.algo=s.option.algo;i.algo_keylen=s.option.algo_keylen;i.algo_ivlen=s.option.algo_ivlen}else i.secure=!1;let o=encodeData(i,"base64");m({topic:clientMethod.kex,payload:o,restart:!0},(t=>{if(!1!==s.option.secure){try{const r=decodeData(t,"base64");if(!r){dm.logEvent(s.option.type,e,"Edge client clientKex error: invalid data rcvd:",""+r);return}if(r.vtk){if(r.ciid===s.ciid){s.vtk=r.vtk;s.secureAccess=r.vtk;if("invalid"===r.vtk){s.option.port?console.log("Edge client invalid secure server access",s.option.host+":"+s.option.port):s.option.path&&console.log("Edge client invalid secure server access",s.option.path);return}}clientTopicStore.forEach((e=>{if(r.ciid===e.ciid){e.vtk=r.vtk;e.secureAccess=r.vtk}}))}n.sharedSecret=n.clientEC.computeSecret(Buffer.from(r.sepk,"base64"));s.salt=r.salt;s.sk=hkdfSync(uni_dig,n.sharedSecret,r.salt,"node-edge-info",s.option.algo_keylen);n.hmac=createHmac("sha256",s.sk);n.hmac.update(n.sharedSecret);n.edgeSign=n.hmac.digest("hex");if(n.edgeSign!==r.esn)throw"Edge client invalid edge.server verification"}catch(e){dm.logEvent("Edge edge.client invalid auth key exchange error:",e.message);throw"Edge edge.client invalid auth key exchange:"+e.message}setImmediate((()=>{n.sharedSecret=null,n.edgeSign=null}))}else dm.logEvent(s.option.type,e,"Edge client communication request is unencrypted (secure = false) , kex is not required (debug only)")}))}catch(e){dm.logEvent("Edge client connect - clientKex error:",e.message)}}():E.read({topic:clientMethod.rdy,restart:!0},(function(){}));let b=!1,S="clientExitProcessError"+a;edgeEmitter.listenerCount(S)<1&&edgeEmitter.on(S,(e=>{"ECONNREFUSED"!==e&&"ENOENT"!==e||(b=!0)}));function k(){let e=null;try{let t=getEndpointAddress(s),r=g(s),i={topic:clientMethod.clientExit,date:new Date,uid:a,epId:r};if(!s.connectError)if("tcp"===o.type||"ipc"===o.type){e=net.createConnection(o,(()=>{}));e.write(JSON.stringify(i))}else{e=dgram.createSocket(o.type);e.send(JSON.stringify(i),o.port,o.ip)}dm.logEvent(o.type,t,"Edge client terminated")}catch(e){console.log("Edge client clientExitProcess error:",e.message);dm.logEvent(o.type,o.ip+":"+o.port,"Edge client clientExitProcess error:",e.message)}}process.on("SIGINT",k);process.on("SIGTERM",k);o.port?dm.logEvent(o.type,o.ip+":"+o.port,"Edge client started","secure:"+o.secure):dm.logEvent(o.type,o.path,"Edge client started","secure:"+o.secure);if(r)return setImmediate(r,E);Object.freeze(E);return E}var serverStatus=[],serverTopicStore=[],serverRestartAttempt=0,stdPublishDataStore=[],serverDataSourceStore=[],settablePublishDataStore=[],serverSubscriberDataStore=[];function decryptServerRcvdData(e,t,r){let i=null;e.forEach(((e,r)=>{if(e.salt===t.salt&&e.sk)try{i=e.sk;let r=edgeDecrypt(e.sk,t,e.algo);(t=JSON.parse(r)).ct=!0}catch(e){dm.logEvent("createServer decryptServerRcvdData - keyStore data edgeDecrypt error:",e.message)}}));if(t.ciphertext){r&&r.end();return null}if(t&&i)return t}function setServerPublishDataStore(e,t){let r=!0;settablePublishDataStore.forEach(((t,i)=>{if(e.topic===t.topic&&e.epId===t.epId){r=!1;clearInterval(t.serverPubInterval);e.pollInterval!==t.pollInterval&&(t.pollInterval=e.pollInterval);t.publishCallback=e.publishCallback;t.serverPubInterval=setInterval(t.publishCallback,t.pollInterval)}}));if(r){clearInterval(e.serverPubInterval);e.serverPubInterval=setInterval(e.publishCallback,e.pollInterval);settablePublishDataStore.push(e)}}var sp,sh,rscb=null,serverExit=null,serverInsecureEnc="base64";function createServer(e,t,r){if(!encodedAccessTkn){dm.logEvent("Edge.server invalid access");throw"Edge.server - invalid access"}sp=e;sh=t;rscb=r;let i=setSecureEdge(),n=null,o=null,s=null,c="tcp",l=!0,a=!0,d=!1,p=!1,u={},g=0,f=null,h=[],m=[],v=[],y=[],E=[],b=[],S=[],k=[],T=uni_algo,I=16,w=16,P={},D=[],C=[],x=0;const M=randomBytes(clientMethod.rbl).toString();if(1===arguments.length&&"string"==typeof e){f=e;c="ipc"}else if(1===arguments.length&&"number"==typeof e){s=e;o="127.0.0.1"}else if(2===arguments.length&&"string"==typeof e&&"function"==typeof t){f=e;r=t;c="ipc"}else if(2===arguments.length&&"number"==typeof e&&"function"==typeof t){s=e;o="127.0.0.1";r=t}else if("number"==typeof e&&"string"==typeof t){s=e;o=t}else if("string"==typeof e&&"number"==typeof t){s=t;o=e}else if("object"==typeof e){if(!e.port||e.host||e.ip)if(e.port&&e.host){s=e.port;o=e.host}else if(e.port&&e.ip){s=e.port;o=e.ip}else{if(!e.path){console.log("\nPlease provide a valid ip address and port number.\n");throw new Error("Edge server - invalid port and address")}f=e.path}else{o="127.0.0.1";s=e.port}if(!0===e.public){a=null;d=!0}!0===e.allowInsecure&&(l=!1);e.type&&(c=e.type);u=e;r=t}if(f)try{fs.unlinkSync(f)}catch(e){}if(o&&s){n=o+":"+s;serverStatus.forEach((e=>{e.port===s&&(p=!0)}))}else if(f){n=f;serverStatus.forEach((e=>{e.path===f&&(p=!0)}))}if(i&&i.edge.secure){u.allowInsecure=!1;l=!0}function N(e,t,r){e.forEach(((i,o)=>{if(i.ciid===t.ciid||i.ciid===t.uid||i.socket&&i.socket.destroyed||i.epId===t.epId)try{e.splice(o,1);dm.logEvent(c,n,"Edge server "+r+"["+o+"] - instance remove success")}catch(e){console.log(c,n,"Edge server "+r+".splice(x, 1) error:",e.message);throw r+".splice(x, 1) error"}}))}function A(e,t){try{const r=decodeData(encodedAccessTkn,"hex");if(d)return!(!t.ct&&!t.resin.includes(r.resin.slice(10,29)));if(r.resin&&t.resin.includes(r.resin.slice(10,29)))return!0;if(e.optionTkn&&t.resin.includes(e.optionTkn))return!0;if(e.fileTkn&&t.resin.includes(e.fileTkn))return!0;if(t.resin&&"invalid"!==t.vtk){t.resin.includes(r.resin.slice(10,29));return!1}return!1}catch(e){dm.logEvent("Edge server validateSecureAccess error:",e.message)}}if(p){let e=null;s?e=o+":"+s:f&&(e=f);let t=edgeEmitter.emit("server-error"+M,{message:c+" server "+e+" is already running"});f&&(t=edgeEmitter.emit("server-error"+M,{message:c+" server path:"+e+" is already running"}));t||dm.logEvent(c,e,"Edge server is already running");try{EdgeGlobalServer.close()}catch(t){dm.logEvent(c,e,"Eddge server - EdgeGlobalServer.close() error:",t.message)}}let O=null,B=null;try{O=function(){try{const e={},t=decodeData(encodedAccessTkn,"hex");let r=/^[0-9a-zA-Z]+$/;if(u.accessTkn){if(u.accessTkn.length<16){console.log("\naccessTkn must be at least 16 bytes long");throw"Edge server invalid access token"}if(u.accessTkn.length>200){console.log("\naccessTkn is too long");throw"Edge server invalid access token"}if(u.accessTkn.match(r)){console.log("\naccessTkn must be a combination alphanumeric and special characters.");throw"Edge invalid access token"}e.optionTkn=u.accessTkn}else e.optionTkn=null;(t.sfileTkn&&t.sfileTkn.port===s&&t.sfileTkn.ip===o||t.sfileTkn&&t.sfileTkn.path===f)&&(e.fileTkn=t.sfileTkn.tkn);return e}catch(e){dm.logEvent("Edge server getServerTknSources error:",e.message)}}();B={publish:h,dataSource:S,read:v,write:y,httpGet:E,httpPost:b,subscribe:m,secure:l,allowInsecure:!l,secureAccess:a,publicAccess:d,optionTkn:O.optionTkn,fileTkn:O.fileTkn,type:c};if(s&&o){B.address={port:s,host:o,type:c};B.host=o;B.port=s}else if(f){B.address={path:f,type:c};B.path=f;B.unixPath=f}serverTopicStore.push(B)}catch(e){dm.logEvent("Edge server capture serverTopicInfo error:",e.message)}function _(e,t){try{let r=!0;t.forEach(((t,i)=>{t===e&&(r=!1)}));r&&t.push(e)}catch(e){dm.logEvent("Edge server - getServerTopic error:",e.message)}}function j(e){const t={},r=[],i=[],n={},o=[];try{for(let t=0;t<e.length;t++)"/"===e[t]&&r.push(t);r.forEach(((t,n)=>{if(0==t&&r[n+1]){let t=e.slice(r[n],r[n+1]);i.push(t)}else if(0!==t&&r[n]&&r[n+1]){let t=e.slice(r[n],r[n+1]);i.push(t)}else{let t=e.slice(r[n],e.length);i.push(t)}}));i.forEach(((e,t)=>{if(e&&e.startsWith("/:")){let r=e.slice(2,e.length),i={key:r,index:t};n[r]=r;o.push(i)}}));t.urlPathKeys=i;t.baseUrl=i[0];t.params=n;t.paramKeys=o;t.rootPath=i[0];return t}catch(e){throw new Error(e)}}function J(e){try{let t=e.indexOf("/:",1);if(t){if((e=e.substring(0,t))&&e.includes("/:"))throw"\nEdge server system error - http path ["+e+"] is invalid, still has param /: included";return e}return null}catch(e){throw e}}let F=!0,R=5e3;function K(e,t){let r=!0;stdPublishDataStore.forEach(((t,i)=>{t.topic===e.topic&&t.epId===e.epId&&(r=!1)}));if(r){stdPublishDataStore.push(e);setTimeout((()=>{stdPublishDataStore.forEach(((t,r)=>{t.topic===e.topic&&t.epId===e.epId&&k.forEach((e=>{e.topic===t.topic&&setImmediate(t.send,e.currentDataValue)}))}))}),1e3)}if(F){let i=R,o={},s="",l=!0,a=null;o.topic=e.topic;o.type="fixed";o.dataChange=!1;o.pollInterval=i;o.autoStopPolling=!0;e.pollInterval&&(i=e.pollInterval);function d(t,r){try{e.pollInterval||(o.pollInterval?i=o.pollInterval:o.interval&&(i=o.interval));i<1e3&&(i=R);clearInterval(a);a=setInterval((()=>{setImmediate(r,o)}),i);l=!1}catch(e){dm.logEvent(c,n,"Edge server stdPublishData - startPubDataPolling error:",e.message)}}function p(e){if(0===stdPublishDataStore.length){clearInterval(a);F=!0}}o.send=function(e){try{let r=(e=validateData(e)).includes("ciphertext");!function(e,t){try{let r=!0,i={topic:e,currentDataValue:t};k.forEach(((i,n)=>{if(i.topic===e){i.currentDataValue=t;r=!1}}));r&&k.push(i)}catch(e){dm.logEvent("Edge server - getPubTopicCurrentData error:",e.message)}}(o.topic,e);if("string"!=typeof e)throw new Error("Edge server stdPublishData invalid input data: "+e);if(s.normalize("NFC")!==e.normalize("NFC")){r||(s=e);o.dataChange=!0;stdPublishDataStore.forEach((e=>{o.topic===e.topic&&e.send(s)}))}else o.dataChange=!1;o.autoStopPolling&&p();l&&d(0,t)}catch(e){dm.logEvent(c,n,"Edge server stdPublishData pubObject.send error:",e.message)}};t(o);l&&d(0,t);F=!1;let u=Object.seal(o);Object.defineProperty(u,"pollInterval",{writable:!1});u.interval&&Object.defineProperty(u,"interval",{writable:!1})}}function q(e,t){let r={},i={},o="";try{r.topic=e.topic;r.type="settable";r.dataChange=!1;i.topic=e.topic;i.type="settable";e.option&&e.option["poll-interval"]?r.pollInterval=e.option["poll-interval"]:e.interval&&(r.pollInterval=e.interval);r.send=function(t){try{let i=(t=validateData(t)).includes("ciphertext");if("string"!=typeof t)throw new Error("Edge server settablePublishData invalid input data: "+t);if(o.normalize("NFC")!==t.normalize("NFC")){i||(o=t);r.dataChange=!0;e.send(o)}else r.dataChange=!1}catch(e){dm.logEvent(c,n,"Edge server settablePublishData pubObject.send error:",e.message)}};t&&setImmediate(t,r);function s(){setImmediate(t,r)}i.pollInterval=R;i.serverPubInterval=null;i.publishCallback=s;e.option&&e.option["poll-interval"]?i.pollInterval=e.option["poll-interval"]:e.interval&&(i.pollInterval=e.interval);i.pollInterval<1e3&&(i.pollInterval=R);e.epId&&(i.epId=e.epId);i.end=e.end;setServerPublishDataStore(i);let l=Object.seal(r);l.pollInterval&&Object.defineProperty(l,"pollInterval",{writable:!1})}catch(a){dm.logEvent(c,n,"Edge server settablePublishData error:",a.message)}}function G(e,t){let r=!0,i=null;e.settable?i="settable":e.std&&(i="std");t.forEach(((o,s)=>{if(e.topic===o.topic&&e.epId===o.epId){r=!1;o.serverPubInterval&&clearInterval(o.serverPubInterval);(e.unsub||e.send)&&setImmediate(e.send,"true");o.end&&o.end();try{t.splice(s,1);dm.logEvent(c,n,"Edge server "+o.topic+" "+i+" unsub - success")}catch(e){dm.logEvent(c,n,"Edge server "+o.topic+" "+i+" unsub error:",e.message);throw"Edge server "+o.topic+" unsub error: "+e.message}}}));if(r){(e.unsub||e.send)&&setImmediate(e.send,"false");dm.logEvent(c,n,"Edge server "+e.topic+" "+i+" no pub instance - nothing to unsub");return!1}return!0}function U(e){stdPublishDataStore.forEach(((t,r)=>{if(e.epId===t.epId&&e.topic===clientMethod.clientExit){t.serverPubInterval&&clearInterval(t.serverPubInterval);try{stdPublishDataStore.splice(r,1);dm.logEvent(c,n,"Edge server",t.topic,"client-exit std unsub - success")}catch(e){dm.logEvent(c,n,"Edge server unsub subscriberStore.splice(x, 1) error: ",e.message);throw"Edge server "+t.topic+" client-exit std unsub error: "+e.message}}}));settablePublishDataStore.forEach(((t,r)=>{if(e.epId===t.epId&&e.topic===clientMethod.clientExit){t.serverPubInterval&&clearInterval(t.serverPubInterval);try{settablePublishDataStore.splice(r,1);dm.logEvent(c,n,"Edge server",t.topic,"client-exit settable unsub - success")}catch(e){dm.logEvent(c,n,"Edge server unsub subscriberStore.splice(x, 1) error: ",e.message);throw"Edge server "+t.topic+"client-exit settable unsub error: "+e.message}}}))}function H(e,t){if(!e){console.log("Edge server serverPublish",method,"error: missing/invalid topic name");dm.logEvent("Edge server serverPublish",method,"error: missing/invalid topic name",e);return}if(!t)throw"Edge server publish error: missing a calback function";let r=null,i=null;if("object"==typeof e&&e.topic&&"string"==typeof e.topic){r=e.topic;Number.isInteger(e.pollInterval)?i=e.pollInterval:Number.isInteger(e.interval)&&(i=e.interval);i<1e3&&(i=R)}else{if("string"!=typeof e)throw"Edge server publish invalid topic";r=e}_(r,h);let n="edge-server-publish"+r;edgeEmitter.listenerCount(n)<1&&edgeEmitter.on(n,(n=>{let o={topic:n.topic,epId:n.epId};if(n.sub&&n.topic===r)if(n.std){o.std=!0;(e.pollInterval||e.interval)&&(n.pollInterval=i);setImmediate(G,o,settablePublishDataStore);setImmediate(K,n,t)}else if(n.settable){o.settable=!0;setImmediate(G,o,stdPublishDataStore);setImmediate(q,n,t)}}));let o="edge-server-unpublish"+r;edgeEmitter.listenerCount(o)<1&&edgeEmitter.on(o,(e=>{e.unsub&&e.topic&&r&&(e.std?setImmediate(G,e,stdPublishDataStore):e.settable&&setImmediate(G,e,settablePublishDataStore))}))}function L(e,t){let r="dataSource";if(e){_(e,S);edgeEmitter.listenerCount("dataSource"+e)<1&&edgeEmitter.on("dataSource"+e,(e=>{t&&setImmediate(t,e)}))}else{console.log("Edge server dataSource",r,"error: missing/invalid topic name");dm.logEvent("Edge server dataSource",r,"error: missing/invalid topic name",e)}}function z(e){let t=!1;serverSu