diff --git a/meshuser.js b/meshuser.js index 96f1c5ea..748f19ea 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1612,6 +1612,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Create the notification message var notification = { action: 'msg', type: 'notify', domain: domain.id, value: command.msg, title: user.name, icon: 0, tag: 'broadcast', id: Math.random() }; + if ((typeof command.maxtime == 'number') && (command.maxtime > 0)) { notification.maxtime = command.maxtime; } // Send the notification on all user sessions for this server for (var i in parent.wssessions2) { @@ -2460,6 +2461,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Create the notification message var notification = { action: 'msg', type: 'notify', id: Math.random(), value: command.msg, title: user.name, icon: 8, userid: user._id, username: user.name }; + if ((typeof command.maxtime == 'number') && (command.maxtime > 0)) { notification.maxtime = command.maxtime; } // Get the list of sessions for this user var sessions = parent.wssessions[command.userid]; diff --git a/package.json b/package.json index 8afac10f..69015530 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "sample-config-advanced.json" ], "dependencies": { + "archiver": "^4.0.2", + "archiver-zip-encrypted": "^1.0.8", "body-parser": "^1.19.0", "cbor": "^4.1.5", "compression": "^1.7.4", @@ -42,14 +44,29 @@ "express": "^4.17.0", "express-handlebars": "^3.1.0", "express-ws": "^4.0.0", + "image-size": "^0.8.3", "ipcheck": "^0.1.0", + "jwt-simple": "^0.5.6", "minimist": "^1.2.0", + "mongodb": "^3.6.0", "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.8.4", + "node-rdpjs-2": "^0.3.5", + "node-windows": "^0.1.14", + "otplib": "^10.2.3", + "passport": "^0.4.1", + "passport-azure-oauth2": "^0.1.0", + "passport-github2": "^0.1.12", + "passport-google-oauth20": "^2.0.0", + "passport-reddit": "^0.2.4", + "passport-twitter": "^1.0.4", + "plivo": "^4.7.0", + "saslprep": "^1.0.3", "ws": "^6.2.1", "xmldom": "^0.1.27", - "yauzl": "^2.10.0" + "yauzl": "^2.10.0", + "yubikeyotp": "^0.2.0" }, "devDependencies": {}, "repository": { diff --git a/views/default.handlebars b/views/default.handlebars index 0708ef2a..6563f00d 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2105,6 +2105,7 @@ if (message.nodeid != null) { n.nodeid = message.nodeid; } if (message.tag != null) { n.tag = message.tag; } if (message.username != null) { n.username = message.username; } + if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); } else if (message.type == 'ps') { showDeskToolsProcesses(message); @@ -2140,6 +2141,7 @@ if (message.id != null) { n.id = message.id; } if (message.tag != null) { n.tag = message.tag; } if (message.username != null) { n.username = message.username; } + if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); } } @@ -2878,6 +2880,7 @@ var n = { text: message.event.value, title: message.event.title, icon: message.event.icon }; if (message.id != null) { n.id = message.id; } if (message.event.tag != null) { n.tag = message.event.tag; } + if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); break; } @@ -5841,7 +5844,9 @@ function showNotes(readonly, noteid) { if (xxdialogMode) return; - setDialogMode(2, "Notes", 2, showNotesEx, '' + "Device group notes can be viewed and changed by other device group administrators." + '', noteid); + var x = ''; + if (noteid.startsWith('node%2F%2F')) { x += '' + "Device group notes can be viewed and changed by other device group administrators." + ''; } + setDialogMode(2, "Notes", 2, showNotesEx, x, noteid); meshserver.send({ action: 'getNotes', id: decodeURIComponent(noteid) }); } @@ -10794,12 +10799,21 @@ function showUserAlertDialog(e, userid) { if (xxdialogMode) return; haltEvent(e); - setDialogMode(2, format("Notify {0}", EscapeHtml(users[decodeURIComponent(userid)].name)), 3, showUserAlertDialogEx, "Send a text notification to this user." + '', userid); + var x = '
' + "Send a text notification to this user." + '
'; + x += ''; + setDialogMode(2, format("Notify {0}", EscapeHtml(users[decodeURIComponent(userid)].name)), 3, showUserAlertDialogEx, x, userid); Q('d2notifyText').focus(); return false; } - function showUserAlertDialogEx(button, userid) { meshserver.send({ action: 'notifyuser', userid: decodeURIComponent(userid), msg: Q('d2notifyText').value }); } + function showUserAlertDialogEx(button, userid) { + meshserver.send({ action: 'notifyuser', userid: decodeURIComponent(userid), msg: Q('d2notifyText').value, maxtime: parseInt(Q('broadcastMessageMaxTime').value) }); + } function p4batchAccountCreate() { if (xxdialogMode) return; @@ -10864,13 +10878,19 @@ function showUserBroadcastDialog(targetid) { if (xxdialogMode) return; - var x = "Broadcast a message to all connected users." + ''; + var x = '
' + "Broadcast a message to all connected users." + '
'; + x += ''; setDialogMode(2, "Broadcast Message", 3, showUserBroadcastDialogEx, x, targetid?decodeURIComponent(targetid):null); Q('broadcastMessage').focus(); } function showUserBroadcastDialogEx(b, targetid) { - meshserver.send({ action: 'userbroadcast', msg: Q('broadcastMessage').value, target: targetid }); + meshserver.send({ action: 'userbroadcast', msg: Q('broadcastMessage').value, target: targetid, maxtime: parseInt(Q('broadcastMessageMaxTime').value) }); } function showCreateNewAccountDialog() { @@ -11621,10 +11641,10 @@ x += '
'; // Add action buttons - x += ''; - if (user.phone && (features & 0x02000000)) { x += ''; } + x += ''; + if (user.phone && (features & 0x02000000)) { x += ''; } if ((typeof user.email == 'string') && (user.emailVerified === true) && (features & 0x00000040)) { x += ''; } - if (!self && (activeSessions > 0)) { x += ''; } + if (!self && (activeSessions > 0)) { x += ''; } // Setup the panel QH('p30html', x); @@ -12319,6 +12339,9 @@ notification.onclick = function (e) { notificationSelected(e.target.id, true); } n.notification = notification; } + + // If the notification has a max time, setup the timer here. + if ((typeof n.maxtime == 'number') && (n.maxtime > 0)) { var trigger = function notifyRemoveTrigger() { notificationDelete(notifyRemoveTrigger.xid); }; trigger.xid = n.id; setTimeout(trigger, n.maxtime * 1000); } } // Remove all notifications