autoAcceptIfLocked and more! (#7319)
stephannn committed
Oct 28, 2025 at 18:20 UTC
49da5da9dd05d7cc1d8503f8c0a717e4ff2d2ef3
5 files changed
+170
-17
agents/meshcore.js
+92
-16
@@ -1176,6 +1176,13 @@ function handleServerCommand(data) {
1176
tunnel.consentTimeout = (tunnel.soptions && tunnel.soptions.consentTimeout) ? tunnel.soptions.consentTimeout : 30;
1177
tunnel.consentAutoAccept = (tunnel.soptions && (tunnel.soptions.consentAutoAccept === true));
1178
tunnel.consentAutoAcceptIfNoUser = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfNoUser === true));
1179
+ tunnel.consentAutoAcceptIfDesktopNoUser = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfDesktopNoUser === true));
1180
+ tunnel.consentAutoAcceptIfTerminalNoUser = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfTerminalNoUser === true));
1181
+ tunnel.consentAutoAcceptIfFileNoUser = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfFileNoUser === true));
1182
+ tunnel.consentAutoAcceptIfLocked = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfLocked === true));
1183
+ tunnel.consentAutoAcceptIfDesktopLocked = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfDesktopLocked === true));
1184
+ tunnel.consentAutoAcceptIfTerminalLocked = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfTerminalLocked === true));
1185
+ tunnel.consentAutoAcceptIfFileLocked = (tunnel.soptions && (tunnel.soptions.consentAutoAcceptIfFileLocked === true));
1186
tunnel.oldStyle = (tunnel.soptions && tunnel.soptions.oldStyle) ? tunnel.soptions.oldStyle : false;
1187
tunnel.tcpaddr = data.tcpaddr;
1188
tunnel.tcpport = data.tcpport;
@@ -3067,7 +3074,7 @@ function onTunnelData(data)
3074
// Perform User-Consent if needed.
3075
if (this.httprequest.consent && (this.httprequest.consent & 16)) {
3076
// User asked for consent so now we check if we can auto accept if no user is present/loggedin
3070
- if (this.httprequest.consentAutoAcceptIfNoUser) {
3077
+ if (this.httprequest.consentAutoAcceptIfNoUser || this.httprequest.consentAutoAcceptIfTerminalNoUser || this.httprequest.consentAutoAcceptIfLocked || this.httprequest.consentAutoAcceptIfTerminalLocked) {
3078
var p = require('user-sessions').enumerateUsers();
3079
p.sessionid = this.httprequest.sessionid;
3080
p.ws = this;
@@ -3076,10 +3083,35 @@ function onTunnelData(data)
3083
for (var i in u) {
3084
if (u[i].State == 'Active') { v.push({ tsid: i, type: u[i].StationName, user: u[i].Username, domain: u[i].Domain }); }
3085
}
3079
- if (v.length == 0) { // No user is present, auto accept
3086
+ var autoAccept = false;
3087
+
3088
+ // Check if we should auto-accept because no user is present
3089
+ if ((this.ws.httprequest.consentAutoAcceptIfNoUser || this.ws.httprequest.consentAutoAcceptIfTerminalNoUser) && (v.length == 0)) {
3090
+ autoAccept = true;
3091
+ }
3092
+
3093
+ // Check if we should auto-accept because all users are locked
3094
+ if ((this.ws.httprequest.consentAutoAcceptIfLocked || this.ws.httprequest.consentAutoAcceptIfTerminalLocked) && (v.length > 0)) {
3095
+ var allUsersLocked = true;
3096
+ if (!meshCoreObj.lusers || meshCoreObj.lusers.length == 0) {
3097
+ // No locked users list available, assume users are not locked
3098
+ allUsersLocked = false;
3099
+ } else {
3100
+ for (var i in v) {
3101
+ var username = v[i].domain ? (v[i].domain + '\\' + v[i].user) : v[i].user;
3102
+ if (meshCoreObj.lusers.indexOf(username) == -1) {
3103
+ allUsersLocked = false;
3104
+ break;
3105
+ }
3106
+ }
3107
+ }
3108
+ if (allUsersLocked) { autoAccept = true; }
3109
+ }
3110
+
3111
+ if (autoAccept) {
3112
this.ws.httprequest.tpromise._res();
3113
} else {
3082
- // User is present so we still need consent
3114
+ // User is present and not all locked, so we still need consent
3115
terminal_consent_ask(this.ws);
3116
}
3117
});
@@ -3188,7 +3220,7 @@ function onTunnelData(data)
3220
if (this.httprequest.consent && (this.httprequest.consent & 8)) {
3221
3222
// User asked for consent but now we check if can auto accept if no user is present
3191
- if (this.httprequest.consentAutoAcceptIfNoUser) {
3223
+ if (this.httprequest.consentAutoAcceptIfNoUser || this.httprequest.consentAutoAcceptIfDesktopNoUser || this.httprequest.consentAutoAcceptIfLocked || this.httprequest.consentAutoAcceptIfDesktopLocked) {
3224
// Get list of users to check if we any actual users logged in, and if users logged in, we still need consent
3225
var p = require('user-sessions').enumerateUsers();
3226
p.sessionid = this.httprequest.sessionid;
@@ -3198,10 +3230,36 @@ function onTunnelData(data)
3230
for (var i in u) {
3231
if (u[i].State == 'Active') { v.push({ tsid: i, type: u[i].StationName, user: u[i].Username, domain: u[i].Domain }); }
3232
}
3201
- if (v.length == 0) { // No user is present, auto accept
3233
+ var autoAccept = false;
3234
+
3235
+ // Check if we can auto-accept because no user is present
3236
+ if ((this.ws.httprequest.consentAutoAcceptIfNoUser || this.ws.httprequest.consentAutoAcceptIfDesktopNoUser) && (v.length == 0)) {
3237
+ // No user is present, auto accept
3238
+ autoAccept = true;
3239
+ }
3240
+
3241
+ // Check if we can auto-accept because all users are locked
3242
+ if ((this.ws.httprequest.consentAutoAcceptIfLocked || this.ws.httprequest.consentAutoAcceptIfDesktopLocked) && (v.length > 0)) {
3243
+ var allUsersLocked = true;
3244
+ if (!meshCoreObj.lusers || meshCoreObj.lusers.length == 0) {
3245
+ // No locked users list available, assume users are not locked
3246
+ allUsersLocked = false;
3247
+ } else {
3248
+ for (var i in v) {
3249
+ var username = v[i].domain ? (v[i].domain + '\\' + v[i].user) : v[i].user;
3250
+ if (meshCoreObj.lusers.indexOf(username) == -1) {
3251
+ allUsersLocked = false;
3252
+ break;
3253
+ }
3254
+ }
3255
+ }
3256
+ if (allUsersLocked) { autoAccept = true; }
3257
+ }
3258
+
3259
+ if (autoAccept) {
3260
kvm_consent_ok(this.ws);
3261
} else {
3204
- // User is present so we still need consent
3262
+ // User is present and not all locked, so we still need consent
3263
kvm_consent_ask(this.ws);
3264
}
3265
});
@@ -3259,10 +3317,7 @@ function onTunnelData(data)
3317
};
3318
3319
// Perform notification if needed. Toast messages may not be supported on all platforms.
3262
- if (this.httprequest.consent && (this.httprequest.consent & 32))
3263
- {
3264
- // User asked for consent so now we check if we can auto accept if no user is present/loggedin
3265
- if (this.httprequest.consentAutoAcceptIfNoUser) {
3320
+ if (this.httprequest.consentAutoAcceptIfNoUser || this.httprequest.consentAutoAcceptIfFileNoUser || this.httprequest.consentAutoAcceptIfLocked || this.httprequest.consentAutoAcceptIfFileLocked) {
3321
var p = require('user-sessions').enumerateUsers();
3322
p.sessionid = this.httprequest.sessionid;
3323
p.ws = this;
@@ -3271,19 +3326,40 @@ function onTunnelData(data)
3326
for (var i in u) {
3327
if (u[i].State == 'Active') { v.push({ tsid: i, type: u[i].StationName, user: u[i].Username, domain: u[i].Domain }); }
3328
}
3274
- if (v.length == 0) { // No user is present, auto accept
3329
+ var autoAccept = false;
3330
+
3331
+ // Check if we should auto-accept because no user is present
3332
+ if ((this.ws.httprequest.consentAutoAcceptIfNoUser || this.ws.httprequest.consentAutoAcceptIfFileNoUser) && (v.length == 0)) {
3333
+ autoAccept = true;
3334
+ }
3335
+
3336
+ // Check if we should auto-accept because all users are locked
3337
+ if ((this.ws.httprequest.consentAutoAcceptIfLocked || this.ws.httprequest.consentAutoAcceptIfFileLocked) && (v.length > 0)) {
3338
+ var allUsersLocked = true;
3339
+ if (!meshCoreObj.lusers || meshCoreObj.lusers.length == 0) {
3340
+ // No locked users list available, assume users are not locked
3341
+ allUsersLocked = false;
3342
+ } else {
3343
+ for (var i in v) {
3344
+ var username = v[i].domain ? (v[i].domain + '\\' + v[i].user) : v[i].user;
3345
+ if (meshCoreObj.lusers.indexOf(username) == -1) {
3346
+ allUsersLocked = false;
3347
+ break;
3348
+ }
3349
+ }
3350
+ }
3351
+ if (allUsersLocked) { autoAccept = true; }
3352
+ }
3353
+
3354
+ if (autoAccept) {
3355
// User Consent Prompt is not required
3356
files_consent_ok(this.ws);
3357
} else {
3278
- // User is present so we still need consent
3358
+ // User is present and not all locked, so we still need consent
3359
files_consent_ask(this.ws);
3360
}
3361
});
3362
} else {
3283
- // User Consent Prompt is required
3284
- files_consent_ask(this);
3285
- }
3286
- } else {
3363
// User Consent Prompt is not required
3364
files_consent_ok(this);
3365
}
meshcentral-config-schema.json
+36
-1
@@ -2080,7 +2080,42 @@
2080
"autoAcceptIfNoUser": {
2081
"type": "boolean",
2082
"default": false,
2083
- "description": "If true, user consent is accepted if no user is logged in."
2083
+ "description": "If true, user consents for desktop, terminal, and file are accepted if no user is logged in."
2084
+ },
2085
+ "autoAcceptIfDesktopNoUser": {
2086
+ "type": "boolean",
2087
+ "default": false,
2088
+ "description": "If true, user consent for desktop access is accepted if no user is logged in."
2089
+ },
2090
+ "autoAcceptIfTerminalNoUser": {
2091
+ "type": "boolean",
2092
+ "default": false,
2093
+ "description": "If true, user consent for terminal access is accepted if no user is logged in."
2094
+ },
2095
+ "autoAcceptIfFileNoUser": {
2096
+ "type": "boolean",
2097
+ "default": false,
2098
+ "description": "If true, user consent for file access is accepted if no user is logged in."
2099
+ },
2100
+ "autoAcceptIfLocked": {
2101
+ "type": "boolean",
2102
+ "default": false,
2103
+ "description": "If true, user consents for desktop, terminal, and file are accepted if device is locked."
2104
+ },
2105
+ "autoAcceptIfDesktopLocked": {
2106
+ "type": "boolean",
2107
+ "default": false,
2108
+ "description": "If true, user consent for desktop access is accepted if device is locked."
2109
+ },
2110
+ "autoAcceptIfTerminalLocked": {
2111
+ "type": "boolean",
2112
+ "default": false,
2113
+ "description": "If true, user consent for terminal access is accepted if device is locked."
2114
+ },
2115
+ "autoAcceptIfFileLocked": {
2116
+ "type": "boolean",
2117
+ "default": false,
2118
+ "description": "If true, user consent for file access is accepted if device is locked."
2119
},
2120
"oldStyle": {
2121
"type": "boolean",
meshdesktopmultiplex.js
+7
@@ -1348,6 +1348,13 @@ function CreateMeshRelayEx2(parent, ws, req, domain, user, cookie) {
1348
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
1349
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
1350
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
1351
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
1352
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
1353
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
1354
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
1355
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
1356
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
1357
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
1358
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
1359
}
1360
if (typeof domain.notificationmessages == 'object') {
meshrelay.js
+28
@@ -906,6 +906,13 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
906
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
907
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
908
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
909
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
910
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
911
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
912
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
913
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
914
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
915
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
916
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
917
}
918
if (typeof domain.notificationmessages == 'object') {
@@ -945,6 +952,13 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
952
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
953
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
954
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
955
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
956
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
957
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
958
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
959
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
960
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
961
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
962
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
963
}
964
if (typeof domain.notificationmessages == 'object') {
@@ -964,6 +978,13 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
978
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
979
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
980
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
981
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
982
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
983
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
984
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
985
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
986
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
987
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
988
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
989
}
990
if (typeof domain.notificationmessages == 'object') {
@@ -1017,6 +1038,13 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
1038
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
1039
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
1040
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
1041
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
1042
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
1043
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
1044
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
1045
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
1046
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
1047
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
1048
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
1049
}
1050
if (typeof domain.notificationmessages == 'object') {
meshuser.js
+7
@@ -1009,6 +1009,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1009
if ((typeof domain.consentmessages.consenttimeout == 'number') && (domain.consentmessages.consenttimeout > 0)) { command.soptions.consentTimeout = domain.consentmessages.consenttimeout; }
1010
if (domain.consentmessages.autoacceptontimeout === true) { command.soptions.consentAutoAccept = true; }
1011
if (domain.consentmessages.autoacceptifnouser === true) { command.soptions.consentAutoAcceptIfNoUser = true; }
1012
+ if (domain.consentmessages.autoacceptifdesktopnouser === true) { command.soptions.consentAutoAcceptIfDesktopNoUser = true; }
1013
+ if (domain.consentmessages.autoacceptifterminalnouser === true) { command.soptions.consentAutoAcceptIfTerminalNoUser = true; }
1014
+ if (domain.consentmessages.autoacceptiffilenouser === true) { command.soptions.consentAautoAcceptIfFileNoUser = true; }
1015
+ if (domain.consentmessages.autoacceptiflocked === true) { command.soptions.consentAutoAcceptIfLocked = true; }
1016
+ if (domain.consentmessages.autoacceptifdesktoplocked === true) { command.soptions.consentAutoAcceptIfDesktopLocked = true; }
1017
+ if (domain.consentmessages.autoacceptifterminallocked === true) { command.soptions.consentAutoAcceptIfTerminalLocked = true; }
1018
+ if (domain.consentmessages.autoacceptiffilelocked === true) { command.soptions.consentAutoAcceptIfFileLocked = true; }
1019
if (domain.consentmessages.oldstyle === true) { command.soptions.oldStyle = true; }
1020
}
1021
if (typeof domain.notificationmessages == 'object') {