server.js
4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Gun Multi-WS Monster */
/* Spawn multiple Gun WebSockets from the same HTTP/HTTPS server
* Each Gun is scoped to its ws.path and intended for ephemeral usage
* MIT Licensed (C) QXIP 2020
*/
var no = require('gun/lib/nomem')(); // no-memory storage adapter for RAD
const fs = require("fs");
const url = require("url");
const Gun = require("gun"); // load defaults
//require("./gun-ws.js"); // required to allow external websockets into gun constructor
//require("./mem.js"); // disable to allow file writing for debug
require("gun/sea");
require("gun/lib/then");
const SEA = Gun.SEA;
const http = require("http");
const https = require("https");
const WebSocket = require("ws");
var debug = process.env.DEBUG || true;
var config = {};
if(debug) console.log(SEA, Gun.SEA);
config.options = {
}
if (!process.env.hasOwnProperty('SSL')||process.env.SSL == false) {
var server = http.createServer();
server.listen(process.env.PORT || 8767);
} else {
config.options.key= process.env.SSLKEY ? fs.readFileSync(process.env.SSLKEY) : fs.readFileSync('/home/coder/ssl/rig/privkey.pem'),
config.options.cert= process.env.SSLCERT ? fs.readFileSync(process.env.SSLCERT) : fs.readFileSync('/home/coder/ssl/rig/fullchain.pem')
var server = https.createServer(config.options);
server.listen(process.env.PORT || 8767);
}
let sigs ={};
async function hasValidToken(msg,pathname) {
return true;
}
// LRU with last used sockets
const QuickLRU = require("quick-lru");
const lru = new QuickLRU({ maxSize: 10, onEviction: false });
server.on("upgrade", async function(request, socket, head) {
let parsed = url.parse(request.url,true);
if(debug) console.log("parsed",parsed);
let sig = parsed.query && parsed.query.sig ? parsed.query.sig : false;
let creator = parsed.query && parsed.query.creator ? parsed.query.creator : "server";
let pathname = parsed.pathname || "/gun";
if (debug) console.log("Got WS request", pathname);
var gun = { gun: false, server: false };
if (pathname) {
let roomname = pathname.split("").slice(1).join("");
console.log("roomname",roomname);
if (lru.has(pathname)) {
// Existing Node
if (debug) console.log("Recycle id", pathname);
gun = await lru.get(pathname);
} else {
// Create Node
if (debug) console.log("Create id", pathname);
// NOTE: Only works with lib/ws.js shim allowing a predefined WS as ws.web parameter in Gun constructor
//gun.server = new WebSocket.Server({ noServer: true, path: pathname });
if (debug) console.log("set peer", request.headers.host + pathname);
if(sig) {
sigs[roomname]=sig;
if(debug) console.log("stored sig ",sig,"to pathname",roomname);
}
//console.log("gunsea",Gun.SEA);
//SEA.throw = 1;
/*Gun.on('opt',function(ctx){
if(ctx.once) return;
ctx.on('in',function(msg){
console.log(msg);
this.to.next(msg);
})
})*/
const g = gun.gun = Gun({
peers: [], // should we use self as peer?
localStorage: false,
store: no,
file: "tmp" + pathname, // make sure not to reuse same storage context
radisk: true, // important for nomem!
multicast: false,
ws: { noServer: true, path: pathname }
});
gun.server = gun.gun.back('opt.ws.web'); // this is the websocket server
lru.set(pathname, gun);
let obj = {roomname:roomname,creator:creator,socket:{}};
if(sig) {
let user = g.user();
user.create(roomname,sig,async function(dack){
console.log("We've got user create ack",dack,roomname,sig);
if(dack.err){ console.log("error in user.create",dack.err); }
user.auth(roomname,sig,async function(auth){
console.log("We've got user auth ack",auth);
if(auth.err){ console.log('error in auth',auth.err); }
//console.log("auth",auth,roomname,sig);
Object.assign(obj,{
pub:dack.pub,
passwordProtected:true
});
console.log("putting object to user",obj,user);
user.get(roomname).put(obj,function(roomack){ //TODO: @marknadal fix me
console.log("roomnode?",roomack);
var roomnode = user.get(roomname);
g.get('rtcmeeting').get(roomname).put(roomnode,function(puback){
console.log("put object",puback);
});
});
});
});
} else {
Object.assign(obj,{passwordProtected:false});
g.get("rtcmeeting").get(roomname).put(obj,function(grack){
console.log("room created",grack);
});
}
}
}
if (gun.server) {
// Handle Request
gun.server.handleUpgrade(request, socket, head, function(ws) {
if (debug) console.log("connecting to gun instance", gun.gun.opt()._.opt.ws.path);
gun.server.emit("connection", ws, request);
});
} else {
if (debug) console.log("destroying socket", pathname);
socket.destroy();
}
});