HTTP cookie session size reduction.
Ylian Saint-Hilaire committed
May 12, 2021 at 10:34 UTC
e012e1427ec0d60db094435deca9bd54fabf33b5
1 file changed
+113
-111
webserver.js
+113
-111
@@ -855,7 +855,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
855
if (httpport != 443) { origin += ':' + httpport; }
856
857
var assertionExpectations = {
858
- challenge: req.session.u2fchallenge,
858
+ challenge: req.session.u2f,
859
origin: origin,
860
factor: 'either',
861
fmt: 'fido-u2f',
@@ -934,7 +934,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
934
935
// Return a U2F hardware key challenge
936
function getHardwareKeyChallenge(req, domain, user, func) {
937
- if (req.session.u2fchallenge) { delete req.session.u2fchallenge; };
937
+ delete req.session.u2f;
938
if (user.otphkeys && (user.otphkeys.length > 0)) {
939
// Get all WebAuthn keys
940
var webAuthnKeys = [];
@@ -943,7 +943,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
943
// Generate a Webauthn challenge, this is really easy, no need to call any modules to do this.
944
var authnOptions = { type: 'webAuthn', keyIds: [], timeout: 60000, challenge: obj.crypto.randomBytes(64).toString('base64') };
945
for (var i = 0; i < webAuthnKeys.length; i++) { authnOptions.keyIds.push(webAuthnKeys[i].keyId); }
946
- req.session.u2fchallenge = authnOptions.challenge;
946
+ req.session.u2f = authnOptions.challenge;
947
parent.debug('web', 'getHardwareKeyChallenge: success');
948
func(JSON.stringify(authnOptions));
949
return;
@@ -977,7 +977,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
977
978
// Normally, use the body username/password. If this is a token, use the username/password in the session.
979
var xusername = req.body.username, xpassword = req.body.password;
980
- if ((xusername == null) && (xpassword == null) && (req.body.token != null)) { xusername = req.session.tokenusername; xpassword = req.session.tokenpassword; }
980
+ if ((xusername == null) && (xpassword == null) && (req.body.token != null)) { xusername = req.session.tuser; xpassword = req.session.tpass; }
981
982
// Authenticate the user
983
obj.authenticate(xusername, xpassword, domain, function (err, userid, passhint, loginOptions) {
@@ -987,7 +987,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
987
// Check if we are in maintenance mode
988
if ((parent.config.settings.maintenancemode != null) && (user.siteadmin != 4294967295)) {
989
req.session.messageid = 115; // Server under maintenance
990
- req.session.loginmode = '1';
990
+ req.session.loginmode = 1;
991
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
992
return;
993
}
@@ -997,14 +997,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
997
var push2fa = ((parent.firebase != null) && (user.otpdev != null));
998
999
// Check if this user has 2-step login active
1000
- if ((req.session.loginmode != '6') && checkUserOneTimePasswordRequired(domain, user, req, loginOptions)) {
1000
+ if ((req.session.loginmode != 6) && checkUserOneTimePasswordRequired(domain, user, req, loginOptions)) {
1001
if ((req.body.hwtoken == '**email**') && email2fa) {
1002
user.otpekey = { k: obj.common.zeroPad(getRandomEightDigitInteger(), 8), d: Date.now() };
1003
obj.db.SetUser(user);
1004
parent.debug('web', 'Sending 2FA email to: ' + user.email);
1005
domain.mailserver.sendAccountLoginMail(domain, user.email, user.otpekey.k, obj.getLanguageCodes(req), req.query.key);
1006
req.session.messageid = 2; // "Email sent" message
1007
- req.session.loginmode = '4';
1007
+ req.session.loginmode = 4;
1008
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1009
return;
1010
}
@@ -1017,7 +1017,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1017
parent.smsserver.sendToken(domain, user.phone, user.otpsms.k, obj.getLanguageCodes(req));
1018
// Ask for a login token & confirm sms was sent
1019
req.session.messageid = 4; // "SMS sent" message
1020
- req.session.loginmode = '4';
1020
+ req.session.loginmode = 4;
1021
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1022
return;
1023
}
@@ -1048,7 +1048,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1048
// Request that the login page wait for device auth
1049
req.session.messageid = 5; // "Sending notification..." message
1050
req.session.passhint = url;
1051
- req.session.loginmode = '8';
1051
+ req.session.loginmode = 8;
1052
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1053
return;
1054
}
@@ -1072,13 +1072,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1072
1073
// Wait and redirect the user
1074
setTimeout(function () {
1075
- req.session.loginmode = '4';
1076
- req.session.tokenemail = ((user.email != null) && (user.emailVerified == true) && (domain.mailserver != null) && (user.otpekey != null));
1077
- req.session.tokensms = ((user.phone != null) && (parent.smsserver != null));
1078
- req.session.tokenpush = ((user.otpdev != null) && (parent.firebase != null));
1079
- req.session.tokenuserid = userid;
1080
- req.session.tokenusername = xusername;
1081
- req.session.tokenpassword = xpassword;
1075
+ req.session.loginmode = 4;
1076
+ if ((user.email != null) && (user.emailVerified == true) && (domain.mailserver != null) && (user.otpekey != null)) { req.session.temail = 1; }
1077
+ if ((user.phone != null) && (parent.smsserver != null)) { req.session.tsms = 1; }
1078
+ if ((user.otpdev != null) && (parent.firebase != null)) { req.session.tpush = 1; }
1079
+ req.session.tuserid = userid;
1080
+ req.session.tuser = xusername;
1081
+ req.session.tpass = xpassword;
1082
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1083
}, randomWaitTime);
1084
} else {
@@ -1095,7 +1095,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1095
if (emailcheck && (user.emailVerified !== true)) {
1096
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
1097
req.session.messageid = 3; // "Email verification required" message
1098
- req.session.loginmode = '7';
1098
+ req.session.loginmode = 7;
1099
req.session.passhint = user.email;
1100
req.session.cuserid = userid;
1101
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
@@ -1116,7 +1116,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1116
if (emailcheck && (user.emailVerified !== true)) {
1117
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
1118
req.session.messageid = 3; // "Email verification required" message
1119
- req.session.loginmode = '7';
1119
+ req.session.loginmode = 7;
1120
req.session.passhint = user.email;
1121
req.session.cuserid = userid;
1122
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
@@ -1170,7 +1170,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1170
if ((typeof user.passchange == 'number') && ((user.passchange == -1) || ((typeof domain.passwordrequirements == 'object') && (typeof domain.passwordrequirements.reset == 'number') && (user.passchange + (domain.passwordrequirements.reset * 86400) < Math.floor(Date.now() / 1000))))) {
1171
// Request a password change
1172
parent.debug('web', 'handleLoginRequest: login ok, password change requested');
1173
- req.session.loginmode = '6';
1173
+ req.session.loginmode = 6;
1174
req.session.messageid = 113; // Password change requested.
1175
req.session.resettokenuserid = userid;
1176
req.session.resettokenusername = xusername;
@@ -1195,21 +1195,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1195
// Regenerate session when signing in to prevent fixation
1196
//req.session.regenerate(function () {
1197
// Store the user's primary key in the session store to be retrieved, or in this case the entire user object
1198
- delete req.session.u2fchallenge;
1198
+ delete req.session.u2f;
1199
delete req.session.loginmode;
1200
- delete req.session.tokenuserid;
1201
- delete req.session.tokenusername;
1202
- delete req.session.tokenpassword;
1203
- delete req.session.tokenemail;
1204
- delete req.session.tokensms;
1205
- delete req.session.tokenpush;
1200
+ delete req.session.tuserid;
1201
+ delete req.session.tuser;
1202
+ delete req.session.tpass;
1203
+ delete req.session.temail;
1204
+ delete req.session.tsms;
1205
+ delete req.session.tpush;
1206
delete req.session.messageid;
1207
delete req.session.passhint;
1208
delete req.session.cuserid;
1209
delete req.session.expire;
1210
+ delete req.session.currentNode;
1211
req.session.userid = userid;
1211
- req.session.domainid = domain.id;
1212
- req.session.currentNode = '';
1212
req.session.ip = req.clientIp;
1213
1214
// If a login token was used, add this information and expire time to the session.
@@ -1253,7 +1252,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1252
// Check if we are in maintenance mode
1253
if (parent.config.settings.maintenancemode != null) {
1254
req.session.messageid = 115; // Server under maintenance
1256
- req.session.loginmode = '1';
1255
+ req.session.loginmode = 1;
1256
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1257
return;
1258
}
@@ -1267,7 +1266,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1266
// Accounts that start with ~ are not allowed
1267
if ((typeof req.body.username != 'string') || (req.body.username.length < 1) || (req.body.username[0] == '~')) {
1268
parent.debug('web', 'handleCreateAccountRequest: unable to create account (0)');
1270
- req.session.loginmode = '2';
1269
+ req.session.loginmode = 2;
1270
req.session.messageid = 100; // Unable to create account.
1271
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1272
return;
@@ -1290,7 +1289,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1289
if (typeof req.body.email == 'string') { i = req.body.email.indexOf('@'); }
1290
if (i == -1) {
1291
parent.debug('web', 'handleCreateAccountRequest: unable to create account (1)');
1293
- req.session.loginmode = '2';
1292
+ req.session.loginmode = 2;
1293
req.session.messageid = 100; // Unable to create account.
1294
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1295
return;
@@ -1299,7 +1298,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1298
for (var i in domain.newaccountemaildomains) { if (emaildomain == domain.newaccountemaildomains[i].toLowerCase()) { emailok = true; } }
1299
if (emailok == false) {
1300
parent.debug('web', 'handleCreateAccountRequest: unable to create account (2)');
1302
- req.session.loginmode = '2';
1301
+ req.session.loginmode = 2;
1302
req.session.messageid = 100; // Unable to create account.
1303
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1304
return;
@@ -1310,13 +1309,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1309
obj.db.isMaxType(domain.limits.maxuseraccounts, 'user', domain.id, function (maxExceed) {
1310
if (maxExceed) {
1311
parent.debug('web', 'handleCreateAccountRequest: account limit reached');
1313
- req.session.loginmode = '2';
1312
+ req.session.loginmode = 2;
1313
req.session.messageid = 101; // Account limit reached.
1314
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1315
} else {
1316
if (!obj.common.validateUsername(req.body.username, 1, 64) || !obj.common.validateEmail(req.body.email, 1, 256) || !obj.common.validateString(req.body.password1, 1, 256) || !obj.common.validateString(req.body.password2, 1, 256) || (req.body.password1 != req.body.password2) || req.body.username == '~' || !obj.common.checkPasswordRequirements(req.body.password1, domain.passwordrequirements)) {
1317
parent.debug('web', 'handleCreateAccountRequest: unable to create account (3)');
1319
- req.session.loginmode = '2';
1318
+ req.session.loginmode = 2;
1319
req.session.messageid = 100; // Unable to create account.
1320
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1321
} else {
@@ -1324,14 +1323,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1323
obj.db.GetUserWithVerifiedEmail(domain.id, req.body.email, function (err, docs) {
1324
if ((docs != null) && (docs.length > 0)) {
1325
parent.debug('web', 'handleCreateAccountRequest: Existing account with this email address');
1327
- req.session.loginmode = '2';
1326
+ req.session.loginmode = 2;
1327
req.session.messageid = 102; // Existing account with this email address.
1328
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1329
} else {
1330
// Check if there is domain.newAccountToken, check if supplied token is valid
1331
if ((domain.newaccountspass != null) && (domain.newaccountspass != '') && (req.body.anewaccountpass != domain.newaccountspass)) {
1332
parent.debug('web', 'handleCreateAccountRequest: Invalid account creation token');
1334
- req.session.loginmode = '2';
1333
+ req.session.loginmode = 2;
1334
req.session.messageid = 103; // Invalid account creation token.
1335
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1336
return;
@@ -1339,7 +1338,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1338
// Check if user exists
1339
if (obj.users['user/' + domain.id + '/' + req.body.username.toLowerCase()]) {
1340
parent.debug('web', 'handleCreateAccountRequest: Username already exists');
1342
- req.session.loginmode = '2';
1341
+ req.session.loginmode = 2;
1342
req.session.messageid = 104; // Username already exists.
1343
} else {
1344
var user = { type: 'user', _id: 'user/' + domain.id + '/' + req.body.username.toLowerCase(), name: req.body.username, email: req.body.email, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
@@ -1373,7 +1372,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1372
1373
obj.users[user._id] = user;
1374
req.session.userid = user._id;
1376
- req.session.domainid = domain.id;
1375
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
1376
// Create a user, generate a salt and hash the password
1377
require('./pass').hash(req.body.password1, function (err, salt, hash, tag) {
@@ -1408,17 +1406,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1406
// Check everything is ok
1407
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (typeof req.body.rpassword1 != 'string') || (typeof req.body.rpassword2 != 'string') || (req.body.rpassword1 != req.body.rpassword2) || (typeof req.body.rpasswordhint != 'string') || (req.session == null) || (typeof req.session.resettokenusername != 'string') || (typeof req.session.resettokenpassword != 'string')) {
1408
parent.debug('web', 'handleResetPasswordRequest: checks failed');
1411
- delete req.session.u2fchallenge;
1409
+ delete req.session.u2f;
1410
delete req.session.loginmode;
1413
- delete req.session.tokenuserid;
1414
- delete req.session.tokenusername;
1415
- delete req.session.tokenpassword;
1411
+ delete req.session.tuserid;
1412
+ delete req.session.tuser;
1413
+ delete req.session.tpass;
1414
delete req.session.resettokenuserid;
1415
delete req.session.resettokenusername;
1416
delete req.session.resettokenpassword;
1419
- delete req.session.tokenemail;
1420
- delete req.session.tokensms;
1421
- delete req.session.tokenpush;
1417
+ delete req.session.temail;
1418
+ delete req.session.tsms;
1419
+ delete req.session.tpush;
1420
delete req.session.messageid;
1421
delete req.session.passhint;
1422
delete req.session.cuserid;
@@ -1435,7 +1433,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1433
// If we have password requirements, check this here.
1434
if (!obj.common.checkPasswordRequirements(req.body.rpassword1, domain.passwordrequirements)) {
1435
parent.debug('web', 'handleResetPasswordRequest: password rejected, use a different one (1)');
1438
- req.session.loginmode = '6';
1436
+ req.session.loginmode = 6;
1437
req.session.messageid = 105; // Password rejected, use a different one.
1438
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1439
return;
@@ -1446,7 +1444,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1444
if (result != 0) {
1445
// This is the same password as an older one, request a password change again
1446
parent.debug('web', 'handleResetPasswordRequest: password rejected, use a different one (2)');
1449
- req.session.loginmode = '6';
1447
+ req.session.loginmode = 6;
1448
req.session.messageid = 105; // Password rejected, use a different one.
1449
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1450
} else {
@@ -1482,26 +1480,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1480
// Login successful
1481
parent.debug('web', 'handleResetPasswordRequest: success');
1482
req.session.userid = userid;
1485
- req.session.domainid = domain.id;
1483
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
1487
- completeLoginRequest(req, res, domain, obj.users[userid], userid, req.session.tokenusername, req.session.tokenpassword, direct, loginOptions);
1484
+ completeLoginRequest(req, res, domain, obj.users[userid], userid, req.session.tuser, req.session.tpass, direct, loginOptions);
1485
}, 0);
1486
}
1487
}, 0);
1488
} else {
1489
// Failed, error out.
1490
parent.debug('web', 'handleResetPasswordRequest: failed authenticate()');
1494
- delete req.session.u2fchallenge;
1491
+ delete req.session.u2f;
1492
delete req.session.loginmode;
1496
- delete req.session.tokenuserid;
1497
- delete req.session.tokenusername;
1498
- delete req.session.tokenpassword;
1493
+ delete req.session.tuserid;
1494
+ delete req.session.tuser;
1495
+ delete req.session.tpass;
1496
delete req.session.resettokenuserid;
1497
delete req.session.resettokenusername;
1498
delete req.session.resettokenpassword;
1502
- delete req.session.tokenemail;
1503
- delete req.session.tokensms;
1504
- delete req.session.tokenpush;
1499
+ delete req.session.temail;
1500
+ delete req.session.tsms;
1501
+ delete req.session.tpush;
1502
delete req.session.messageid;
1503
delete req.session.passhint;
1504
delete req.session.cuserid;
@@ -1524,12 +1521,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1521
1522
// Get the email from the body or session.
1523
var email = req.body.email;
1527
- if ((email == null) || (email == '')) { email = req.session.tokenemail; }
1524
+ if ((email == null) || (email == '')) { email = req.session.temail; }
1525
1526
// Check the email string format
1527
if (!email || checkEmail(email) == false) {
1528
parent.debug('web', 'handleResetAccountRequest: Invalid email');
1532
- req.session.loginmode = '3';
1529
+ req.session.loginmode = 3;
1530
req.session.messageid = 106; // Invalid email.
1531
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1532
} else {
@@ -1549,7 +1546,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1546
// Check if we have any account that match this email address
1547
if ((err != null) || (docs.length == 0)) {
1548
parent.debug('web', 'handleResetAccountRequest: Account not found');
1552
- req.session.loginmode = '3';
1549
+ req.session.loginmode = 3;
1550
req.session.messageid = 1; // If valid, reset mail sent. Instead of "Account not found" (107), we send this hold on message so users can't know if this account exists or not.
1551
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1552
} else {
@@ -1580,26 +1577,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1577
obj.setbadLogin(req);
1578
}
1579
}
1583
- req.session.loginmode = '5';
1584
- delete req.session.tokenemail;
1585
- req.session.tokenemail = email;
1580
+ req.session.loginmode = 5;
1581
+ req.session.temail = email;
1582
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1583
}
1584
} else {
1585
// Send email to perform recovery.
1590
- delete req.session.tokenemail;
1586
+ delete req.session.temail;
1587
if (domain.mailserver != null) {
1588
domain.mailserver.sendAccountResetMail(domain, user.name, user._id, user.email, obj.getLanguageCodes(req), req.query.key);
1589
if (i == 0) {
1590
parent.debug('web', 'handleResetAccountRequest: Hold on, reset mail sent.');
1595
- req.session.loginmode = '1';
1591
+ req.session.loginmode = 1;
1592
req.session.messageid = 1; // If valid, reset mail sent.
1593
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1594
}
1595
} else {
1596
if (i == 0) {
1597
parent.debug('web', 'handleResetAccountRequest: Unable to sent email.');
1602
- req.session.loginmode = '3';
1598
+ req.session.loginmode = 3;
1599
req.session.messageid = 109; // Unable to sent email.
1600
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1601
}
@@ -1612,14 +1608,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1608
domain.mailserver.sendAccountResetMail(domain, user.name, user._id, user.email, obj.getLanguageCodes(req), req.query.key);
1609
if (i == 0) {
1610
parent.debug('web', 'handleResetAccountRequest: Hold on, reset mail sent.');
1615
- req.session.loginmode = '1';
1611
+ req.session.loginmode = 1;
1612
req.session.messageid = 1; // If valid, reset mail sent.
1613
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1614
}
1615
} else {
1616
if (i == 0) {
1617
parent.debug('web', 'handleResetAccountRequest: Unable to sent email.');
1622
- req.session.loginmode = '3';
1618
+ req.session.loginmode = 3;
1619
req.session.messageid = 109; // Unable to sent email.
1620
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1621
}
@@ -1644,7 +1640,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1640
1641
// Get the email from the body or session.
1642
var email = req.body.email;
1647
- if ((email == null) || (email == '')) { email = req.session.tokenemail; }
1643
+ if ((email == null) || (email == '')) { email = req.session.temail; }
1644
1645
// Check if this request is for an allows email domain
1646
if ((domain.newaccountemaildomains != null) && Array.isArray(domain.newaccountemaildomains)) {
@@ -1652,7 +1648,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1648
if (typeof req.body.email == 'string') { i = req.body.email.indexOf('@'); }
1649
if (i == -1) {
1650
parent.debug('web', 'handleCreateAccountRequest: unable to create account (1)');
1655
- req.session.loginmode = '7';
1651
+ req.session.loginmode = 7;
1652
req.session.messageid = 106; // Invalid email.
1653
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1654
return;
@@ -1661,7 +1657,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1657
for (var i in domain.newaccountemaildomains) { if (emaildomain == domain.newaccountemaildomains[i].toLowerCase()) { emailok = true; } }
1658
if (emailok == false) {
1659
parent.debug('web', 'handleCreateAccountRequest: unable to create account (2)');
1664
- req.session.loginmode = '7';
1660
+ req.session.loginmode = 7;
1661
req.session.messageid = 106; // Invalid email.
1662
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1663
return;
@@ -1671,7 +1667,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1667
// Check the email string format
1668
if (!email || checkEmail(email) == false) {
1669
parent.debug('web', 'handleCheckAccountEmailRequest: Invalid email');
1674
- req.session.loginmode = '7';
1670
+ req.session.loginmode = 7;
1671
req.session.messageid = 106; // Invalid email.
1672
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1673
} else {
@@ -1699,7 +1695,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1695
// Send the response
1696
req.session.messageid = 2; // Email sent.
1697
}
1702
- req.session.loginmode = '7';
1698
+ req.session.loginmode = 7;
1699
delete req.session.cuserid;
1700
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
1701
});
@@ -2044,7 +2040,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2040
if ((loginCookie != null) && (domain.id == loginCookie.domainid)) { user = obj.users[loginCookie.userid]; }
2041
} else {
2042
// Check if the user is logged and we have all required parameters
2047
- if (!req.session || !req.session.userid || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.domainid != domain.id)) {
2043
+ if (!req.session || !req.session.userid || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.userid.split('/')[1] != domain.id)) {
2044
parent.debug('web', 'handleDeleteAccountRequest: required parameters not present.');
2045
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
2046
return;
@@ -2221,7 +2217,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2217
if (req.session.loginToken != null) { res.sendStatus(404); return; } // Do not allow this command when logged in using a login token
2218
2219
// Check if the user is logged and we have all required parameters
2224
- if (!req.session || !req.session.userid || !req.body.apassword0 || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.domainid != domain.id)) {
2220
+ if (!req.session || !req.session.userid || !req.body.apassword0 || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.userid.split('/')[1] != domain.id)) {
2221
parent.debug('web', 'handlePasswordChangeRequest: failed checks (2).');
2222
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
2223
return;
@@ -2353,11 +2349,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2349
parent.DispatchEvent(targets, obj, event);
2350
2351
req.session.userid = userid;
2356
- req.session.domainid = domain.id;
2352
} else {
2353
// New users not allowed
2354
parent.debug('web', 'handleStrategyLogin: Can\'t create new accounts');
2360
- req.session.loginmode = '1';
2355
+ req.session.loginmode = 1;
2356
req.session.messageid = 100; // Unable to create account.
2357
res.redirect(domain.url + getQueryPortion(req));
2358
return;
@@ -2378,7 +2373,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2373
}
2374
parent.debug('web', 'handleStrategyLogin: succesful login: ' + userid);
2375
req.session.userid = userid;
2381
- req.session.domainid = domain.id;
2376
}
2377
}
2378
//res.redirect(domain.url); // This does not handle cookie correctly.
@@ -2422,8 +2416,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2416
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + req.connection.user + ' from ' + req.clientIp + ' port ' + req.connection.remotePort); }
2417
parent.debug('web', 'handleRootRequest: user/pass in URL auth ok.');
2418
req.session.userid = userid;
2425
- req.session.domainid = domain.id;
2426
- req.session.currentNode = '';
2419
+ delete req.session.currentNode;
2420
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
2421
handleRootRequestEx(req, res, domain, direct);
2422
});
@@ -2452,10 +2445,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2445
2446
if (obj.args.nousers == true) {
2447
// If in single user mode, setup things here.
2455
- if (req.session && req.session.loginmode) { delete req.session.loginmode; }
2448
+ delete req.session.loginmode;
2449
req.session.userid = 'user/' + domain.id + '/~';
2457
- req.session.domainid = domain.id;
2458
- req.session.currentNode = '';
2450
+ delete req.session.currentNode;
2451
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
2452
if (obj.users[req.session.userid] == null) {
2453
// Create the dummy user ~ with impossible password
@@ -2466,10 +2458,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2458
} else if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
2459
// If a default user is active, setup the session here.
2460
parent.debug('web', 'handleRootRequestEx: auth using default user.');
2469
- if (req.session && req.session.loginmode) { delete req.session.loginmode; }
2461
+ delete req.session.loginmode;
2462
req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase();
2471
- req.session.domainid = domain.id;
2472
- req.session.currentNode = '';
2463
+ delete req.session.currentNode;
2464
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
2465
} else if (req.query.login && (obj.parent.loginCookieEncryptionKey != null)) {
2466
var loginCookie = obj.parent.decodeCookie(req.query.login, obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
@@ -2477,10 +2468,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2468
if ((loginCookie != null) && (loginCookie.a == 3) && (loginCookie.u != null) && (loginCookie.u.split('/')[1] == domain.id)) {
2469
// If a login cookie was provided, setup the session here.
2470
parent.debug('web', 'handleRootRequestEx: cookie auth ok.');
2480
- if (req.session && req.session.loginmode) { delete req.session.loginmode; }
2471
+ delete req.session.loginmode;
2472
req.session.userid = loginCookie.u;
2482
- req.session.domainid = domain.id;
2483
- req.session.currentNode = '';
2473
+ delete req.session.currentNode;
2474
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
2475
} else {
2476
parent.debug('web', 'handleRootRequestEx: cookie auth failed.');
@@ -2496,8 +2486,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2486
req.session.userid = 'user/' + domain.id + '/' + req.connection.user.toLowerCase();
2487
req.session.usersid = req.connection.userSid;
2488
req.session.usersGroups = req.connection.userGroups;
2499
- req.session.domainid = domain.id;
2500
- req.session.currentNode = '';
2489
+ delete req.session.currentNode;
2490
req.session.ip = req.clientIp; // Bind this session to the IP address of the request
2491
2492
// Check if this user exists, create it if not.
@@ -2571,7 +2560,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2560
}
2561
2562
const xdbGetFunc = function dbGetFunc(err, states) {
2574
- if (dbGetFunc.req.session.domainid != domain.id) { // Check if the session is for the correct domain
2563
+ if (dbGetFunc.req.session.userid.split('/')[1] != domain.id) { // Check if the session is for the correct domain
2564
parent.debug('web', 'handleRootRequestEx: incorrect domain.');
2565
dbGetFunc.req.session = null;
2566
dbGetFunc.res.redirect(domain.url + getQueryPortion(dbGetFunc.req)); // BAD***
@@ -2583,7 +2572,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2572
// Locked account
2573
parent.debug('web', 'handleRootRequestEx: locked account.');
2574
delete dbGetFunc.req.session.userid;
2586
- delete dbGetFunc.req.session.domainid;
2575
delete dbGetFunc.req.session.currentNode;
2576
delete dbGetFunc.req.session.passhint;
2577
delete dbGetFunc.req.session.cuserid;
@@ -2674,7 +2662,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2662
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
2663
2664
// Clean up the U2F challenge if needed
2677
- if (dbGetFunc.req.session.u2fchallenge) { delete dbGetFunc.req.session.u2fchallenge; };
2665
+ if (dbGetFunc.req.session.u2f) { delete dbGetFunc.req.session.u2f; };
2666
2667
// Intel AMT Scanning options
2668
var amtscanoptions = '';
@@ -2748,8 +2736,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2736
// Send back the login application
2737
// If this is a 2 factor auth request, look for a hardware key challenge.
2738
// Normal login 2 factor request
2751
- if (req.session && (req.session.loginmode == '4') && (req.session.tokenuserid)) {
2752
- var user = obj.users[req.session.tokenuserid];
2739
+ if (req.session && (req.session.loginmode == 4) && (req.session.tuserid)) {
2740
+ var user = obj.users[req.session.tuserid];
2741
if (user != null) {
2742
parent.debug('web', 'handleRootRequestEx: sending 2FA challenge.');
2743
getHardwareKeyChallenge(req, domain, user, function (hwchallenge) { handleRootRequestLogin(req, res, domain, hwchallenge, passRequirements); });
@@ -2757,8 +2745,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2745
}
2746
}
2747
// Password recovery 2 factor request
2760
- if (req.session && (req.session.loginmode == '5') && (req.session.tokenemail)) {
2761
- obj.db.GetUserWithVerifiedEmail(domain.id, req.session.tokenemail, function (err, docs) {
2748
+ if (req.session && (req.session.loginmode == 5) && (req.session.temail)) {
2749
+ obj.db.GetUserWithVerifiedEmail(domain.id, req.session.temail, function (err, docs) {
2750
if ((err != null) || (docs.length == 0)) {
2751
parent.debug('web', 'handleRootRequestEx: password recover 2FA fail.');
2752
req.session = null;
@@ -2787,14 +2775,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2775
if ((parent.config != null) && (parent.config.settings != null) && ((parent.config.settings.allowframing == true) || (typeof parent.config.settings.allowframing == 'string'))) { features += 32; } // Allow site within iframe
2776
if (domain.usernameisemail) { features += 0x00200000; } // Username is email address
2777
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
2790
- var loginmode = '';
2778
+ var loginmode = 0;
2779
if (req.session) { loginmode = req.session.loginmode; delete req.session.loginmode; } // Clear this state, if the user hits refresh, we want to go back to the login page.
2780
2781
// Format an error message if needed
2782
var passhint = null, msgid = 0;
2783
if (req.session != null) {
2784
msgid = req.session.messageid;
2797
- if ((msgid == 5) || (loginmode == '7') || ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true))) { passhint = EscapeHtml(req.session.passhint); }
2785
+ if ((msgid == 5) || (loginmode == 7) || ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true))) { passhint = EscapeHtml(req.session.passhint); }
2786
delete req.session.messageid;
2787
delete req.session.passhint;
2788
}
@@ -2807,14 +2795,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2795
2796
// Encrypt the hardware key challenge state if needed
2797
var hwstate = null;
2810
- if (hardwareKeyChallenge) { hwstate = obj.parent.encodeCookie({ u: req.session.tokenusername, p: req.session.tokenpassword, c: req.session.u2fchallenge }, obj.parent.loginCookieEncryptionKey) }
2798
+ if (hardwareKeyChallenge) { hwstate = obj.parent.encodeCookie({ u: req.session.tuser, p: req.session.tpass, c: req.session.u2f }, obj.parent.loginCookieEncryptionKey) }
2799
2800
// Check if we can use OTP tokens with email. We can't use email for 2FA password recovery (loginmode 5).
2813
- var otpemail = (loginmode != 5) && (domain.mailserver != null) && (req.session != null) && ((req.session.tokenemail == true) || (typeof req.session.tokenemail == 'string'));
2801
+ var otpemail = (loginmode != 5) && (domain.mailserver != null) && (req.session != null) && ((req.session.temail === 1) || (typeof req.session.temail == 'string'));
2802
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.email2factor == false)) { otpemail = false; }
2815
- var otpsms = (parent.smsserver != null) && (req.session != null) && (req.session.tokensms == true);
2803
+ var otpsms = (parent.smsserver != null) && (req.session != null) && (req.session.tsms === 1);
2804
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.sms2factor == false)) { otpsms = false; }
2817
- var otppush = (parent.firebase != null) && (req.session != null) && (req.session.tokenpush == true);
2805
+ var otppush = (parent.firebase != null) && (req.session != null) && (req.session.tpush === 1);
2806
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.push2factor == false)) { otppush = false; }
2807
2808
// See if we support two-factor trusted cookies
@@ -2882,7 +2870,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2870
case 'tokenlogin': {
2871
if (req.body.hwstate) {
2872
var cookie = obj.parent.decodeCookie(req.body.hwstate, obj.parent.loginCookieEncryptionKey, 10);
2885
- if (cookie != null) { req.session.tokenusername = cookie.u; req.session.tokenpassword = cookie.p; req.session.u2fchallenge = cookie.c; }
2873
+ if (cookie != null) { req.session.tuser = cookie.u; req.session.tpass = cookie.p; req.session.u2f = cookie.c; }
2874
}
2875
handleLoginRequest(req, res, true); break;
2876
}
@@ -2891,7 +2879,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2879
var cookie = obj.parent.decodeCookie(req.body.hwstate, obj.parent.loginCookieEncryptionKey, 1);
2880
if ((cookie != null) && (typeof cookie.u == 'string') && (cookie.d == domain.id) && (cookie.a == 'pushAuth')) {
2881
// Push authentication is a success, login the user
2894
- req.session = { userid: cookie.u, domainid: cookie.d }
2882
+ req.session = { userid: cookie.u };
2883
2884
// Check if we need to remember this device
2885
if ((req.body.remembertoken === 'on') && ((domain.twofactorcookiedurationdays == null) || (domain.twofactorcookiedurationdays > 0))) {
@@ -2944,7 +2932,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2932
parent.debug('web', 'handleXTermRequest: sending xterm');
2933
res.set({ 'Cache-Control': 'no-store' });
2934
if (req.session && req.session.userid) {
2947
- if (req.session.domainid != domain.id) { res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2935
+ if (req.session.userid.split('/')[1] != domain.id) { res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2936
var user = obj.users[req.session.userid];
2937
if ((user == null) || (req.query.nodeid == null)) { res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the user exists
2938
@@ -2979,7 +2967,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2967
// Send the terms from the database
2968
res.set({ 'Cache-Control': 'no-store' });
2969
if (req.session && req.session.userid) {
2982
- if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2970
+ if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2971
var user = obj.users[req.session.userid];
2972
var logoutcontrols = { name: user.name };
2973
var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
@@ -2998,7 +2986,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2986
// Send the terms from terms.txt
2987
res.set({ 'Cache-Control': 'no-store' });
2988
if (req.session && req.session.userid) {
3001
- if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2989
+ if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2990
var user = obj.users[req.session.userid];
2991
var logoutcontrols = { name: user.name };
2992
var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
@@ -3013,7 +3001,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3001
parent.debug('web', 'handleTermsRequest: sending default terms');
3002
res.set({ 'Cache-Control': 'no-store' });
3003
if (req.session && req.session.userid) {
3016
- if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
3004
+ if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
3005
var user = obj.users[req.session.userid];
3006
var logoutcontrols = { name: user.name };
3007
var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
@@ -5286,6 +5274,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5274
5275
// Add HTTP security headers to all responses
5276
obj.app.use(function (req, res, next) {
5277
+
5278
+ // Remove legacy values from the session to keep the session as small as possible
5279
+ delete req.session.domainid;
5280
+ delete req.session.u2fchallenge
5281
+ delete req.session.nowInMinutes;
5282
+ delete req.session.tokenuserid;
5283
+ delete req.session.tokenusername;
5284
+ delete req.session.tokenpassword;
5285
+ delete req.session.tokenemail;
5286
+ delete req.session.tokensms;
5287
+ delete req.session.tokenpush;
5288
+ delete req.session.tusername;
5289
+ delete req.session.tpassword;
5290
+
5291
// Useful for debugging reverse proxy issues
5292
parent.debug('httpheaders', req.method, req.url, req.headers);
5293
@@ -5378,7 +5380,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5380
if ((req.session.ip != null) && (req.clientIp != null) && (req.session.ip != req.clientIp)) { req.session = {}; }
5381
5382
// Extend the session time by forcing a change to the session every minute.
5381
- if (req.session.userid != null) { req.session.nowInMinutes = Math.floor(Date.now() / 60e3); } else { delete req.session.nowInMinutes; }
5383
+ if (req.session.userid != null) { req.session.t = Math.floor(Date.now() / 60e3); } else { delete req.session.t; }
5384
5385
// Debugging code, this will stop the agent from crashing if two responses are made to the same request.
5386
const render = res.render;
@@ -6373,7 +6375,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6375
// A default user is active
6376
func(ws, req, domain, obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]);
6377
return;
6376
- } else if (req.session && (req.session.userid != null) && (req.session.domainid == domain.id) && (obj.users[req.session.userid])) {
6378
+ } else if (req.session && (req.session.userid != null) && (req.session.userid.split('/')[1] == domain.id) && (obj.users[req.session.userid])) {
6379
// This user is logged in using the ExpressJS session
6380
func(ws, req, domain, obj.users[req.session.userid]);
6381
return;