Updated windows user consent

Bryan Roe committed Dec 13, 2021 at 17:37 UTC 39aa68b693fbd777d91b0746fa90f4e5ed738f78
1 file changed +172 -8
agents/meshcore.js
+172 -8
@@ -929,6 +929,42 @@ function sendWakeOnLanEx(hexMacList) {
929 return (ret);
930 }
931
932 +function server_promise_default(res, rej)
933 +{
934 + this.resolve = res;
935 + this.reject = rej;
936 +}
937 +function server_getUserImage(userid)
938 +{
939 + var promise = require('promise');
940 + var ret = new promise(server_promise_default);
941 +
942 + if (require('MeshAgent')._promises == null) { require('MeshAgent')._promises = {}; }
943 + require('MeshAgent')._promises[ret._hashCode()] = ret;
944 + require('MeshAgent').SendCommand({ action: 'getUserImage', userid: userid, promise: ret._hashCode(), default: true });
945 + return (ret);
946 +}
947 +require('MeshAgent')._consentTimers = {};
948 +function server_set_consentTimer(id)
949 +{
950 + require('MeshAgent')._consentTimers[id] = new Date();
951 +}
952 +function server_check_consentTimer(id)
953 +{
954 + if (require('MeshAgent')._consentTimers[id] != null)
955 + {
956 + if((new Date()) - require('MeshAgent')._consentTimers[id] < (60000*5))
957 + {
958 + return (true);
959 + }
960 + else
961 + {
962 + require('MeshAgent')._consentTimers[id] = null;
963 + }
964 + }
965 + return (false);
966 +}
967 +
968 // Handle a mesh agent command
969 function handleServerCommand(data) {
970 if (typeof data == 'object') {
@@ -994,6 +1030,13 @@ function handleServerCommand(data) {
1030 tunnel.realname = (data.realname ? data.realname : data.username) + (data.guestname ? (' - ' + data.guestname) : '');
1031 tunnel.guestname = data.guestname;
1032 tunnel.userid = data.userid;
1033 +
1034 + if (server_check_consentTimer(tunnel.userid))
1035 + {
1036 + sendConsoleText('Deleting Consent Requirement');
1037 + tunnel.consent = (tunnel.consent & -57);
1038 + }
1039 +
1040 tunnel.desktopviewonly = data.desktopviewonly;
1041 tunnel.remoteaddr = data.remoteaddr;
1042 tunnel.state = 0;
@@ -1457,6 +1500,12 @@ function handleServerCommand(data) {
1500 case 'getUserImage':
1501 if (data.pipe == true) { delete data.pipe; delete data.action; data.cmd = 'getUserImage'; broadcastToRegisteredApps(data); }
1502 if (data.tag == 'info') { sendConsoleText(JSON.stringify(data, null, 2)); }
1503 + if (data.promise != null && require('MeshAgent')._promises[data.promise] != null)
1504 + {
1505 + var p = require('MeshAgent')._promises[data.promise];
1506 + delete require('MeshAgent')._promises[data.promise];
1507 + p.resolve(data.image);
1508 + }
1509 break;
1510 case 'wget': // Server uses this command to tell the agent to download a file using HTTPS/GET and place it in a given path. This is used for one-to-many file uploads.
1511 agentFileHttpPendingRequests.push(data);
@@ -1986,10 +2035,45 @@ function onTunnelData(data) {
2035 if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
2036 if (this.httprequest.soptions.consentMsgTerminal != null) { consentMessage = this.httprequest.soptions.consentMsgTerminal.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
2037 }
1989 - this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30);
2038 + if (process.platform == 'win32')
2039 + {
2040 + var enhanced = false;
2041 + try
2042 + {
2043 + require('win-userconsent');
2044 + enhanced = true;
2045 + }
2046 + catch (z)
2047 + {
2048 + }
2049 + if (enhanced)
2050 + {
2051 + var ipr = server_getUserImage(this.httprequest.userid);
2052 + ipr.consentTitle = consentTitle;
2053 + ipr.consentMessage = consentMessage;
2054 + ipr.username = this.httprequest.realname;
2055 + this.httprequest.tpromise._consent = ipr.then(function (img)
2056 + {
2057 + this.consent = require('win-userconsent').create(this.consentTitle, this.consentMessage, this.username, { b64Image: img.split(',').pop(), timeout: 30000 });
2058 + this.__childPromise.close = this.consent.close.bind(this.consent);
2059 + return (this.consent);
2060 + });
2061 + }
2062 + else
2063 + {
2064 + this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30);
2065 + }
2066 + }
2067 + else
2068 + {
2069 + this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30);
2070 + }
2071 this.httprequest.tpromise._consent.retPromise = this.httprequest.tpromise;
2072 this.httprequest.tpromise._consent.then(
1992 - function () {
2073 + function (always)
2074 + {
2075 + if (always) { server_set_consentTimer(this.retPromise.httprequest.userid); }
2076 +
2077 // Success
2078 MeshServerLogEx(27, null, "Local user accepted remote terminal request (" + this.retPromise.httprequest.remoteaddr + ")", this.retPromise.that.httprequest);
2079 this.retPromise.that.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null, msgid: 0 }));
@@ -2312,7 +2396,8 @@ function onTunnelData(data) {
2396 }
2397
2398 // Perform notification if needed. Toast messages may not be supported on all platforms.
2315 - if (this.httprequest.consent && (this.httprequest.consent & 8)) {
2399 + if (this.httprequest.consent && (this.httprequest.consent & 8))
2400 + {
2401 // User Consent Prompt is required
2402 // Send a console message back using the console channel, "\n" is supported.
2403 this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: "Waiting for user to grant access...", msgid: 1 }));
@@ -2321,13 +2406,56 @@ function onTunnelData(data) {
2406 if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
2407 if (this.httprequest.soptions.consentMsgDesktop != null) { consentMessage = this.httprequest.soptions.consentMsgDesktop.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
2408 }
2324 - var pr = require('message-box').create(consentTitle, consentMessage, 30, null, tsid);
2409 + var pr;
2410 + if (process.platform == 'win32')
2411 + {
2412 + var enhanced = false;
2413 + try
2414 + {
2415 + require('win-userconsent');
2416 + enhanced = true;
2417 + }
2418 + catch(z)
2419 + {
2420 + }
2421 + if (enhanced)
2422 + {
2423 + var ipr = server_getUserImage(this.httprequest.userid);
2424 + ipr.consentTitle = consentTitle;
2425 + ipr.consentMessage = consentMessage;
2426 + ipr.tsid = tsid;
2427 + ipr.username = this.httprequest.realname;
2428 + pr = ipr.then(function (img)
2429 + {
2430 + this.consent = require('win-userconsent').create(this.consentTitle, this.consentMessage, this.username, { b64Image: img.split(',').pop(), uid: this.tsid, timeout: 30000 });
2431 + this.__childPromise.close = this.consent.close.bind(this.consent);
2432 + return (this.consent);
2433 + });
2434 + }
2435 + else
2436 + {
2437 + pr = require('message-box').create(consentTitle, consentMessage, 30, null, tsid);
2438 + }
2439 + }
2440 + else
2441 + {
2442 + pr = require('message-box').create(consentTitle, consentMessage, 30, null, tsid);
2443 + }
2444 pr.ws = this;
2445 this.pause();
2446 this._consentpromise = pr;
2328 - this.prependOnceListener('end', function () { if (this._consentpromise && this._consentpromise.close) { this._consentpromise.close(); } });
2447 + this.prependOnceListener('end', function ()
2448 + {
2449 + if (this._consentpromise && this._consentpromise.close)
2450 + {
2451 + this._consentpromise.close();
2452 + }
2453 + });
2454 pr.then(
2330 - function () {
2455 + function (always)
2456 + {
2457 + if (always) { server_set_consentTimer(this.ws.httprequest.userid); }
2458 +
2459 // Success
2460 this.ws._consentpromise = null;
2461 MeshServerLogEx(30, null, "Starting remote desktop after local user accepted (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
@@ -2473,13 +2601,49 @@ function onTunnelData(data) {
2601 if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
2602 if (this.httprequest.soptions.consentMsgFiles != null) { consentMessage = this.httprequest.soptions.consentMsgFiles.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
2603 }
2476 - var pr = require('message-box').create(consentTitle, consentMessage, 30);
2604 + var pr;
2605 + if (process.platform == 'win32')
2606 + {
2607 + var enhanced = false;
2608 + try
2609 + {
2610 + require('win-userconsent');
2611 + enhanced = true;
2612 + }
2613 + catch (z)
2614 + {
2615 + }
2616 + if (enhanced)
2617 + {
2618 + var ipr = server_getUserImage(this.httprequest.userid);
2619 + ipr.consentTitle = consentTitle;
2620 + ipr.consentMessage = consentMessage;
2621 + ipr.username = this.httprequest.realname;
2622 + pr = ipr.then(function (img)
2623 + {
2624 + this.consent = require('win-userconsent').create(this.consentTitle, this.consentMessage, this.username, { b64Image: img.split(',').pop(), timeout: 30000 });
2625 + this.__childPromise.close = this.consent.close.bind(this.consent);
2626 + return (this.consent);
2627 + });
2628 + }
2629 + else
2630 + {
2631 + pr = require('message-box').create(consentTitle, consentMessage, 30, null);
2632 + }
2633 + }
2634 + else
2635 + {
2636 + pr = require('message-box').create(consentTitle, consentMessage, 30, null);
2637 + }
2638 pr.ws = this;
2639 this.pause();
2640 this._consentpromise = pr;
2641 this.prependOnceListener('end', function () { if (this._consentpromise && this._consentpromise.close) { this._consentpromise.close(); } });
2642 pr.then(
2482 - function () {
2643 + function (always)
2644 + {
2645 + if (always) { server_set_consentTimer(this.ws.httprequest.userid); }
2646 +
2647 // Success
2648 this.ws._consentpromise = null;
2649 MeshServerLogEx(40, null, "Starting remote files after local user accepted (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);