Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
expeehaa committed May 4, 2020
2 parents 64bd4e6 + 276e14c commit 1327440
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 13 deletions.
6 changes: 4 additions & 2 deletions README
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Stylusboard #

Shared whiteboard server for [Stylus Labs Write](http://www.styluslabs.com) - enables multiple users to collaborate in real time on a handwritten document.
In Write, enable advanced preferences, then in the Advanced -> Whiteboard server field enter the host name or IP address of the machine running `stylusboard`.
In Write, enable advanced preferences, then in the Advanced -> Whiteboard server field enter the host name or IP address of the machine running this server.

Last tested with an ancient version of node.js (0.10.36)
Run `node.js whiteboard.js`. Last tested with an ancient version of node.js (0.10.36)

Linux executable packaged with jx: http://www.styluslabs.com/write/stylusboard (Download and run this to get started quickly).

By default, runs in anonymous mode, accepting all connections. To require login, specify a sqlite database file with the --db argument or db option in config file. dbUtil.js can be used to create and add users to the database - run `node dbUtil.js help` for options.

Contact support at styluslabs.com with any issues or to request changes to the client-side code in Write.
97 changes: 97 additions & 0 deletions dbUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
var wbDB = require('./whiteboardDB');
var fs = require('fs');
var pargs = require('minimist')(process.argv);

if(pargs["db"] && !fs.existsSync(pargs["db"]))
console.log("Database file " + pargs["db"] + " will be created.");

var db = wbDB.openDB(pargs["db"], function(err) {
if(err) {
console.log("Error opening database " + pargs["db"] + ": ", err);
process.exit(-102);
}
});

// copied from stylusweb app

var addNewAccount = function(newData, callback)
{
// check for conflict
db.get("SELECT username, email FROM users WHERE username = ? OR email = ?", newData.user, newData.email,
function(err, row) {
if(row) {
callback(row.username == newData.user ? 'username-taken' : 'email-taken');
}
else {
// no conflict
var pwhash = wbDB.saltAndHash(newData.pass);
db.run("INSERT INTO users(username, password, email, displayname) VALUES(?, ?, ?, ?)",
newData.user, pwhash, newData.email, newData.displayname, callback);
}
});
}

var updatePasswordByUser = function(username, newPass, callback)
{
var pwhash = wbDB.saltAndHash(newPass);
db.run("UPDATE users SET password = ? WHERE username = ?", pwhash, username, callback);
}

var deleteAccountByUser = function(username, callback)
{
db.run("DELETE FROM users WHERE username = ?", username, callback);
}


// commands
args = pargs._.slice(2);
var cmd = args[0];

if(cmd == "adduser") {
var userData = {'user': args[1], 'pass': args[2], 'email': args[3], 'displayname': args[4]};
addNewAccount(userData, function(e){
if(e)
console.log("Error adding user: ", e);
else
console.log("User added.");
});
}
else if(cmd == "updatepw") {
var user = args[1];
var pass = args[2];
updatePasswordByUser(user, pass, function(e){
if(e)
console.log("Error updating password: ", e);
else if(!this.changes)
console.log("User not found.");
else
console.log("Password updated.");
});
}
else if(cmd == "rmuser") {
var user = args[1];
deleteAccountByUser(user, function(e){
if(e)
console.log("Error removing user: ", e);
else
console.log("User deleted.");
});
}
else if(cmd == "list") {
db.all("SELECT username FROM users", function(err, rows) {
rows.forEach(function(row){ console.log(row.username); });
});
}
else {
console.log("Stylus Labs whiteboard database utility");
console.log("Available commands:");
//console.log(" node dbTool.js --db <path to database file> createdb");
console.log(" adduser <username> <password> [[<email> <displayname>]] - add new user");
console.log(" updatepw <username> <newpassword> - change password for user");
console.log(" rmuser <username> - delete user");
console.log(" list - list all users");
console.log("Arguments:");
console.log(" --db <path to database file> (required)");
console.log("Example");
console.log("node dbUtil.js --db db1.sqlite adduser user1 passwd1");
}
26 changes: 15 additions & 11 deletions whiteboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,13 @@ var swbserver = net.createServer(function(stream) {
var client = new Client(stream);

stream.setTimeout(0);
stream.setEncoding("utf8");
stream.setEncoding("binary");
swblog.info(`${client.remote} connected`);

stream.on("data", function(data) {
swblog.debug(`SWB server rcvd from ${client.remote} data:`, data);
if(pargs["dump"]) {
swblog.debug(`SWB server rcvd from ${client.remote} data:`, data);
}

while(data.length > 0) {
if(client.expectdatalen > 0) {
Expand All @@ -228,14 +230,16 @@ var swbserver = net.createServer(function(stream) {
if(client.expectdatalen > data.length) {
client.expectdatalen -= data.length;
} else {
swblog.debug(`SWB server rcvd ${client.tempdata.length} bytes of data from ${client.remote}`);

data = data.substr(client.expectdatalen);
client.expectdatalen = 0;
var wb = client.whiteboard;
wb.history += client.tempdata;

wb.clients.forEach(function(c) {
// echo to all clients, including sender
c.stream.write(client.tempdata);
c.stream.write(client.tempdata, "binary");
});

client.tempdata = "";
Expand All @@ -262,9 +266,9 @@ var swbserver = net.createServer(function(stream) {
// get list of current SWB users
var repo = args["document"];
if(whiteboards[repo]) {
stream.write(whiteboards[repo].clients.map(c=>c.name).join(","));
stream.write(whiteboards[repo].clients.map(c=>c.name).join(","), "binary");
} else {
stream.write("-");
stream.write("-", "binary");
}
} else if(command == "/start") {
// arguments: version (protocal version) - ignored for now;, user, document, (history) offset (optional),
Expand All @@ -281,7 +285,7 @@ var swbserver = net.createServer(function(stream) {
}
} else if(!wb || args["token"] != md5(args["user"] + wb.token)) {
swblog.warn(`${client.remote}: whiteboard not found or invalid token`);
stream.write("<undo><accessdenied message='Whiteboard not found. Please try again.'/></undo>\n");
stream.write("<undo><accessdenied message='Whiteboard not found. Please try again.'/></undo>\n", "binary");
disconnectClient(client);
return;
}
Expand All @@ -292,9 +296,9 @@ var swbserver = net.createServer(function(stream) {
if(wb.history.length > 0) {
var histoffset = parseInt(args["offset"]);
if(histoffset > 0)
stream.write(wb.history.slice(histoffset));
stream.write(wb.history.slice(histoffset, "binary"));
else
stream.write(wb.history);
stream.write(wb.history, "binary");
}

wb.clients.push(client);
Expand All @@ -306,7 +310,7 @@ var swbserver = net.createServer(function(stream) {
// use full disconnect procedure to send "disconnect" signal since we'll send "connect" signal below
if(c.name == args["user"] && c != client) {
swblog.info(`disconnecting ${c.remote} due to connection of ${client.remote} for user: ${c.name}`);
c.stream.write("<undo><accessdenied message='User logged in from another location.'/></undo>\n");
c.stream.write("<undo><accessdenied message='User logged in from another location.'/></undo>\n", "binary");
disconnectClient(c);
}
});
Expand All @@ -315,7 +319,7 @@ var swbserver = net.createServer(function(stream) {
var msg = `<undo><connect name='${client.name}' uuid='${args["uuid"]}'/></undo>\n`;
wb.history += msg;
wb.clients.forEach(function(c) {
c.stream.write(msg);
c.stream.write(msg, "binary");
});
} else if(command == "/data") {
client.expectdatalen = parseInt(args["length"]);
Expand Down Expand Up @@ -346,7 +350,7 @@ var swbserver = net.createServer(function(stream) {
var msg = `<undo><disconnect name='${client.name}'/></undo>\n`;
wb.history += msg;
wb.clients.forEach(function(c) {
c.stream.write(msg);
c.stream.write(msg, "binary");
});
}
}
Expand Down

0 comments on commit 1327440

Please sign in to comment.