Fix database escaping problem in device groups.
Ylian Saint-Hilaire committed
Dec 30, 2020 at 18:52 UTC
5a4fdd3d8dc14c0865bbf492b4964fefbc80a5d4
1 file changed
+100
-47
db.js
+100
-47
@@ -97,64 +97,116 @@ module.exports.CreateDB = function (parent, func) {
97
obj.file.remove({ type: 'smbios' }, { multi: true });
98
}
99
100
- // Remove all objects that have a "meshid" that no longer points to a valid mesh.
101
- obj.GetAllType('mesh', function (err, docs) {
102
- if (err != null) { parent.debug('db', 'ERROR (GetAll mesh): ' + err); }
103
- var meshlist = [];
104
- if ((err == null) && (docs.length > 0)) { for (var i in docs) { meshlist.push(docs[i]._id); } }
105
- if ((obj.databaseType == 4) || (obj.databaseType == 5)) {
106
- // MariaDB
107
- sqlDbQuery('DELETE FROM MeshCentral.Main WHERE (extra LIKE ("mesh/%") AND (extra NOT IN ?)', [meshlist], func);
108
- } else if (obj.databaseType == 3) {
109
- // MongoDB
110
- obj.file.deleteMany({ meshid: { $exists: true, $nin: meshlist } }, { multi: true });
111
- } else {
112
- // NeDB or MongoJS
113
- obj.file.remove({ meshid: { $exists: true, $nin: meshlist } }, { multi: true });
114
- }
100
+ // List of valid identifiers
101
+ var validIdentifiers = {}
102
+
103
+ // Load all user groups
104
+ obj.GetAllType('ugrp', function (err, docs) {
105
+ if (err != null) { parent.debug('db', 'ERROR (GetAll user): ' + err); }
106
+ if ((err == null) && (docs.length > 0)) {
107
+ for (var i in docs) {
108
+ // Add this as a valid user identifier
109
+ validIdentifiers[docs[i]._id] = 1;
110
+ }
111
116
- // Fix all of the creating & login to ticks by seconds, not milliseconds.
117
- obj.GetAllType('user', function (err, docs) {
118
- if (err != null) { parent.debug('db', 'ERROR (GetAll user): ' + err); }
119
- if ((err == null) && (docs.length > 0)) {
120
- for (var i in docs) {
121
- var fixed = false;
112
+ // Fix all of the creating & login to ticks by seconds, not milliseconds.
113
+ obj.GetAllType('user', function (err, docs) {
114
+ if (err != null) { parent.debug('db', 'ERROR (GetAll user): ' + err); }
115
+ if ((err == null) && (docs.length > 0)) {
116
+ for (var i in docs) {
117
+ var fixed = false;
118
123
- // Fix email address capitalization
124
- if (docs[i].email && (docs[i].email != docs[i].email.toLowerCase())) {
125
- docs[i].email = docs[i].email.toLowerCase(); fixed = true;
126
- }
119
+ // Add this as a valid user identifier
120
+ validIdentifiers[docs[i]._id] = 1;
121
128
- // Fix account creation
129
- if (docs[i].creation) {
130
- if (docs[i].creation > 1300000000000) { docs[i].creation = Math.floor(docs[i].creation / 1000); fixed = true; }
131
- if ((docs[i].creation % 1) != 0) { docs[i].creation = Math.floor(docs[i].creation); fixed = true; }
132
- }
122
+ // Fix email address capitalization
123
+ if (docs[i].email && (docs[i].email != docs[i].email.toLowerCase())) {
124
+ docs[i].email = docs[i].email.toLowerCase(); fixed = true;
125
+ }
126
134
- // Fix last account login
135
- if (docs[i].login) {
136
- if (docs[i].login > 1300000000000) { docs[i].login = Math.floor(docs[i].login / 1000); fixed = true; }
137
- if ((docs[i].login % 1) != 0) { docs[i].login = Math.floor(docs[i].login); fixed = true; }
138
- }
127
+ // Fix account creation
128
+ if (docs[i].creation) {
129
+ if (docs[i].creation > 1300000000000) { docs[i].creation = Math.floor(docs[i].creation / 1000); fixed = true; }
130
+ if ((docs[i].creation % 1) != 0) { docs[i].creation = Math.floor(docs[i].creation); fixed = true; }
131
+ }
132
+
133
+ // Fix last account login
134
+ if (docs[i].login) {
135
+ if (docs[i].login > 1300000000000) { docs[i].login = Math.floor(docs[i].login / 1000); fixed = true; }
136
+ if ((docs[i].login % 1) != 0) { docs[i].login = Math.floor(docs[i].login); fixed = true; }
137
+ }
138
+
139
+ // Fix last password change
140
+ if (docs[i].passchange) {
141
+ if (docs[i].passchange > 1300000000000) { docs[i].passchange = Math.floor(docs[i].passchange / 1000); fixed = true; }
142
+ if ((docs[i].passchange % 1) != 0) { docs[i].passchange = Math.floor(docs[i].passchange); fixed = true; }
143
+ }
144
140
- // Fix last password change
141
- if (docs[i].passchange) {
142
- if (docs[i].passchange > 1300000000000) { docs[i].passchange = Math.floor(docs[i].passchange / 1000); fixed = true; }
143
- if ((docs[i].passchange % 1) != 0) { docs[i].passchange = Math.floor(docs[i].passchange); fixed = true; }
145
+ // Fix subscriptions
146
+ if (docs[i].subscriptions != null) { delete docs[i].subscriptions; fixed = true; }
147
+
148
+ // Save the user if needed
149
+ if (fixed) { obj.Set(docs[i]); }
150
}
151
146
- // Fix subscriptions
147
- if (docs[i].subscriptions != null) { delete docs[i].subscriptions; fixed = true; }
152
+ // Remove all objects that have a "meshid" that no longer points to a valid mesh.
153
+ // Fix any incorrectly escaped user identifiers
154
+ obj.GetAllType('mesh', function (err, docs) {
155
+ if (err != null) { parent.debug('db', 'ERROR (GetAll mesh): ' + err); }
156
+ var meshlist = [];
157
+ if ((err == null) && (docs.length > 0)) {
158
+ for (var i in docs) {
159
+ var meshChange = false;
160
+ docs[i] = common.unEscapeLinksFieldName(docs[i]);
161
+ meshlist.push(docs[i]._id);
162
+
163
+ // Make sure all mesh types are number type, if not, fix it.
164
+ if (typeof docs[i].mtype == 'string') { docs[i].mtype = parseInt(docs[i].mtype); meshChange = true; }
165
+
166
+ // Take a look at the links
167
+ if (docs[i].links != null) {
168
+ for (var j in docs[i].links) {
169
+ if (validIdentifiers[j] == null) {
170
+ // This identifier is not known, let see if we can fix it.
171
+ var xid = j, xid2 = common.unEscapeFieldName(xid);
172
+ while ((xid != xid2) && (validIdentifiers[xid2] == null)) { xid = xid2; xid2 = common.unEscapeFieldName(xid2); }
173
+ if (validIdentifiers[xid2] == 1) {
174
+ //console.log('Fixing id: ' + j + ' to ' + common.escapeFieldName(xid2));
175
+ docs[i].links[xid2] = docs[i].links[j];
176
+ delete docs[i].links[j];
177
+ meshChange = true;
178
+ } else {
179
+ // TODO: here, we may want to clean up links to users and user groups that do not exist anymore.
180
+ //console.log('Unknown id: ' + j);
181
+ }
182
+ }
183
+ }
184
+ }
185
149
- // Save the user if needed
150
- if (fixed) { obj.Set(docs[i]); }
186
+ // Save the updated device group if needed
187
+ if (meshChange) { obj.Set(docs[i]); }
188
+ }
189
+ }
190
+ if ((obj.databaseType == 4) || (obj.databaseType == 5)) {
191
+ // MariaDB
192
+ sqlDbQuery('DELETE FROM MeshCentral.Main WHERE (extra LIKE ("mesh/%") AND (extra NOT IN ?)', [meshlist], func);
193
+ } else if (obj.databaseType == 3) {
194
+ // MongoDB
195
+ obj.file.deleteMany({ meshid: { $exists: true, $nin: meshlist } }, { multi: true });
196
+ } else {
197
+ // NeDB or MongoJS
198
+ obj.file.remove({ meshid: { $exists: true, $nin: meshlist } }, { multi: true });
199
+ }
200
152
- // We are done
153
- if (func) { func(); }
201
+ // We are done
202
+ validIdentifiers = null;
203
+ if (func) { func(); }
204
+ });
205
}
155
- }
156
- });
206
+ });
207
+ }
208
});
209
+
210
};
211
212
// Get encryption key
@@ -1331,6 +1383,7 @@ module.exports.CreateDB = function (parent, func) {
1383
1384
// Check that the server is capable of performing a backup
1385
obj.checkBackupCapability = function (func) {
1386
+ if ((parent.config.settings.autobackup == null) || (parent.config.settings.autobackup == false)) { func(); }
1387
if ((obj.databaseType == 2) || (obj.databaseType == 3)) {
1388
// Check that we have access to MongoDump
1389
var backupPath = parent.backuppath;