@openinc/parse-server-opendash 4.0.33 → 4.0.38
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 +1 -0
- package/dist/features/permissions/types/Permissions.d.ts +3 -0
- package/dist/features/permissions/types/Permissions.js +4 -0
- package/dist/functions/openinc-config.js +22 -7
- package/dist/hooks/Alarm.js +5 -1
- package/dist/hooks/BDE_WorkTime.js +4 -2
- package/dist/hooks/_ChangeLog.js +20 -19
- package/dist/types/Alarm.d.ts +4 -0
- package/dist/types/Alarm.js +6 -0
- package/dist/types/Meta_Config.d.ts +1 -1
- package/dist/types/Meta_Entry.d.ts +1 -1
- package/package.json +12 -19
- package/schema/Alarm.json +5 -0
package/README.md
CHANGED
|
@@ -39,6 +39,10 @@ var Permissions;
|
|
|
39
39
|
// Access
|
|
40
40
|
DOCUMENTATION["see_app"] = "documentation:can-see-app";
|
|
41
41
|
})(DOCUMENTATION = Permissions.DOCUMENTATION || (Permissions.DOCUMENTATION = {}));
|
|
42
|
+
let BDE;
|
|
43
|
+
(function (BDE) {
|
|
44
|
+
BDE["timetracking_can_edit_times"] = "bde:timetracking-edit-times";
|
|
45
|
+
})(BDE = Permissions.BDE || (Permissions.BDE = {}));
|
|
42
46
|
// can also be used for nested permissions
|
|
43
47
|
// Example:
|
|
44
48
|
// export namespace TestPlugin {
|
|
@@ -12,13 +12,7 @@ async function init(name) {
|
|
|
12
12
|
const userId = request.user?.id;
|
|
13
13
|
let roles = [];
|
|
14
14
|
if (request.user) {
|
|
15
|
-
|
|
16
|
-
const roleObjects = await new node_1.default.Query(node_1.default.Role)
|
|
17
|
-
.equalTo("users", request.user)
|
|
18
|
-
.find({ useMasterKey: true });
|
|
19
|
-
roles = roleObjects
|
|
20
|
-
.map((role) => role.getName())
|
|
21
|
-
.filter(Boolean);
|
|
15
|
+
roles = await getUserRoles(request.user);
|
|
22
16
|
}
|
|
23
17
|
const parseSchema = await node_1.default.Schema.all();
|
|
24
18
|
const schema = parseSchema
|
|
@@ -50,6 +44,27 @@ async function init(name) {
|
|
|
50
44
|
};
|
|
51
45
|
});
|
|
52
46
|
}
|
|
47
|
+
// Returns all role names the user belongs to, including transitive parent roles.
|
|
48
|
+
// In Parse, roles can contain other roles via the "roles" relation, so a user in
|
|
49
|
+
// role "staff" also inherits permissions from "admin" if "staff" is a child of "admin".
|
|
50
|
+
async function getUserRoles(user) {
|
|
51
|
+
// visited prevents infinite loops in case of cyclic role definitions
|
|
52
|
+
const visited = new Set();
|
|
53
|
+
async function collect(roleQuery) {
|
|
54
|
+
const found = await roleQuery.find({ useMasterKey: true });
|
|
55
|
+
for (const role of found) {
|
|
56
|
+
const name = role.getName();
|
|
57
|
+
if (name && !visited.has(name)) {
|
|
58
|
+
visited.add(name);
|
|
59
|
+
// Find parent roles that contain this role as a child and continue upward
|
|
60
|
+
await collect(new node_1.default.Query(node_1.default.Role).equalTo("roles", role));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Entry point: direct roles of the user
|
|
65
|
+
await collect(new node_1.default.Query(node_1.default.Role).equalTo("users", user));
|
|
66
|
+
return [...visited];
|
|
67
|
+
}
|
|
53
68
|
async function getTenants() {
|
|
54
69
|
try {
|
|
55
70
|
const tenants = await new node_1.default.Query(index_js_2.Tenant)
|
package/dist/hooks/Alarm.js
CHANGED
|
@@ -8,7 +8,11 @@ async function init() {
|
|
|
8
8
|
(0, index_js_2.beforeSaveHook)(index_js_3.Alarm, async (request) => {
|
|
9
9
|
const { object, original, user } = request;
|
|
10
10
|
await (0, index_js_2.defaultHandler)(request);
|
|
11
|
-
//
|
|
11
|
+
//Do not allow tenant users to read alarms of other users by default, but allow custom ACLs
|
|
12
|
+
await (0, index_js_2.defaultAclHandler)(request, {
|
|
13
|
+
allowCustomACL: true,
|
|
14
|
+
denyTenantUserRead: true,
|
|
15
|
+
});
|
|
12
16
|
});
|
|
13
17
|
(0, index_js_2.afterSaveHook)(index_js_3.Alarm, async ({ object, original, user }) => {
|
|
14
18
|
if (index_js_1.ConfigInstance.getInstance().getBoolean("OPENWARE")) {
|
|
@@ -12,6 +12,8 @@ async function init() {
|
|
|
12
12
|
});
|
|
13
13
|
(0, index_js_1.afterSaveHook)(index_js_2.BDE_WorkTime, async (request) => {
|
|
14
14
|
const { object, original, user } = request;
|
|
15
|
+
if (object.get("status") === "disrupted")
|
|
16
|
+
return;
|
|
15
17
|
await addToWorkOrder(object);
|
|
16
18
|
});
|
|
17
19
|
}
|
|
@@ -22,7 +24,7 @@ async function addToWorkOrder(workTime) {
|
|
|
22
24
|
const workOrder = await workTime.workOrder?.fetch({ useMasterKey: true });
|
|
23
25
|
if (!workOrder)
|
|
24
26
|
return;
|
|
25
|
-
workOrder.set("amountGood", (workOrder.amountGood || 0) + workTime.amountGood);
|
|
26
|
-
workOrder.set("amountScrap", (workOrder.amountScrap || 0) + workTime.amountScrap);
|
|
27
|
+
workOrder.set("amountGood", (workOrder.amountGood || 0) + (workTime.amountGood || 0));
|
|
28
|
+
workOrder.set("amountScrap", (workOrder.amountScrap || 0) + (workTime.amountScrap || 0));
|
|
27
29
|
await workOrder.save(null, { useMasterKey: true });
|
|
28
30
|
}
|
package/dist/hooks/_ChangeLog.js
CHANGED
|
@@ -7,21 +7,22 @@ exports.init = init;
|
|
|
7
7
|
const node_1 = __importDefault(require("parse/node"));
|
|
8
8
|
const AMQPBusConnection_js_1 = require("../features/openware/services/AMQPBusConnection.js");
|
|
9
9
|
const index_js_1 = require("../features/schema/index.js");
|
|
10
|
-
const index_js_2 = require("../
|
|
10
|
+
const index_js_2 = require("../features/config/index.js");
|
|
11
|
+
const index_js_3 = require("../types/index.js");
|
|
11
12
|
async function init() {
|
|
12
13
|
const schema = await node_1.default.Schema.all();
|
|
13
|
-
const
|
|
14
|
-
console.log(`ChangeLog publishing enabled: ${
|
|
14
|
+
const config = index_js_2.ConfigInstance.getInstance();
|
|
15
|
+
console.log(`ChangeLog publishing enabled: ${config.getBoolean("CHANGELOG_PUBLISH_ENABLE")}`);
|
|
15
16
|
const blacklistedClasses = [
|
|
16
17
|
"_Session",
|
|
17
18
|
"_Installation",
|
|
18
|
-
...(
|
|
19
|
+
...(config.get("CHANGELOG_BLACKLIST") || "")
|
|
19
20
|
.split(",")
|
|
20
21
|
.map((c) => c.trim())
|
|
21
22
|
.filter((c) => c.length > 0),
|
|
22
23
|
];
|
|
23
24
|
console.log(`ChangeLog blacklisted classes: ${blacklistedClasses.join(", ") || "None"}`);
|
|
24
|
-
(0, index_js_1.beforeSaveHook)(
|
|
25
|
+
(0, index_js_1.beforeSaveHook)(index_js_3.Changelog.className, async (request) => {
|
|
25
26
|
const { object, original, user } = request;
|
|
26
27
|
await (0, index_js_1.defaultHandler)(request);
|
|
27
28
|
await (0, index_js_1.defaultAclHandler)(request);
|
|
@@ -29,16 +30,16 @@ async function init() {
|
|
|
29
30
|
object.getACL().setReadAccess(user.id, true);
|
|
30
31
|
}
|
|
31
32
|
});
|
|
32
|
-
if (
|
|
33
|
+
if (config.getBoolean("CHANGELOG_PUBLISH_ENABLE")) {
|
|
33
34
|
const params = {
|
|
34
|
-
host:
|
|
35
|
-
vhost:
|
|
36
|
-
port: parseInt(
|
|
37
|
-
username:
|
|
38
|
-
password:
|
|
39
|
-
exchange:
|
|
40
|
-
topicPrefix:
|
|
41
|
-
managementPort: parseInt(
|
|
35
|
+
host: config.get("CHANGELOG_PUBLISH_HOST") || "localhost",
|
|
36
|
+
vhost: config.get("CHANGELOG_PUBLISH_VHOST") || "configuration",
|
|
37
|
+
port: parseInt(config.get("CHANGELOG_PUBLISH_PORT") || "5672"),
|
|
38
|
+
username: config.get("CHANGELOG_PUBLISH_USERNAME") || "guest",
|
|
39
|
+
password: config.get("CHANGELOG_PUBLISH_PASSWORD") || "guest",
|
|
40
|
+
exchange: config.get("CHANGELOG_PUBLISH_EXCHANGE") || "topic",
|
|
41
|
+
topicPrefix: config.get("CHANGELOG_PUBLISH_TOPIC_PREFIX") || "config",
|
|
42
|
+
managementPort: parseInt(config.get("CHANGELOG_PUBLISH_MANAGEMENT_PORT") || "15672"),
|
|
42
43
|
};
|
|
43
44
|
const connection = new AMQPBusConnection_js_1.AMQPBusConnection(params);
|
|
44
45
|
try {
|
|
@@ -47,7 +48,7 @@ async function init() {
|
|
|
47
48
|
console.log(`Establishing Connection to ${url} for ChangeLog publishing...`);
|
|
48
49
|
await connection.connect();
|
|
49
50
|
console.log(`Connected to AMQPBus at ${url} for ChangeLog publishing.`);
|
|
50
|
-
(0, index_js_1.afterSaveHook)(
|
|
51
|
+
(0, index_js_1.afterSaveHook)(index_js_3.Changelog.className, async (request) => {
|
|
51
52
|
const { object: changelog } = request;
|
|
52
53
|
const msg = JSON.stringify(changelog.toJSON());
|
|
53
54
|
const topic = `${params.topicPrefix && params.topicPrefix.length > 0
|
|
@@ -63,8 +64,8 @@ async function init() {
|
|
|
63
64
|
}
|
|
64
65
|
schema.forEach((classSchema) => {
|
|
65
66
|
if (!classSchema.className ||
|
|
66
|
-
classSchema.className ===
|
|
67
|
-
classSchema.className ===
|
|
67
|
+
classSchema.className === index_js_3.Changelog.className ||
|
|
68
|
+
classSchema.className === index_js_3.Permission.className) {
|
|
68
69
|
console.log(`Skipping ChangeLog hook for class ${classSchema.className}`);
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
@@ -81,7 +82,7 @@ async function init() {
|
|
|
81
82
|
console.log(`Skipping ChangeLog entry for class ${classSchema.className} and object ${object.id} due to blacklisted class.`);
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
|
-
const changelog = new
|
|
85
|
+
const changelog = new index_js_3.Changelog();
|
|
85
86
|
changelog.set("nameOfClass", classSchema.className);
|
|
86
87
|
changelog.set("changedObject", object.id);
|
|
87
88
|
changelog.set("operation", "delete");
|
|
@@ -109,7 +110,7 @@ async function init() {
|
|
|
109
110
|
console.log(`Skipping ChangeLog entry for class ${classSchema.className} and object ${object.id} due to ${context.skipChangelog ? "context flag" : "blacklisted class"}.`);
|
|
110
111
|
return;
|
|
111
112
|
}
|
|
112
|
-
const changelog = new
|
|
113
|
+
const changelog = new index_js_3.Changelog();
|
|
113
114
|
changelog.set("nameOfClass", classSchema.className);
|
|
114
115
|
changelog.set("changedObject", object.id);
|
|
115
116
|
changelog.set("operation", original ? "update" : "create");
|
package/dist/types/Alarm.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Parse from "parse/node";
|
|
2
|
+
import type { Tenant } from "./Tenant";
|
|
2
3
|
import type { _User } from "./_User";
|
|
3
4
|
export interface AlarmAttributes {
|
|
4
5
|
id: string;
|
|
@@ -12,6 +13,7 @@ export interface AlarmAttributes {
|
|
|
12
13
|
item_source?: string | undefined;
|
|
13
14
|
name?: string | undefined;
|
|
14
15
|
sent?: number | undefined;
|
|
16
|
+
tenant?: Tenant | undefined;
|
|
15
17
|
trigger?: any | undefined;
|
|
16
18
|
user: _User;
|
|
17
19
|
}
|
|
@@ -32,6 +34,8 @@ export declare class Alarm extends Parse.Object<AlarmAttributes> {
|
|
|
32
34
|
set name(value: string | undefined);
|
|
33
35
|
get sent(): number | undefined;
|
|
34
36
|
set sent(value: number | undefined);
|
|
37
|
+
get tenant(): Tenant | undefined;
|
|
38
|
+
set tenant(value: Tenant | undefined);
|
|
35
39
|
get trigger(): any | undefined;
|
|
36
40
|
set trigger(value: any | undefined);
|
|
37
41
|
get user(): _User;
|
package/dist/types/Alarm.js
CHANGED
|
@@ -52,6 +52,12 @@ class Alarm extends node_1.default.Object {
|
|
|
52
52
|
set sent(value) {
|
|
53
53
|
super.set("sent", value);
|
|
54
54
|
}
|
|
55
|
+
get tenant() {
|
|
56
|
+
return super.get("tenant");
|
|
57
|
+
}
|
|
58
|
+
set tenant(value) {
|
|
59
|
+
super.set("tenant", value);
|
|
60
|
+
}
|
|
55
61
|
get trigger() {
|
|
56
62
|
return super.get("trigger");
|
|
57
63
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Parse from "parse/node";
|
|
2
|
+
import { MetaConfig } from "./custom/MetaField";
|
|
2
3
|
import type { Meta_Config } from "./Meta_Config";
|
|
3
4
|
import type { Tenant } from "./Tenant";
|
|
4
|
-
import { MetaConfig } from "./custom/MetaField";
|
|
5
5
|
export interface Meta_EntryAttributes {
|
|
6
6
|
id: string;
|
|
7
7
|
objectId: string;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openinc/parse-server-opendash",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.38",
|
|
4
4
|
"description": "Parse Server Cloud Code for open.INC Stack.",
|
|
5
|
-
"packageManager": "pnpm@
|
|
5
|
+
"packageManager": "pnpm@11.9.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"parse",
|
|
8
8
|
"opendash"
|
|
@@ -69,17 +69,17 @@
|
|
|
69
69
|
"@openinc/parse-server-schema": "^4.1.1",
|
|
70
70
|
"amqplib": "^0.10.9",
|
|
71
71
|
"cron": "^4.4.0",
|
|
72
|
-
"dayjs": "^1.11.
|
|
72
|
+
"dayjs": "^1.11.21",
|
|
73
73
|
"dotenv": "^17.4.2",
|
|
74
74
|
"fast-equals": "^6.0.0",
|
|
75
|
-
"i18next": "^26.0
|
|
75
|
+
"i18next": "^26.2.0",
|
|
76
76
|
"i18next-fs-backend": "^2.6.5",
|
|
77
77
|
"jsonwebtoken": "^9.0.3",
|
|
78
|
-
"jwks-rsa": "^4.0
|
|
79
|
-
"nodemailer": "^
|
|
78
|
+
"jwks-rsa": "^4.1.0",
|
|
79
|
+
"nodemailer": "^9.0.1",
|
|
80
80
|
"nunjucks": "^3.2.4",
|
|
81
|
-
"parse": "^8.
|
|
82
|
-
"parse-server": "^9.
|
|
81
|
+
"parse": "^8.6.0",
|
|
82
|
+
"parse-server": "^9.9.0",
|
|
83
83
|
"pdf-img-convert": "2.0.0",
|
|
84
84
|
"rimraf": "^6.1.3",
|
|
85
85
|
"table": "^6.9.0",
|
|
@@ -88,22 +88,15 @@
|
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@types/jsonwebtoken": "^9.0.10",
|
|
91
|
-
"@types/node": "^25.
|
|
92
|
-
"@types/nodemailer": "^
|
|
91
|
+
"@types/node": "^25.9.4",
|
|
92
|
+
"@types/nodemailer": "^8.0.1",
|
|
93
93
|
"@types/nunjucks": "^3.2.6",
|
|
94
94
|
"@types/safe-timers": "^1.1.2",
|
|
95
95
|
"@types/web-push": "^3.6.4",
|
|
96
|
-
"concurrently": "^9.2.
|
|
96
|
+
"concurrently": "^9.2.3",
|
|
97
97
|
"ts-node": "^10.9.2",
|
|
98
98
|
"typedoc": "^0.28.19",
|
|
99
|
-
"typedoc-plugin-markdown": "^4.
|
|
99
|
+
"typedoc-plugin-markdown": "^4.12.0",
|
|
100
100
|
"typescript": "^5.9.3"
|
|
101
|
-
},
|
|
102
|
-
"pnpm": {
|
|
103
|
-
"auditConfig": {
|
|
104
|
-
"ignoreGhsas": [
|
|
105
|
-
"GHSA-w5hq-g745-h8pq"
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
101
|
}
|
|
109
102
|
}
|