node-edge
Version:
node-edge is a tcp communication library for edge computing using local area networking.
7 lines • 65.5 kB
JavaScript
/**!
* node-edge.js
* v1.5.8
*
* Copyright(c) 2022 Ed Alegrid
*/
"use strict";const fs=require("fs"),os=require("os"),net=require("node:net"),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,dm=(()=>{let e="m2mConfig/neLog",t=" Date Event";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 Array.from(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")}return e}catch(e){dm.logEvent("Edge validateData error:",e.message)}}function encodeData(e,t){try{return"object"==typeof e?"obj"+Buffer.from(JSON.stringify(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){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)throw"Edge edgeEncrypt invalid parameters";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)throw"Edge edgeDecrypt invalid parameters";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}}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{i=decodeData(r,"hex")}catch(e){i=encodeData(r,"hex");dm.logEvent("Edge getFileAccTkn JSON.parse(Buffer.from(rTk) error:",e.message)}finally{return i}}var accessEdgepoint=null;function accessEdgeEndpoint(){function e(e){let t=null,r=null;try{t=e.payload;r=Buffer.from(JSON.stringify(t)).toString("hex");fs.writeFileSync(stkPath,r)}catch(e){if("ENOENT"!==e.code){dm.logEvent("Edge setServerAccessTkn fs.mkdirSync error:",e.message);throw e}fs.mkdirSync(bPath+"/server");fs.writeFileSync(stkPath,r)}try{let t=getFileAccTkn("server");!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);e.fileTkn=t.tkn}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");fs.writeFileSync(ctkPath,s);let t=getFileAccTkn("client");!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);e.fileTkn=r.tkn}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.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)}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(Array.isArray(d)){e=d[0];i.option.secure&&e.ciphertext&&i.sk&&(e=decryptClientRcvdData(i,e))}if('The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Object'===e){dm.logEvent("clientConnect clientSocket.on(data) - must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of Object:",""+e);throw'The "string" argument must be of type string or ...'}if("invalid json payload"===e){dm.logEvent("clientConnect clientSocket.on(data) - invalid json payload",""+e);throw"invalid edge.client rcvd data as json payload"}if("string"==typeof e){if(e.includes("ciphertext")){dm.logEvent("clientConnect clientSocket.on(data) - invalid edge.client rcvd data w/ ciphertext",""+e);throw"invalid edge.client rcvd data w/ ciphertext"}throw"client - invalid data type"}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}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||r.end():o&&o.restart?dm.logEvent(i.option.type,a,"Edge client - *restart option "+n.method,n.topic):"publish-type-pattern"===n.type||r.close());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)}s?s(e):c&&c(e);return}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{edgeEmitter.emit("client-ready"+n.ciid,!0);startStopClientPublishDataPolling(n.ciid)}return}if(e.error){if("secondary-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}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)}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 if(r.option.secure)setTimeout((()=>{if(setAccessTkn(r,i)&&r.sk){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)}}))}}),1e3);else{const e=decodeData(encodedAccessTkn,"hex");i.resin=e.resin;i.ak=randomBytes(32).toString();"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)}}catch(e){dm.logEvent("Edge clientConnect - prepare and send the client payload error:",e.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)}function connect(e,t,r){if(!encodedAccessTkn){dm.logEvent("Edge.client invalid access");throw"Edge.client - invalid access"}let i={},n={},o={},s=[],c=null;const l=randomBytes(clientMethod.rbl).toString(),a=getRandomIntInclusive(2e3,5e3);if("string"==typeof e){c=e;n={path:e};n.type="ipc";1==arguments.length||2==arguments.length&&"function"==typeof t&&(r=t)}else if("number"==typeof e)if(1==arguments.length)n={port:e,host:"127.0.0.1"};else if(2==arguments.length&&"string"==typeof t)n={port:e,host:t};else if(2==arguments.length&&"function"==typeof t){n={port:e,host:"127.0.0.1"};r=t}else 3==arguments.length&&"string"==typeof t&&"function"==typeof r&&(n={port:e,host:t});else if("object"==typeof e){2==arguments.length&&"function"==typeof t&&(r=t);n=e;if(n.path){n.type="ipc";c=e.path}else{n.ip||(n.ip="127.0.0.1");n.ip&&(n.host=n.ip)}if("aes-128-gcm"===n.algo){n.algo_keylen=16;n.algo_ivlen=16}else if("aes-192-gcm"===n.algo){n.algo_keylen=24;n.algo_ivlen=16}else if("aes-256-gcm"===n.algo){n.algo_keylen=32;n.algo_ivlen=16}else if("chacha20-poly1305"===n.algo){n.algo_keylen=32;n.algo_ivlen=12}}!n.ip&&n.host&&(n.ip=n.host);void 0===n.secure&&(n.secure=!0);void 0===n.restart&&(n.restart=!0);if(!n.algo&&n.secure){n.algo=uni_algo;n.algo_keylen=16;n.algo_ivlen=16}void 0===n.type&&(n.type="tcp");n.type;"tcp"===n.type||n.host&&(net.isIPv6(n.host)?n.type="udp6":n.type="udp4");o.vtk="std";o.wait=!0;o.fileTkn=null;o.delay=a;o.secureAccess=null;o.ciid=l;o.connectError=!1;o.matchClientInstance=!1;o.option=n;o.subTopicStore=[];o.pubTopicStore=[];o.readTopicStore=[];o.writeTopicStore=[];o.httpGetTopicStore=[];o.httpPostTopicStore=[];o.read=m;o.write=h;o.subscribe=g;c&&"string"==typeof c?oneClientInstanceStore.forEach((e=>{e.path===o.option.path&&(o.matchClientInstance=!0)})):oneClientInstanceStore.forEach((e=>{e.port===o.option.port&&e.host===o.option.host&&(o.matchClientInstance=!0)}));try{!1===o.matchClientInstance&&oneClientInstanceStore.push(o.option);!function(){try{const e={},t=decodeData(encodedAccessTkn,"hex");o.option.accessTkn?e.optionTkn=o.option.accessTkn:e.optionTkn=null;t.cfileTkn&&Array.isArray(t.cfileTkn)&&t.cfileTkn.forEach((t=>{if(t.ip===o.option.host&&t.port===o.option.port){e.fileTkn=t.tkn;o.fileTkn=t.tkn}else if(t.path===o.option.path){e.fileTkn=t.tkn;o.fileTkn=t.tkn}}));return e}catch(e){dm.logEvent("Edge client connect - getClientInstanceTknSources error:",e.message)}}();let e={};if(!1===o.matchClientInstance){e={ciid:l,secure:o.option.secure,secureAccess:o.vtk,subscribe:o.subTopicStore,read:o.readTopicStore,write:o.writeTopicStore,httpGet:o.httpGetTopicStore,httpPost:o.httpPostTopicStore,publish:o.pubTopicStore,optionTkn:o.option.accessTkn,fileTkn:o.fileTkn,vtk:o.vtk,container:edgeInfo.isContainer(),nodeEdgeV:edgeInfo.nodeEdgeV,npmv:edgeInfo.npmv.toString(),type:o.option.type};if(o.option.host&&o.option.port){e.address={port:o.option.port,host:o.option.host,type:o.option.type};e.host=o.option.host;e.port=o.option.port}else if(o.option.path){e.address={path:o.option.path,type:o.option.type};e.path=c}setImmediate((()=>{clientTopicStore.push(e)}))}}catch(e){dm.logEvent("Edge client connect - capture clientTopicInfo into clientTopicStore[] error:",e.message)}function d(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 p(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 u(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 g(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,c=!0;try{if(!0===o.matchClientInstance)return;let a=u(o);i=randomBytes(clientMethod.rbl).toString();"object"==typeof e?r=e.topic:"string"==typeof e&&(r=e);s.forEach((e=>{if(e.topic===r&&e.ciid===l&&e.method===clientMethod.sub){i=e.mid;c=!1}}));let d={method:clientMethod.sub,topic:r,mid:i,ciid:l,date:Date.now(),epId:a,subscribe:o.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")}}s.push(d);let g=null,f=Object.assign({},d);f.restart=restart;f.arg=e;f.type=n.type;f.cb=t;captureRestartTopic(d,f);"tcp"===n.type||"ipc"===n.type?g=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(g=dgram.createSocket(n.type));clientConnect(g,o,d,f,t)}catch(e){dm.logEvent("Edge client connect - subscribe error:",e.message)}}function f(e,t){try{if(!0===o.matchClientInstance)return;let r=u(o),i=null,c={method:clientMethod.unsub,topic:e,ciid:l,date:Date.now(),epId:r,unsub:!0};s.forEach((t=>{if(e===t.topic&&t.method===clientMethod.sub){c.mid=t.mid;t.settable&&(c.settable=t.settable)}}));"tcp"===n.type||"ipc"===n.type?i=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(i=dgram.createSocket(n.type));return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(i,o,c,null,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - unsubscribe error:",e.message)}}function h(e,t,r){let i=null,s=null,c=null,a=null,p={},u=null;try{if(!0===o.matchClientInstance)return;i=randomBytes(clientMethod.rbl).toString();if("object"==typeof e){s=e.topic;a=e.restart;e.payload&&(c=e.payload);e.pl&&(c=e.pl);"function"==typeof t&&(r=t)}else if("string"==typeof e){s=e;c=t}if("object"==typeof t&&"client-publish"===t.type){u="client-publish";c=t.data}let g=null;g=n.secure?c:encodeData(c,"base64");p=d({},s);p.rootTopic||(p.rootTopic=s);if("string"!=typeof s)throw"Edge client write error: invalid topic name (internal error)";let f={};f=s===clientMethod.kex?{method:clientMethod.write,topic:s,payload:c,mid:i,ciid:l,write:o.write,date:Date.now()}:{method:clientMethod.write,topic:s,payload:g,rootTopic:p.rootTopic,subTopic:p.subTopic,baseTopic:p.baseTopic,mid:i,ciid:l,write:o.write,type:u,date:Date.now()};let h=Object.assign({},f);if(a){h.restart=a;h.arg=e;h.type=n.type;h.cb=r;captureRestartTopic(f,h)}let m=null;if("tcp"===n.type||"ipc"===n.type)m=net.createConnection(n,(()=>{}));else if("udp4"===n.type||"udp6"===n.type){m=dgram.createSocket(n.type);if(f.topic===clientMethod.kex){m.connect(n.port,n.ip,(e=>{if(e){dm.logEvent("Edge client kex connect error:",e);throw"Edge client kex connect error:"+e}clientConnect(m,o,f,h,r,null,null)}));return}}return new Promise((function(e,t){r&&(e=null,t=null);clientConnect(m,o,f,h,r,e,t)}))}catch(e){dm.logEvent("Edge client connect - sendData/write error:",e.message)}}function m(e,t){let r=null,i=null,c=null,a={};try{if(!0===o.matchClientInstance)return;c=randomBytes(clientMethod.rbl).toString();if("object"==typeof e){r=e.topic;i=e.restart}else"string"==typeof e&&(r=e);s.forEach((e=>{e.topic===r&&e.method===clientMethod.sub&&(c=e.mid)}));a=d({},r);a.subTopic||(a.rootTopic=r);if("string"!=typeof r)throw"Edge client read error: invalid topic name (internal error)";let p={method:clientMethod.read,topic:r,rootTopic:a.rootTopic,subTopic:a.subTopic,baseTopic:a.baseTopic,mid:c,ciid:l,read:o.read,date:Date.now()},u=Object.assign({},p);if(i){u.restart=i;u.arg=e;u.type=n.type;u.cb=t;captureRestartTopic(p,u)}let g=null;if("tcp"===n.type||"ipc"===n.type)g=net.createConnection(n,(()=>{}));else if("udp4"===n.type||"udp6"===n.type){g=dgram.createSocket(n.type);if(p.topic===clientMethod.rdy){g.connect(n.port,n.ip,(e=>{if(e){dm.logEvent("Edge client ready connect error:",e);throw"Edge client ready connect error:"+e}clientConnect(g,o,p,u,t,null,null)}));return}}return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(g,o,p,u,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - getData error:",e.message)}}function v(e,t){let r={},i="",n=5e3;try{if(!0===o.matchClientInstance)return;let s=randomBytes(clientMethod.rbl).toString();r.topic=e;r.dataChange=!1;r.mid=s;r.ciid=l;r.date=Date.now();r.polling?n=r.polling:r.interval&&(n=r.interval);n<1e3&&(n=1e3);o.pubTopicStore.push(e);r.send=async t=>{let n=null,s=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(o.option.secure){if(!t||!o.sk)return;{let e=edgeEncrypt(o.sk,t,o.option.algo,o.option.algo_ivlen);n={type:"client-publish",data:JSON.stringify(e)}}}else n={type:"client-publish",data:t};s=await h(e,n);if(s.topic===e&&!0===s.unsub){startStopClientPublishDataPolling(l,"stop");h(e,{unsub:!0,result:"success"})}else if(s.topic===e&&s.interval){r.pollInterval=s.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(a){dm.logEvent("Edge client connect - clientPublish error:",a.message)}}const y=Object.create(null);y.subscribe=g;y.sub=g;y.unsubscribe=f;y.unsub=f;y.read=m;y.write=h;y.get=function(e,t){let r=null;try{if(!0===o.matchClientInstance)return;let i=randomBytes(clientMethod.rbl).toString();"object"==typeof e?r=e.topic:"string"==typeof e&&(r=e);s.forEach((t=>{t.topic===e&&t.method===clientMethod.sub&&(i=t.mid)}));let c=null,a=p({},r),d={method:clientMethod.get,topic:r,query:a.query,baseUrl:a.baseUrl,urlPathKeys:a.urlPathKeys,mid:i,ciid:l,date:Date.now()};"tcp"===n.type||"ipc"===n.type?c=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(c=dgram.createSocket(n.type));return new Promise((function(e,r){t&&(e=null,r=null);clientConnect(c,o,d,null,t,e,r)}))}catch(e){dm.logEvent("Edge client connect - httpGet error:",e.message)}};y.post=function(e,t,r){let i=null,s=null;try{if(!0===o.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&&(s=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;s=t}let a=null;a=n.secure?s:encodeData(s,"base64");let d=null,u=p({},i),g={method:clientMethod.post,topic:i,body:a,query:u.query,baseUrl:u.baseUrl,urlPathKeys:u.urlPathKeys,mid:c,ciid:l,date:Date.now()};"tcp"===n.type||"ipc"===n.type?d=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(d=dgram.createSocket(n.type));return new Promise((function(e,t){r&&(e=null,t=null);clientConnect(d,o,g,null,r,e,t)}))}catch(e){dm.logEvent("Edge client connect - httpPost error:",e.message)}};y.getResources=function(e){try{if(!0===o.matchClientInstance)return;let t=null,r=randomBytes(clientMethod.rbl).toString(),i={method:clientMethod.getResources,topic:"getResources",mid:r,ciid:l,date:Date.now()};"tcp"===n.type||"ipc"===n.type?t=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(t=dgram.createSocket(n.type));return new Promise((function(r,n){e&&(r=null,n=null);clientConnect(t,o,i,null,e,r,n)}))}catch(e){dm.logEvent("Edge client connect - getResources error:",e.message)}};y.getSubscribers=function(e){try{if(!0===o.matchClientInstance)return;let t=null,r=randomBytes(clientMethod.rbl).toString(),i={method:clientMethod.getSubscribers,topic:"getSubscribers",mid:r,ciid:l,date:Date.now()};"tcp"===n.type||"ipc"===n.type?t=net.createConnection(n,(()=>{})):"udp4"!==n.type&&"udp6"!==n.type||(t=dgram.createSocket(n.type));return new Promise((function(r,n){e&&(r=null,n=null);clientConnect(t,o,i,null,e,r,n)}))}catch(e){dm.logEvent("Edge client connect - getSubsribers error:",e.message)}};y.on=function(e,t){try{if(!0===o.matchClientInstance)return;let r=getEndpointAddress(o);if("ready"===e){let i="client-"+e+l;edgeEmitter.listenerCount(i)<1&&edgeEmitter.on(i,(e=>{t&&setImmediate((()=>{t(e)}));n.port,dm.logEvent(n.type,r,"Edge client ready",""+e)}))}else if("error"===e){let r="client-"+e+l;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)}};y.publish=v;y.pub=v;y.close=function(){setTimeout((()=>{dm.logEvent("Edge client connect - close executed");process.exit()}),3e3)};n.secure?function(){let e=getEndpointAddress(o);try{if(!encodedAccessTkn)return;if(!0===o.matchClientInstance)return;i.clientEC=createECDH("prime256v1");i.cepk=i.clientEC.generateKeys(uni_enc,"compressed");const t=createHash("sha256"),r=decodeData(encodedAccessTkn,"hex"),n={ciid:l,cepk:i.cepk,stid:r.resin};if(o.option.tkn){t.update(o.option.tkn);let e=t.digest("utf8");n.optid=clientMethod.hrn+e+clientMethod.trn}else if(o.option.accessTkn){t.update(o.option.accessTkn);let e=t.digest("utf8");n.optid=clientMethod.hrn+e+clientMethod.trn}else if(o.fileTkn){t.update(o.fileTkn);let e=t.digest("utf8");n.fiid=clientMethod.hrn+e+clientMethod.trn}if(o.option.secure&&o.option.algo){n.algo=o.option.algo;n.algo_keylen=o.option.algo_keylen;n.algo_ivlen=o.option.algo_ivlen}else n.secure=!1;let s=encodeData(n,"base64");h({topic:clientMethod.kex,payload:s,restart:!0},(t=>{if(!1!==o.option.secure){try{const r=decodeData(t,"base64");if(!r){dm.logEvent(o.option.type,e,"Edge client clientKex error: invalid data rcvd:",""+r);return}if(r.vtk){if(r.ciid===o.ciid){o.vtk=r.vtk;o.secureAccess=r.vtk;if("invalid"===r.vtk){o.option.port?console.log("Edge client invalid secure server access",o.option.host+":"+o.option.port):o.option.path&&console.log("Edge client invalid secure server access",o.option.path);return}}clientTopicStore.forEach((e=>{if(r.ciid===e.ciid){e.vtk=r.vtk;e.secureAccess=r.vtk}}))}i.sharedSecret=i.clientEC.computeSecret(Buffer.from(r.sepk,"base64"));o.salt=r.salt;o.sk=hkdfSync(uni_dig,i.sharedSecret,r.salt,"node-edge-info",o.option.algo_keylen);i.hmac=createHmac("sha256",o.sk);i.hmac.update(i.sharedSecret);i.edgeSign=i.hmac.digest("hex");if(i.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((()=>{i.sharedSecret=null,i.edgeSign=null}))}else dm.logEvent(o.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)}}():y.read({topic:clientMethod.rdy,restart:!0},(function(){}));let E=!1,b="clientExitProcessError"+l;edgeEmitter.listenerCount(b)<1&&edgeEmitter.on(b,(e=>{"ECONNREFUSED"!==e&&"ENOENT"!==e||(E=!0)}));function S(){let e=null;try{let t=getEndpointAddress(o),r=u(o),i={topic:clientMethod.clientExit,date:new Date,uid:l,epId:r};if(!o.connectError)if("tcp"===n.type||"ipc"===n.type){e=net.createConnection(n,(()=>{}));e.write(JSON.stringify(i))}else{e=dgram.createSocket(n.type);e.send(JSON.stringify(i),n.port,n.ip)}dm.logEvent(n.type,t,"Edge client terminated")}catch(e){console.log("Edge client clientExitProcess error:",e.message);dm.logEvent(n.type,n.ip+":"+n.port,"Edge client clientExitProcess error:",e.message)}}process.on("SIGINT",S);process.on("SIGTERM",S);n.port?dm.logEvent(n.type,n.ip+":"+n.port,"Edge client started","secure:"+n.secure):dm.logEvent(n.type,n.path,"Edge client started","secure:"+n.secure);if(r)return setImmediate(r,y);Object.freeze(y);return y}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;t.sec=!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)}}function createServer(e,t,r){if(!encodedAccessTkn){dm.logEvent("Edge.server invalid access");throw"Edge.server - invalid access"}let i=null,n=null,o="tcp",s=!0,c=!0,l=!1,a=!1,d={},p=0,u=null,g=[],f=[],h=[],m=[],v=[],y=[],E=[],b=[],S=uni_algo,k=16,T=16,I={},w=[],D=[],P=0;const C=randomBytes(clientMethod.rbl).toString();if(1===arguments.length&&"string"==typeof e){u=e;o="ipc"}else if(1===arguments.length&&"number"==typeof e){n=e;i="127.0.0.1"}else if(2===arguments.length&&"string"==typeof e&&"function"==typeof t){u=e;r=t;o="ipc"}else if(2===arguments.length&&"number"==typeof e&&"function"==typeof t){n=e;i="127.0.0.1";r=t}else if("number"==typeof e&&"string"==typeof t){n=e;i=t}else if("string"==typeof e&&"number"==typeof t){n=t;i=e}else if("object"==typeof e){if(!e.port||e.host||e.ip)if(e.port&&e.host){n=e.port;i=e.host}else if(e.port&&e.ip){n=e.port;i=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")}u=e.path}else{i="127.0.0.1";n=e.port}if(!0===e.public){c=null;l=!0}!0===e.allowInsecure&&(s=!1);e.type&&(o=e.type);d=e;r=t}if(u)try{fs.unlinkSync(u)}catch(e){}i&&n?serverStatus.forEach((e=>{e.port===n&&(a=!0)})):u&&serverStatus.forEach((e=>{e.path===u&&(a=!0)}));let x=null;n&&i?x=i+":"+n:u&&(x=u);function M(e,t,r){e.forEach(((i,n)=>{if(i.ciid===t.ciid||i.ciid===t.uid||i.socket&&i.socket.destroyed||i.epId===t.epId)try{e.splice(n,1);dm.logEvent(o,x,"Edge server "+r+"["+n+"] - instance remove success")}catch(e){console.log(o,x,"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(l)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(a){let e=null;n?e=i+":"+n:u&&(e=u);let t=edgeEmitter.emit("server-error"+C,{message:o+" server "+e+" is already running"});u&&(t=edgeEmitter.emit("server-error"+C,{message:o+" server path:"+e+" is already running"}));t||dm.logEvent(o,e,"Edge server is already running");try{EdgeGlobalServer.close()}catch(t){dm.logEvent(o,e,"Eddge server - EdgeGlobalServer.close() error:",t.message)}}let N=null,O=null;try{N=function(){try{const e={},t=decodeData(encodedAccessTkn,"hex");let r=/^[0-9a-zA-Z]+$/;if(d.accessTkn){if(d.accessTkn.length<16){console.log("\naccessTkn must be at least 16 bytes long");throw"Edge server invalid access token"}if(d.accessTkn.length>200){console.log("\naccessTkn is too long");throw"Edge server invalid access token"}if(d.accessTkn.match(r)){console.log("\naccessTkn must be a combination alphanumeric and special characters.");throw"Edge invalid access token"}e.optionTkn=d.accessTkn}else e.optionTkn=null;(t.sfileTkn&&t.sfileTkn.port===n&&t.sfileTkn.ip===i||t.sfileTkn&&t.sfileTkn.path===u)&&(e.fileTkn=t.sfileTkn.tkn);return e}catch(e){dm.logEvent("Edge server getServerTknSources error:",e.message)}}();O={publish:g,dataSource:h,read:m,write:v,httpGet:y,httpPost:E,subscribe:f,secure:s,allowInsecure:!s,secureAccess:c,publicAccess:l,optionTkn:N.optionTkn,fileTkn:N.fileTkn,type:o};if(n&&i){O.address={port:n,host:i,type:o};O.host=i;O.port=n}else if(u){O.address={path:u,type:o};O.path=u;O.unixPath=u}serverTopicStore.push(O)}catch(e){dm.logEvent("Edge server capture serverTopicInfo error:",e.message)}function B(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 R(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,_=5e3;function J(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&&b.forEach((e=>{e.topic===t.topic&&setImmediate(t.send,e.currentDataValue)}))}))}),1e3)}if(F){let i=_,n={},s="",c=!0,l=null;n.topic=e.topic;n.type="fixed";n.dataChange=!1;n.pollInterval=i;n.autoStopPolling=!0;e.pollInterval&&(i=e.pollInterval);function a(t,r){try{e.pollInterval||(n.pollInterval?i=n.pollInterval:n.interval&&(i=n.interval));i<1e3&&(i=_);clearInterval(l);l=setInterval((()=>{setImmediate(r,n)}),i);c=!1}catch(e){dm.logEvent(o,x,"Edge server stdPublishData - startPubDataPolling error:",e.message)}}function d(e){if(0===stdPublishDataStore.length){clearInterval(l);F=!0}}n.send=function(e){try{let r=(e=validateData(e)).includes("ciphertext");!function(e,t){try{let r=!0,i={topic:e,currentDataValue:t};b.forEach(((i,n)=>{if(i.topic===e){i.currentDataValue=t;r=!1}}));r&&b.push(i)}catch(e){dm.logEvent("Edge server - getPubTopicCurrentData error:",e.message)}}(n.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);n.dataChange=!0;stdPublishDataStore.forEach((e=>{n.topic===e.topic&&setImmediate(e.send,s)}))}else n.dataChange=!1;n.autoStopPolling&&d();c&&a(0,t)}catch(e){dm.logEvent(o,x,"Edge server stdPublishData pubObject.send error:",e.message)}};t(n);c&&a(0,t);F=!1;let p=Object.seal(n);Object.defineProperty(p,"pollInterval",{writable:!1});p.interval&&Object.defineProperty(p,"interval",{writable:!1})}}function K(e,t){let r={},i={},n="";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(n.normalize("NFC")!==t.normalize("NFC")){i||(n=t);r.dataChange=!0;e.send(n)}else r.dataChange=!1}catch(e){dm.logEvent(o,x,"Edge server settablePublishData pubObject.send error:",e.message)}};t&&setImmediate(t,r);function s(){setImmediate(t,r)}i.pollInterval=_;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=_);e.epId&&(i.epId=e.epId);i.end=e.end;setServerPublishDataStore(i);let c=Object.seal(r);c.pollInterval&&Object.defineProperty(c,"pollInterval",{writable:!1})}catch(l){dm.logEvent(o,x,"Edge server settablePublishData error:",l.message)}}function q(e,t){let r=!0,i=null;e.settable?i="settable":e.std&&(i="std");t.forEach(((n,s)=>{if(e.topic===n.topic&&e.epId===n.epId){r=!1;n.serverPubInterval&&clearInterval(n.serverPubInterval);(e.unsub||e.send)&&setImmediate(e.send,"true");n.end&&n.end();try{t.splice(s,1);dm.logEvent(o,x,"Edge server "+n.topic+" "+i+" unsub - success")}catch(e){dm.logEvent(o,x,"Edge server "+n.topic+" "+i+" unsub error:",e.message);throw"Edge server "+n.topic+" unsub error: "+e.message}}}));if(r){(e.unsub||e.send)&&setImmediate(e.send,"false");dm.logEvent(o,x,"Edge server "+e.topic+" "+i+" no pub instance - nothing to unsub");return!1}return!0}function G(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(o,x,"Edge server",t.topic,"client-exit std unsub - success")}catch(e){dm.logEvent(o,x,"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(o,x,"Edge server",t.topic,"client-exit settable unsub - success")}catch(e){dm.logEvent(o,x,"Edge server unsub subscriberStore.splice(x, 1) error: ",e.message);throw"Edge server "+t.topic+"client-exit settable unsub error: "+e.message}}}))}function U(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=_)}else{if("string"!=typeof e)throw"Edge server publish invalid topic";r=e}B(r,g);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(q,o,settablePublishDataStore);setImmediate(J,n,t)}else if(n.settable){o.settable=!0;setImmediate(q,o,stdPublishDataStore);setImmediate(K,n,t)}}));let o="edge-server-unpublish"+r;edgeEmitter.listenerCount(o)<1&&edgeEmitter.on(o,(e=>{e.unsub&&e.topic&&r&&(e.std?setImmediate(q,e,stdPublishDataStore):e.settable&&setImmediate(q,e,settablePublishDataStore))}))}function H(e,t){let r="dataSource";if(e){B(e,h);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 L(e){let t=!1;serverSubscriberDataStore.forEach(((r,i)=>{r.topic===e&&r.unsub&&(t=!0)}));return t}function z(e,t){if(!e){console.log("Edge server subscribe error: missing/invalid topic name");dm.logEvent("Edge server subscribe error: missing/invalid topic name",e);return}if(!t)throw"Edge server subscribe requires a callback function";let r=null,i=null,n=null,o=!0;if("object"==typeof e){e.topic&&(r=e.topic);if(!Number.isInteger(e.interval)){console.log("Edge server subscribe invalid option interval - must be an integer number");throw"Edge server subscribe invalid option interval: "+e.interval}i=e.interval<1e3?1e3:e.interval}else"string"==typeof e&&(r=e);B(r,f);edgeEmitter.listenerCount("dataSource"+r)<1&&edgeEmitter.on("dataSource"+r,(e=>{try{if(r!==e.topic)throw"Edge server subscribe invalid topic";if(L(r))return;if(e.payload){n||setServerSubscriberDataStore(e);n=e.payload;if("string"==typeof e.payload)try{let t=JSON.parse(n);n=t;if(Array.isArray(t))n=t[0];else if("object"==typeof t)n=JSON.stringify(t);else{if("number"!=typeof t)throw"Edge server invalid client-publish rcvd payload data - not an object or number";n=Buffer.from(e.payload)}}catch(t){"string"==typeof e.payload&&(n=Buffer.from(e.payload))}else{if("object"!=typeof e.payload)throw"Edge ser