@conduction/nextcloud-vue 2.119.0 → 2.121.0

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 (179) hide show
  1. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js +9 -0
  2. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js.map +1 -0
  3. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js +226 -0
  4. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js +211 -0
  6. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js +9 -0
  8. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js.map +1 -0
  9. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js +64 -0
  10. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js.map +1 -0
  11. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js +89 -0
  12. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js.map +1 -0
  13. package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
  14. package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
  15. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +53 -1
  16. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  17. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +546 -523
  18. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  19. package/dist/esm/components/CnIndexPage/useNamedSource.js +9 -0
  20. package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
  21. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js +9 -0
  22. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js.map +1 -0
  23. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js +257 -0
  24. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js.map +1 -0
  25. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js +266 -0
  26. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js.map +1 -0
  27. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue.js +1 -1
  28. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js +14 -7
  29. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js.map +1 -1
  30. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue3.js.map +1 -1
  31. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js +9 -0
  32. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js.map +1 -0
  33. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js +278 -0
  34. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js.map +1 -0
  35. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js +128 -0
  36. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js.map +1 -0
  37. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js +9 -0
  38. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js.map +1 -0
  39. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js +214 -0
  40. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js.map +1 -0
  41. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js +125 -0
  42. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js.map +1 -0
  43. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js +9 -0
  44. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js.map +1 -0
  45. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js +163 -0
  46. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js.map +1 -0
  47. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js +131 -0
  48. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js.map +1 -0
  49. package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js +127 -0
  50. package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js.map +1 -0
  51. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js +9 -0
  52. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js.map +1 -0
  53. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js +82 -0
  54. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js.map +1 -0
  55. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js +61 -0
  56. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js.map +1 -0
  57. package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js +60 -0
  58. package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js.map +1 -0
  59. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js +10 -0
  60. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js.map +1 -0
  61. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js +226 -0
  62. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js.map +1 -0
  63. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js +126 -0
  64. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js.map +1 -0
  65. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js +10 -0
  66. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js.map +1 -0
  67. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js +944 -0
  68. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js.map +1 -0
  69. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js +276 -0
  70. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js.map +1 -0
  71. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js +9 -0
  72. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js.map +1 -0
  73. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js +354 -0
  74. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js.map +1 -0
  75. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js +392 -0
  76. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js.map +1 -0
  77. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js +9 -0
  78. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js.map +1 -0
  79. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js +180 -0
  80. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js.map +1 -0
  81. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js +208 -0
  82. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js.map +1 -0
  83. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js +9 -0
  84. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js.map +1 -0
  85. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js +244 -0
  86. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js.map +1 -0
  87. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js +76 -0
  88. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js.map +1 -0
  89. package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js +290 -0
  90. package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js.map +1 -0
  91. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +9 -0
  92. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js.map +1 -0
  93. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js +448 -0
  94. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -0
  95. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +303 -0
  96. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -0
  97. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
  98. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +19 -2
  99. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  100. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +73 -62
  101. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  102. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +6 -0
  103. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  104. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +42 -32
  105. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  106. package/dist/esm/composables/indexSources.js +116 -16
  107. package/dist/esm/composables/indexSources.js.map +1 -1
  108. package/dist/esm/index.js +9 -0
  109. package/dist/esm/index.js.map +1 -1
  110. package/dist/esm/l10n/en.json.js +207 -1
  111. package/dist/esm/l10n/en.json.js.map +1 -1
  112. package/dist/esm/l10n/nl.json.js +207 -1
  113. package/dist/esm/l10n/nl.json.js.map +1 -1
  114. package/dist/esm/library-style.js +1 -1
  115. package/dist/esm/nextcloud-vue.css +951 -16
  116. package/dist/esm/utils/aiFeatures.js +245 -0
  117. package/dist/esm/utils/aiFeatures.js.map +1 -0
  118. package/dist/esm/utils/aiSuggestionTracker.js +182 -0
  119. package/dist/esm/utils/aiSuggestionTracker.js.map +1 -0
  120. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  121. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  122. package/dist/esm/utils/objectPermissions.js +552 -0
  123. package/dist/esm/utils/objectPermissions.js.map +1 -0
  124. package/dist/esm/utils/objectTranslations.js +180 -0
  125. package/dist/esm/utils/objectTranslations.js.map +1 -0
  126. package/dist/esm/utils/stateMachineValidation.js +254 -0
  127. package/dist/esm/utils/stateMachineValidation.js.map +1 -0
  128. package/dist/esm/utils/widgetDispatch.js +3 -1
  129. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  130. package/dist/nextcloud-vue.cjs.js +23038 -14567
  131. package/dist/nextcloud-vue.cjs.js.map +2 -2
  132. package/dist/nextcloud-vue.css +951 -16
  133. package/l10n/en.json +207 -1
  134. package/l10n/nl.json +207 -1
  135. package/package.json +1 -1
  136. package/src/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue +416 -0
  137. package/src/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue +136 -0
  138. package/src/components/CnAiFeaturesWidget/__tests__/CnAiFeaturesWidget.spec.js +213 -0
  139. package/src/components/CnAiFeaturesWidget/index.js +14 -0
  140. package/src/components/CnIndexPage/CnIndexPage.vue +74 -3
  141. package/src/components/CnIndexPage/useNamedSource.js +9 -0
  142. package/src/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue +499 -0
  143. package/src/components/CnObjectPermissionsTab/__tests__/CnObjectPermissionsTab.spec.js +186 -0
  144. package/src/components/CnObjectPermissionsTab/index.js +13 -0
  145. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +8 -1
  146. package/src/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue +424 -0
  147. package/src/components/CnObjectTranslationsWidget/__tests__/CnObjectTranslationsWidget.spec.js +189 -0
  148. package/src/components/CnObjectTranslationsWidget/index.js +13 -0
  149. package/src/components/CnReadinessChecklist/CnReadinessChecklist.vue +335 -0
  150. package/src/components/CnReadinessChecklist/index.js +9 -0
  151. package/src/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue +300 -0
  152. package/src/components/CnSchemaRulesWidget/index.js +10 -0
  153. package/src/components/CnSchemaRulesWidget/schemaRules.js +123 -0
  154. package/src/components/CnSearchIndexStatus/CnSearchIndexStatus.vue +160 -0
  155. package/src/components/CnSearchIndexStatus/index.js +10 -0
  156. package/src/components/CnSearchIndexStatus/searchIndexStatus.js +56 -0
  157. package/src/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue +328 -0
  158. package/src/components/CnShippedConfigurationSection/index.js +9 -0
  159. package/src/components/CnStateMachineEditor/CnStateMachineEditor.vue +1332 -0
  160. package/src/components/CnStateMachineEditor/CnStateMachineFields.vue +791 -0
  161. package/src/components/CnStateMachineEditor/CnStateMachineNode.vue +442 -0
  162. package/src/components/CnStateMachineEditor/CnStateMachinePanel.vue +326 -0
  163. package/src/components/CnStateMachineEditor/index.js +8 -0
  164. package/src/components/CnStateMachineEditor/stateMachineFields.js +287 -0
  165. package/src/components/CnTimelineWidget/CnTimelineManage.vue +827 -0
  166. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +29 -3
  167. package/src/components/CnWidgetGrid/builtInWidgets.js +6 -0
  168. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +10 -0
  169. package/src/components/index.js +8 -0
  170. package/src/composables/indexSources.js +116 -16
  171. package/src/css/index-page.css +7 -0
  172. package/src/index.js +9 -0
  173. package/src/utils/aiFeatures.js +241 -0
  174. package/src/utils/aiSuggestionTracker.js +178 -0
  175. package/src/utils/libraryWidgetKeys.js +2 -0
  176. package/src/utils/objectPermissions.js +548 -0
  177. package/src/utils/objectTranslations.js +176 -0
  178. package/src/utils/stateMachineValidation.js +250 -0
  179. package/src/utils/widgetDispatch.js +3 -1
