Working on recurring device sharing links.
Ylian Saint-Hilaire committed
Jan 16, 2022 at 16:26 UTC
3589ddeaff1b8a17eba43bf1d3c3508ad9fbf9ee
2 files changed
+53
-11
meshuser.js
+16
-3
@@ -3834,6 +3834,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3834
else if ((command.end != null) && (typeof command.end != 'number')) { err = 'Invalid end time'; } // Check the end time in UTC seconds
3835
else if (common.validateInt(command.consent, 0, 256) == false) { err = 'Invalid flags'; } // Check the flags
3836
else if (common.validateInt(command.p, 1, 7) == false) { err = 'Invalid protocol'; } // Check the protocol, 1 = Terminal, 2 = Desktop, 4 = Files
3837
+ else if ((command.recurring != null) && (common.validateInt(command.recurring, 1, 2) == false)) { err = 'Invalid recurring value'; } // Check the recurring value, 1 = Daily, 2 = Weekly
3838
+ else if ((command.recurring != null) && ((command.end != null) || (command.start == null) || (command.expire == null))) { err = 'Invalid recurring command'; }
3839
else if ((command.expire == null) && ((command.start == null) || (command.end == null) || (command.start > command.end))) { err = 'No time specified'; } // Check that a time range is present
3840
else {
3841
if (command.nodeid.split('/').length == 1) { command.nodeid = 'node/' + domain.id + '/' + command.nodeid; }
@@ -3893,8 +3895,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3895
if ((rights != MESHRIGHT_ADMIN) && ((rights & MESHRIGHT_REMOTEVIEWONLY) != 0)) { command.viewOnly = true; command.p = (command.p & 1); }
3896
3897
// Create cookie
3896
- var publicid = getRandomPassword(), startTime = null, expireTime = null;
3897
- if (command.expire != null) {
3898
+ var publicid = getRandomPassword(), startTime = null, expireTime = null, duration = null;
3899
+ if (command.recurring) {
3900
+ // Recurring share
3901
+ startTime = command.start * 1000;
3902
+ duration = command.expire;
3903
+ } else if (command.expire != null) {
3904
if (command.expire !== 0) {
3905
// Now until expire in hours
3906
startTime = Date.now();
@@ -3911,6 +3917,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3917
//var cookie = { a: 5, p: command.p, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, pid: publicid }; // Old style sharing cookie
3918
var cookie = { a: 6, pid: publicid }; // New style sharing cookie
3919
if ((startTime != null) && (expireTime != null)) { command.start = startTime; command.expire = cookie.e = expireTime; }
3920
+ else if ((startTime != null) && (duration != null)) { command.start = startTime; }
3921
const inviteCookie = parent.parent.encodeCookie(cookie, parent.parent.invitationLinkEncryptionKey);
3922
if (inviteCookie == null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'createDeviceShareLink', responseid: command.responseid, result: 'Unable to generate shareing cookie' })); } catch (ex) { } } return; }
3923
@@ -3929,13 +3936,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3936
// Create a device sharing database entry
3937
var shareEntry = { _id: 'deviceshare-' + publicid, type: 'deviceshare', xmeshid: node.meshid, nodeid: node._id, p: command.p, domain: node.domain, publicid: publicid, userid: user._id, guestName: command.guestname, consent: command.consent, url: url };
3938
if ((startTime != null) && (expireTime != null)) { shareEntry.startTime = startTime; shareEntry.expireTime = expireTime; }
3939
+ else if ((startTime != null) && (duration != null)) { shareEntry.startTime = startTime; shareEntry.duration = duration; }
3940
+ if (command.recurring) { shareEntry.recurring = command.recurring; }
3941
if (command.viewOnly === true) { shareEntry.viewOnly = true; }
3942
parent.db.Set(shareEntry);
3943
3944
// Send out an event that we added a device share
3945
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
3946
var event;
3938
- if ((startTime != null) && (expireTime != null)) {
3947
+ if (command.recurring == 1) {
3948
+ event = { etype: 'node', userid: user._id, username: user.name, meshid: node.meshid, nodeid: node._id, action: 'addedDeviceShare', msg: 'Added device share ' + command.guestname + ' recurring daily.', msgid: 138, msgArgs: [command.guestname], domain: domain.id };
3949
+ } else if (command.recurring == 2) {
3950
+ event = { etype: 'node', userid: user._id, username: user.name, meshid: node.meshid, nodeid: node._id, action: 'addedDeviceShare', msg: 'Added device share ' + command.guestname + ' recurring weekly.', msgid: 139, msgArgs: [command.guestname], domain: domain.id };
3951
+ } else if ((startTime != null) && (expireTime != null)) {
3952
event = { etype: 'node', userid: user._id, username: user.name, meshid: node.meshid, nodeid: node._id, action: 'addedDeviceShare', msg: 'Added device share: ' + command.guestname + '.', msgid: 101, msgArgs: [command.guestname, 'DATETIME:' + startTime, 'DATETIME:' + expireTime], domain: domain.id };
3953
} else {
3954
event = { etype: 'node', userid: user._id, username: user.name, meshid: node.meshid, nodeid: node._id, action: 'addedDeviceShare', msg: 'Added device share ' + command.guestname + ' with unlimited time.', msgid: 131, msgArgs: [command.guestname], domain: domain.id };
views/default.handlebars
+37
-8
@@ -3456,10 +3456,18 @@
3456
x += addHtmlValue("Device", node.name);
3457
x += addHtmlValue("Guest Name", message.guestname);
3458
x += addHtmlValue("User Input", message.viewOnly ? "Not allowed, view only" : "Allowed");
3459
- if ((message.start != null) && (message.expire)) {
3460
- x += addHtmlValue("Start Time", printDateTime(new Date(message.start)));
3461
- x += addHtmlValue("Expire Time", printDateTime(new Date(message.expire)));
3459
+ if (message.start && message.expire) {
3460
+ if (message.recurring) {
3461
+ x += addHtmlValue("Start Time", printDateTime(new Date(message.start)));
3462
+ if (message.expire < 2) { x += addHtmlValue("Duration", format("{0} minute", message.expire) ); }
3463
+ else { x += addHtmlValue("Duration", format("{0} minutes", message.expire) ); }
3464
+ } else {
3465
+ x += addHtmlValue("Start Time", printDateTime(new Date(message.start)));
3466
+ x += addHtmlValue("Expire Time", printDateTime(new Date(message.expire)));
3467
+ }
3468
}
3469
+ if (message.recurring == 1) { x += addHtmlValue("Recurring", "Daily"); }
3470
+ if (message.recurring == 2) { x += addHtmlValue("Recurring", "Weekly"); }
3471
var y = [];
3472
if (message.consent & 0x0007) { y.push("Notify"); }
3473
if (message.consent & 0x0038) { y.push("Prompt"); }
@@ -7186,6 +7194,15 @@
7194
var type = ['', "Terminal", "Desktop", "Desktop + Terminal", "Files", "Terminal + Files", "Desktop + Files", "Desktop + Terminal + Files"][dshare.p];
7195
var details = type;
7196
if ((dshare.startTime != null) && (dshare.expireTime != null)) { details = format("{0}, {1} to {2}", type, printFlexDateTime(new Date(dshare.startTime)), printFlexDateTime(new Date(dshare.expireTime))); }
7197
+ if ((dshare.startTime != null) && (dshare.duration != null)) {
7198
+ if (dshare.duration < 2) {
7199
+ details = format("{0}, {1} for {2} minute", type, printFlexDateTime(new Date(dshare.startTime)), dshare.duration);
7200
+ } else {
7201
+ details = format("{0}, {1} for {2} minutes", type, printFlexDateTime(new Date(dshare.startTime)), dshare.duration);
7202
+ }
7203
+ }
7204
+ if (dshare.recurring == 1) { details += ", Reccuring daily"; }
7205
+ if (dshare.recurring == 2) { details += ", Reccuring weekly"; }
7206
if (((dshare.p & 2) != 0) && (dshare.viewOnly === true)) { details += ", View only desktop"; }
7207
if (dshare.consent != null) {
7208
if (dshare.consent == 0) { details += ", No Consent"; } else {
@@ -7460,7 +7477,7 @@
7477
var allFeatures = '<option value=7>' + "Desktop + Terminal + Files" + '</option>';
7478
if ((rights != 0xFFFFFFFF) && ((rights & 0x700) != 0)) { allFeatures = ''; }
7479
7463
- var y = '';
7480
+ var y = '', z = '';
7481
if ((currentNode.agent.caps & 1) == 1) { y += (deskFull + '<option value=3>' + "Desktop, View only" + '</option>'); } // Agent is desktop capable
7482
if ((currentNode.agent.caps & 2) == 2) { y += fullTerm; } // Agent is terminal capable
7483
if ((currentNode.agent.caps & 4) == 4) { y += fullFiles; } // Agent is files capable
@@ -7475,12 +7492,18 @@
7492
if ((serverinfo.guestdevicesharingmaxtime == null) || ((i > 0) && (i <= serverinfo.guestdevicesharingmaxtime))) {
7493
y += '<option value=' + i + '>' + options[i] + '</option>';
7494
}
7495
+ if ((i > 0) && (i <= 720) && ((serverinfo.guestdevicesharingmaxtime == null) || ((i > 0) && (i <= serverinfo.guestdevicesharingmaxtime)))) {
7496
+ z += '<option value=' + i + '>' + options[i] + '</option>';
7497
+ }
7498
}
7479
- x += addHtmlValue("Validity", '<select id=d2timeRange style=float:right;width:250px onchange=showShareDeviceValidate()><option value=0>' + "Starting now" + '</option><option value=1>' + "Time range" + '</option></select>');
7499
+ x += addHtmlValue("Validity", '<select id=d2timeRange style=float:right;width:250px onchange=showShareDeviceValidate()><option value=0>' + "Starting now" + '</option><option value=1>' + "Time range" + '</option><option value=2>' + "Recurring daily" + '</option><option value=3>' + "Recurring weekly" + '</option></select>');
7500
x += '<div id=d2modenow>';
7501
x += addHtmlValue("Expire Time", '<select id=d2inviteExpire style=float:right;width:250px>' + y + '</select>');
7502
x += '</div><div id=d2moderange style=display:none>';
7503
x += addHtmlValue("Time Range", '<input id=d2timeRangeSelector style=float:right;width:250px class=flatpickr type="text" placeholder="' + "Select Date & Time..." + '" data-id="altinput">');
7504
+ x += '</div><div id=d2moderecurring style=display:none>';
7505
+ x += addHtmlValue("Start Time", '<input id=d2timeStartSelector style=float:right;width:250px class=flatpickr type="text" placeholder="' + "Select Date & Time..." + '" data-id="altinput">');
7506
+ x += addHtmlValue("Duration", '<select id=d2inviteDuration style=float:right;width:250px>' + z + '</select>');
7507
x += '</div>';
7508
if (currentNode.agent.caps & 1) { x += addHtmlValue("User Consent", '<select id=d2userConsent style=float:right;width:250px><option value=1>' + "Prompt for consent" + '</option><option value=0>' + "Notify Only" + '</option></select>'); }
7509
setDialogMode(2, "Share Device", 3, showShareDeviceEx, x);
@@ -7488,12 +7511,14 @@
7511
var tomorrow = new Date();
7512
tomorrow.setDate(tomorrow.getDate() + 1);
7513
var rangeTime = flatpickr('#d2timeRangeSelector', { mode: 'range', enableTime: true, minDate: new Date(), defaultDate: [ new Date(), tomorrow ] });
7491
- xxdialogTag = rangeTime;
7514
+ var startTime = flatpickr('#d2timeStartSelector', { enableTime: true, minDate: new Date(), defaultDate: new Date() });
7515
+ xxdialogTag = { range: rangeTime, start: startTime };
7516
}
7517
7518
function showShareDeviceValidate() {
7519
QV('d2modenow', Q('d2timeRange').value == 0);
7520
QV('d2moderange', Q('d2timeRange').value == 1);
7521
+ QV('d2moderecurring', Q('d2timeRange').value >= 2);
7522
var ok = true;
7523
if (Q('d2inviteName').value.trim().length == 0) { ok = false; }
7524
QE('idx_dlgOkButton', ok);
@@ -7519,8 +7544,10 @@
7544
7545
if (Q('d2timeRange').value == 0) {
7546
meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: q, expire: parseInt(Q('d2inviteExpire').value), consent: consent, viewOnly: viewOnly });
7547
+ } else if (Q('d2timeRange').value == 1) {
7548
+ meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: q, start: Math.floor(tag.range.selectedDates[0].getTime() / 1000), end: Math.floor(tag.range.selectedDates[1].getTime() / 1000), consent: consent, viewOnly: viewOnly });
7549
} else {
7523
- meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: q, start: Math.floor(tag.selectedDates[0].getTime() / 1000), end: Math.floor(tag.selectedDates[1].getTime() / 1000), consent: consent, viewOnly: viewOnly });
7550
+ meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: q, start: Math.floor(tag.start.selectedDates[0].getTime() / 1000), expire: parseInt(Q('d2inviteDuration').value), recurring: Q('d2timeRange').value - 1, consent: consent, viewOnly: viewOnly });
7551
}
7552
}
7553
@@ -13378,7 +13405,9 @@
13405
134: "Forcibly disconnected desktop session of user {0}",
13406
135: "Forcibly disconnected terminal session of user {0}",
13407
136: "Forcibly disconnected files session of user {0}",
13381
- 137: "Forcibly disconnected routing session of user {0}"
13408
+ 137: "Forcibly disconnected routing session of user {0}",
13409
+ 138: "Added device share {0} recurring daily.",
13410
+ 139: "Added device share {0} recurring weekly."
13411
};
13412
13413
// Highlights the device being hovered