@iobroker/db-objects-redis 4.0.21 → 4.1.0-alpha.0-20220819-74ceeddc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/build/index.d.ts +5 -0
  2. package/build/index.js +35 -0
  3. package/build/lib/objects/constants.d.ts +32 -0
  4. package/build/lib/objects/constants.d.ts.map +1 -0
  5. package/build/lib/objects/constants.js +35 -0
  6. package/build/lib/objects/constants.js.map +1 -0
  7. package/{lib → build/lib}/objects/lua-v3/custom.lua +0 -0
  8. package/{lib → build/lib}/objects/lua-v3/filter.lua +0 -0
  9. package/{lib → build/lib}/objects/lua-v3/programs.lua +0 -0
  10. package/{lib → build/lib}/objects/lua-v3/script.lua +0 -0
  11. package/{lib → build/lib}/objects/lua-v3/variables.lua +0 -0
  12. package/{lib → build/lib}/objects/lua-v4/custom.lua +0 -0
  13. package/{lib → build/lib}/objects/lua-v4/filter.lua +0 -0
  14. package/{lib → build/lib}/objects/lua-v4/programs.lua +0 -0
  15. package/{lib → build/lib}/objects/lua-v4/redlock_acquire.lua +0 -0
  16. package/{lib → build/lib}/objects/lua-v4/redlock_extend.lua +0 -0
  17. package/{lib → build/lib}/objects/lua-v4/redlock_release.lua +0 -0
  18. package/{lib → build/lib}/objects/lua-v4/script.lua +0 -0
  19. package/{lib → build/lib}/objects/lua-v4/variables.lua +0 -0
  20. package/{lib → build/lib}/objects/lua-v4-no-sets/custom.lua +0 -0
  21. package/{lib → build/lib}/objects/lua-v4-no-sets/filter.lua +0 -0
  22. package/{lib → build/lib}/objects/lua-v4-no-sets/programs.lua +0 -0
  23. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_acquire.lua +0 -0
  24. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_extend.lua +0 -0
  25. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_release.lua +0 -0
  26. package/{lib → build/lib}/objects/lua-v4-no-sets/script.lua +0 -0
  27. package/{lib → build/lib}/objects/lua-v4-no-sets/variables.lua +0 -0
  28. package/build/lib/objects/objectsInRedisClient.d.ts +340 -0
  29. package/build/lib/objects/objectsInRedisClient.d.ts.map +1 -0
  30. package/{lib → build/lib}/objects/objectsInRedisClient.js +1730 -2130
  31. package/build/lib/objects/objectsInRedisClient.js.map +1 -0
  32. package/build/lib/objects/objectsUtils.d.ts +57 -0
  33. package/build/lib/objects/objectsUtils.d.ts.map +1 -0
  34. package/build/lib/objects/objectsUtils.js +637 -0
  35. package/build/lib/objects/objectsUtils.js.map +1 -0
  36. package/package.json +13 -8
  37. package/index.js +0 -8
  38. package/lib/objects/objectsUtils.js +0 -777
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Common functions between client and server
3
+ *
4
+ * Copyright 2013-2022 bluefox <dogafox@gmail.com>
5
+ *
6
+ * MIT License
7
+ *
8
+ */
9
+ 'use strict';
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || function (mod) {
27
+ if (mod && mod.__esModule) return mod;
28
+ var result = {};
29
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
30
+ __setModuleDefault(result, mod);
31
+ return result;
32
+ };
33
+ var __importDefault = (this && this.__importDefault) || function (mod) {
34
+ return (mod && mod.__esModule) ? mod : { "default": mod };
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.checkObjectRights = exports.checkObject = exports.sanitizePath = exports.getUserGroup = exports.checkFileRights = exports.checkFile = exports.insert = exports.WMStrm = exports.getMimeType = exports.REG_CHECK_ID = exports.ERRORS = exports.CONSTS = void 0;
38
+ const stream_1 = require("stream");
39
+ const path_1 = __importDefault(require("path"));
40
+ const deep_clone_1 = __importDefault(require("deep-clone"));
41
+ const db_base_1 = require("@iobroker/db-base");
42
+ const CONSTS = __importStar(require("./constants"));
43
+ exports.CONSTS = __importStar(require("./constants"));
44
+ exports.ERRORS = CONSTS.ERRORS;
45
+ exports.REG_CHECK_ID = CONSTS.REG_CHECK_ID;
46
+ const USER_STARTS_WITH = CONSTS.USER_STARTS_WITH;
47
+ const GROUP_STARTS_WITH = CONSTS.GROUP_STARTS_WITH;
48
+ const memStore = {};
49
+ const mimeTypes = {
50
+ '.css': { type: 'text/css', binary: false },
51
+ '.bmp': { type: 'image/bmp', binary: true },
52
+ '.png': { type: 'image/png', binary: true },
53
+ '.jpg': { type: 'image/jpeg', binary: true },
54
+ '.jpeg': { type: 'image/jpeg', binary: true },
55
+ '.gif': { type: 'image/gif', binary: true },
56
+ '.ico': { type: 'image/x-icon', binary: true },
57
+ '.webp': { type: 'image/webp', binary: true },
58
+ '.wbmp': { type: 'image/vnd.wap.wbmp', binary: true },
59
+ '.tif': { type: 'image/tiff', binary: true },
60
+ '.js': { type: 'application/javascript', binary: false },
61
+ '.html': { type: 'text/html', binary: false },
62
+ '.htm': { type: 'text/html', binary: false },
63
+ '.json': { type: 'application/json', binary: false },
64
+ '.md': { type: 'text/markdown', binary: false },
65
+ '.xml': { type: 'text/xml', binary: false },
66
+ '.svg': { type: 'image/svg+xml', binary: false },
67
+ '.eot': { type: 'application/vnd.ms-fontobject', binary: true },
68
+ '.ttf': { type: 'application/font-sfnt', binary: true },
69
+ '.cur': { type: 'application/x-win-bitmap', binary: true },
70
+ '.woff': { type: 'application/font-woff', binary: true },
71
+ '.wav': { type: 'audio/wav', binary: true },
72
+ '.mp3': { type: 'audio/mpeg3', binary: true },
73
+ '.avi': { type: 'video/avi', binary: true },
74
+ '.qt': { type: 'video/quicktime', binary: true },
75
+ '.ppt': { type: 'application/vnd.ms-powerpoint', binary: true },
76
+ '.pptx': { type: 'application/vnd.ms-powerpoint', binary: true },
77
+ '.doc': { type: 'application/msword', binary: true },
78
+ '.docx': { type: 'application/msword', binary: true },
79
+ '.xls': { type: 'application/vnd.ms-excel', binary: true },
80
+ '.xlsx': { type: 'application/vnd.ms-excel', binary: true },
81
+ '.mp4': { type: 'video/mp4', binary: true },
82
+ '.mkv': { type: 'video/mkv', binary: true },
83
+ '.zip': { type: 'application/zip', binary: true },
84
+ '.ogg': { type: 'audio/ogg', binary: true },
85
+ '.manifest': { type: 'text/cache-manifest', binary: false },
86
+ '.pdf': { type: 'application/pdf', binary: true },
87
+ '.gz': { type: 'application/gzip', binary: true },
88
+ '.gzip': { type: 'application/gzip', binary: true }
89
+ };
90
+ function isKnownMimeType(ext) {
91
+ return ext in mimeTypes;
92
+ }
93
+ // For objects
94
+ const defaultAcl = {
95
+ groups: [],
96
+ acl: {
97
+ file: {
98
+ list: false,
99
+ read: false,
100
+ write: false,
101
+ create: false,
102
+ delete: false
103
+ },
104
+ object: {
105
+ list: false,
106
+ read: false,
107
+ write: false,
108
+ create: false,
109
+ delete: false
110
+ },
111
+ state: {
112
+ list: false,
113
+ read: false,
114
+ write: false,
115
+ create: false,
116
+ delete: false
117
+ },
118
+ users: {
119
+ list: false,
120
+ read: false,
121
+ write: false,
122
+ create: false,
123
+ delete: false
124
+ }
125
+ }
126
+ };
127
+ // FIXME: This should have better types. Probably Record<string, {acl: ioBroker.ObjectPermissions, [x: string | number | symbol]: any}>
128
+ let users = {};
129
+ let groups = [];
130
+ function getMimeType(ext) {
131
+ if (!ext) {
132
+ return { mimeType: 'text/html', isBinary: false };
133
+ }
134
+ if (ext instanceof Array) {
135
+ ext = ext[0];
136
+ }
137
+ ext = ext.toLowerCase();
138
+ let mimeType = 'text/javascript';
139
+ let isBinary = false;
140
+ if (isKnownMimeType(ext)) {
141
+ mimeType = mimeTypes[ext].type;
142
+ isBinary = mimeTypes[ext].binary;
143
+ }
144
+ return { mimeType, isBinary };
145
+ }
146
+ exports.getMimeType = getMimeType;
147
+ /**
148
+ * Writable memory stream
149
+ */
150
+ class WMStrm extends stream_1.Writable {
151
+ constructor(key, options) {
152
+ super(options); // init super
153
+ this.key = key; // save key
154
+ memStore[key] = Buffer.alloc(0); // empty
155
+ }
156
+ _write(chunk, enc, cb) {
157
+ if (chunk) {
158
+ // our memory store stores things in buffers
159
+ const buffer = Buffer.isBuffer(chunk)
160
+ ? chunk // already is Buffer use it
161
+ : Buffer.from(chunk, enc); // string, convert
162
+ // concatenate to the buffer already there
163
+ if (!memStore[this.key]) {
164
+ memStore[this.key] = Buffer.alloc(0);
165
+ console.log(`memstore for ${this.key} is null`);
166
+ }
167
+ memStore[this.key] = Buffer.concat([memStore[this.key], buffer]);
168
+ }
169
+ if (!cb) {
170
+ throw new Error('Callback is empty');
171
+ }
172
+ cb();
173
+ }
174
+ }
175
+ exports.WMStrm = WMStrm;
176
+ function insert(objects, id, attName, _ignore, options, _obj, callback) {
177
+ if (typeof options === 'string') {
178
+ options = { mimeType: options };
179
+ }
180
+ // return pipe for write into redis
181
+ const strm = new WMStrm(`${id}/${attName}`, {});
182
+ strm.on('finish', () => {
183
+ let error = null;
184
+ if (!memStore[id + '/' + attName]) {
185
+ error = `File ${id} / ${attName} is empty`;
186
+ }
187
+ objects.writeFile(id, attName, memStore[id + '/' + attName] || '', options, () => {
188
+ if (memStore[id + '/' + attName] !== undefined) {
189
+ delete memStore[id + '/' + attName];
190
+ }
191
+ return db_base_1.tools.maybeCallbackWithError(callback, error, null);
192
+ });
193
+ });
194
+ return strm;
195
+ }
196
+ exports.insert = insert;
197
+ function checkFile(fileOptions, options, flag, defaultNewAcl) {
198
+ if (typeof fileOptions.acl !== 'object') {
199
+ fileOptions = {};
200
+ fileOptions.mimeType = (0, deep_clone_1.default)(fileOptions);
201
+ fileOptions.acl = {
202
+ owner: (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER,
203
+ ownerGroup: (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP,
204
+ permissions: (defaultNewAcl && defaultNewAcl.file) ||
205
+ CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ // '0644'
206
+ };
207
+ }
208
+ // Set default owner group
209
+ fileOptions.acl.ownerGroup =
210
+ fileOptions.acl.ownerGroup || (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP;
211
+ fileOptions.acl.owner = fileOptions.acl.owner || (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER;
212
+ fileOptions.acl.permissions =
213
+ fileOptions.acl.permissions ||
214
+ (defaultNewAcl && defaultNewAcl.file) ||
215
+ CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ; // '0644'
216
+ if (options.user !== CONSTS.SYSTEM_ADMIN_USER &&
217
+ options.groups.indexOf(CONSTS.SYSTEM_ADMIN_GROUP) === -1 &&
218
+ fileOptions.acl) {
219
+ if (fileOptions.acl.owner !== options.user) {
220
+ // Check if the user is in the group
221
+ if (options.groups.indexOf(fileOptions.acl.ownerGroup) !== -1) {
222
+ // Check group rights
223
+ if (!(fileOptions.acl.permissions & (flag << 4))) {
224
+ return false;
225
+ }
226
+ }
227
+ else {
228
+ // everybody
229
+ if (!(fileOptions.acl.permissions & flag)) {
230
+ return false;
231
+ }
232
+ }
233
+ }
234
+ else {
235
+ // Check user rights
236
+ if (!(fileOptions.acl.permissions & (flag << 8))) {
237
+ return false;
238
+ }
239
+ }
240
+ }
241
+ return true;
242
+ }
243
+ exports.checkFile = checkFile;
244
+ function checkFileRights(objects, id, name, options, flag, callback) {
245
+ const _options = options || {};
246
+ if (!_options.user) {
247
+ // Before files converted, lets think: if no options it is admin
248
+ _options.user = 'system.user.admin';
249
+ _options.params = _options;
250
+ _options.group = 'system.group.administrator';
251
+ }
252
+ if (!_options.acl) {
253
+ objects.getUserGroup(_options.user, (_user, groups, acl) => {
254
+ _options.acl = acl || {};
255
+ _options.groups = groups;
256
+ _options.group = groups ? groups[0] : null;
257
+ checkFileRights(objects, id, name, _options, flag, callback);
258
+ });
259
+ return;
260
+ }
261
+ // If user may write
262
+ if (flag === CONSTS.ACCESS_WRITE && !_options.acl.file.write) {
263
+ // write
264
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, _options);
265
+ }
266
+ // If user may read
267
+ if (flag === CONSTS.ACCESS_READ && !_options.acl.file.read) {
268
+ // read
269
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, _options);
270
+ }
271
+ _options.checked = true;
272
+ objects.checkFile(id, name, _options, flag, (err, options, opt) => {
273
+ if (err) {
274
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
275
+ }
276
+ else {
277
+ return db_base_1.tools.maybeCallbackWithError(callback, null, options, opt);
278
+ }
279
+ });
280
+ }
281
+ exports.checkFileRights = checkFileRights;
282
+ // For users and groups
283
+ function getDefaultAdminRights(acl, _isState) {
284
+ return {
285
+ ...acl,
286
+ file: {
287
+ list: true,
288
+ read: true,
289
+ write: true,
290
+ create: true,
291
+ delete: true
292
+ },
293
+ object: {
294
+ create: true,
295
+ list: true,
296
+ read: true,
297
+ write: true,
298
+ delete: true
299
+ },
300
+ users: {
301
+ create: true,
302
+ list: true,
303
+ read: true,
304
+ write: true,
305
+ delete: true
306
+ },
307
+ state: {
308
+ read: true,
309
+ write: true,
310
+ delete: true,
311
+ create: true,
312
+ list: true
313
+ },
314
+ other: {
315
+ execute: false,
316
+ http: false,
317
+ sendto: false
318
+ }
319
+ };
320
+ }
321
+ function getUserGroup(objects, user, callback) {
322
+ if (!user || typeof user !== 'string' || !user.startsWith(USER_STARTS_WITH)) {
323
+ console.log(`invalid user name: ${user}`);
324
+ user = JSON.stringify(user);
325
+ // deep copy
326
+ return db_base_1.tools.maybeCallbackWithError(callback, `invalid user name: ${user}`, user, [], (0, deep_clone_1.default)(defaultAcl.acl));
327
+ }
328
+ if (users[user]) {
329
+ return db_base_1.tools.maybeCallbackWithError(callback, null, user, users[user].groups, users[user].acl);
330
+ }
331
+ let error;
332
+ // Read all groups
333
+ objects.getObjectList({ startkey: 'system.group.', endkey: 'system.group.\u9999' }, { checked: true }, (err, arr) => {
334
+ if (err) {
335
+ error = err;
336
+ }
337
+ groups = [];
338
+ if (arr) {
339
+ // Read all groups
340
+ for (const g in arr.rows) {
341
+ const val = arr.rows[g].value;
342
+ if (!val) {
343
+ continue;
344
+ }
345
+ groups[g] = val;
346
+ if (groups[g]._id === CONSTS.SYSTEM_ADMIN_GROUP) {
347
+ groups[g].common.acl = getDefaultAdminRights(groups[g].common.acl);
348
+ }
349
+ }
350
+ }
351
+ objects.getObjectList({ startkey: 'system.user.', endkey: 'system.user.\u9999' }, { checked: true }, (err, arr) => {
352
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
353
+ if (err) {
354
+ error = err;
355
+ }
356
+ users = {};
357
+ if (arr) {
358
+ for (const row of arr.rows) {
359
+ // cannot use here Object.assign, because required deep copy
360
+ users[row.value._id] = (0, deep_clone_1.default)(defaultAcl);
361
+ }
362
+ }
363
+ users[CONSTS.SYSTEM_ADMIN_USER] = users[CONSTS.SYSTEM_ADMIN_USER] || (0, deep_clone_1.default)(defaultAcl);
364
+ users[CONSTS.SYSTEM_ADMIN_USER].acl = getDefaultAdminRights(users[CONSTS.SYSTEM_ADMIN_USER].acl);
365
+ for (let g = 0; g < groups.length; g++) {
366
+ if (!groups[g] || !groups[g].common || !groups[g].common.members) {
367
+ continue;
368
+ }
369
+ for (let m = 0; m < groups[g].common.members.length; m++) {
370
+ const u = groups[g].common.members[m];
371
+ if (!users[u]) {
372
+ error =
373
+ error ||
374
+ `Unknown user in group "${groups[g]._id.replace('system.group.', '')}": ${u}`;
375
+ continue;
376
+ }
377
+ users[u].groups.push(groups[g]._id);
378
+ if (groups[g].common.acl && groups[g].common.acl.file) {
379
+ if (!users[u].acl || !users[u].acl.file) {
380
+ users[u].acl = users[u].acl || {};
381
+ users[u].acl.file = users[u].acl.file || {};
382
+ users[u].acl.file.create = groups[g].common.acl.file.create;
383
+ users[u].acl.file.read = groups[g].common.acl.file.read;
384
+ users[u].acl.file.write = groups[g].common.acl.file.write;
385
+ users[u].acl.file.delete = groups[g].common.acl.file.delete;
386
+ users[u].acl.file.list = groups[g].common.acl.file.list;
387
+ }
388
+ else {
389
+ users[u].acl.file.create =
390
+ users[u].acl.file.create || groups[g].common.acl.file.create;
391
+ users[u].acl.file.read = users[u].acl.file.read || groups[g].common.acl.file.read;
392
+ users[u].acl.file.write =
393
+ users[u].acl.file.write || groups[g].common.acl.file.write;
394
+ users[u].acl.file.delete =
395
+ users[u].acl.file.delete || groups[g].common.acl.file.delete;
396
+ users[u].acl.file.list = users[u].acl.file.list || groups[g].common.acl.file.list;
397
+ }
398
+ }
399
+ if (groups[g].common.acl && groups[g].common.acl.object) {
400
+ if (!users[u].acl || !users[u].acl.object) {
401
+ users[u].acl = users[u].acl || {};
402
+ users[u].acl.object = users[u].acl.object || {};
403
+ users[u].acl.object.create = groups[g].common.acl.object.create;
404
+ users[u].acl.object.read = groups[g].common.acl.object.read;
405
+ users[u].acl.object.write = groups[g].common.acl.object.write;
406
+ users[u].acl.object.delete = groups[g].common.acl.object.delete;
407
+ users[u].acl.object.list = groups[g].common.acl.object.list;
408
+ }
409
+ else {
410
+ users[u].acl.object.create =
411
+ users[u].acl.object.create || groups[g].common.acl.object.create;
412
+ users[u].acl.object.read =
413
+ users[u].acl.object.read || groups[g].common.acl.object.read;
414
+ users[u].acl.object.write =
415
+ users[u].acl.object.write || groups[g].common.acl.object.write;
416
+ users[u].acl.object.delete =
417
+ users[u].acl.object.delete || groups[g].common.acl.object.delete;
418
+ users[u].acl.object.list =
419
+ users[u].acl.object.list || groups[g].common.acl.object.list;
420
+ }
421
+ }
422
+ if (groups[g].common.acl && groups[g].common.acl.users) {
423
+ if (!users[u].acl || !users[u].acl.users) {
424
+ users[u].acl = users[u].acl || {};
425
+ users[u].acl.users = users[u].acl.users || {};
426
+ users[u].acl.users.create = groups[g].common.acl.users.create;
427
+ users[u].acl.users.read = groups[g].common.acl.users.read;
428
+ users[u].acl.users.write = groups[g].common.acl.users.write;
429
+ users[u].acl.users.delete = groups[g].common.acl.users.delete;
430
+ users[u].acl.users.list = groups[g].common.acl.users.list;
431
+ }
432
+ else {
433
+ users[u].acl.users.create =
434
+ users[u].acl.users.create || groups[g].common.acl.users.create;
435
+ users[u].acl.users.read =
436
+ users[u].acl.users.read || groups[g].common.acl.users.read;
437
+ users[u].acl.users.write =
438
+ users[u].acl.users.write || groups[g].common.acl.users.write;
439
+ users[u].acl.users.delete =
440
+ users[u].acl.users.delete || groups[g].common.acl.users.delete;
441
+ users[u].acl.users.list =
442
+ users[u].acl.users.list || groups[g].common.acl.users.list;
443
+ }
444
+ }
445
+ if (groups[g].common.acl && groups[g].common.acl.state) {
446
+ if (!users[u].acl || !users[u].acl.state) {
447
+ users[u].acl = users[u].acl || {};
448
+ users[u].acl.state = users[u].acl.state || {};
449
+ users[u].acl.state.create = (_a = groups[g].common.acl.state) === null || _a === void 0 ? void 0 : _a.create;
450
+ users[u].acl.state.read = (_b = groups[g].common.acl.state) === null || _b === void 0 ? void 0 : _b.read;
451
+ users[u].acl.state.write = (_c = groups[g].common.acl.state) === null || _c === void 0 ? void 0 : _c.write;
452
+ users[u].acl.state.delete = (_d = groups[g].common.acl.state) === null || _d === void 0 ? void 0 : _d.delete;
453
+ users[u].acl.state.list = (_e = groups[g].common.acl.state) === null || _e === void 0 ? void 0 : _e.list;
454
+ }
455
+ else {
456
+ users[u].acl.state.create =
457
+ users[u].acl.state.create || ((_f = groups[g].common.acl.state) === null || _f === void 0 ? void 0 : _f.create);
458
+ users[u].acl.state.read =
459
+ users[u].acl.state.read || ((_g = groups[g].common.acl.state) === null || _g === void 0 ? void 0 : _g.read);
460
+ users[u].acl.state.write =
461
+ users[u].acl.state.write || ((_h = groups[g].common.acl.state) === null || _h === void 0 ? void 0 : _h.write);
462
+ users[u].acl.state.delete =
463
+ users[u].acl.state.delete || ((_j = groups[g].common.acl.state) === null || _j === void 0 ? void 0 : _j.delete);
464
+ users[u].acl.state.list =
465
+ users[u].acl.state.list || ((_k = groups[g].common.acl.state) === null || _k === void 0 ? void 0 : _k.list);
466
+ }
467
+ }
468
+ }
469
+ }
470
+ return db_base_1.tools.maybeCallbackWithError(callback, error, user, users[user] ? users[user].groups : [], users[user] ? users[user].acl : (0, deep_clone_1.default)(defaultAcl.acl));
471
+ });
472
+ });
473
+ }
474
+ exports.getUserGroup = getUserGroup;
475
+ function sanitizePath(id, name) {
476
+ if (!name) {
477
+ name = '';
478
+ }
479
+ if (name[0] === '/') {
480
+ name = name.substring(1);
481
+ }
482
+ if (!id) {
483
+ throw new Error('Empty ID');
484
+ }
485
+ id = id.replace(/[\][*,;'"`<>\\?/]/g, ''); // remove all invalid characters from states plus slashes
486
+ id = id.replace(/\.\./g, ''); // do not allow to write in parent directories
487
+ if (name.includes('..')) {
488
+ name = path_1.default.normalize('/' + name);
489
+ }
490
+ if (name.includes('..')) {
491
+ // Also after normalization we still have .. in it - should not happen if normalize worked correctly
492
+ name = name.replace(/\.\./g, '');
493
+ name = path_1.default.normalize('/' + name);
494
+ }
495
+ name = name.replace(/\\/g, '/'); // replace win path backslashes
496
+ if (name[0] === '/') {
497
+ name = name.substring(1);
498
+ } // do not allow absolute paths
499
+ return { id: id, name: name };
500
+ }
501
+ exports.sanitizePath = sanitizePath;
502
+ function checkObject(obj, options, flag) {
503
+ // read rights of object
504
+ if (!obj || !('common' in obj) || !obj.acl || flag === CONSTS.ACCESS_LIST) {
505
+ return true;
506
+ }
507
+ if (options.user === CONSTS.SYSTEM_ADMIN_USER) {
508
+ return true;
509
+ }
510
+ // admins may always see everything
511
+ if (options.group === CONSTS.SYSTEM_ADMIN_GROUP || options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP)) {
512
+ return true;
513
+ }
514
+ // FIXME: what if flag is ACCESS_DELETE or ACCESS_CREATE? currently it will end in false
515
+ if (flag === CONSTS.ACCESS_DELETE || flag === CONSTS.ACCESS_CREATE) {
516
+ return false;
517
+ }
518
+ // checkObject always called after checkObjectRights and admin is checked there
519
+ if (obj.acl.owner !== options.user) {
520
+ // Check if the user is in the group
521
+ if ((options.group && options.group === obj.acl.ownerGroup) ||
522
+ (options.groups && options.groups.includes(obj.acl.ownerGroup))) {
523
+ // Check group rights
524
+ if (!(obj.acl.object & (flag << 4))) {
525
+ return false;
526
+ }
527
+ }
528
+ else {
529
+ // everybody
530
+ if (!(obj.acl.object & flag)) {
531
+ return false;
532
+ }
533
+ }
534
+ }
535
+ else {
536
+ // Check group rights
537
+ if (!(obj.acl.object & (flag << 8))) {
538
+ return false;
539
+ }
540
+ }
541
+ return true; // ALL OK
542
+ }
543
+ exports.checkObject = checkObject;
544
+ function checkObjectRights(objects, id, object, options, flag, callback) {
545
+ options = options || {};
546
+ if (!options.user) {
547
+ // Before files converted, lets think: if no options it is admin
548
+ options = {
549
+ user: CONSTS.SYSTEM_ADMIN_USER,
550
+ params: options,
551
+ group: CONSTS.SYSTEM_ADMIN_GROUP,
552
+ groups: [CONSTS.SYSTEM_ADMIN_GROUP],
553
+ acl: getDefaultAdminRights()
554
+ };
555
+ }
556
+ if (!options.acl) {
557
+ return objects.getUserGroup(options.user, (_user, groups, acl) => {
558
+ // TODO: ts needs it because we are doing async call before
559
+ options = options || {};
560
+ options.acl = acl || {};
561
+ options.groups = groups;
562
+ options.group = groups ? groups[0] : null;
563
+ checkObjectRights(objects, id, object, options, flag, callback);
564
+ });
565
+ }
566
+ // now options are filled and we can go
567
+ if (options.user === CONSTS.SYSTEM_ADMIN_USER ||
568
+ options.group === CONSTS.SYSTEM_ADMIN_GROUP ||
569
+ (options.groups && options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP))) {
570
+ return db_base_1.tools.maybeCallbackWithError(callback, null, options);
571
+ }
572
+ // if user or group objects
573
+ if (typeof id === 'string' && (id.startsWith(USER_STARTS_WITH) || id.startsWith(GROUP_STARTS_WITH))) {
574
+ // If user may write
575
+ if (flag === CONSTS.ACCESS_WRITE && !options.acl.users.write) {
576
+ // write
577
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
578
+ }
579
+ // If user may read
580
+ if (flag === CONSTS.ACCESS_READ && !options.acl.users.read) {
581
+ // read
582
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
583
+ }
584
+ // If user may delete
585
+ if (flag === CONSTS.ACCESS_DELETE && !options.acl.users.delete) {
586
+ // delete
587
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
588
+ }
589
+ // If user may list
590
+ if (flag === CONSTS.ACCESS_LIST && !options.acl.users.list) {
591
+ // list
592
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
593
+ }
594
+ // If user may create
595
+ if (flag === CONSTS.ACCESS_CREATE && !options.acl.users.create) {
596
+ // create
597
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
598
+ }
599
+ // If user may write
600
+ if (flag === CONSTS.ACCESS_DELETE) {
601
+ // he may delete
602
+ flag = CONSTS.ACCESS_WRITE;
603
+ }
604
+ }
605
+ // If user may write
606
+ if (flag === CONSTS.ACCESS_WRITE && !options.acl.object.write) {
607
+ // write
608
+ db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
609
+ }
610
+ // If user may read
611
+ if (flag === CONSTS.ACCESS_READ && !options.acl.object.read) {
612
+ // read
613
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
614
+ }
615
+ // If user may delete
616
+ if (flag === CONSTS.ACCESS_DELETE && !options.acl.object.delete) {
617
+ // delete
618
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
619
+ }
620
+ // If user may list
621
+ if (flag === CONSTS.ACCESS_LIST && !options.acl.object.list) {
622
+ // list
623
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
624
+ }
625
+ if (flag === CONSTS.ACCESS_DELETE) {
626
+ // write
627
+ flag = CONSTS.ACCESS_WRITE;
628
+ }
629
+ if (id && !checkObject(object, options, flag)) {
630
+ return db_base_1.tools.maybeCallbackWithError(callback, exports.ERRORS.ERROR_PERMISSION, options);
631
+ }
632
+ else {
633
+ return db_base_1.tools.maybeCallbackWithError(callback, null, options);
634
+ }
635
+ }
636
+ exports.checkObjectRights = checkObjectRights;
637
+ //# sourceMappingURL=objectsUtils.js.map