hola-server 1.0.10 → 2.0.1
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.
- package/README.md +196 -1
- package/core/array.js +79 -142
- package/core/bash.js +208 -259
- package/core/chart.js +26 -16
- package/core/cron.js +14 -3
- package/core/date.js +15 -44
- package/core/encrypt.js +19 -9
- package/core/file.js +42 -29
- package/core/lhs.js +32 -6
- package/core/meta.js +213 -289
- package/core/msg.js +20 -7
- package/core/number.js +105 -103
- package/core/obj.js +15 -12
- package/core/random.js +9 -6
- package/core/role.js +69 -77
- package/core/thread.js +12 -2
- package/core/type.js +300 -261
- package/core/url.js +20 -12
- package/core/validate.js +29 -26
- package/db/db.js +297 -227
- package/db/entity.js +631 -963
- package/db/gridfs.js +120 -166
- package/design/add_default_field_attr.md +56 -0
- package/http/context.js +22 -8
- package/http/cors.js +25 -8
- package/http/error.js +27 -9
- package/http/express.js +70 -41
- package/http/params.js +70 -42
- package/http/router.js +51 -40
- package/http/session.js +59 -36
- package/index.js +85 -9
- package/package.json +2 -2
- package/router/clone.js +28 -36
- package/router/create.js +21 -26
- package/router/delete.js +24 -28
- package/router/read.js +137 -123
- package/router/update.js +38 -56
- package/setting.js +22 -6
- package/skills/array.md +155 -0
- package/skills/bash.md +91 -0
- package/skills/chart.md +54 -0
- package/skills/code.md +422 -0
- package/skills/context.md +177 -0
- package/skills/date.md +58 -0
- package/skills/express.md +255 -0
- package/skills/file.md +60 -0
- package/skills/lhs.md +54 -0
- package/skills/meta.md +1023 -0
- package/skills/msg.md +30 -0
- package/skills/number.md +88 -0
- package/skills/obj.md +36 -0
- package/skills/params.md +206 -0
- package/skills/random.md +22 -0
- package/skills/role.md +59 -0
- package/skills/session.md +281 -0
- package/skills/storage.md +743 -0
- package/skills/thread.md +22 -0
- package/skills/type.md +547 -0
- package/skills/url.md +34 -0
- package/skills/validate.md +48 -0
- package/test/cleanup/close-db.js +5 -0
- package/test/core/array.js +226 -0
- package/test/core/chart.js +51 -0
- package/test/core/file.js +59 -0
- package/test/core/lhs.js +44 -0
- package/test/core/number.js +167 -12
- package/test/core/obj.js +47 -0
- package/test/core/random.js +24 -0
- package/test/core/thread.js +20 -0
- package/test/core/type.js +216 -0
- package/test/core/validate.js +67 -0
- package/test/db/db-ops.js +99 -0
- package/test/db/pipe_test.txt +0 -0
- package/test/db/test_case_design.md +528 -0
- package/test/db/test_db_class.js +613 -0
- package/test/db/test_entity_class.js +414 -0
- package/test/db/test_gridfs_class.js +234 -0
- package/test/entity/create.js +1 -1
- package/test/entity/delete-mixed.js +156 -0
- package/test/entity/ref-filter.js +63 -0
- package/tool/gen_i18n.js +55 -21
- package/test/crud/router.js +0 -99
- package/test/router/user.js +0 -17
package/core/number.js
CHANGED
|
@@ -1,179 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Number manipulation and mathematical utility functions.
|
|
3
|
+
* @module core/number
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
const { has_value } = require('./validate');
|
|
2
7
|
const { is_object } = require('./obj');
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
|
-
* Parse
|
|
6
|
-
* @param {
|
|
7
|
-
* @returns
|
|
10
|
+
* Parse string value to number, returns 0 if invalid.
|
|
11
|
+
* @param {string|number} str - Value to parse.
|
|
12
|
+
* @returns {number} Parsed number or 0.
|
|
8
13
|
*/
|
|
9
|
-
const parse_num =
|
|
14
|
+
const parse_num = (str) => {
|
|
10
15
|
const value = parseFloat(str);
|
|
11
16
|
return value ? value : 0;
|
|
12
17
|
};
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
|
-
* Parse
|
|
16
|
-
* @param {
|
|
17
|
-
* @returns
|
|
20
|
+
* Parse string value to number with 2 decimal places.
|
|
21
|
+
* @param {string|number} str - Value to parse.
|
|
22
|
+
* @returns {number} Parsed number rounded to 2 decimal places.
|
|
18
23
|
*/
|
|
19
|
-
const to_fixed2 =
|
|
24
|
+
const to_fixed2 = (str) => {
|
|
20
25
|
const value = parse_num(str);
|
|
21
26
|
return value ? parseFloat(value.toFixed(2)) : 0;
|
|
22
27
|
};
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
|
-
* Round
|
|
26
|
-
* @param {number
|
|
27
|
-
* @returns
|
|
30
|
+
* Round number to 2 decimal places.
|
|
31
|
+
* @param {number} num - Number to round.
|
|
32
|
+
* @returns {number} Rounded number.
|
|
28
33
|
*/
|
|
29
|
-
const round_to_fixed2 =
|
|
30
|
-
return Math.round(num * 100) / 100;
|
|
31
|
-
};
|
|
34
|
+
const round_to_fixed2 = (num) => Math.round(num * 100) / 100;
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
|
-
* Generate range array
|
|
35
|
-
* @param {
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {
|
|
38
|
-
* @returns
|
|
37
|
+
* Generate range array. Example: range(3) = [0,1,2], range(1,5) = [1,2,3,4,5]
|
|
38
|
+
* @param {number} start - Start value or length if end not provided.
|
|
39
|
+
* @param {number} [end] - End value (inclusive).
|
|
40
|
+
* @param {number} [step=1] - Step increment.
|
|
41
|
+
* @returns {number[]} Array of numbers in the range.
|
|
39
42
|
*/
|
|
40
|
-
const range = (start, end, step = 1) =>
|
|
43
|
+
const range = (start, end, step = 1) => {
|
|
44
|
+
if (!end) return Array.from({ length: start }, (_, key) => key);
|
|
45
|
+
return [...Array(Math.floor((end - start) / step) + 1)].map((_, i) => start + i * step);
|
|
46
|
+
};
|
|
41
47
|
|
|
42
48
|
/**
|
|
43
|
-
* Generate scale array
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {
|
|
46
|
-
* @param {
|
|
47
|
-
* @returns
|
|
49
|
+
* Generate scale array with exponential growth. Example: scale(2,10) = [2,4,8]
|
|
50
|
+
* @param {number} start - Start value.
|
|
51
|
+
* @param {number} end - End value.
|
|
52
|
+
* @param {number} [ratio=2] - Scale multiplier.
|
|
53
|
+
* @returns {number[]} Array of scaled numbers.
|
|
48
54
|
*/
|
|
49
|
-
const scale = (start, end,
|
|
55
|
+
const scale = (start, end, ratio = 2) => {
|
|
56
|
+
const length = Math.floor(Math.log(end / start) / Math.log(ratio)) + 1;
|
|
57
|
+
return [...Array(length)].map((_, i) => start * Math.pow(ratio, i));
|
|
58
|
+
};
|
|
50
59
|
|
|
51
60
|
/**
|
|
52
|
-
* Create a space
|
|
53
|
-
* @param {
|
|
54
|
-
* @param {
|
|
55
|
-
* @returns
|
|
61
|
+
* Create a space object representing a min-max range.
|
|
62
|
+
* @param {number} min - Minimum value.
|
|
63
|
+
* @param {number} max - Maximum value.
|
|
64
|
+
* @returns {{min: number, max: number}} Space object.
|
|
65
|
+
* @throws {Error} If min or max not provided.
|
|
56
66
|
*/
|
|
57
67
|
const space = (min, max) => {
|
|
58
|
-
if (has_value(min)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
throw new Error("min and max not provide for space");
|
|
63
|
-
}
|
|
68
|
+
if (!has_value(min) || !has_value(max)) throw new Error("min and max not provided for space");
|
|
69
|
+
return { min, max };
|
|
70
|
+
};
|
|
64
71
|
|
|
65
72
|
/**
|
|
66
|
-
* Check
|
|
67
|
-
* @param {value
|
|
68
|
-
* @returns
|
|
73
|
+
* Check if value is a space object (has min and max properties).
|
|
74
|
+
* @param {*} value - Value to check.
|
|
75
|
+
* @returns {boolean} True if value is a space object.
|
|
69
76
|
*/
|
|
70
|
-
const is_space = (value) =>
|
|
71
|
-
return is_object(value) && has_value(value.min) && has_value(value.max);
|
|
72
|
-
}
|
|
77
|
+
const is_space = (value) => is_object(value) && has_value(value.min) && has_value(value.max);
|
|
73
78
|
|
|
74
79
|
/**
|
|
75
|
-
*
|
|
76
|
-
* @param {
|
|
77
|
-
* @returns
|
|
80
|
+
* Check if value is an integer.
|
|
81
|
+
* @param {*} value - Value to check.
|
|
82
|
+
* @returns {boolean} True if value is an integer.
|
|
78
83
|
*/
|
|
79
|
-
const is_integer = (value) =>
|
|
80
|
-
const regex_pattern = /^-?[0-9]+$/;
|
|
81
|
-
return regex_pattern.test(value);
|
|
82
|
-
}
|
|
84
|
+
const is_integer = (value) => /^-?[0-9]+$/.test(value);
|
|
83
85
|
|
|
84
86
|
/**
|
|
85
|
-
* Check
|
|
86
|
-
* @param {
|
|
87
|
-
* @returns
|
|
87
|
+
* Check if object contains any space objects as property values.
|
|
88
|
+
* @param {Object} obj - Object to check.
|
|
89
|
+
* @returns {boolean} True if any property is a space object.
|
|
88
90
|
*/
|
|
89
91
|
const contains_space = (obj) => {
|
|
90
92
|
for (const key in obj) {
|
|
91
|
-
|
|
92
|
-
if (is_space(value)) {
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
93
|
+
if (is_space(obj[key])) return true;
|
|
95
94
|
}
|
|
96
95
|
return false;
|
|
97
|
-
}
|
|
96
|
+
};
|
|
98
97
|
|
|
99
98
|
/**
|
|
100
|
-
* Generate
|
|
101
|
-
* @param {
|
|
102
|
-
* @param {
|
|
103
|
-
* @returns
|
|
99
|
+
* Generate random number between min and max.
|
|
100
|
+
* @param {number} min - Minimum value.
|
|
101
|
+
* @param {number} max - Maximum value.
|
|
102
|
+
* @returns {number} Random number (integer if both bounds are integers).
|
|
104
103
|
*/
|
|
105
104
|
const random_number = (min, max) => {
|
|
106
105
|
const random = Math.random() * (max - min) + min;
|
|
107
|
-
return is_integer(min) && is_integer(max) ? Math.floor(random) :
|
|
108
|
-
}
|
|
106
|
+
return is_integer(min) && is_integer(max) ? Math.floor(random) : to_fixed2(random);
|
|
107
|
+
};
|
|
109
108
|
|
|
110
109
|
/**
|
|
111
|
-
*
|
|
112
|
-
* @param {
|
|
113
|
-
* @param {
|
|
114
|
-
* @param {
|
|
115
|
-
* @returns
|
|
110
|
+
* Generate Latin Hypercube Sampling ranges for a given range.
|
|
111
|
+
* @param {number} min - Minimum value.
|
|
112
|
+
* @param {number} max - Maximum value.
|
|
113
|
+
* @param {number} n - Number of samples.
|
|
114
|
+
* @returns {{min: number, max: number}[]} Array of sample ranges.
|
|
116
115
|
*/
|
|
117
116
|
const lhs_samples = (min, max, n) => {
|
|
118
117
|
const all_int = is_integer(min + "") && is_integer(max + "");
|
|
119
118
|
const interval = (max - min) / n;
|
|
120
119
|
const ranges = [];
|
|
120
|
+
|
|
121
121
|
for (let i = 0; i < n; i++) {
|
|
122
122
|
const start = i * interval + min;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let obj = {};
|
|
132
|
-
if (all_int) {
|
|
133
|
-
obj = { min: Math.floor(min_value), max: Math.floor(max_value) };
|
|
134
|
-
} else {
|
|
135
|
-
obj = { min: to_fixed2(min_value), max: to_fixed2(max_value) };
|
|
136
|
-
}
|
|
137
|
-
ranges.push(obj);
|
|
123
|
+
const end = (i === n - 1) ? max : start + interval;
|
|
124
|
+
const min_val = Math.min(start, end);
|
|
125
|
+
const max_val = Math.max(start, end);
|
|
126
|
+
|
|
127
|
+
ranges.push(all_int
|
|
128
|
+
? { min: Math.floor(min_val), max: Math.floor(max_val) }
|
|
129
|
+
: { min: to_fixed2(min_val), max: to_fixed2(max_val) }
|
|
130
|
+
);
|
|
138
131
|
}
|
|
139
132
|
return ranges;
|
|
140
|
-
}
|
|
133
|
+
};
|
|
141
134
|
|
|
142
135
|
/**
|
|
143
|
-
* Create
|
|
144
|
-
* @param {object
|
|
145
|
-
* @returns
|
|
136
|
+
* Create random sample object from configuration with arrays or space objects.
|
|
137
|
+
* @param {Object} obj - Configuration object with arrays or space values.
|
|
138
|
+
* @returns {Object} Sample object with randomly selected values.
|
|
146
139
|
*/
|
|
147
140
|
const random_sample = (obj) => {
|
|
148
141
|
const sample_obj = {};
|
|
149
142
|
for (const key in obj) {
|
|
150
143
|
const value = obj[key];
|
|
151
144
|
if (Array.isArray(value)) {
|
|
152
|
-
|
|
153
|
-
sample_obj[key] = value[random];
|
|
145
|
+
sample_obj[key] = value[Math.floor(random_number(0, value.length))];
|
|
154
146
|
} else if (is_space(value)) {
|
|
155
|
-
|
|
156
|
-
sample_obj[key] = random;
|
|
147
|
+
sample_obj[key] = random_number(value.min, value.max);
|
|
157
148
|
} else {
|
|
158
149
|
sample_obj[key] = value;
|
|
159
150
|
}
|
|
160
151
|
}
|
|
161
152
|
return sample_obj;
|
|
162
|
-
}
|
|
153
|
+
};
|
|
163
154
|
|
|
164
155
|
/**
|
|
165
|
-
* Extract
|
|
166
|
-
* @param {
|
|
167
|
-
* @returns
|
|
156
|
+
* Extract numeric value from string containing numbers.
|
|
157
|
+
* @param {string} value - String to extract number from.
|
|
158
|
+
* @returns {number} Extracted number or 0 if not found.
|
|
168
159
|
*/
|
|
169
160
|
const extract_number = (value) => {
|
|
170
161
|
const numbers = value.match(/([+\-0-9\\.]+)/g);
|
|
171
|
-
if (!numbers)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const values = numbers.map(Number).filter(v => has_value(v));
|
|
176
|
-
return values.length == 1 ? values[0] : 0;
|
|
177
|
-
}
|
|
162
|
+
if (!numbers) return 0;
|
|
163
|
+
const values = numbers.map(Number).filter((v) => has_value(v));
|
|
164
|
+
return values.length === 1 ? values[0] : 0;
|
|
165
|
+
};
|
|
178
166
|
|
|
179
|
-
module.exports = {
|
|
167
|
+
module.exports = {
|
|
168
|
+
parse_num,
|
|
169
|
+
extract_number,
|
|
170
|
+
to_fixed2,
|
|
171
|
+
round_to_fixed2,
|
|
172
|
+
range,
|
|
173
|
+
scale,
|
|
174
|
+
space,
|
|
175
|
+
is_space,
|
|
176
|
+
contains_space,
|
|
177
|
+
is_integer,
|
|
178
|
+
random_number,
|
|
179
|
+
random_sample,
|
|
180
|
+
lhs_samples
|
|
181
|
+
};
|
package/core/obj.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
* @fileoverview Object manipulation utility functions.
|
|
3
|
+
* @module core/obj
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a new object by copying specified attributes from source object.
|
|
8
|
+
* @param {Object} obj - Source object to copy from.
|
|
9
|
+
* @param {string[]} attrs - Array of attribute names to copy.
|
|
10
|
+
* @returns {Object} New object containing only the specified attributes.
|
|
6
11
|
*/
|
|
7
12
|
const copy_obj = (obj, attrs) => {
|
|
8
13
|
const copied = {};
|
|
9
|
-
attrs.forEach(attr => copied[attr] = obj[attr]);
|
|
14
|
+
attrs.forEach((attr) => { copied[attr] = obj[attr]; });
|
|
10
15
|
return copied;
|
|
11
16
|
};
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
|
-
* Check
|
|
15
|
-
* @param {
|
|
16
|
-
* @returns
|
|
19
|
+
* Check if a value is a plain object (not null, not array).
|
|
20
|
+
* @param {*} obj - Value to check.
|
|
21
|
+
* @returns {boolean} True if value is a plain object, false otherwise.
|
|
17
22
|
*/
|
|
18
|
-
const is_object = (obj) =>
|
|
19
|
-
return typeof obj === 'object' && obj !== null && !Array.isArray(obj);
|
|
20
|
-
}
|
|
23
|
+
const is_object = (obj) => typeof obj === 'object' && obj !== null && !Array.isArray(obj);
|
|
21
24
|
|
|
22
|
-
module.exports = { copy_obj, is_object }
|
|
25
|
+
module.exports = { copy_obj, is_object };
|
package/core/random.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @
|
|
2
|
+
* @fileoverview Random generation utility functions.
|
|
3
|
+
* @module core/random
|
|
4
4
|
*/
|
|
5
|
-
const random_code = function () {
|
|
6
|
-
return Math.floor(Math.random() * 1000000);
|
|
7
|
-
};
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Generate random 6-digit code.
|
|
8
|
+
* @returns {number} Random number between 0 and 999999.
|
|
9
|
+
*/
|
|
10
|
+
const random_code = () => Math.floor(Math.random() * 1000000);
|
|
11
|
+
|
|
12
|
+
module.exports = { random_code };
|
package/core/role.js
CHANGED
|
@@ -1,116 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Role-based access control utility functions.
|
|
3
|
+
* @module core/role
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
const { get_settings } = require("../setting");
|
|
2
7
|
|
|
3
8
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {
|
|
6
|
-
* @returns
|
|
9
|
+
* Find a role by name from settings.
|
|
10
|
+
* @param {string} role_name - Role name to find.
|
|
11
|
+
* @returns {Object|undefined} Role object or undefined if not found.
|
|
7
12
|
*/
|
|
8
|
-
const
|
|
13
|
+
const find_role = (role_name) => {
|
|
9
14
|
const settings = get_settings();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
return is_valid_role(role_name);
|
|
15
|
-
}
|
|
15
|
+
return settings.roles ? settings.roles.find((role) => role.name === role_name) : undefined;
|
|
16
|
+
};
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Validate role name exists in settings configuration.
|
|
20
|
+
* @param {string} role_name - Role name to validate.
|
|
21
|
+
* @returns {boolean} True if role is valid and configured.
|
|
22
|
+
*/
|
|
23
|
+
const validate_meta_role = (role_name) => {
|
|
18
24
|
const settings = get_settings();
|
|
19
|
-
|
|
20
|
-
return
|
|
21
|
-
}
|
|
25
|
+
if (!settings.roles) return false;
|
|
26
|
+
return find_role(role_name) !== undefined;
|
|
27
|
+
};
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Check if role name exists in settings.
|
|
31
|
+
* @param {string} role_name - Role name to check.
|
|
32
|
+
* @returns {boolean} True if role exists.
|
|
33
|
+
*/
|
|
34
|
+
const is_valid_role = (role_name) => find_role(role_name) !== undefined;
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Check if role has root/admin privileges.
|
|
38
|
+
* @param {string} role_name - Role name to check.
|
|
39
|
+
* @returns {boolean} True if role is root.
|
|
40
|
+
*/
|
|
41
|
+
const is_root_role = (role_name) => {
|
|
42
|
+
const role = find_role(role_name);
|
|
43
|
+
return role ? role.root === true : true;
|
|
44
|
+
};
|
|
36
45
|
|
|
37
46
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @param {
|
|
40
|
-
* @returns
|
|
47
|
+
* Get user role from session.
|
|
48
|
+
* @param {Object} req - HTTP request object.
|
|
49
|
+
* @returns {string|null} User's role or null.
|
|
41
50
|
*/
|
|
42
51
|
const get_session_user_role = (req) => {
|
|
43
52
|
const user = req && req.session ? req.session.user : null;
|
|
44
53
|
return user ? user.role : null;
|
|
45
|
-
}
|
|
54
|
+
};
|
|
46
55
|
|
|
47
56
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @param {
|
|
50
|
-
* @returns
|
|
57
|
+
* Get user object from session.
|
|
58
|
+
* @param {Object} req - HTTP request object.
|
|
59
|
+
* @returns {Object|null} User object or null.
|
|
51
60
|
*/
|
|
52
|
-
const get_session_user = (req) =>
|
|
53
|
-
return req && req.session ? req.session.user : null;
|
|
54
|
-
}
|
|
61
|
+
const get_session_user = (req) => req && req.session ? req.session.user : null;
|
|
55
62
|
|
|
56
63
|
/**
|
|
57
|
-
*
|
|
58
|
-
* @param {
|
|
64
|
+
* Check if current user has root privileges.
|
|
65
|
+
* @param {Object} req - HTTP request object.
|
|
66
|
+
* @returns {boolean} True if user is root.
|
|
59
67
|
*/
|
|
60
|
-
const is_root_user = (req) =>
|
|
61
|
-
return is_root_role(get_session_user_role(req));
|
|
62
|
-
}
|
|
68
|
+
const is_root_user = (req) => is_root_role(get_session_user_role(req));
|
|
63
69
|
|
|
64
70
|
/**
|
|
65
|
-
* Get
|
|
66
|
-
* @param {
|
|
67
|
-
* @param {
|
|
68
|
-
* @returns
|
|
71
|
+
* Get user's role permissions for a meta entity.
|
|
72
|
+
* @param {Object} req - HTTP request object.
|
|
73
|
+
* @param {Object} meta - Meta entity definition.
|
|
74
|
+
* @returns {[string, string]} Array of [mode, view] permissions.
|
|
69
75
|
*/
|
|
70
76
|
const get_user_role_right = (req, meta) => {
|
|
71
77
|
const settings = get_settings();
|
|
72
|
-
|
|
73
|
-
if (!settings.roles || !meta.roles) {
|
|
74
|
-
return [meta.mode, "*"];
|
|
75
|
-
}
|
|
78
|
+
if (!settings.roles || !meta.roles) return [meta.mode, "*"];
|
|
76
79
|
|
|
77
80
|
const user_role = get_session_user_role(req);
|
|
78
|
-
if (!user_role)
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
+
if (!user_role) return ["", ""];
|
|
82
|
+
if (!is_valid_role(user_role)) return ["", ""];
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const role_mode = role_settings[1];
|
|
89
|
-
const role_view = role_settings.length == 3 ? role_settings[2] : "*";
|
|
90
|
-
if (user_role == role_name) {
|
|
91
|
-
// * stands to get the mode from meta definition
|
|
92
|
-
if (role_mode == "*") {
|
|
93
|
-
return [meta.mode, role_view];
|
|
94
|
-
} else {
|
|
95
|
-
return [role_mode, role_view];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
84
|
+
for (const role of meta.roles) {
|
|
85
|
+
const role_settings = role.split(":");
|
|
86
|
+
const [role_name, role_mode] = role_settings;
|
|
87
|
+
const role_view = role_settings.length === 3 ? role_settings[2] : "*";
|
|
88
|
+
if (user_role === role_name) {
|
|
89
|
+
return role_mode === "*" ? [meta.mode, role_view] : [role_mode, role_view];
|
|
98
90
|
}
|
|
99
91
|
}
|
|
100
92
|
return ["", ""];
|
|
101
|
-
}
|
|
93
|
+
};
|
|
102
94
|
|
|
103
95
|
/**
|
|
104
|
-
* Check
|
|
105
|
-
* @param {
|
|
106
|
-
* @param {
|
|
107
|
-
* @param {
|
|
108
|
-
* @param {
|
|
109
|
-
* @returns
|
|
96
|
+
* Check if user has required mode permission on meta.
|
|
97
|
+
* @param {Object} req - HTTP request object.
|
|
98
|
+
* @param {Object} meta - Meta entity definition.
|
|
99
|
+
* @param {string} mode - Required mode (c/r/u/d).
|
|
100
|
+
* @param {string} view - Required view.
|
|
101
|
+
* @returns {boolean} True if user has permission.
|
|
110
102
|
*/
|
|
111
103
|
const check_user_role = (req, meta, mode, view) => {
|
|
112
104
|
const [role_mode, role_view] = get_user_role_right(req, meta);
|
|
113
|
-
return role_mode.includes(mode) && (role_view
|
|
114
|
-
}
|
|
105
|
+
return role_mode.includes(mode) && (role_view === "*" || role_view.includes(view));
|
|
106
|
+
};
|
|
115
107
|
|
|
116
108
|
module.exports = { is_root_role, is_root_user, validate_meta_role, check_user_role, get_user_role_right, get_session_user };
|
package/core/thread.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Threading and async utility functions.
|
|
3
|
+
* @module core/thread
|
|
4
|
+
*/
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Sleep for specified milliseconds.
|
|
8
|
+
* @param {number} ms - Milliseconds to sleep.
|
|
9
|
+
* @returns {Promise<void>} Promise that resolves after delay.
|
|
10
|
+
*/
|
|
11
|
+
const snooze = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
|
|
13
|
+
module.exports = { snooze };
|