@@ -0,0 +1,552 @@
1
+ import axios__default from '@nextcloud/axios';
2
+ import { translate } from '@nextcloud/l10n';
3
+ import { prefixUrl } from './headers.js';
4
+
5
+ /**
6
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
7
+ * SPDX-License-Identifier: EUPL-1.2
8
+ *
9
+ * Who holds which right on one OpenRegister object, and where each grant came
10
+ * from. The reads behind CnObjectPermissionsTab.
11
+ *
12
+ * Every function here is a read. Nothing decides who may open an object: the
13
+ * grant, its provenance, the deny and the inheritance live in OpenRegister, and
14
+ * these helpers hand on what it answered. A deny is never subtracted from a
15
+ * grant, a missing answer is never filled with a default, and nothing is
16
+ * cached: a copy of an access decision is a second decision nobody updates.
17
+ *
18
+ * The object's own permission set (`/permissions`) is preferred; an older
19
+ * OpenRegister answers 404 to it, and then five reads are the fallback:
20
+ *
21
+ * GET {apiBase}/permissions the verb catalogue + deny mode
22
+ * GET {apiBase}/objects/{register}/{schema}/{id}/shares grants written on the object
23
+ * GET {apiBase}/permissions/compare-roles?register= each role and its verbs
24
+ * GET {apiBase}/scopes?register=&schema= the caller's own verdict + provenance
25
+ * GET {apiBase}/permissions/deny-preview?register=&schema= the deny rules as written
26
+ *
27
+ * plus the history read `{...}/{id}/permissions/history?at=` for "who held a
28
+ * right on a date".
29
+ *
30
+ * A failed read answers `null`, never `[]`: "we could not ask" and "nobody
31
+ * holds this" are opposite answers that would otherwise render as the same
32
+ * empty table.
33
+ */
34
+
35
+ /** The OpenRegister API root a target defaults to. */
36
+ const DEFAULT_API_BASE = '/apps/openregister/api';
37
+
38
+ /**
39
+ * Normalise a target to `{register, schema, apiBase}`.
40
+ *
41
+ * @param {object} target The object's register, schema and optional apiBase.
42
+ * @return {{register: string, schema: string, apiBase: string}} The target.
43
+ */
44
+ function normalise(target = {}) {
45
+ return {
46
+ register: String(target.register || ''),
47
+ schema: String(target.schema || ''),
48
+ apiBase: String(target.apiBase || DEFAULT_API_BASE).replace(/\/$/, ''),
49
+ }
50
+ }
51
+
52
+ /**
53
+ * GET one path, keeping the status beside the body.
54
+ *
55
+ * The status is part of the answer: a 403 on the access set means the reader
56
+ * may open the object and may not enumerate who else can, which is not a
57
+ * failed read. A transport failure has no status and reports 0. A non-JSON
58
+ * body (the SPA shell answering 200) is a failed read, not "no rules".
59
+ *
60
+ * @param {string} url App-absolute URL.
61
+ * @param {object} params Query parameters.
62
+ * @return {Promise<{status: number, data: object|null}>} The status and the body.
63
+ */
64
+ async function readResult(url, params = {}) {
65
+ try {
66
+ const response = await axios__default.get(prefixUrl(url), { params });
67
+ if (typeof response?.data !== 'object' || response.data === null) {
68
+ return { status: response?.status || 0, data: null }
69
+ }
70
+ return { status: response.status || 200, data: response.data }
71
+ } catch (error) {
72
+ return { status: error?.response?.status || 0, data: null }
73
+ }
74
+ }
75
+
76
+ /**
77
+ * GET one path, answering null when it cannot be read.
78
+ *
79
+ * @param {string} url App-absolute URL.
80
+ * @param {object} params Query parameters.
81
+ * @return {Promise<object|null>} The body, or null.
82
+ */
83
+ async function read(url, params = {}) {
84
+ const { data } = await readResult(url, params);
85
+ return data
86
+ }
87
+
88
+ /**
89
+ * The URL of one object, under its target.
90
+ *
91
+ * @param {object} target The target.
92
+ * @param {string} objectId The object id.
93
+ * @param {string} [schema] A schema other than the target's.
94
+ * @return {string} The URL.
95
+ */
96
+ function objectUrl(target, objectId, schema) {
97
+ const { register, apiBase } = normalise(target);
98
+ return `${apiBase}/objects/${register}/${schema || normalise(target).schema}/${objectId}`
99
+ }
100
+
101
+ /**
102
+ * The grantable verbs and the deny enforcement mode.
103
+ *
104
+ * @param {object} target The target (only `apiBase` is read).
105
+ * @return {Promise<object|null>} `{permissions, denyEnforcement}`, or null.
106
+ */
107
+ function fetchPermissionCatalogue(target) {
108
+ return read(`${normalise(target).apiBase}/permissions`)
109
+ }
110
+
111
+ /**
112
+ * The grants written on one object.
113
+ *
114
+ * @param {object} target The target.
115
+ * @param {string} objectId The object id.
116
+ * @return {Promise<Array|null>} The grants, or null.
117
+ */
118
+ async function fetchObjectGrants(target, objectId) {
119
+ const body = await read(`${objectUrl(target, objectId)}/shares`);
120
+ if (body === null || !Array.isArray(body.results)) {
121
+ return null
122
+ }
123
+ return body.results
124
+ }
125
+
126
+ /**
127
+ * Each role in the register and the verbs it holds.
128
+ *
129
+ * @param {object} target The target.
130
+ * @return {Promise<object|null>} `{roles}`, or null.
131
+ */
132
+ function fetchRoleGrants(target) {
133
+ const { apiBase, register } = normalise(target);
134
+ return read(`${apiBase}/permissions/compare-roles`, { register })
135
+ }
136
+
137
+ /**
138
+ * The caller's own effective verbs on the schema, with their provenance.
139
+ *
140
+ * The endpoint answers a matrix even when narrowed, so the row is picked by
141
+ * schema name rather than by position.
142
+ *
143
+ * @param {object} target The target.
144
+ * @return {Promise<object|null>} The scope entry, or null.
145
+ */
146
+ async function fetchCallerScope(target) {
147
+ const { apiBase, register, schema } = normalise(target);
148
+ const body = await read(`${apiBase}/scopes`, { register, schema });
149
+ if (body === null || !Array.isArray(body.scopes)) {
150
+ return null
151
+ }
152
+ const scope = body.scopes.find((entry) => entry?.schema === schema);
153
+ if (!scope) {
154
+ return null
155
+ }
156
+ return { user: body.user, isAdmin: body.isAdmin, groups: body.groups, ...scope }
157
+ }
158
+
159
+ /**
160
+ * The deny rules as written for the register and schema.
161
+ *
162
+ * @param {object} target The target.
163
+ * @return {Promise<object|null>} `{denyEnforcement, enforcing, rules}`, or null.
164
+ */
165
+ function fetchDenyRules(target) {
166
+ const { apiBase, register, schema } = normalise(target);
167
+ return read(`${apiBase}/permissions/deny-preview`, { register, schema })
168
+ }
169
+
170
+ /**
171
+ * The permission set OpenRegister publishes for this object, with its status.
172
+ *
173
+ * @param {object} target The target.
174
+ * @param {string} objectId The object id.
175
+ * @return {Promise<{status: number, set: object|null}>} The status and the set.
176
+ */
177
+ async function fetchObjectPermissions(target, objectId) {
178
+ const { status, data } = await readResult(`${objectUrl(target, objectId)}/permissions`);
179
+ if (data === null || Array.isArray(data.holders) === false) {
180
+ return { status, set: null }
181
+ }
182
+ return { status, set: data }
183
+ }
184
+
185
+ /**
186
+ * The set as it stood at a moment, from the object's audit trail.
187
+ *
188
+ * @param {object} target The target.
189
+ * @param {string} objectId The object id.
190
+ * @param {string} at An ISO-8601 moment.
191
+ * @return {Promise<{status: number, history: object|null}>} The status and the history.
192
+ */
193
+ async function fetchAccessHistory(target, objectId, at) {
194
+ const { status, data } = await readResult(`${objectUrl(target, objectId)}/permissions/history`, { at });
195
+ if (data === null || Array.isArray(data.changes) === false) {
196
+ return { status, history: null }
197
+ }
198
+ return { status, history: data }
199
+ }
200
+
201
+ /**
202
+ * The end and the area written on one rule, as OpenRegister reported them.
203
+ *
204
+ * Neither is compared to anything: whether an expired grant still answers is
205
+ * resolved in OpenRegister. A role grant carries the whole holder list, so the
206
+ * entry naming this principal is picked out of it.
207
+ *
208
+ * @param {object|Array|string|null} rule The rule as written.
209
+ * @param {string} principal The holder of the row.
210
+ * @return {{until: string, scopedTo: object|null}} The end and the area.
211
+ */
212
+ function constraintsOf(rule, principal) {
213
+ const none = { until: '', scopedTo: null };
214
+ if (rule === null || typeof rule !== 'object') {
215
+ return none
216
+ }
217
+
218
+ let entry = rule;
219
+ if (Array.isArray(rule)) {
220
+ entry = rule.find((candidate) => candidate === principal
221
+ || (candidate !== null
222
+ && typeof candidate === 'object'
223
+ && [candidate.principal, candidate.group, candidate.role, candidate.user].includes(principal)));
224
+ }
225
+
226
+ if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) {
227
+ return none
228
+ }
229
+
230
+ return {
231
+ until: typeof entry.until === 'string' ? entry.until : '',
232
+ scopedTo: entry.scopedTo || null,
233
+ }
234
+ }
235
+
236
+ /**
237
+ * One reported rule as a row.
238
+ *
239
+ * @param {object} rule The rule.
240
+ * @param {boolean} refusing Whether the rule takes a right away.
241
+ * @param {boolean} enforcing Whether refusals are in force.
242
+ * @return {object} The row.
243
+ */
244
+ function ruleRow(rule, refusing, enforcing) {
245
+ const principal = rule?.principal || '';
246
+ const { until, scopedTo } = constraintsOf(rule?.rule ?? null, principal);
247
+
248
+ let source = rule?.level || 'object';
249
+ if (refusing === true) {
250
+ source = enforcing === true ? 'deny' : 'staged-deny';
251
+ }
252
+
253
+ return {
254
+ holder: principal,
255
+ right: rule?.action || '',
256
+ source,
257
+ detail: rule?.role || '',
258
+ inheritedFrom: rule?.inheritedFrom || '',
259
+ level: rule?.level || '',
260
+ role: rule?.role || '',
261
+ declared: rule?.declared !== false,
262
+ conditional: rule?.conditional === true,
263
+ until,
264
+ scopedTo,
265
+ }
266
+ }
267
+
268
+ /**
269
+ * The object's own permission set as rows. A deny is its own row.
270
+ *
271
+ * @param {object|null} set The set from `fetchObjectPermissions`.
272
+ * @return {Array<object>} The rows.
273
+ */
274
+ function objectPermissionRows(set) {
275
+ if (set === null || typeof set !== 'object') {
276
+ return []
277
+ }
278
+
279
+ const enforcing = set.denyEnforcement === 'enforcing';
280
+ const rows = [];
281
+ for (const holder of set.holders || []) {
282
+ for (const rule of holder?.rules || []) {
283
+ rows.push(ruleRow(rule, false, enforcing));
284
+ }
285
+ }
286
+ for (const rule of set.denied || []) {
287
+ rows.push(ruleRow(rule, true, enforcing));
288
+ }
289
+ return rows
290
+ }
291
+
292
+ /**
293
+ * The set as it stood at the moment asked about.
294
+ *
295
+ * `asOf: null` (the trail does not reach back that far) is "unanswered", never
296
+ * an empty table: an empty table would claim nobody held a right that day.
297
+ *
298
+ * @param {object|null} history The history from `fetchAccessHistory`.
299
+ * @return {{answered: boolean, at: string, rows: Array<object>, setBy: string, changedAfterwardsBy: object|null}} The answer.
300
+ */
301
+ function asOfRows(history) {
302
+ const unanswered = { answered: false, at: history?.at || '', rows: [], setBy: '', changedAfterwardsBy: null };
303
+
304
+ const asOf = history?.asOf || null;
305
+ if (asOf === null || typeof asOf !== 'object') {
306
+ return unanswered
307
+ }
308
+
309
+ const rows = [];
310
+ for (const holder of asOf.holders || []) {
311
+ for (const rule of holder?.rules || []) {
312
+ rows.push(ruleRow(rule, false, false));
313
+ }
314
+ }
315
+
316
+ return {
317
+ answered: true,
318
+ at: asOf.at || history?.at || '',
319
+ rows,
320
+ setBy: asOf.setBy || '',
321
+ changedAfterwardsBy: asOf.changedAfterwardsBy || null,
322
+ }
323
+ }
324
+
325
+ /**
326
+ * All answers as one list of rows. A renderer, not an evaluator: each row
327
+ * restates ONE reported rule, and no row is the product of two.
328
+ *
329
+ * When the object answered for itself the share, role and deny reads are not
330
+ * replayed on top (the same grant would be counted twice). The caller's own
331
+ * verdict always rides along last, because it is the one answer about this
332
+ * reader rather than a rule about everybody.
333
+ *
334
+ * @param {object} answers The reads.
335
+ * @param {object|null} answers.objectPermissions The object's own set.
336
+ * @param {Array|null} answers.objectGrants Grants on the object.
337
+ * @param {object|null} answers.roleGrants Roles and their verbs.
338
+ * @param {object|null} answers.callerScope The caller's own verdict.
339
+ * @param {object|null} answers.denyRules The deny rules.
340
+ * @return {Array<object>} The rows.
341
+ */
342
+ function grantRows({ objectPermissions = null, objectGrants, roleGrants, callerScope, denyRules }) {
343
+ const rows = [];
344
+
345
+ if (objectPermissions !== null) {
346
+ rows.push(...objectPermissionRows(objectPermissions));
347
+ }
348
+
349
+ for (const grant of (objectPermissions === null ? objectGrants : null) || []) {
350
+ for (const right of grant?.actions || []) {
351
+ rows.push({
352
+ holder: grant.principal || grant.userId || grant.groupId || '',
353
+ right,
354
+ // `inheritedFrom` is the id of the ancestor, not a source key.
355
+ source: grant.source || (grant.inheritedFrom ? 'inherited' : 'share'),
356
+ inheritedFrom: grant.inheritedFrom || '',
357
+ detail: grant.expires ? String(grant.expires) : '',
358
+ });
359
+ }
360
+ }
361
+
362
+ for (const role of (objectPermissions === null ? roleGrants?.roles : null) || []) {
363
+ for (const right of role?.actions || []) {
364
+ rows.push({ holder: role.role || '', right, source: 'role', detail: '' });
365
+ }
366
+ }
367
+
368
+ for (const rule of (objectPermissions === null ? denyRules?.rules : null) || []) {
369
+ rows.push({
370
+ holder: rule.principal || '',
371
+ right: rule.action || '',
372
+ source: denyRules.enforcing ? 'deny' : 'staged-deny',
373
+ detail: rule.level ? `${rule.level}: ${rule.subject || ''}` : '',
374
+ });
375
+ }
376
+
377
+ for (const [right, record] of Object.entries(callerScope?.provenance || {})) {
378
+ rows.push({
379
+ holder: callerScope.user || '',
380
+ right,
381
+ source: record?.source || 'unknown',
382
+ granted: record?.granted,
383
+ detail: record?.role || record?.principal || '',
384
+ stagedDeny: record?.stagedDeny || null,
385
+ });
386
+ }
387
+
388
+ return rows
389
+ }
390
+
391
+ /**
392
+ * The id a reference carries, as a uuid string or as an expanded object.
393
+ *
394
+ * @param {unknown} value The reference.
395
+ * @return {string} The id, or ''.
396
+ */
397
+ function referenceId(value) {
398
+ if (value && typeof value === 'object') {
399
+ return String(value['@self']?.id ?? value.id ?? value.uuid ?? '')
400
+ }
401
+ return String(value ?? '')
402
+ }
403
+
404
+ /**
405
+ * The object's decided field rules, and the per-role field rules its TYPE
406
+ * object declares.
407
+ *
408
+ * Two reads, because they answer different questions: `@self.fieldRules` is
409
+ * what OpenRegister decided for THIS reader, the declaration on the type
410
+ * object is the rule behind it. Neither is evaluated here.
411
+ *
412
+ * @param {object} target The target.
413
+ * @param {string} objectId The object id.
414
+ * @param {object} config Where the declaration lives.
415
+ * @param {string} config.typeField Field on the object referencing its type object.
416
+ * @param {string} config.typeSchema Schema of the type object (same register).
417
+ * @param {string} [config.declarationField] Field on the type object holding the rules.
418
+ * @return {Promise<{decided: object|null, declared: Array<object>|null}>} The answer.
419
+ */
420
+ async function fetchFieldRoleRules(target, objectId, config) {
421
+ if (!objectId || !config?.typeField || !config?.typeSchema) {
422
+ return { decided: null, declared: null }
423
+ }
424
+
425
+ const object = await read(objectUrl(target, objectId));
426
+ if (object === null) {
427
+ return { decided: null, declared: null }
428
+ }
429
+
430
+ const decided = object['@self']?.fieldRules ?? null;
431
+ const typeId = referenceId(object[config.typeField]);
432
+ if (!typeId) {
433
+ return { decided, declared: null }
434
+ }
435
+
436
+ const type = await read(objectUrl(target, typeId, config.typeSchema));
437
+ if (type === null) {
438
+ return { decided, declared: null }
439
+ }
440
+
441
+ const declared = type[config.declarationField || 'fieldRoleRules'];
442
+ return { decided, declared: Array.isArray(declared) ? declared : [] }
443
+ }
444
+
445
+ /**
446
+ * The two things a role rule can do to a field. The spelling is OpenRegister's
447
+ * contract (`hidden`, `readOnly`); any other rule is dropped.
448
+ */
449
+ const ROLE_RULES = ['hidden', 'readOnly'];
450
+
451
+ /**
452
+ * The reader's word for each field rule.
453
+ *
454
+ * @return {object} The labels, by rule id.
455
+ */
456
+ function roleRuleLabels() {
457
+ return {
458
+ hidden: translate('nextcloud-vue', 'Not shown'),
459
+ readOnly: translate('nextcloud-vue', 'Cannot be changed'),
460
+ }
461
+ }
462
+
463
+ /**
464
+ * A declared list of names, blanks and repeats removed.
465
+ *
466
+ * @param {unknown} value The list.
467
+ * @return {Array<string>} The names.
468
+ */
469
+ function names(value) {
470
+ if (Array.isArray(value) === false) {
471
+ return []
472
+ }
473
+ const found = [];
474
+ value.forEach((entry) => {
475
+ const name = String(entry ?? '').trim();
476
+ if (name !== '' && found.includes(name) === false) {
477
+ found.push(name);
478
+ }
479
+ });
480
+ return found
481
+ }
482
+
483
+ /**
484
+ * Whether OpenRegister applied this rule to the reader. False when the object
485
+ * carries no decision at all (an older OpenRegister), never invented.
486
+ *
487
+ * @param {string} field The field.
488
+ * @param {string} rule The rule.
489
+ * @param {object|null} decided The object's `@self.fieldRules`.
490
+ * @return {boolean} True when the reader met this rule.
491
+ */
492
+ function appliesToMe(field, rule, decided) {
493
+ const applied = decided?.[rule];
494
+ if (Array.isArray(applied) === false) {
495
+ return false
496
+ }
497
+ return applied.map((name) => String(name)).includes(field)
498
+ }
499
+
500
+ /**
501
+ * The declared field rules as rows. A row naming no field, or an unknown rule,
502
+ * is dropped rather than rendered blank.
503
+ *
504
+ * @param {Array<object>|null} declared The declaration.
505
+ * @param {object|null} decided The object's `@self.fieldRules`.
506
+ * @return {Array<object>} The rows.
507
+ */
508
+ function fieldRoleRows(declared, decided) {
509
+ if (Array.isArray(declared) === false) {
510
+ return []
511
+ }
512
+
513
+ return declared
514
+ .filter((rule) => rule && ROLE_RULES.includes(rule.rule) && typeof rule.field === 'string' && rule.field.trim() !== '')
515
+ .map((rule) => {
516
+ const field = rule.field.trim();
517
+ return {
518
+ field,
519
+ rule: rule.rule,
520
+ groups: names(rule.groups),
521
+ heldBy: names(rule.heldBy),
522
+ reason: String(rule.reason ?? '').trim(),
523
+ appliesToMe: appliesToMe(field, rule.rule, decided),
524
+ }
525
+ })
526
+ }
527
+
528
+ /**
529
+ * One field-rule row as a whole sentence (whole sentences, so a translator can
530
+ * reorder the groups).
531
+ *
532
+ * @param {object} row One row from `fieldRoleRows`.
533
+ * @return {string} The sentence.
534
+ */
535
+ function roleRuleSentence(row) {
536
+ const groups = row?.groups?.join(', ') ?? '';
537
+ const heldBy = row?.heldBy?.join(', ') ?? '';
538
+
539
+ if (row?.rule === 'hidden' && heldBy !== '') {
540
+ return translate('nextcloud-vue', '{groups} do not see this field. {heldBy} do.', { groups, heldBy })
541
+ }
542
+ if (row?.rule === 'hidden') {
543
+ return translate('nextcloud-vue', '{groups} do not see this field.', { groups })
544
+ }
545
+ if (heldBy !== '') {
546
+ return translate('nextcloud-vue', '{groups} cannot change this field. {heldBy} can.', { groups, heldBy })
547
+ }
548
+ return translate('nextcloud-vue', '{groups} cannot change this field.', { groups })
549
+ }
550
+
551
+ export { DEFAULT_API_BASE, ROLE_RULES, asOfRows, constraintsOf, fetchAccessHistory, fetchCallerScope, fetchDenyRules, fetchFieldRoleRules, fetchObjectGrants, fetchObjectPermissions, fetchPermissionCatalogue, fetchRoleGrants, fieldRoleRows, grantRows, objectPermissionRows, roleRuleLabels, roleRuleSentence };
552
+ //# sourceMappingURL=objectPermissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objectPermissions.js","sources":["../../../src/utils/objectPermissions.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Who holds which right on one OpenRegister object, and where each grant came\n * from. The reads behind CnObjectPermissionsTab.\n *\n * Every function here is a read. Nothing decides who may open an object: the\n * grant, its provenance, the deny and the inheritance live in OpenRegister, and\n * these helpers hand on what it answered. A deny is never subtracted from a\n * grant, a missing answer is never filled with a default, and nothing is\n * cached: a copy of an access decision is a second decision nobody updates.\n *\n * The object's own permission set (`/permissions`) is preferred; an older\n * OpenRegister answers 404 to it, and then five reads are the fallback:\n *\n * GET {apiBase}/permissions the verb catalogue + deny mode\n * GET {apiBase}/objects/{register}/{schema}/{id}/shares grants written on the object\n * GET {apiBase}/permissions/compare-roles?register= each role and its verbs\n * GET {apiBase}/scopes?register=&schema= the caller's own verdict + provenance\n * GET {apiBase}/permissions/deny-preview?register=&schema= the deny rules as written\n *\n * plus the history read `{...}/{id}/permissions/history?at=` for \"who held a\n * right on a date\".\n *\n * A failed read answers `null`, never `[]`: \"we could not ask\" and \"nobody\n * holds this\" are opposite answers that would otherwise render as the same\n * empty table.\n */\nimport axios from '@nextcloud/axios'\nimport { translate as t } from '@nextcloud/l10n'\nimport { prefixUrl } from './headers.js'\n\n/** The OpenRegister API root a target defaults to. */\nexport const DEFAULT_API_BASE = '/apps/openregister/api'\n\n/**\n * Normalise a target to `{register, schema, apiBase}`.\n *\n * @param {object} target The object's register, schema and optional apiBase.\n * @return {{register: string, schema: string, apiBase: string}} The target.\n */\nfunction normalise(target = {}) {\n\treturn {\n\t\tregister: String(target.register || ''),\n\t\tschema: String(target.schema || ''),\n\t\tapiBase: String(target.apiBase || DEFAULT_API_BASE).replace(/\\/$/, ''),\n\t}\n}\n\n/**\n * GET one path, keeping the status beside the body.\n *\n * The status is part of the answer: a 403 on the access set means the reader\n * may open the object and may not enumerate who else can, which is not a\n * failed read. A transport failure has no status and reports 0. A non-JSON\n * body (the SPA shell answering 200) is a failed read, not \"no rules\".\n *\n * @param {string} url App-absolute URL.\n * @param {object} params Query parameters.\n * @return {Promise<{status: number, data: object|null}>} The status and the body.\n */\nasync function readResult(url, params = {}) {\n\ttry {\n\t\tconst response = await axios.get(prefixUrl(url), { params })\n\t\tif (typeof response?.data !== 'object' || response.data === null) {\n\t\t\treturn { status: response?.status || 0, data: null }\n\t\t}\n\t\treturn { status: response.status || 200, data: response.data }\n\t} catch (error) {\n\t\treturn { status: error?.response?.status || 0, data: null }\n\t}\n}\n\n/**\n * GET one path, answering null when it cannot be read.\n *\n * @param {string} url App-absolute URL.\n * @param {object} params Query parameters.\n * @return {Promise<object|null>} The body, or null.\n */\nasync function read(url, params = {}) {\n\tconst { data } = await readResult(url, params)\n\treturn data\n}\n\n/**\n * The URL of one object, under its target.\n *\n * @param {object} target The target.\n * @param {string} objectId The object id.\n * @param {string} [schema] A schema other than the target's.\n * @return {string} The URL.\n */\nfunction objectUrl(target, objectId, schema) {\n\tconst { register, apiBase } = normalise(target)\n\treturn `${apiBase}/objects/${register}/${schema || normalise(target).schema}/${objectId}`\n}\n\n/**\n * The grantable verbs and the deny enforcement mode.\n *\n * @param {object} target The target (only `apiBase` is read).\n * @return {Promise<object|null>} `{permissions, denyEnforcement}`, or null.\n */\nexport function fetchPermissionCatalogue(target) {\n\treturn read(`${normalise(target).apiBase}/permissions`)\n}\n\n/**\n * The grants written on one object.\n *\n * @param {object} target The target.\n * @param {string} objectId The object id.\n * @return {Promise<Array|null>} The grants, or null.\n */\nexport async function fetchObjectGrants(target, objectId) {\n\tconst body = await read(`${objectUrl(target, objectId)}/shares`)\n\tif (body === null || !Array.isArray(body.results)) {\n\t\treturn null\n\t}\n\treturn body.results\n}\n\n/**\n * Each role in the register and the verbs it holds.\n *\n * @param {object} target The target.\n * @return {Promise<object|null>} `{roles}`, or null.\n */\nexport function fetchRoleGrants(target) {\n\tconst { apiBase, register } = normalise(target)\n\treturn read(`${apiBase}/permissions/compare-roles`, { register })\n}\n\n/**\n * The caller's own effective verbs on the schema, with their provenance.\n *\n * The endpoint answers a matrix even when narrowed, so the row is picked by\n * schema name rather than by position.\n *\n * @param {object} target The target.\n * @return {Promise<object|null>} The scope entry, or null.\n */\nexport async function fetchCallerScope(target) {\n\tconst { apiBase, register, schema } = normalise(target)\n\tconst body = await read(`${apiBase}/scopes`, { register, schema })\n\tif (body === null || !Array.isArray(body.scopes)) {\n\t\treturn null\n\t}\n\tconst scope = body.scopes.find((entry) => entry?.schema === schema)\n\tif (!scope) {\n\t\treturn null\n\t}\n\treturn { user: body.user, isAdmin: body.isAdmin, groups: body.groups, ...scope }\n}\n\n/**\n * The deny rules as written for the register and schema.\n *\n * @param {object} target The target.\n * @return {Promise<object|null>} `{denyEnforcement, enforcing, rules}`, or null.\n */\nexport function fetchDenyRules(target) {\n\tconst { apiBase, register, schema } = normalise(target)\n\treturn read(`${apiBase}/permissions/deny-preview`, { register, schema })\n}\n\n/**\n * The permission set OpenRegister publishes for this object, with its status.\n *\n * @param {object} target The target.\n * @param {string} objectId The object id.\n * @return {Promise<{status: number, set: object|null}>} The status and the set.\n */\nexport async function fetchObjectPermissions(target, objectId) {\n\tconst { status, data } = await readResult(`${objectUrl(target, objectId)}/permissions`)\n\tif (data === null || Array.isArray(data.holders) === false) {\n\t\treturn { status, set: null }\n\t}\n\treturn { status, set: data }\n}\n\n/**\n * The set as it stood at a moment, from the object's audit trail.\n *\n * @param {object} target The target.\n * @param {string} objectId The object id.\n * @param {string} at An ISO-8601 moment.\n * @return {Promise<{status: number, history: object|null}>} The status and the history.\n */\nexport async function fetchAccessHistory(target, objectId, at) {\n\tconst { status, data } = await readResult(`${objectUrl(target, objectId)}/permissions/history`, { at })\n\tif (data === null || Array.isArray(data.changes) === false) {\n\t\treturn { status, history: null }\n\t}\n\treturn { status, history: data }\n}\n\n/**\n * The end and the area written on one rule, as OpenRegister reported them.\n *\n * Neither is compared to anything: whether an expired grant still answers is\n * resolved in OpenRegister. A role grant carries the whole holder list, so the\n * entry naming this principal is picked out of it.\n *\n * @param {object|Array|string|null} rule The rule as written.\n * @param {string} principal The holder of the row.\n * @return {{until: string, scopedTo: object|null}} The end and the area.\n */\nexport function constraintsOf(rule, principal) {\n\tconst none = { until: '', scopedTo: null }\n\tif (rule === null || typeof rule !== 'object') {\n\t\treturn none\n\t}\n\n\tlet entry = rule\n\tif (Array.isArray(rule)) {\n\t\tentry = rule.find((candidate) => candidate === principal\n\t\t\t|| (candidate !== null\n\t\t\t\t&& typeof candidate === 'object'\n\t\t\t\t&& [candidate.principal, candidate.group, candidate.role, candidate.user].includes(principal)))\n\t}\n\n\tif (entry === null || typeof entry !== 'object' || Array.isArray(entry)) {\n\t\treturn none\n\t}\n\n\treturn {\n\t\tuntil: typeof entry.until === 'string' ? entry.until : '',\n\t\tscopedTo: entry.scopedTo || null,\n\t}\n}\n\n/**\n * One reported rule as a row.\n *\n * @param {object} rule The rule.\n * @param {boolean} refusing Whether the rule takes a right away.\n * @param {boolean} enforcing Whether refusals are in force.\n * @return {object} The row.\n */\nfunction ruleRow(rule, refusing, enforcing) {\n\tconst principal = rule?.principal || ''\n\tconst { until, scopedTo } = constraintsOf(rule?.rule ?? null, principal)\n\n\tlet source = rule?.level || 'object'\n\tif (refusing === true) {\n\t\tsource = enforcing === true ? 'deny' : 'staged-deny'\n\t}\n\n\treturn {\n\t\tholder: principal,\n\t\tright: rule?.action || '',\n\t\tsource,\n\t\tdetail: rule?.role || '',\n\t\tinheritedFrom: rule?.inheritedFrom || '',\n\t\tlevel: rule?.level || '',\n\t\trole: rule?.role || '',\n\t\tdeclared: rule?.declared !== false,\n\t\tconditional: rule?.conditional === true,\n\t\tuntil,\n\t\tscopedTo,\n\t}\n}\n\n/**\n * The object's own permission set as rows. A deny is its own row.\n *\n * @param {object|null} set The set from `fetchObjectPermissions`.\n * @return {Array<object>} The rows.\n */\nexport function objectPermissionRows(set) {\n\tif (set === null || typeof set !== 'object') {\n\t\treturn []\n\t}\n\n\tconst enforcing = set.denyEnforcement === 'enforcing'\n\tconst rows = []\n\tfor (const holder of set.holders || []) {\n\t\tfor (const rule of holder?.rules || []) {\n\t\t\trows.push(ruleRow(rule, false, enforcing))\n\t\t}\n\t}\n\tfor (const rule of set.denied || []) {\n\t\trows.push(ruleRow(rule, true, enforcing))\n\t}\n\treturn rows\n}\n\n/**\n * The set as it stood at the moment asked about.\n *\n * `asOf: null` (the trail does not reach back that far) is \"unanswered\", never\n * an empty table: an empty table would claim nobody held a right that day.\n *\n * @param {object|null} history The history from `fetchAccessHistory`.\n * @return {{answered: boolean, at: string, rows: Array<object>, setBy: string, changedAfterwardsBy: object|null}} The answer.\n */\nexport function asOfRows(history) {\n\tconst unanswered = { answered: false, at: history?.at || '', rows: [], setBy: '', changedAfterwardsBy: null }\n\n\tconst asOf = history?.asOf || null\n\tif (asOf === null || typeof asOf !== 'object') {\n\t\treturn unanswered\n\t}\n\n\tconst rows = []\n\tfor (const holder of asOf.holders || []) {\n\t\tfor (const rule of holder?.rules || []) {\n\t\t\trows.push(ruleRow(rule, false, false))\n\t\t}\n\t}\n\n\treturn {\n\t\tanswered: true,\n\t\tat: asOf.at || history?.at || '',\n\t\trows,\n\t\tsetBy: asOf.setBy || '',\n\t\tchangedAfterwardsBy: asOf.changedAfterwardsBy || null,\n\t}\n}\n\n/**\n * All answers as one list of rows. A renderer, not an evaluator: each row\n * restates ONE reported rule, and no row is the product of two.\n *\n * When the object answered for itself the share, role and deny reads are not\n * replayed on top (the same grant would be counted twice). The caller's own\n * verdict always rides along last, because it is the one answer about this\n * reader rather than a rule about everybody.\n *\n * @param {object} answers The reads.\n * @param {object|null} answers.objectPermissions The object's own set.\n * @param {Array|null} answers.objectGrants Grants on the object.\n * @param {object|null} answers.roleGrants Roles and their verbs.\n * @param {object|null} answers.callerScope The caller's own verdict.\n * @param {object|null} answers.denyRules The deny rules.\n * @return {Array<object>} The rows.\n */\nexport function grantRows({ objectPermissions = null, objectGrants, roleGrants, callerScope, denyRules }) {\n\tconst rows = []\n\n\tif (objectPermissions !== null) {\n\t\trows.push(...objectPermissionRows(objectPermissions))\n\t}\n\n\tfor (const grant of (objectPermissions === null ? objectGrants : null) || []) {\n\t\tfor (const right of grant?.actions || []) {\n\t\t\trows.push({\n\t\t\t\tholder: grant.principal || grant.userId || grant.groupId || '',\n\t\t\t\tright,\n\t\t\t\t// `inheritedFrom` is the id of the ancestor, not a source key.\n\t\t\t\tsource: grant.source || (grant.inheritedFrom ? 'inherited' : 'share'),\n\t\t\t\tinheritedFrom: grant.inheritedFrom || '',\n\t\t\t\tdetail: grant.expires ? String(grant.expires) : '',\n\t\t\t})\n\t\t}\n\t}\n\n\tfor (const role of (objectPermissions === null ? roleGrants?.roles : null) || []) {\n\t\tfor (const right of role?.actions || []) {\n\t\t\trows.push({ holder: role.role || '', right, source: 'role', detail: '' })\n\t\t}\n\t}\n\n\tfor (const rule of (objectPermissions === null ? denyRules?.rules : null) || []) {\n\t\trows.push({\n\t\t\tholder: rule.principal || '',\n\t\t\tright: rule.action || '',\n\t\t\tsource: denyRules.enforcing ? 'deny' : 'staged-deny',\n\t\t\tdetail: rule.level ? `${rule.level}: ${rule.subject || ''}` : '',\n\t\t})\n\t}\n\n\tfor (const [right, record] of Object.entries(callerScope?.provenance || {})) {\n\t\trows.push({\n\t\t\tholder: callerScope.user || '',\n\t\t\tright,\n\t\t\tsource: record?.source || 'unknown',\n\t\t\tgranted: record?.granted,\n\t\t\tdetail: record?.role || record?.principal || '',\n\t\t\tstagedDeny: record?.stagedDeny || null,\n\t\t})\n\t}\n\n\treturn rows\n}\n\n/**\n * The id a reference carries, as a uuid string or as an expanded object.\n *\n * @param {unknown} value The reference.\n * @return {string} The id, or ''.\n */\nfunction referenceId(value) {\n\tif (value && typeof value === 'object') {\n\t\treturn String(value['@self']?.id ?? value.id ?? value.uuid ?? '')\n\t}\n\treturn String(value ?? '')\n}\n\n/**\n * The object's decided field rules, and the per-role field rules its TYPE\n * object declares.\n *\n * Two reads, because they answer different questions: `@self.fieldRules` is\n * what OpenRegister decided for THIS reader, the declaration on the type\n * object is the rule behind it. Neither is evaluated here.\n *\n * @param {object} target The target.\n * @param {string} objectId The object id.\n * @param {object} config Where the declaration lives.\n * @param {string} config.typeField Field on the object referencing its type object.\n * @param {string} config.typeSchema Schema of the type object (same register).\n * @param {string} [config.declarationField] Field on the type object holding the rules.\n * @return {Promise<{decided: object|null, declared: Array<object>|null}>} The answer.\n */\nexport async function fetchFieldRoleRules(target, objectId, config) {\n\tif (!objectId || !config?.typeField || !config?.typeSchema) {\n\t\treturn { decided: null, declared: null }\n\t}\n\n\tconst object = await read(objectUrl(target, objectId))\n\tif (object === null) {\n\t\treturn { decided: null, declared: null }\n\t}\n\n\tconst decided = object['@self']?.fieldRules ?? null\n\tconst typeId = referenceId(object[config.typeField])\n\tif (!typeId) {\n\t\treturn { decided, declared: null }\n\t}\n\n\tconst type = await read(objectUrl(target, typeId, config.typeSchema))\n\tif (type === null) {\n\t\treturn { decided, declared: null }\n\t}\n\n\tconst declared = type[config.declarationField || 'fieldRoleRules']\n\treturn { decided, declared: Array.isArray(declared) ? declared : [] }\n}\n\n/**\n * The two things a role rule can do to a field. The spelling is OpenRegister's\n * contract (`hidden`, `readOnly`); any other rule is dropped.\n */\nexport const ROLE_RULES = ['hidden', 'readOnly']\n\n/**\n * The reader's word for each field rule.\n *\n * @return {object} The labels, by rule id.\n */\nexport function roleRuleLabels() {\n\treturn {\n\t\thidden: t('nextcloud-vue', 'Not shown'),\n\t\treadOnly: t('nextcloud-vue', 'Cannot be changed'),\n\t}\n}\n\n/**\n * A declared list of names, blanks and repeats removed.\n *\n * @param {unknown} value The list.\n * @return {Array<string>} The names.\n */\nfunction names(value) {\n\tif (Array.isArray(value) === false) {\n\t\treturn []\n\t}\n\tconst found = []\n\tvalue.forEach((entry) => {\n\t\tconst name = String(entry ?? '').trim()\n\t\tif (name !== '' && found.includes(name) === false) {\n\t\t\tfound.push(name)\n\t\t}\n\t})\n\treturn found\n}\n\n/**\n * Whether OpenRegister applied this rule to the reader. False when the object\n * carries no decision at all (an older OpenRegister), never invented.\n *\n * @param {string} field The field.\n * @param {string} rule The rule.\n * @param {object|null} decided The object's `@self.fieldRules`.\n * @return {boolean} True when the reader met this rule.\n */\nfunction appliesToMe(field, rule, decided) {\n\tconst applied = decided?.[rule]\n\tif (Array.isArray(applied) === false) {\n\t\treturn false\n\t}\n\treturn applied.map((name) => String(name)).includes(field)\n}\n\n/**\n * The declared field rules as rows. A row naming no field, or an unknown rule,\n * is dropped rather than rendered blank.\n *\n * @param {Array<object>|null} declared The declaration.\n * @param {object|null} decided The object's `@self.fieldRules`.\n * @return {Array<object>} The rows.\n */\nexport function fieldRoleRows(declared, decided) {\n\tif (Array.isArray(declared) === false) {\n\t\treturn []\n\t}\n\n\treturn declared\n\t\t.filter((rule) => rule && ROLE_RULES.includes(rule.rule) && typeof rule.field === 'string' && rule.field.trim() !== '')\n\t\t.map((rule) => {\n\t\t\tconst field = rule.field.trim()\n\t\t\treturn {\n\t\t\t\tfield,\n\t\t\t\trule: rule.rule,\n\t\t\t\tgroups: names(rule.groups),\n\t\t\t\theldBy: names(rule.heldBy),\n\t\t\t\treason: String(rule.reason ?? '').trim(),\n\t\t\t\tappliesToMe: appliesToMe(field, rule.rule, decided),\n\t\t\t}\n\t\t})\n}\n\n/**\n * One field-rule row as a whole sentence (whole sentences, so a translator can\n * reorder the groups).\n *\n * @param {object} row One row from `fieldRoleRows`.\n * @return {string} The sentence.\n */\nexport function roleRuleSentence(row) {\n\tconst groups = row?.groups?.join(', ') ?? ''\n\tconst heldBy = row?.heldBy?.join(', ') ?? ''\n\n\tif (row?.rule === 'hidden' && heldBy !== '') {\n\t\treturn t('nextcloud-vue', '{groups} do not see this field. {heldBy} do.', { groups, heldBy })\n\t}\n\tif (row?.rule === 'hidden') {\n\t\treturn t('nextcloud-vue', '{groups} do not see this field.', { groups })\n\t}\n\tif (heldBy !== '') {\n\t\treturn t('nextcloud-vue', '{groups} cannot change this field. {heldBy} can.', { groups, heldBy })\n\t}\n\treturn t('nextcloud-vue', '{groups} cannot change this field.', { groups })\n}\n"],"names":["axios","t"],"mappings":"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"}