User management improvements.
Ylian Saint-Hilaire committed
May 27, 2020 at 18:26 UTC
8443416afa713cd03d8ea1af54c0f7796aa3abd7
4 files changed
+183
-17
meshuser.js
+36
-4
@@ -1433,8 +1433,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1433
}
1434
case 'deleteuser':
1435
{
1436
- console.log(command);
1437
-
1436
// Delete a user account
1437
var err = null, delusersplit, deluserid, deluser, deluserdomain;
1438
try {
@@ -1494,12 +1492,23 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1492
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
1493
parent.parent.DispatchEvent(parent.CreateNodeDispatchTargets(node.meshid, node._id), obj, event);
1494
});
1495
+ } else if (i.startsWith('ugrp/')) {
1496
+ // Get the device group
1497
+ var ugroup = parent.userGroups[i];
1498
+ if (ugroup) {
1499
+ // Remove user from the user group
1500
+ if (ugroup.links[deluser._id] != null) { delete ugroup.links[deluser._id]; parent.db.Set(ugroup); }
1501
+
1502
+ // Notify user group change
1503
+ change = 'Removed user ' + deluser.name + ' from user group ' + ugroup.name;
1504
+ var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Removed user ' + deluser.name + ' from user group ' + ugroup.name, addUserDomain: deluserdomain.id };
1505
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
1506
+ parent.parent.DispatchEvent(['*', ugroup._id, user._id, deluser._id], obj, event);
1507
+ }
1508
}
1509
}
1510
}
1511
1501
- // TODO (UserGroups): Remove user groups??
1502
-
1512
db.Remove('ws' + deluser._id); // Remove user web state
1513
db.Remove('nt' + deluser._id); // Remove notes for this user
1514
@@ -1707,6 +1716,29 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1716
if (command.resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); }
1717
if (user.groups) { newuser.groups = user.groups; } // New accounts are automatically part of our groups (Realms).
1718
1719
+ // Auto-join any user groups
1720
+ if (typeof newuserdomain.newaccountsusergroups == 'object') {
1721
+ for (var i in newuserdomain.newaccountsusergroups) {
1722
+ var ugrpid = newuserdomain.newaccountsusergroups[i];
1723
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + newuserdomain.id + '/' + ugrpid; }
1724
+ var ugroup = parent.userGroups[ugrpid];
1725
+ if (ugroup != null) {
1726
+ // Add group to the user
1727
+ if (newuser.links == null) { newuser.links = {}; }
1728
+ newuser.links[ugroup._id] = { rights: 1 };
1729
+
1730
+ // Add user to the group
1731
+ ugroup.links[newuser._id] = { userid: newuser._id, name: newuser.name, rights: 1 };
1732
+ db.Set(ugroup);
1733
+
1734
+ // Notify user group change
1735
+ var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + newuser.name + ' to user group ' + ugroup.name, addUserDomain: newuserdomain.id };
1736
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
1737
+ parent.parent.DispatchEvent(['*', ugroup._id, user._id, newuser._id], obj, event);
1738
+ }
1739
+ }
1740
+ }
1741
+
1742
parent.users[newuserid] = newuser;
1743
1744
// Create a user, generate a salt and hash the password
public/scripts/amt-wsman-0.2.0-min.js
+1
-1
@@ -1 +1 @@
1
-var WsmanStackCreateService=function(e,s,r,a,o,t){var p={};function l(e){if(!e)return"";var s=" ";for(var r in e)e.hasOwnProperty(r)&&0===r.indexOf("@")&&(s+=r.substring(1)+'="'+e[r]+'" ');return s}function w(e){if(!e)return"";if("string"==typeof e)return e;if(e.InstanceID)return'<w:SelectorSet><w:Selector Name="InstanceID">'+e.InstanceID+"</w:Selector></w:SelectorSet>";var s="<w:SelectorSet>";for(var r in e)if(e.hasOwnProperty(r)){if(s+='<w:Selector Name="'+r+'">',e[r].ReferenceParameters){s+="<a:EndpointReference>",s+="<a:Address>"+e[r].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+e[r].ReferenceParameters.ResourceURI+"</w:ResourceURI><w:SelectorSet>";var a=e[r].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(a))for(var o=0;o<a.length;o++)s+="<w:Selector"+l(a[o])+">"+a[o].Value+"</w:Selector>";else s+="<w:Selector"+l(a)+">"+a.Value+"</w:Selector>";s+="</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>"}else s+=e[r];s+="</w:Selector>"}return s+="</w:SelectorSet>"}return p.NextMessageId=1,p.Address="/wsman",p.comm=CreateWsmanComm(e,s,r,a,o,t),p.PerformAjax=function(e,o,s,r,a){null==a&&(a=""),p.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope" '+a+"><Header><a:Action>"+e,function(e,s,r){if(200==s){var a=p.ParseWsman(e);a&&null!=a?o(p,a.Header.ResourceURI,a,200,r):o(p,null,{Header:{HttpError:s}},601,r)}else o(p,null,{Header:{HttpError:s}},s,r)},s,r)},p.CancelAllQueries=function(e){p.comm.CancelAllQueries(e)},p.GetNameFromUrl=function(e){var s=e.lastIndexOf("/");return-1==s?e:e.substring(s+1)},p.ExecSubscribe=function(e,s,r,a,o,t,n,l,d,c){var m="",i="";null!=d&&null!=c&&(m="<t:IssuedTokens><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>"+d+'</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">'+c+"</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>",i='<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'),l=null!=l&&null!=l?"<a:ReferenceParameters>"+l+"</a:ReferenceParameters>":"";var u="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+w(n)+m+'</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.dmtf.org/wbem/wsman/1/wsman/'+s+'"><e:NotifyTo><a:Address>'+r+"</a:Address></e:NotifyTo>"+i+"</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>";p.PerformAjax(u+"</Body></Envelope>",a,o,t,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:m="http://x.com"')},p.ExecUnSubscribe=function(e,s,r,a,o){var t="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+w(o)+"</Header><Body><e:Unsubscribe/>";p.PerformAjax(t+"</Body></Envelope>",s,r,a,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')},p.ExecPut=function(e,s,r,a,o,t){var n="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>"+w(t)+"</Header><Body>"+function(e,s){if(!e||null==s)return"";var r=p.GetNameFromUrl(e),a="<r:"+r+' xmlns:r="'+e+'">';for(var o in s)if(s.hasOwnProperty(o)&&0!==o.indexOf("__")&&0!==o.indexOf("@")&&void 0!==s[o]&&null!==s[o]&&"function"!=typeof s[o])if("object"==typeof s[o]&&s[o].ReferenceParameters){a+="<r:"+o+"><a:Address>"+s[o].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+s[o].ReferenceParameters.ResourceURI+"</w:ResourceURI><w:SelectorSet>";var t=s[o].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(t))for(var n=0;n<t.length;n++)a+="<w:Selector"+l(t[n])+">"+t[n].Value+"</w:Selector>";else a+="<w:Selector"+l(t)+">"+t.Value+"</w:Selector>";a+="</w:SelectorSet></a:ReferenceParameters></r:"+o+">"}else if(Array.isArray(s[o]))for(n=0;n<s[o].length;n++)a+="<r:"+o+">"+s[o][n].toString()+"</r:"+o+">";else a+="<r:"+o+">"+s[o].toString()+"</r:"+o+">";return a+="</r:"+r+">"}(e,s);p.PerformAjax(n+"</Body></Envelope>",r,a,o)},p.ExecCreate=function(e,s,r,a,o,t){var n=p.GetNameFromUrl(e),l="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(t)+"</Header><Body><g:"+n+' xmlns:g="'+e+'">';for(var d in s)l+="<g:"+d+">"+s[d]+"</g:"+d+">";p.PerformAjax(l+"</g:"+n+"></Body></Envelope>",r,a,o)},p.ExecCreateXml=function(e,s,r,a,o){var t=p.GetNameFromUrl(e);p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout></Header><Body><r:"+t+' xmlns:r="'+e+'">'+s+"</r:"+t+"></Body></Envelope>",r,a,o)},p.ExecDelete=function(e,s,r,a,o){var t="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(s)+"</Header><Body /></Envelope>";p.PerformAjax(t,r,a,o)},p.ExecGet=function(e,s,r,a){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>",s,r,a)},p.ExecMethod=function(e,s,r,a,o,t,n){var l="";for(var d in r)if(null!=r[d])if(Array.isArray(r[d]))for(var c in r[d])l+="<r:"+d+">"+r[d][c]+"</r:"+d+">";else l+="<r:"+d+">"+r[d]+"</r:"+d+">";p.ExecMethodXml(e,s,l,a,o,t,n)},p.ExecMethodXml=function(e,s,r,a,o,t,n){p.PerformAjax(e+"/"+s+"</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(n)+"</Header><Body><r:"+s+'_INPUT xmlns:r="'+e+'">'+r+"</r:"+s+"_INPUT></Body></Envelope>",a,o,t)},p.ExecEnum=function(e,s,r,a){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration" /></Body></Envelope>',s,r,a)},p.ExecPull=function(e,s,r,a,o){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration"><EnumerationContext>'+s+"</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>",r,a,o)},p.ParseWsman=function(s){try{s.childNodes||(s=function(e){{if(window.DOMParser)return(new DOMParser).parseFromString(e,"text/xml");var s=new ActiveXObject("Microsoft.XMLDOM");return s.async=!1,s.loadXML(e),s}}(s));var e,r={Header:{}},a=s.getElementsByTagName("Header")[0];if(!(a=a||s.getElementsByTagName("a:Header")[0]))return null;for(var o=0;o<a.childNodes.length;o++){var t=a.childNodes[o];r.Header[t.localName]=t.textContent}var n=s.getElementsByTagName("Body")[0];return(n=n||s.getElementsByTagName("a:Body")[0])?(0<n.childNodes.length&&((e=n.childNodes[0].localName).indexOf("_OUTPUT")==e.length-7&&(e=e.substring(0,e.length-7)),r.Header.Method=e,r.Body=function e(s){var r,a={};for(var o=0;o<s.childNodes.length;o++){var t=s.childNodes[o];"true"==(r=0==t.childElementCount?t.textContent:e(t))&&(r=!0),"false"==r&&(r=!1);var n=r;if(0<t.attributes.length){n={Value:r};for(var l=0;l<t.attributes.length;l++)n["@"+t.attributes[l].name]=t.attributes[l].value}a[t.localName]instanceof Array?a[t.localName].push(n):null==a[t.localName]?a[t.localName]=n:a[t.localName]=[a[t.localName],n]}return a}(n.childNodes[0])),r):null}catch(e){return console.log("Unable to parse XML: "+s),null}},p}
\ No newline at end of file
1
+var WsmanStackCreateService=function(e,s,r,a,o,t){var p={};function l(e){if(!e)return"";var s=" ";for(var r in e)e.hasOwnProperty(r)&&0===r.indexOf("@")&&(s+=r.substring(1)+'="'+e[r]+'" ');return s}function w(e){if(!e)return"";if("string"==typeof e)return e;if(e.InstanceID)return'<w:SelectorSet><w:Selector Name="InstanceID">'+e.InstanceID+"</w:Selector></w:SelectorSet>";var s="<w:SelectorSet>";for(var r in e)if(e.hasOwnProperty(r)){if(s+='<w:Selector Name="'+r+'">',e[r].ReferenceParameters){s+="<a:EndpointReference>",s+="<a:Address>"+e[r].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+e[r].ReferenceParameters.ResourceURI+"</w:ResourceURI><w:SelectorSet>";var a=e[r].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(a))for(var o=0;o<a.length;o++)s+="<w:Selector"+l(a[o])+">"+a[o].Value+"</w:Selector>";else s+="<w:Selector"+l(a)+">"+a.Value+"</w:Selector>";s+="</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>"}else s+=e[r];s+="</w:Selector>"}return s+="</w:SelectorSet>"}return p.NextMessageId=1,p.Address="/wsman",p.comm=CreateWsmanComm(e,s,r,a,o,t),p.PerformAjax=function(e,o,s,r,a){null==a&&(a=""),p.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope" '+a+"><Header><a:Action>"+e,function(e,s,r){if(200==s){var a=p.ParseWsman(e);a&&null!=a?o(p,a.Header.ResourceURI,a,200,r):o(p,null,{Header:{HttpError:s}},601,r)}else o(p,null,{Header:{HttpError:s}},s,r)},s,r)},p.CancelAllQueries=function(e){p.comm.CancelAllQueries(e)},p.GetNameFromUrl=function(e){var s=e.lastIndexOf("/");return-1==s?e:e.substring(s+1)},p.ExecSubscribe=function(e,s,r,a,o,t,n,l,c,d){var m="",i="";null!=c&&null!=d&&(m="<t:IssuedTokens><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>"+c+'</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">'+d+"</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>",i='<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'),l=null!=l&&null!=l?"<a:ReferenceParameters>"+l+"</a:ReferenceParameters>":"";var u="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+w(n)+m+'</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.dmtf.org/wbem/wsman/1/wsman/'+s+'"><e:NotifyTo><a:Address>'+r+"</a:Address></e:NotifyTo>"+i+"</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>";p.PerformAjax(u+"</Body></Envelope>",a,o,t,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:m="http://x.com"')},p.ExecUnSubscribe=function(e,s,r,a,o){var t="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>"+w(o)+"</Header><Body><e:Unsubscribe/>";p.PerformAjax(t+"</Body></Envelope>",s,r,a,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')},p.ExecPut=function(e,s,r,a,o,t){var n="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>"+w(t)+"</Header><Body>"+function(e,s){if(!e||null==s)return"";var r=p.GetNameFromUrl(e),a="<r:"+r+' xmlns:r="'+e+'">';for(var o in s)if(s.hasOwnProperty(o)&&0!==o.indexOf("__")&&0!==o.indexOf("@")&&void 0!==s[o]&&null!==s[o]&&"function"!=typeof s[o])if("object"==typeof s[o]&&s[o].ReferenceParameters){a+="<r:"+o+"><a:Address>"+s[o].Address+"</a:Address><a:ReferenceParameters><w:ResourceURI>"+s[o].ReferenceParameters.ResourceURI+"</w:ResourceURI><w:SelectorSet>";var t=s[o].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(t))for(var n=0;n<t.length;n++)a+="<w:Selector"+l(t[n])+">"+t[n].Value+"</w:Selector>";else a+="<w:Selector"+l(t)+">"+t.Value+"</w:Selector>";a+="</w:SelectorSet></a:ReferenceParameters></r:"+o+">"}else if(Array.isArray(s[o]))for(n=0;n<s[o].length;n++)a+="<r:"+o+">"+s[o][n].toString()+"</r:"+o+">";else a+="<r:"+o+">"+s[o].toString()+"</r:"+o+">";return a+="</r:"+r+">"}(e,s);p.PerformAjax(n+"</Body></Envelope>",r,a,o)},p.ExecCreate=function(e,s,r,a,o,t){var n=p.GetNameFromUrl(e),l="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(t)+"</Header><Body><g:"+n+' xmlns:g="'+e+'">';for(var c in s)l+="<g:"+c+">"+s[c]+"</g:"+c+">";p.PerformAjax(l+"</g:"+n+"></Body></Envelope>",r,a,o)},p.ExecCreateXml=function(e,s,r,a,o){var t=p.GetNameFromUrl(e);p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout></Header><Body><r:"+t+' xmlns:r="'+e+'">'+s+"</r:"+t+"></Body></Envelope>",r,a,o)},p.ExecDelete=function(e,s,r,a,o){var t="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(s)+"</Header><Body /></Envelope>";p.PerformAjax(t,r,a,o)},p.ExecGet=function(e,s,r,a){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>",s,r,a)},p.ExecMethod=function(e,s,r,a,o,t,n){var l="";for(var c in r)if(null!=r[c])if(Array.isArray(r[c]))for(var d in r[c])l+="<r:"+c+">"+r[c][d]+"</r:"+c+">";else l+="<r:"+c+">"+r[c]+"</r:"+c+">";p.ExecMethodXml(e,s,l,a,o,t,n)},p.ExecMethodXml=function(e,s,r,a,o,t,n){p.PerformAjax(e+"/"+s+"</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++"</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>"+w(n)+"</Header><Body><r:"+s+'_INPUT xmlns:r="'+e+'">'+r+"</r:"+s+"_INPUT></Body></Envelope>",a,o,t)},p.ExecEnum=function(e,s,r,a){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration" /></Body></Envelope>',s,r,a)},p.ExecPull=function(e,s,r,a,o){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>"+p.Address+"</a:To><w:ResourceURI>"+e+"</w:ResourceURI><a:MessageID>"+p.NextMessageId+++'</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration"><EnumerationContext>'+s+"</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>",r,a,o)},p.ParseWsman=function(s){try{s.childNodes||(s=function(e){{if(window.DOMParser)return(new DOMParser).parseFromString(e,"text/xml");var s=new ActiveXObject("Microsoft.XMLDOM");return s.async=!1,s.loadXML(e),s}}(s));var e,r={Header:{}},a=s.getElementsByTagName("Header")[0];if(!(a=a||s.getElementsByTagName("a:Header")[0]))return null;for(var o=0;o<a.childNodes.length;o++){var t=a.childNodes[o];r.Header[t.localName]=t.textContent}var n=s.getElementsByTagName("Body")[0];return(n=n||s.getElementsByTagName("a:Body")[0])?(0<n.childNodes.length&&((e=n.childNodes[0].localName).indexOf("_OUTPUT")==e.length-7&&(e=e.substring(0,e.length-7)),r.Header.Method=e,r.Body=function e(s){var r,a={};for(var o=0;o<s.childNodes.length;o++){var t=s.childNodes[o];"true"==(r=0==t.childElementCount?t.textContent:e(t))&&(r=!0),"false"==r&&(r=!1);var n=r;if(0<t.attributes.length){n={Value:r};for(var l=0;l<t.attributes.length;l++)n["@"+t.attributes[l].name]=t.attributes[l].value}a[t.localName]instanceof Array?a[t.localName].push(n):null==a[t.localName]?a[t.localName]=n:a[t.localName]=[a[t.localName],n]}return a}(n.childNodes[0])),r):null}catch(e){return console.log("Unable to parse XML: "+s),null}},p}
\ No newline at end of file
views/default.handlebars
+2
-2
@@ -10663,7 +10663,7 @@
10663
10664
var x = '<div style=min-height:80px><table style=width:100%>';
10665
if ((args.hide & 8) != 0) { x += '<br />' + addDeviceAttribute("Name", gname); } // If title bar is hidden, display the user group name here
10666
- if (serverinfo.crossDomain != null) {
10666
+ if ((serverinfo.crossDomain != null) || (debugmode != 0)) {
10667
var d = group._id.split('/')[1];
10668
x += addDeviceAttribute("Domain", (d != '')?EscapeHtml(d):('<i>' + "Default" + '</i>'));
10669
x += addDeviceAttribute("Group Identifier", EscapeHtml(group._id));
@@ -10972,7 +10972,7 @@
10972
var email = user.email?EscapeHtml(user.email):'<i>' + "Not set" + '</i>', everify = '';
10973
if (serverinfo.emailcheck) { everify = ((user.emailVerified == true) ? '<b style=color:green;cursor:pointer title="' + "Email is verified" + '">✓</b> ' : '<b style=color:red;cursor:pointer title="' + "Email not verified" + '">✗</b> '); }
10974
10975
- if (serverinfo.crossDomain) {
10975
+ if ((serverinfo.crossDomain) || (debugmode != 0)) {
10976
var d = user._id.split('/')[1];
10977
x += addDeviceAttribute("Domain", ((d != '')?EscapeHtml(d):('<i>' + "Default" + '</i>')));
10978
x += addDeviceAttribute("User Identifier", EscapeHtml(user._id));
webserver.js
+144
-10
@@ -385,15 +385,36 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
385
if (user == null) {
386
// Create a new user
387
var user = { type: 'user', _id: userid, name: username, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
388
- if (email) {
389
- user['email'] = email;
390
- user['emailVerified'] = true;
391
- }
388
+ if (email) { user['email'] = email; user['emailVerified'] = true; }
389
if (domain.newaccountsrights) { user.siteadmin = domain.newaccountsrights; }
390
if (obj.common.validateStrArray(domain.newaccountrealms)) { user.groups = domain.newaccountrealms; }
391
var usercount = 0;
392
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
393
if (usercount == 0) { user.siteadmin = 4294967295; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
394
+
395
+ // Auto-join any user groups
396
+ if (typeof domain.newaccountsusergroups == 'object') {
397
+ for (var i in domain.newaccountsusergroups) {
398
+ var ugrpid = domain.newaccountsusergroups[i];
399
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + domain.id + '/' + ugrpid; }
400
+ var ugroup = obj.userGroups[ugrpid];
401
+ if (ugroup != null) {
402
+ // Add group to the user
403
+ if (user.links == null) { user.links = {}; }
404
+ user.links[ugroup._id] = { rights: 1 };
405
+
406
+ // Add user to the group
407
+ ugroup.links[user._id] = { userid: user._id, name: user.name, rights: 1 };
408
+ db.Set(ugroup);
409
+
410
+ // Notify user group change
411
+ var event = { etype: 'ugrp', ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + user.name + ' to user group ' + ugroup.name, addUserDomain: domain.id };
412
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
413
+ parent.DispatchEvent(['*', ugroup._id, user._id], obj, event);
414
+ }
415
+ }
416
+ }
417
+
418
obj.users[user._id] = user;
419
obj.db.SetUser(user);
420
var event = { etype: 'user', userid: userid, username: username, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id };
@@ -483,6 +504,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
504
var usercount = 0;
505
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
506
if (usercount == 0) { user.siteadmin = 4294967295; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
507
+
508
+ // Auto-join any user groups
509
+ if (typeof domain.newaccountsusergroups == 'object') {
510
+ for (var i in domain.newaccountsusergroups) {
511
+ var ugrpid = domain.newaccountsusergroups[i];
512
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + domain.id + '/' + ugrpid; }
513
+ var ugroup = obj.userGroups[ugrpid];
514
+ if (ugroup != null) {
515
+ // Add group to the user
516
+ if (user.links == null) { user.links = {}; }
517
+ user.links[ugroup._id] = { rights: 1 };
518
+
519
+ // Add user to the group
520
+ ugroup.links[user._id] = { userid: user._id, name: user.name, rights: 1 };
521
+ db.Set(ugroup);
522
+
523
+ // Notify user group change
524
+ var event = { etype: 'ugrp', ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + user.name + ' to user group ' + ugroup.name, addUserDomain: domain.id };
525
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
526
+ parent.DispatchEvent(['*', ugroup._id, user._id], obj, event);
527
+ }
528
+ }
529
+ }
530
+
531
obj.users[user._id] = user;
532
obj.db.SetUser(user);
533
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id };
@@ -1147,6 +1192,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1192
if (obj.common.validateStrArray(domain.newaccountrealms)) { user.groups = domain.newaccountrealms; }
1193
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (req.body.apasswordhint)) { var hint = req.body.apasswordhint; if (hint.length > 250) { hint = hint.substring(0, 250); } user.passhint = hint; }
1194
if (domainUserCount == 0) { user.siteadmin = 4294967295; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
1195
+
1196
+ // Auto-join any user groups
1197
+ if (typeof domain.newaccountsusergroups == 'object') {
1198
+ for (var i in domain.newaccountsusergroups) {
1199
+ var ugrpid = domain.newaccountsusergroups[i];
1200
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + domain.id + '/' + ugrpid; }
1201
+ var ugroup = obj.userGroups[ugrpid];
1202
+ if (ugroup != null) {
1203
+ // Add group to the user
1204
+ if (user.links == null) { user.links = {}; }
1205
+ user.links[ugroup._id] = { rights: 1 };
1206
+
1207
+ // Add user to the group
1208
+ ugroup.links[user._id] = { userid: user._id, name: user.name, rights: 1 };
1209
+ db.Set(ugroup);
1210
+
1211
+ // Notify user group change
1212
+ var event = { etype: 'ugrp', ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + user.name + ' to user group ' + ugroup.name, addUserDomain: domain.id };
1213
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
1214
+ parent.DispatchEvent(['*', ugroup._id, user._id], obj, event);
1215
+ }
1216
+ }
1217
+ }
1218
+
1219
obj.users[user._id] = user;
1220
req.session.userid = user._id;
1221
req.session.domainid = domain.id;
@@ -1619,20 +1688,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1688
for (var i in deluser.links) {
1689
if (i.startsWith('mesh/')) {
1690
// Get the device group
1622
- mesh = parent.meshes[i];
1691
+ var mesh = obj.meshes[i];
1692
if (mesh) {
1693
// Remove user from the mesh
1694
if (mesh.links[deluser._id] != null) { delete mesh.links[deluser._id]; parent.db.Set(mesh); }
1695
1696
// Notify mesh change
1628
- change = 'Removed user ' + deluser.name + ' from group ' + mesh.name;
1697
+ var change = 'Removed user ' + deluser.name + ' from group ' + mesh.name;
1698
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id, invite: mesh.invite };
1699
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
1631
- parent.parent.DispatchEvent(['*', mesh._id, deluser._id, user._id], obj, event);
1700
+ parent.DispatchEvent(['*', mesh._id, deluser._id, user._id], obj, event);
1701
}
1702
} else if (i.startsWith('node/')) {
1703
// Get the node and the rights for this node
1635
- parent.GetNodeWithRights(domain, deluser, i, function (node, rights, visible) {
1704
+ obj.GetNodeWithRights(domain, deluser, i, function (node, rights, visible) {
1705
if ((node == null) || (node.links == null) || (node.links[deluser._id] == null)) return;
1706
1707
// Remove the link and save the node to the database
@@ -1641,10 +1710,23 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1710
db.Set(obj.cleanDevice(node));
1711
1712
// Event the node change
1644
- var event = { etype: 'node', userid: user._id, username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id, msg: (command.rights == 0) ? ('Removed user device rights for ' + node.name) : ('Changed user device rights for ' + node.name), node: parent.CloneSafeNode(node) }
1713
+ var event = { etype: 'node', userid: user._id, username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id, msg: ('Removed user device rights for ' + node.name), node: obj.CloneSafeNode(node) }
1714
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
1646
- parent.parent.DispatchEvent(['*', node.meshid, node._id], obj, event);
1715
+ parent.DispatchEvent(['*', node.meshid, node._id], obj, event);
1716
});
1717
+ } else if (i.startsWith('ugrp/')) {
1718
+ // Get the device group
1719
+ var ugroup = obj.userGroups[i];
1720
+ if (ugroup) {
1721
+ // Remove user from the user group
1722
+ if (ugroup.links[deluser._id] != null) { delete ugroup.links[deluser._id]; parent.db.Set(ugroup); }
1723
+
1724
+ // Notify user group change
1725
+ var change = 'Removed user ' + deluser.name + ' from user group ' + ugroup.name;
1726
+ var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Removed user ' + deluser.name + ' from user group ' + ugroup.name, addUserDomain: domain.id };
1727
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
1728
+ parent.DispatchEvent(['*', ugroup._id, user._id, deluser._id], obj, event);
1729
+ }
1730
}
1731
}
1732
}
@@ -1765,6 +1847,34 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1847
if (domain.newaccountsrights) { user.siteadmin = domain.newaccountsrights; } // New accounts automatically assigned server rights.
1848
if (newAccountRealms) { user.groups = newAccountRealms; } // New accounts automatically part of some groups (Realms).
1849
obj.users[userid] = user;
1850
+
1851
+ // Auto-join any user groups
1852
+ var newaccountsusergroups = null;
1853
+ if (typeof domain.newaccountsusergroups == 'object') { newaccountsusergroups = domain.newaccountsusergroups; }
1854
+ if (typeof domain.authstrategies[req.user.strategy].newaccountsusergroups == 'object') { newaccountsusergroups = domain.authstrategies[req.user.strategy].newaccountsusergroups; }
1855
+ if (newaccountsusergroups) {
1856
+ for (var i in newaccountsusergroups) {
1857
+ var ugrpid = newaccountsusergroups[i];
1858
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + domain.id + '/' + ugrpid; }
1859
+ var ugroup = obj.userGroups[ugrpid];
1860
+ if (ugroup != null) {
1861
+ // Add group to the user
1862
+ if (user.links == null) { user.links = {}; }
1863
+ user.links[ugroup._id] = { rights: 1 };
1864
+
1865
+ // Add user to the group
1866
+ ugroup.links[user._id] = { userid: user._id, name: user.name, rights: 1 };
1867
+ db.Set(ugroup);
1868
+
1869
+ // Notify user group change
1870
+ var event = { etype: 'ugrp', ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + user.name + ' to user group ' + ugroup.name, addUserDomain: domain.id };
1871
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
1872
+ parent.DispatchEvent(['*', ugroup._id, user._id], obj, event);
1873
+ }
1874
+ }
1875
+ }
1876
+
1877
+ // Save the user
1878
obj.db.SetUser(user);
1879
1880
// Event user creation
@@ -1914,6 +2024,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2024
if (obj.common.validateStrArray(domain.newaccountrealms)) { user2.groups = domain.newaccountrealms; }
2025
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
2026
if (usercount == 0) { user2.siteadmin = 4294967295; } // If this is the first user, give the account site admin.
2027
+
2028
+ // Auto-join any user groups
2029
+ if (typeof domain.newaccountsusergroups == 'object') {
2030
+ for (var i in domain.newaccountsusergroups) {
2031
+ var ugrpid = domain.newaccountsusergroups[i];
2032
+ if (ugrpid.indexOf('/') < 0) { ugrpid = 'ugrp/' + domain.id + '/' + ugrpid; }
2033
+ var ugroup = obj.userGroups[ugrpid];
2034
+ if (ugroup != null) {
2035
+ // Add group to the user
2036
+ if (user2.links == null) { user2.links = {}; }
2037
+ user2.links[ugroup._id] = { rights: 1 };
2038
+
2039
+ // Add user to the group
2040
+ ugroup.links[user2._id] = { userid: user2._id, name: user2.name, rights: 1 };
2041
+ db.Set(ugroup);
2042
+
2043
+ // Notify user group change
2044
+ var event = { etype: 'ugrp', ugrpid: ugroup._id, name: ugroup.name, desc: ugroup.desc, action: 'usergroupchange', links: ugroup.links, msg: 'Added user ' + user2.name + ' to user group ' + ugroup.name, addUserDomain: domain.id };
2045
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
2046
+ parent.DispatchEvent(['*', ugroup._id, user2._id], obj, event);
2047
+ }
2048
+ }
2049
+ }
2050
+
2051
obj.users[req.session.userid] = user2;
2052
obj.db.SetUser(user2);
2053
var event = { etype: 'user', userid: req.session.userid, username: req.connection.user, account: obj.CloneSafeUser(user2), action: 'accountcreate', msg: 'Domain account created, user ' + req.connection.user, domain: domain.id };