diff --git a/dist/server.js b/dist/server.js index 1e2792b..b4f5d6e 100644 --- a/dist/server.js +++ b/dist/server.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -var Y=Object.create;var S=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=n=>S(n,"__esModule",{value:!0});var ne=(n,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of Q(r))!ee.call(n,o)&&(e||o!=="default")&&S(n,o,{get:()=>r[o],enumerable:!(t=q(r,o))||t.enumerable});return n},u=(n,r)=>ne(te(S(n!=null?Y(Z(n)):{},"default",!r&&n&&n.__esModule?{get:()=>n.default,enumerable:!0}:{value:n,enumerable:!0})),n);var N=require("commander"),M=u(require("fs")),J=u(require("http")),K=u(require("https"));var A=u(require("pino")),re=process.env.NODE_ENV==="development"?"debug":"info",f=(0,A.default)({name:"sigver",level:re});var j=u(require("url")),W=u(require("ws"));var H=require("rxjs"),m=require("rxjs/operators");var G=u(require("crypto")),_=2147483647,E=new Set,g=class extends Error{constructor(r,e=""){super();this.name=this.constructor.name,this.code=r,this.message=`${r}: ${e}`}},P=4741,$=4742,y=4743,D=4744,R=4745,F=512;function C(n){if(n==="")throw new g(P,`The key ${n} is an empty string`);if(n.length>F)throw new g(P,`The key length exceeds the limit of ${F} characters`)}function v(){let n=G.randomBytes(4).readUInt32BE(0);return n>_&&(n-=_),n===0||E.has(n)?v():(E.add(n),n)}function k(n){E.delete(n)}var T=new Map;function L(n,r,e,t){let o=n.group||T.get(t);if(o===void 0)return o=new U(t),o.addMember(n,r),T.set(t,o),!0;if(o.size===1){if(n.group!==void 0)return!0;if(o.hasMembersInCommon(e))return o.addMember(n,r),!0;let i=o.getFirstMember();if(n.triedMembers.includes(i.netfluxId))return o.addMember(n,r),o.removeMember(i),i.close(D,"replaced by a peer as prevented him from joining the group"),!0}return o.hasMembersInCommon(e)?(o.addMember(n,r),!0):(o.removeMember(n),n.bindWith(o.selectMemberFor(n)),!1)}var U=class{constructor(r){this.key=r,this.members=new Set}get size(){return this.members.size}getFirstMember(){return this.members.values().next().value}hasMembersInCommon(r){if(r.length!==0){for(let e of this.members)if(r.includes(e.netfluxId))return!0}return!1}addMember(r,e){return r.becomeMember(this,e),this.members.add(r),!0}removeMember(r){r.noLongerAMember(),this.members.delete(r),this.size===0&&T.delete(this.key)}selectMemberFor(r){let e;for(let t of this.members){let o=t.netfluxId;if(o!==void 0&&!r.triedMembers.includes(o)){if(t.favored)return t;e===void 0&&(e=t)}}return e!==void 0?e:(r.triedMembers=[],this.selectMemberFor(r))}};var d=u(require("protobufjs/minimal")),b=d.Reader,x=d.Writer,I=d.util,a=d.roots.default||(d.roots.default={}),l=a.Message=(()=>{function n(e){if(e)for(let t=Object.keys(e),o=0;o>>3){case 1:s.heartbeat=t.bool();break;case 2:s.content=a.Content.decode(t,t.uint32());break;case 3:s.connect=a.GroupData.decode(t,t.uint32());break;case 4:s.connected=t.bool();break;default:t.skipType(c&7);break}}return s},n})(),ve=a.Content=(()=>{function n(r){if(r)for(let e=Object.keys(r),t=0;t>>3){case 1:i.senderId=e.uint32();break;case 2:i.recipientId=e.uint32();break;case 3:i.lastData=e.bool();break;case 4:i.data=e.bytes();break;default:e.skipType(s&7);break}}return i},n})(),Ie=a.GroupData=(()=>{function n(r){if(this.members=[],r)for(let e=Object.keys(r),t=0;t>>3){case 1:i.id=e.uint32();break;case 2:if(i.members&&i.members.length||(i.members=[]),(s&7)===2){let c=e.uint32()+e.pos;for(;e.pos{switch(s.type){case"connect":{let{id:c,members:p}=s.connect;L(this,c,p,r)?t(ce):t(ae);break}case"heartbeat":i=0;break;case void 0:this.close(y,"Wrong message format or unknown message");break}});let i=0;this.heartbeatInterval=setInterval(()=>{i++,i>=oe&&(clearInterval(this.heartbeatInterval),this.close($,"Too many missed hearbeats")),t(se)},ie)}send(r){this.sendFunc(l.encode(l.create(r)).finish())}close(r,e){this.closeFunc(r,e)}onMessage(r){try{this.next(l.decode(r))}catch(e){this.close(y,e.message)}}becomeMember(r,e){this.group=r,this.triedMembers=[],this.netfluxId=e}noLongerAMember(){this.group=void 0,this.netfluxId=void 0}onClose(){clearInterval(this.heartbeatInterval),this.group!==void 0&&this.group.removeMember(this),this.complete(),k(this.signalingId)}bindWith(r){this.subToMember!==void 0&&this.subToMember.unsubscribe(),this.subToJoining!==void 0&&this.subToJoining.unsubscribe(),k(this.signalingId),this.signalingId=v(),this.triedMembers.push(r.netfluxId),this.subToMember=r.pipe((0,m.filter)(({content:e})=>e!=null&&e.recipientId===this.signalingId),(0,m.pluck)("content")).subscribe(({lastData:e,data:t})=>{this.send({content:{recipientId:this.signalingId,senderId:0,data:t}}),e&&this.subToMember.unsubscribe()},()=>this.send({content:{recipientId:this.signalingId,senderId:0}}),()=>this.send({content:{recipientId:this.signalingId,senderId:0}})),this.subToJoining=this.pipe((0,m.filter)(({content:e})=>e!=null),(0,m.pluck)("content")).subscribe(({lastData:e,data:t})=>{r.send({content:{recipientId:0,senderId:this.signalingId,data:t}}),e&&this.subToJoining.unsubscribe()},()=>r.send({content:{recipientId:0,senderId:this.signalingId}}),()=>r.send({content:{recipientId:0,senderId:this.signalingId}}))}};function B(n){let r=new W.default.Server({perMessageDeflate:!1,server:n});return r.on("error",e=>f.fatal("WebSocketServer error",e)),r.on("connection",(e,t)=>{try{if(t.url===void 0)throw new Error("URL is undefined");let{key:o,favored:i}=le(t.url);C(o);let s=new O(o,i,c=>{try{e.send(c)}catch(p){f.error("Fail to send data",p.message),e.close(R,p.message)}},(c,p)=>e.close(c,p));e.onmessage=({data:c})=>{c instanceof Uint8Array?s.onMessage(c):(f.error("Wrong data type"),s.close(y,"Wrong data type"))},e.onerror=c=>s.error(c),e.onclose=()=>s.onClose()}catch(o){f.error("WebSocket connection error: ",o.message),e.close(o.code,o.message)}}),r}function le(n){let{pathname:r,query:e}=j.parse(n,!0);if(r==null)throw new g(R,"URL pathname is undefined");return{key:r.slice(1),favored:"favored"in e}}var de="0.0.0.0",ue="8000",w=new N.Command;w.version("0.0.0-development").description("Signaling server for WebRTC. Used by Netflux API (https://coast-team.github.io/netflux/)").option("-h, --host ","Select host address to bind to",de).option("-p, --port ","Select port to use",ue).option("-k, --key ","Private key for the certificate.").option("-c, --cert ","The server certificate.").option("-a, --ca ","The additional intermediate certificate or certificates that web browsers will need in order to validate the server certificate.").on("--help",()=>{console.log(` +var Y=Object.create;var S=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=n=>S(n,"__esModule",{value:!0});var ne=(n,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of Q(r))!ee.call(n,o)&&(e||o!=="default")&&S(n,o,{get:()=>r[o],enumerable:!(t=q(r,o))||t.enumerable});return n},u=(n,r)=>ne(te(S(n!=null?Y(Z(n)):{},"default",!r&&n&&n.__esModule?{get:()=>n.default,enumerable:!0}:{value:n,enumerable:!0})),n);var N=require("commander"),M=u(require("fs")),J=u(require("http")),K=u(require("https"));var A=u(require("pino")),re=process.env.NODE_ENV==="development"?"debug":"info",f=(0,A.default)({name:"sigver",level:re});var j=u(require("url")),W=u(require("ws"));var H=require("rxjs"),m=require("rxjs/operators");var G=u(require("crypto")),_=2147483647,E=new Set,g=class extends Error{constructor(r,e=""){super();this.name=this.constructor.name,this.code=r,this.message=`${r}: ${e}`}},P=4741,$=4742,y=4743,D=4744,R=4745,F=512;function C(n){if(n==="")throw new g(P,`The key ${n} is an empty string`);if(n.length>F)throw new g(P,`The key length exceeds the limit of ${F} characters`)}function v(){let n=G.randomBytes(4).readUInt32BE(0);return n>_&&(n-=_),n===0||E.has(n)?v():(E.add(n),n)}function k(n){E.delete(n)}var T=new Map;function L(n,r,e,t){let o=n.group||T.get(t);if(o===void 0)return o=new U(t),o.addMember(n,r),T.set(t,o),!0;if(o.size===1){if(n.group!==void 0)return!0;if(o.hasMembersInCommon(e))return o.addMember(n,r),!0;let i=o.getFirstMember();if(n.triedMembers.includes(i.netfluxId))return o.addMember(n,r),o.removeMember(i),i.close(D,"replaced by a peer as prevented him from joining the group"),!0}return o.hasMembersInCommon(e)?(o.addMember(n,r),!0):(o.removeMember(n),n.bindWith(o.selectMemberFor(n)),!1)}var U=class{constructor(r){this.key=r,this.members=new Set}get size(){return this.members.size}getFirstMember(){return this.members.values().next().value}hasMembersInCommon(r){if(r.length!==0){for(let e of this.members)if(r.includes(e.netfluxId))return!0}return!1}addMember(r,e){return r.becomeMember(this,e),this.members.add(r),!0}removeMember(r){r.noLongerAMember(),this.members.delete(r),this.size===0&&T.delete(this.key)}selectMemberFor(r){let e;for(let t of this.members){let o=t.netfluxId;if(o!==void 0&&!r.triedMembers.includes(o)){if(t.favored)return t;e===void 0&&(e=t)}}return e!==void 0?e:(r.triedMembers=[],this.selectMemberFor(r))}};var d=u(require("protobufjs/minimal")),b=d.Reader,x=d.Writer,I=d.util,a=d.roots.default||(d.roots.default={}),l=a.Message=(()=>{function n(e){if(e)for(let t=Object.keys(e),o=0;o>>3){case 1:s.heartbeat=t.bool();break;case 2:s.content=a.Content.decode(t,t.uint32());break;case 3:s.connect=a.GroupData.decode(t,t.uint32());break;case 4:s.connected=t.bool();break;default:t.skipType(c&7);break}}return s},n})(),ve=a.Content=(()=>{function n(r){if(r)for(let e=Object.keys(r),t=0;t>>3){case 1:i.senderId=e.uint32();break;case 2:i.recipientId=e.uint32();break;case 3:i.lastData=e.bool();break;case 4:i.data=e.bytes();break;default:e.skipType(s&7);break}}return i},n})(),Ie=a.GroupData=(()=>{function n(r){if(this.members=[],r)for(let e=Object.keys(r),t=0;t>>3){case 1:i.id=e.uint32();break;case 2:if(i.members&&i.members.length||(i.members=[]),(s&7)===2){let c=e.uint32()+e.pos;for(;e.pos{switch(s.type){case"connect":{let{id:c,members:p}=s.connect;L(this,c,p,r)?t(ce):t(ae);break}case"heartbeat":i=0;break;case void 0:this.close(y,"Wrong message format or unknown message");break}});let i=0;this.heartbeatInterval=setInterval(()=>{i++,i>=oe&&(clearInterval(this.heartbeatInterval),this.close($,"Too many missed hearbeats")),t(se)},ie)}send(r){this.sendFunc(l.encode(l.create(r)).finish())}close(r,e){this.closeFunc(r,e)}onMessage(r){try{this.next(l.decode(r))}catch(e){this.close(y,e.message)}}becomeMember(r,e){this.group=r,this.triedMembers=[],this.netfluxId=e}noLongerAMember(){this.group=void 0,this.netfluxId=void 0}onClose(){clearInterval(this.heartbeatInterval),this.group!==void 0&&this.group.removeMember(this),this.complete(),k(this.signalingId)}bindWith(r){this.subToMember!==void 0&&this.subToMember.unsubscribe(),this.subToJoining!==void 0&&this.subToJoining.unsubscribe(),k(this.signalingId),this.signalingId=v(),this.triedMembers.push(r.netfluxId),this.subToMember=r.pipe((0,m.filter)(({content:e})=>e!=null&&e.recipientId===this.signalingId),(0,m.pluck)("content")).subscribe(({lastData:e,data:t})=>{this.send({content:{recipientId:this.signalingId,senderId:0,data:t}}),e&&this.subToMember.unsubscribe()},()=>this.send({content:{recipientId:this.signalingId,senderId:0}}),()=>this.send({content:{recipientId:this.signalingId,senderId:0}})),this.subToJoining=this.pipe((0,m.filter)(({content:e})=>e!=null),(0,m.pluck)("content")).subscribe(({lastData:e,data:t})=>{r.send({content:{recipientId:0,senderId:this.signalingId,data:t}}),e&&this.subToJoining.unsubscribe()},()=>r.send({content:{recipientId:0,senderId:this.signalingId}}),()=>r.send({content:{recipientId:0,senderId:this.signalingId}}))}};function B(n){let r=new W.default.Server({perMessageDeflate:!1,server:n});return r.on("error",e=>f.fatal("WebSocketServer error",e)),r.on("connection",(e,t)=>{try{if(t.url===void 0)throw new Error("URL is undefined");let{key:o,favored:i}=le(t.url);C(o);let s=new O(o,i,c=>{try{e.send(c)}catch(p){f.error("Fail to send data",p.message),e.close(R,p.message)}},(c,p)=>e.close(c,p));e.onmessage=({data:c})=>{c instanceof Uint8Array?s.onMessage(c):(f.error("Wrong data type"),s.close(y,"Wrong data type"))},e.onerror=c=>s.error(c),e.onclose=()=>s.onClose()}catch(o){f.error("WebSocket connection error: ",o.message),e.close(o.code,o.message)}}),r}function le(n){let{pathname:r,query:e}=j.parse(n,!0);if(r==null)throw new g(R,"URL pathname is undefined");return{key:r.slice(1),favored:"favored"in e}}var de="0.0.0.0",ue="8000",w=new N.Command;w.version("21.0.0").description("Signaling server for WebRTC. Used by Netflux API (https://coast-team.github.io/netflux/)").option("-h, --host ","Select host address to bind to",de).option("-p, --port ","Select port to use",ue).option("-k, --key ","Private key for the certificate.").option("-c, --cert ","The server certificate.").option("-a, --ca ","The additional intermediate certificate or certificates that web browsers will need in order to validate the server certificate.").on("--help",()=>{console.log(` Examples: $ sigver # Signaling server is listening on 0.0.0.0:8000 diff --git a/package-lock.json b/package-lock.json index 50a00a1..fdcd855 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sigver", - "version": "0.0.0-development", + "version": "21.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -596,14 +596,6 @@ "dev": true, "requires": { "lodash": "^4.17.14" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - } } }, "async-listener": { @@ -1979,9 +1971,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "ip": { @@ -2332,6 +2324,12 @@ "type-check": "~0.3.2" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", diff --git a/package.json b/package.json index 9bf80b3..5f8b687 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sigver", "description": "Signaling server for Netflux API based on WebSocket", - "version": "0.0.0-development", + "version": "21.0.0", "type": "commonjs", "main": "./dist/server.js", "exports": "./dist/server.js",