RLG-Web: make login sessions time out.
After enough inactivity, log the user out automatically.
This commit is contained in:
parent
aba0a4b7da
commit
20d72fc066
2 changed files with 55 additions and 4 deletions
12
rlgterm.js
12
rlgterm.js
|
|
@ -164,6 +164,9 @@ function processMsg(msg) {
|
||||||
else if (msgDict.t == "E") {
|
else if (msgDict.t == "E") {
|
||||||
if (msgDict.c == 1 || msgDict.c == 6 || msgDict.c == 7) {
|
if (msgDict.c == 1 || msgDict.c == 6 || msgDict.c == 7) {
|
||||||
gameover();
|
gameover();
|
||||||
|
if (msgDict.c == 1) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
debug(1, "Server error: " + msgDict.s);
|
debug(1, "Server error: " + msgDict.s);
|
||||||
}
|
}
|
||||||
|
|
@ -496,6 +499,9 @@ function startgame(game) {
|
||||||
}
|
}
|
||||||
else if (reply.t == 'E') {
|
else if (reply.t == 'E') {
|
||||||
debug(1, "Could not start game: " + reply.s);
|
debug(1, "Could not start game: " + reply.s);
|
||||||
|
if (reply.c == 1) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
req.open('POST', '/play', true);
|
req.open('POST', '/play', true);
|
||||||
|
|
@ -551,6 +557,12 @@ function gameover() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
lcred = null;
|
||||||
|
lname = null;
|
||||||
|
setmode("login");
|
||||||
|
}
|
||||||
|
|
||||||
function stop() {
|
function stop() {
|
||||||
if (!termemu.sessid)
|
if (!termemu.sessid)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
47
rlgwebd.js
47
rlgwebd.js
|
|
@ -59,7 +59,7 @@ var allowlogin = true;
|
||||||
* been authenticated.
|
* been authenticated.
|
||||||
*/
|
*/
|
||||||
/* TODO take a callback, or emit success/err events. */
|
/* TODO take a callback, or emit success/err events. */
|
||||||
function TermSession(game, user, dims) {
|
function TermSession(game, user, dims, lkey) {
|
||||||
/* First make sure starting the game will work. */
|
/* First make sure starting the game will work. */
|
||||||
if (game in games) {
|
if (game in games) {
|
||||||
this.game = games[game];
|
this.game = games[game];
|
||||||
|
|
@ -69,6 +69,7 @@ function TermSession(game, user, dims) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.player = String(user);
|
this.player = String(user);
|
||||||
|
this.key = lkey;
|
||||||
/* This order seems to best avoid race conditions... */
|
/* This order seems to best avoid race conditions... */
|
||||||
this.alive = false;
|
this.alive = false;
|
||||||
this.sessid = randkey(2);
|
this.sessid = randkey(2);
|
||||||
|
|
@ -361,6 +362,14 @@ function reaper() {
|
||||||
fs.fstat(session.record.fd, function (err, stats) {
|
fs.fstat(session.record.fd, function (err, stats) {
|
||||||
if (!err && now - stats.mtime > playtimeout) {
|
if (!err && now - stats.mtime > playtimeout) {
|
||||||
tslog("Reaping %s", session.sessid);
|
tslog("Reaping %s", session.sessid);
|
||||||
|
/* Dissociate it with its login name. */
|
||||||
|
var sn = logins[session.key].sessions.indexOf(session.sessid);
|
||||||
|
if (sn >= 0) {
|
||||||
|
logins[session.key].sessions.splice(sn, 1);
|
||||||
|
if (now - logins[session.key].ts > playtimeout)
|
||||||
|
logins[session.key].ts = new Date(now - playtimeout);
|
||||||
|
}
|
||||||
|
/* Shut it down. */
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -368,6 +377,35 @@ function reaper() {
|
||||||
for (var sessid in sessions) {
|
for (var sessid in sessions) {
|
||||||
reapcheck(sessions[sessid]);
|
reapcheck(sessions[sessid]);
|
||||||
}
|
}
|
||||||
|
/* HELPME this is about as clever as I can code, so I can't tell whether
|
||||||
|
* there are any bugs. */
|
||||||
|
for (var lkey in logins) {
|
||||||
|
if (logins[lkey].sessions.length == 0) {
|
||||||
|
/* A login with no current games can be killed for inactivity. */
|
||||||
|
if (now - logins[lkey].ts > playtimeout * 4) {
|
||||||
|
tslog("Login for %s (key %s) timed out", logins[lkey].name, lkey);
|
||||||
|
delete logins[lkey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Check for games that have terminated normally, and update
|
||||||
|
* the timestamp. */
|
||||||
|
var expired = [];
|
||||||
|
var targarray = logins[lkey].sessions;
|
||||||
|
/* Let's not find out what happens if you modify an array
|
||||||
|
* you're iterating through. */
|
||||||
|
for (var i = 0; i < targarray.length; i++) {
|
||||||
|
if (!(targarray[i] in sessions))
|
||||||
|
expired.push(targarray[i]);
|
||||||
|
}
|
||||||
|
if (expired.length > 0) {
|
||||||
|
logins[lkey].ts = new Date(now);
|
||||||
|
for (var j = 0; j < expired.length; j++) {
|
||||||
|
targarray.splice(targarray.indexOf(expired[j], 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function login(req, res, formdata) {
|
function login(req, res, formdata) {
|
||||||
|
|
@ -400,7 +438,7 @@ function login(req, res, formdata) {
|
||||||
var lkey = randkey(2);
|
var lkey = randkey(2);
|
||||||
while (lkey in logins)
|
while (lkey in logins)
|
||||||
lkey = randkey(2);
|
lkey = randkey(2);
|
||||||
logins[lkey] = {"name": username, "ts": new Date()};
|
logins[lkey] = {"name": username, "ts": new Date(), "sessions": []};
|
||||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||||
var reply = {"t": "l", "k": lkey, "u": username};
|
var reply = {"t": "l", "k": lkey, "u": username};
|
||||||
res.write(JSON.stringify(reply));
|
res.write(JSON.stringify(reply));
|
||||||
|
|
@ -452,7 +490,7 @@ function startgame(req, res, formdata) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Game starting has been approved.
|
// Game starting has been approved.
|
||||||
var nsession = new TermSession(gname, username, dims);
|
var nsession = new TermSession(gname, username, dims, lkey);
|
||||||
if (nsession) {
|
if (nsession) {
|
||||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||||
var reply = {"t": "l", "id": nsession.sessid, "w": nsession.w, "h":
|
var reply = {"t": "l", "id": nsession.sessid, "w": nsession.w, "h":
|
||||||
|
|
@ -461,6 +499,7 @@ function startgame(req, res, formdata) {
|
||||||
res.end();
|
res.end();
|
||||||
tslog("%s playing %s (key %s, pid %d)", username, gname,
|
tslog("%s playing %s (key %s, pid %d)", username, gname,
|
||||||
nsession.sessid, nsession.child.pid);
|
nsession.sessid, nsession.child.pid);
|
||||||
|
logins[lkey].sessions.push(nsession.sessid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sendError(res, 5, "Failed to open TTY");
|
sendError(res, 5, "Failed to open TTY");
|
||||||
|
|
@ -506,7 +545,7 @@ function register(req, res, formdata) {
|
||||||
var lkey = randkey(2);
|
var lkey = randkey(2);
|
||||||
while (lkey in logins)
|
while (lkey in logins)
|
||||||
lkey = randkey(2);
|
lkey = randkey(2);
|
||||||
logins[lkey] = {"name": uname, "ts": new Date()};
|
logins[lkey] = {"name": uname, "ts": new Date(), "sessions": []};
|
||||||
var reply = {"t": "r", "k": lkey, "u": uname};
|
var reply = {"t": "r", "k": lkey, "u": uname};
|
||||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||||
res.write(JSON.stringify(reply));
|
res.write(JSON.stringify(reply));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue