diff --git a/meshuser.js b/meshuser.js index 367a6b40..d55a9412 100644 --- a/meshuser.js +++ b/meshuser.js @@ -4961,7 +4961,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const doc = docs[i]; if (doc.expireTime < now) { // This share is expired. - parent.db.Remove(doc._id, function () { }); delete docs[i]; removed = true; + parent.db.Remove(doc._id, function () { }); removed = true; } else { // This share is ok, remove extra data we don't need to send. delete doc._id; delete doc.domain; delete doc.nodeid; delete doc.type; @@ -5611,14 +5611,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'loginTokens': { // Respond with the list of currently valid login tokens + if ((typeof domain.passwordrequirements != 'object') && (domain.passwordrequirements.logintokens == false)) break; // Login tokens are not supported on this server + + // If remove is an array or strings, we are going to be removing these and returning the results. + if (common.validateStrArray(command.remove, 1) == false) { delete command.remove; } + parent.db.GetAllTypeNodeFiltered(['logintoken-' + user._id], domain.id, 'logintoken', null, function (err, docs) { if (err != null) return; var now = Date.now(), removed = 0, okDocs = []; for (var i = 0; i < docs.length; i++) { const doc = docs[i]; - if (doc.expireTime < now) { + if (((doc.expire != 0) && (doc.expire < now)) || (doc.tokenUser == null) || ((command.remove != null) && (command.remove.indexOf(doc.tokenUser) >= 0))) { // This share is expired. - parent.db.Remove(doc._id, function () { }); delete docs[i]; removed++; + parent.db.Remove(doc._id, function () { }); removed++; } else { // This share is ok, remove extra data we don't need to send. delete doc._id; delete doc.domain; delete doc.nodeid; delete doc.type; delete doc.userid; delete doc.salt; delete doc.hash; @@ -5668,10 +5673,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Dispatch the new event var targets = ['*', 'server-users', user._id]; if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } } - var event = { etype: 'user', userid: user._id, username: user.name, action: 'loginTokenAdded', msgid: 115, msg: "Added login token", domain: domain.id }; + var event = { etype: 'user', userid: user._id, username: user.name, action: 'loginTokenAdded', msgid: 115, msg: "Added login token", domain: domain.id, newToken: { name: command.name, tokenUser: tokenUser, created: created, expire: expire } }; parent.parent.DispatchEvent(targets, obj, event); }); - break; } case 'getDeviceDetails': { diff --git a/views/default.handlebars b/views/default.handlebars index 282bcfcf..2c5c5fb7 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -385,8 +385,9 @@


+
Device Groups - ( New ) + - New

@@ -2004,6 +2005,7 @@ if (updateNaggleFlags & 8192) { updateUserGroups(); } if (updateNaggleFlags & 16384) { updateUsers(); } if (updateNaggleFlags & 32768) { updateRecordings(); } + if (updateNaggleFlags & 65536) { updateLoginTokens(); } updateNaggleTimer = null; updateNaggleFlags = 0; gotoStartViewPage(); @@ -3169,11 +3171,17 @@ if ((Q('DevFilterSelect').value == 2) || (Q('DevFilterSelect').value == 6)) { mainUpdate(1); } break; } - case 'loginTokenChanged': { + case 'loginTokenChanged': { // Login tokens have changed if (message.event.userid != userinfo._id) return; loginTokens = message.event.loginTokens; - // TODO: Update - console.log('t1', loginTokens); + mainUpdate(65536); + break; + } + case 'loginTokenAdded': { // A login token was added + if (message.event.userid != userinfo._id) return; + if (loginTokens == null) { loginTokens = []; } + loginTokens.push(message.event.newToken); + mainUpdate(65536); break; } case 'stopped': { // Server is stopping. @@ -3342,7 +3350,7 @@ saveAs(new Blob([message.data], { type: 'application/octet-stream' }), "devicelist" + '.' + message.type); break; } - case 'createLoginToken': { + case 'createLoginToken': { // A new login token was created if (xxdialogMode) return; var x = "Take note of this username and password, the password cannot be shown again." + '

'; x += addHtmlValue("Name", EscapeHtml(message.name)) @@ -3352,10 +3360,9 @@ setDialogMode(2, "Create Login Token", 1, null, x); break; } - case 'loginTokens': { + case 'loginTokens': { // Reveiced the list of login tokens loginTokens = message.loginTokens; - // TODO: Update - console.log('t2', loginTokens); + mainUpdate(65536); break; } default: @@ -10437,6 +10444,38 @@ QV('p2noMeshFound', count == 0); } + + function updateLoginTokens() { + var x = '', count = 1; + if ((loginTokens != null) && (loginTokens.length > 0)) { + x += '

' + "Active Login Tokens" + ' - ' + "New" + '

'; + for (var i = 0; i < loginTokens.length; i++) { + var ltoken = loginTokens[i]; + var trash = ''; + var details = ''; + if (ltoken.expire != 0) { details = EscapeHtml(format("Expires {0}", printDateTime(new Date(ltoken.expire)))) + ' '; } + x += ''; + } + x += '
' + "Name" + '' + "Username" + '
 ' + EscapeHtml(ltoken.name) + '
' + details + trash + '
' + EscapeHtml(ltoken.tokenUser) + '

'; + QV('accountCreateLoginTokenSpan', false); + } else { + QV('accountCreateLoginTokenSpan', features2 & 0x00000080); + } + QH('p2logintokens', x); + } + + function p2removeLoginToken(e, tokenUser) { + tokenUser = decodeURIComponent(tokenUser); + if (loginTokens == null) return; + var token = null; + for (var i = 0; i < loginTokens.length; i++) { if (loginTokens[i].tokenUser == tokenUser) { token = loginTokens[i]; } } + if (token == null) return; + var x = "Confirm removal of this login token?" + '

'; + x += addHtmlValue("Name", EscapeHtml(token.name)); + x += addHtmlValue("Username", EscapeHtml(token.tokenUser)); + setDialogMode(2, "Remove Login Token", 3, function(b, tokenUser) { meshserver.send({ action: 'loginTokens', remove: [ tokenUser ] }); }, x, tokenUser); + } + function gotoMesh(meshid) { currentMesh = meshes[meshid]; p20updateMesh();