@openinc/parse-server-opendash 4.0.34 → 4.0.39
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_Article.js +6 -1
- package/dist/hooks/BDE_WorkTime.js +4 -2
- package/dist/hooks/MES_Order.js +2 -2
- package/dist/types/Alarm.d.ts +4 -0
- package/dist/types/Alarm.js +6 -0
- package/dist/types/BDE_Article.d.ts +3 -0
- package/dist/types/BDE_Article.js +6 -0
- package/dist/types/MES_Article.d.ts +7 -0
- package/dist/types/MES_Order.d.ts +4 -4
- package/dist/types/MES_OrderPlan.d.ts +4 -4
- 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/schema/BDE_Article.json +5 -0
- package/schema/MES_Order.json +1 -1
- package/schema/MES_OrderPlan.json +1 -1
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")) {
|
|
@@ -7,7 +7,12 @@ async function init() {
|
|
|
7
7
|
(0, index_js_1.beforeSaveHook)(index_js_2.BDE_Article, async (request) => {
|
|
8
8
|
const { object, original, user } = request;
|
|
9
9
|
await (0, index_js_1.defaultHandler)(request);
|
|
10
|
-
|
|
10
|
+
// Ported from the former MES_Article hook: tenant users may manage the
|
|
11
|
+
// shared article catalog, and custom ACLs are honoured.
|
|
12
|
+
await (0, index_js_1.defaultAclHandler)(request, {
|
|
13
|
+
allowCustomACL: true,
|
|
14
|
+
allowTenantUserWrite: true,
|
|
15
|
+
});
|
|
11
16
|
// TODO
|
|
12
17
|
});
|
|
13
18
|
(0, index_js_1.afterSaveHook)(index_js_2.BDE_Article, async (request) => {
|
|
@@ -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/MES_Order.js
CHANGED
|
@@ -97,8 +97,8 @@ async function init() {
|
|
|
97
97
|
.get("article")
|
|
98
98
|
?.fetch({ useMasterKey: true });
|
|
99
99
|
if (article) {
|
|
100
|
-
object.set("articlenr", article.get("
|
|
101
|
-
object.set("articlename", article?.get("
|
|
100
|
+
object.set("articlenr", article.get("articleNumber"));
|
|
101
|
+
object.set("articlename", article?.get("description"));
|
|
102
102
|
object.set("targettime", object.targettime
|
|
103
103
|
? object.targettime
|
|
104
104
|
: article?.get("targettime") || 0);
|
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
|
}
|
|
@@ -8,6 +8,7 @@ export interface BDE_ArticleAttributes {
|
|
|
8
8
|
articleNumber?: string | undefined;
|
|
9
9
|
description?: string | undefined;
|
|
10
10
|
isDeleted: boolean;
|
|
11
|
+
targettime?: number | undefined;
|
|
11
12
|
tenant?: Tenant | undefined;
|
|
12
13
|
unit?: string | undefined;
|
|
13
14
|
}
|
|
@@ -20,6 +21,8 @@ export declare class BDE_Article extends Parse.Object<BDE_ArticleAttributes> {
|
|
|
20
21
|
set description(value: string | undefined);
|
|
21
22
|
get isDeleted(): boolean;
|
|
22
23
|
set isDeleted(value: boolean);
|
|
24
|
+
get targettime(): number | undefined;
|
|
25
|
+
set targettime(value: number | undefined);
|
|
23
26
|
get tenant(): Tenant | undefined;
|
|
24
27
|
set tenant(value: Tenant | undefined);
|
|
25
28
|
get unit(): string | undefined;
|
|
@@ -28,6 +28,12 @@ class BDE_Article extends node_1.default.Object {
|
|
|
28
28
|
set isDeleted(value) {
|
|
29
29
|
super.set("isDeleted", value);
|
|
30
30
|
}
|
|
31
|
+
get targettime() {
|
|
32
|
+
return super.get("targettime");
|
|
33
|
+
}
|
|
34
|
+
set targettime(value) {
|
|
35
|
+
super.set("targettime", value);
|
|
36
|
+
}
|
|
31
37
|
get tenant() {
|
|
32
38
|
return super.get("tenant");
|
|
33
39
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import Parse from "parse/node";
|
|
2
2
|
import type { Tenant } from "./Tenant";
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Superseded by {@link BDE_Article} (OD3_BDE_Article). The MES
|
|
5
|
+
* module now stores articles as BDE_Article (artnr → articleNumber,
|
|
6
|
+
* name → description, targettime → targettime). This class is kept only so
|
|
7
|
+
* existing OD3_MES_Article records remain readable until they are migrated.
|
|
8
|
+
* Do not reference it for new records.
|
|
9
|
+
*/
|
|
3
10
|
export interface MES_ArticleAttributes {
|
|
4
11
|
id: string;
|
|
5
12
|
objectId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Parse from "parse/node";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BDE_Article } from "./BDE_Article";
|
|
3
3
|
import type { Source } from "./Source";
|
|
4
4
|
import type { Tenant } from "./Tenant";
|
|
5
5
|
export interface MES_OrderAttributes {
|
|
@@ -7,7 +7,7 @@ export interface MES_OrderAttributes {
|
|
|
7
7
|
objectId: string;
|
|
8
8
|
createdAt: Date;
|
|
9
9
|
updatedAt: Date;
|
|
10
|
-
article?:
|
|
10
|
+
article?: BDE_Article | undefined;
|
|
11
11
|
articlename?: string | undefined;
|
|
12
12
|
articlenr?: string | undefined;
|
|
13
13
|
duration: number;
|
|
@@ -24,8 +24,8 @@ export interface MES_OrderAttributes {
|
|
|
24
24
|
export declare class MES_Order extends Parse.Object<MES_OrderAttributes> {
|
|
25
25
|
static className: string;
|
|
26
26
|
constructor(data?: Partial<MES_OrderAttributes>);
|
|
27
|
-
get article():
|
|
28
|
-
set article(value:
|
|
27
|
+
get article(): BDE_Article | undefined;
|
|
28
|
+
set article(value: BDE_Article | undefined);
|
|
29
29
|
get articlename(): string | undefined;
|
|
30
30
|
set articlename(value: string | undefined);
|
|
31
31
|
get articlenr(): string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Parse from "parse/node";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BDE_Article } from "./BDE_Article";
|
|
3
3
|
import type { Source } from "./Source";
|
|
4
4
|
import type { Tenant } from "./Tenant";
|
|
5
5
|
export interface MES_OrderPlanAttributes {
|
|
@@ -7,7 +7,7 @@ export interface MES_OrderPlanAttributes {
|
|
|
7
7
|
objectId: string;
|
|
8
8
|
createdAt: Date;
|
|
9
9
|
updatedAt: Date;
|
|
10
|
-
article?:
|
|
10
|
+
article?: BDE_Article | undefined;
|
|
11
11
|
ordernr: string;
|
|
12
12
|
planEnd?: Date | undefined;
|
|
13
13
|
planStart?: Date | undefined;
|
|
@@ -19,8 +19,8 @@ export interface MES_OrderPlanAttributes {
|
|
|
19
19
|
export declare class MES_OrderPlan extends Parse.Object<MES_OrderPlanAttributes> {
|
|
20
20
|
static className: string;
|
|
21
21
|
constructor(data?: Partial<MES_OrderPlanAttributes>);
|
|
22
|
-
get article():
|
|
23
|
-
set article(value:
|
|
22
|
+
get article(): BDE_Article | undefined;
|
|
23
|
+
set article(value: BDE_Article | undefined);
|
|
24
24
|
get ordernr(): string;
|
|
25
25
|
set ordernr(value: string);
|
|
26
26
|
get planEnd(): Date | undefined;
|
|
@@ -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.39",
|
|
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.
|
|
76
|
-
"i18next-fs-backend": "^2.6.
|
|
75
|
+
"i18next": "^26.3.1",
|
|
76
|
+
"i18next-fs-backend": "^2.6.6",
|
|
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
81
|
"parse": "^8.6.0",
|
|
82
|
-
"parse-server": "
|
|
82
|
+
"parse-server": "9.9.1-alpha.13",
|
|
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.9.
|
|
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
|
}
|
package/schema/Alarm.json
CHANGED
package/schema/BDE_Article.json
CHANGED
package/schema/MES_Order.json
CHANGED