@openinc/parse-server-opendash 4.0.20 → 4.0.22

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.
@@ -30,6 +30,42 @@ function getUsername(user) {
30
30
  async function init(name) {
31
31
  node_1.default.Cloud.define(name, handleRequest, { requireUser: false });
32
32
  }
33
+ async function userCanWriteTicket(ticketId, user) {
34
+ if (!user?.id)
35
+ return false;
36
+ const ticket = await new node_1.default.Query(index_js_2.Maintenance_Ticket).get(ticketId, {
37
+ useMasterKey: true,
38
+ });
39
+ const acl = ticket.getACL();
40
+ // Without object-level ACL, class-level permissions apply.
41
+ if (!acl)
42
+ return true;
43
+ if (acl.getPublicWriteAccess() || acl.getWriteAccess(user.id))
44
+ return true;
45
+ const directRoles = await new node_1.default.Query(node_1.default.Role)
46
+ .equalTo("users", user)
47
+ .find({ useMasterKey: true });
48
+ const rolesToCheck = [...directRoles];
49
+ const visitedRoleIds = new Set(directRoles.map((role) => role.id).filter((id) => !!id));
50
+ // Traverse parent roles so ACL checks also honor nested role relations.
51
+ for (let i = 0; i < rolesToCheck.length; i += 1) {
52
+ const role = rolesToCheck[i];
53
+ const roleName = role.get("name");
54
+ if (roleName && acl.getRoleWriteAccess(roleName)) {
55
+ return true;
56
+ }
57
+ const parentRoles = await new node_1.default.Query(node_1.default.Role)
58
+ .equalTo("roles", role)
59
+ .find({ useMasterKey: true });
60
+ for (const parentRole of parentRoles) {
61
+ if (!parentRole.id || visitedRoleIds.has(parentRole.id))
62
+ continue;
63
+ visitedRoleIds.add(parentRole.id);
64
+ rolesToCheck.push(parentRole);
65
+ }
66
+ }
67
+ return false;
68
+ }
33
69
  async function handleRequest(request) {
34
70
  const result = {
35
71
  success: true,
@@ -56,7 +92,9 @@ async function handleRequest(request) {
56
92
  result.ticket = ticket;
57
93
  return result;
58
94
  }
59
- const ticket = await saveTicketData(request.params, user);
95
+ const shouldUseMasterKeyForUpdate = !!request.params.existingTicketId &&
96
+ (await userCanWriteTicket(request.params.existingTicketId, user));
97
+ const ticket = await saveTicketData(request.params, user, shouldUseMasterKeyForUpdate ? { useMasterKey: true } : undefined);
60
98
  result.success = true;
61
99
  result.ticket = ticket;
62
100
  return result;
@@ -12,6 +12,7 @@ export interface Maintenance_TicketAttributes {
12
12
  assignedroles: Parse.Relation<Maintenance_Ticket, _Role>;
13
13
  assignedusers: Parse.Relation<Maintenance_Ticket, _User>;
14
14
  description?: string | undefined;
15
+ displayAt?: Date | undefined;
15
16
  enabled: boolean;
16
17
  latestPriorityValue?: number | undefined;
17
18
  meta?: TicketMeta | undefined;
@@ -27,6 +28,8 @@ export declare class Maintenance_Ticket extends Parse.Object<Maintenance_TicketA
27
28
  get assignedusers(): Parse.Relation<Maintenance_Ticket, _User>;
28
29
  get description(): string | undefined;
29
30
  set description(value: string | undefined);
31
+ get displayAt(): Date | undefined;
32
+ set displayAt(value: Date | undefined);
30
33
  get enabled(): boolean;
31
34
  set enabled(value: boolean);
32
35
  get latestPriorityValue(): number | undefined;
@@ -22,6 +22,12 @@ class Maintenance_Ticket extends node_1.default.Object {
22
22
  set description(value) {
23
23
  super.set("description", value);
24
24
  }
25
+ get displayAt() {
26
+ return super.get("displayAt");
27
+ }
28
+ set displayAt(value) {
29
+ super.set("displayAt", value);
30
+ }
25
31
  get enabled() {
26
32
  return super.get("enabled");
27
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openinc/parse-server-opendash",
3
- "version": "4.0.20",
3
+ "version": "4.0.22",
4
4
  "description": "Parse Server Cloud Code for open.INC Stack.",
5
5
  "packageManager": "pnpm@10.33.0",
6
6
  "keywords": [
@@ -14,6 +14,10 @@
14
14
  "type": "String",
15
15
  "required": false
16
16
  },
17
+ "displayAt": {
18
+ "type": "Date",
19
+ "required": false
20
+ },
17
21
  "enabled": {
18
22
  "type": "Boolean",
19
23
  "required": false,