@objectstack/plugin-security 7.3.0 → 7.4.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/dist/index.d.mts +192 -319
- package/dist/index.d.ts +192 -319
- package/dist/index.js +1932 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1934 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,891 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/translations/en.objects.generated.ts
|
|
12
|
+
var enObjects;
|
|
13
|
+
var init_en_objects_generated = __esm({
|
|
14
|
+
"src/translations/en.objects.generated.ts"() {
|
|
15
|
+
"use strict";
|
|
16
|
+
enObjects = {
|
|
17
|
+
sys_role: {
|
|
18
|
+
label: "Role",
|
|
19
|
+
pluralLabel: "Roles",
|
|
20
|
+
description: "Role definitions for RBAC access control",
|
|
21
|
+
fields: {
|
|
22
|
+
label: {
|
|
23
|
+
label: "Display Name"
|
|
24
|
+
},
|
|
25
|
+
name: {
|
|
26
|
+
label: "API Name",
|
|
27
|
+
help: "Unique machine name for the role (e.g. admin, editor, viewer)"
|
|
28
|
+
},
|
|
29
|
+
description: {
|
|
30
|
+
label: "Description"
|
|
31
|
+
},
|
|
32
|
+
permissions: {
|
|
33
|
+
label: "Permissions",
|
|
34
|
+
help: "JSON-serialized array of permission strings"
|
|
35
|
+
},
|
|
36
|
+
active: {
|
|
37
|
+
label: "Active"
|
|
38
|
+
},
|
|
39
|
+
is_default: {
|
|
40
|
+
label: "Default Role",
|
|
41
|
+
help: "Automatically assigned to new users"
|
|
42
|
+
},
|
|
43
|
+
id: {
|
|
44
|
+
label: "Role ID"
|
|
45
|
+
},
|
|
46
|
+
created_at: {
|
|
47
|
+
label: "Created At"
|
|
48
|
+
},
|
|
49
|
+
updated_at: {
|
|
50
|
+
label: "Updated At"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
_views: {
|
|
54
|
+
active: {
|
|
55
|
+
label: "Active"
|
|
56
|
+
},
|
|
57
|
+
default_roles: {
|
|
58
|
+
label: "Default"
|
|
59
|
+
},
|
|
60
|
+
custom: {
|
|
61
|
+
label: "Custom"
|
|
62
|
+
},
|
|
63
|
+
all_roles: {
|
|
64
|
+
label: "All"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
_actions: {
|
|
68
|
+
activate_role: {
|
|
69
|
+
label: "Activate Role",
|
|
70
|
+
successMessage: "Role activated"
|
|
71
|
+
},
|
|
72
|
+
deactivate_role: {
|
|
73
|
+
label: "Deactivate Role",
|
|
74
|
+
confirmText: "Deactivate this role? Users with the role keep their assignment but the role stops granting permissions until re-activated.",
|
|
75
|
+
successMessage: "Role deactivated"
|
|
76
|
+
},
|
|
77
|
+
set_default_role: {
|
|
78
|
+
label: "Set as Default",
|
|
79
|
+
confirmText: "Make this the default role for new users? Existing users are unaffected.",
|
|
80
|
+
successMessage: "Default role updated"
|
|
81
|
+
},
|
|
82
|
+
clone_role: {
|
|
83
|
+
label: "Clone Role",
|
|
84
|
+
successMessage: "Role cloned"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
sys_permission_set: {
|
|
89
|
+
label: "Permission Set",
|
|
90
|
+
pluralLabel: "Permission Sets",
|
|
91
|
+
description: "Named permission groupings for fine-grained access control",
|
|
92
|
+
fields: {
|
|
93
|
+
label: {
|
|
94
|
+
label: "Display Name"
|
|
95
|
+
},
|
|
96
|
+
name: {
|
|
97
|
+
label: "API Name",
|
|
98
|
+
help: "Unique machine name for the permission set"
|
|
99
|
+
},
|
|
100
|
+
description: {
|
|
101
|
+
label: "Description"
|
|
102
|
+
},
|
|
103
|
+
object_permissions: {
|
|
104
|
+
label: "Object Permissions",
|
|
105
|
+
help: "JSON-serialized object-level CRUD permissions"
|
|
106
|
+
},
|
|
107
|
+
field_permissions: {
|
|
108
|
+
label: "Field Permissions",
|
|
109
|
+
help: "JSON-serialized field-level read/write permissions"
|
|
110
|
+
},
|
|
111
|
+
system_permissions: {
|
|
112
|
+
label: "System Permissions",
|
|
113
|
+
help: 'JSON-serialized array of system capability names (e.g. ["setup.access","studio.access","manage_users"])'
|
|
114
|
+
},
|
|
115
|
+
row_level_security: {
|
|
116
|
+
label: "Row-Level Security",
|
|
117
|
+
help: "JSON-serialized array of row-level security policies (USING/CHECK clauses)"
|
|
118
|
+
},
|
|
119
|
+
tab_permissions: {
|
|
120
|
+
label: "Tab Permissions",
|
|
121
|
+
help: "JSON-serialized map of app tab visibility (visible | hidden | default_on | default_off)"
|
|
122
|
+
},
|
|
123
|
+
active: {
|
|
124
|
+
label: "Active"
|
|
125
|
+
},
|
|
126
|
+
id: {
|
|
127
|
+
label: "Permission Set ID"
|
|
128
|
+
},
|
|
129
|
+
created_at: {
|
|
130
|
+
label: "Created At"
|
|
131
|
+
},
|
|
132
|
+
updated_at: {
|
|
133
|
+
label: "Updated At"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
_views: {
|
|
137
|
+
active: {
|
|
138
|
+
label: "Active"
|
|
139
|
+
},
|
|
140
|
+
inactive: {
|
|
141
|
+
label: "Inactive"
|
|
142
|
+
},
|
|
143
|
+
all_permsets: {
|
|
144
|
+
label: "All"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
_actions: {
|
|
148
|
+
activate_permission_set: {
|
|
149
|
+
label: "Activate",
|
|
150
|
+
successMessage: "Permission set activated"
|
|
151
|
+
},
|
|
152
|
+
deactivate_permission_set: {
|
|
153
|
+
label: "Deactivate",
|
|
154
|
+
confirmText: "Deactivate this permission set? Existing assignments stay in place but stop granting access until re-activated.",
|
|
155
|
+
successMessage: "Permission set deactivated"
|
|
156
|
+
},
|
|
157
|
+
clone_permission_set: {
|
|
158
|
+
label: "Clone",
|
|
159
|
+
successMessage: "Permission set cloned"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
sys_user_permission_set: {
|
|
164
|
+
label: "User Permission Set",
|
|
165
|
+
pluralLabel: "User Permission Sets",
|
|
166
|
+
description: "Direct assignment of a permission set to a user (optionally scoped to an organization).",
|
|
167
|
+
fields: {
|
|
168
|
+
id: {
|
|
169
|
+
label: "Assignment ID",
|
|
170
|
+
help: "UUID of the assignment."
|
|
171
|
+
},
|
|
172
|
+
user_id: {
|
|
173
|
+
label: "User",
|
|
174
|
+
help: "Foreign key to sys_user."
|
|
175
|
+
},
|
|
176
|
+
permission_set_id: {
|
|
177
|
+
label: "Permission Set",
|
|
178
|
+
help: "Foreign key to sys_permission_set."
|
|
179
|
+
},
|
|
180
|
+
organization_id: {
|
|
181
|
+
label: "Organization",
|
|
182
|
+
help: "Optional organization scope. NULL = applies in every org context."
|
|
183
|
+
},
|
|
184
|
+
granted_by: {
|
|
185
|
+
label: "Granted By",
|
|
186
|
+
help: "User who granted this permission set."
|
|
187
|
+
},
|
|
188
|
+
created_at: {
|
|
189
|
+
label: "Created At"
|
|
190
|
+
},
|
|
191
|
+
updated_at: {
|
|
192
|
+
label: "Updated At"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
sys_role_permission_set: {
|
|
197
|
+
label: "Role Permission Set",
|
|
198
|
+
pluralLabel: "Role Permission Sets",
|
|
199
|
+
description: "Binds a permission set to a role.",
|
|
200
|
+
fields: {
|
|
201
|
+
id: {
|
|
202
|
+
label: "Binding ID",
|
|
203
|
+
help: "UUID of the role-permission-set binding."
|
|
204
|
+
},
|
|
205
|
+
role_id: {
|
|
206
|
+
label: "Role",
|
|
207
|
+
help: "Foreign key to sys_role."
|
|
208
|
+
},
|
|
209
|
+
permission_set_id: {
|
|
210
|
+
label: "Permission Set",
|
|
211
|
+
help: "Foreign key to sys_permission_set."
|
|
212
|
+
},
|
|
213
|
+
created_at: {
|
|
214
|
+
label: "Created At"
|
|
215
|
+
},
|
|
216
|
+
updated_at: {
|
|
217
|
+
label: "Updated At"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// src/translations/zh-CN.objects.generated.ts
|
|
226
|
+
var zhCNObjects;
|
|
227
|
+
var init_zh_CN_objects_generated = __esm({
|
|
228
|
+
"src/translations/zh-CN.objects.generated.ts"() {
|
|
229
|
+
"use strict";
|
|
230
|
+
zhCNObjects = {
|
|
231
|
+
sys_role: {
|
|
232
|
+
label: "\u89D2\u8272",
|
|
233
|
+
pluralLabel: "\u89D2\u8272",
|
|
234
|
+
description: "\u7528\u4E8E RBAC \u8BBF\u95EE\u63A7\u5236\u7684\u89D2\u8272\u5B9A\u4E49",
|
|
235
|
+
fields: {
|
|
236
|
+
label: {
|
|
237
|
+
label: "\u663E\u793A\u540D\u79F0"
|
|
238
|
+
},
|
|
239
|
+
name: {
|
|
240
|
+
label: "API \u540D\u79F0",
|
|
241
|
+
help: "\u89D2\u8272\u7684\u552F\u4E00\u673A\u5668\u540D\u79F0\uFF08\u4F8B\u5982 admin\u3001editor\u3001viewer\uFF09"
|
|
242
|
+
},
|
|
243
|
+
description: {
|
|
244
|
+
label: "\u63CF\u8FF0"
|
|
245
|
+
},
|
|
246
|
+
permissions: {
|
|
247
|
+
label: "\u6743\u9650",
|
|
248
|
+
help: "\u6743\u9650\u5B57\u7B26\u4E32\u6570\u7EC4\u7684 JSON \u5E8F\u5217\u5316\u5185\u5BB9"
|
|
249
|
+
},
|
|
250
|
+
active: {
|
|
251
|
+
label: "\u542F\u7528"
|
|
252
|
+
},
|
|
253
|
+
is_default: {
|
|
254
|
+
label: "\u9ED8\u8BA4\u89D2\u8272",
|
|
255
|
+
help: "\u81EA\u52A8\u5206\u914D\u7ED9\u65B0\u7528\u6237"
|
|
256
|
+
},
|
|
257
|
+
id: {
|
|
258
|
+
label: "\u89D2\u8272 ID"
|
|
259
|
+
},
|
|
260
|
+
created_at: {
|
|
261
|
+
label: "\u521B\u5EFA\u65F6\u95F4"
|
|
262
|
+
},
|
|
263
|
+
updated_at: {
|
|
264
|
+
label: "\u66F4\u65B0\u65F6\u95F4"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
_views: {
|
|
268
|
+
active: {
|
|
269
|
+
label: "\u542F\u7528"
|
|
270
|
+
},
|
|
271
|
+
default_roles: {
|
|
272
|
+
label: "\u9ED8\u8BA4"
|
|
273
|
+
},
|
|
274
|
+
custom: {
|
|
275
|
+
label: "\u81EA\u5B9A\u4E49"
|
|
276
|
+
},
|
|
277
|
+
all_roles: {
|
|
278
|
+
label: "\u5168\u90E8"
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
_actions: {
|
|
282
|
+
activate_role: {
|
|
283
|
+
label: "\u6FC0\u6D3B\u89D2\u8272",
|
|
284
|
+
successMessage: "\u89D2\u8272\u5DF2\u6FC0\u6D3B"
|
|
285
|
+
},
|
|
286
|
+
deactivate_role: {
|
|
287
|
+
label: "\u505C\u7528\u89D2\u8272",
|
|
288
|
+
confirmText: "\u786E\u5B9A\u8981\u505C\u7528\u6B64\u89D2\u8272\u5417\uFF1F\u62E5\u6709\u8BE5\u89D2\u8272\u7684\u7528\u6237\u4ECD\u4FDD\u7559\u5176\u5206\u914D\uFF0C\u4F46\u5728\u91CD\u65B0\u6FC0\u6D3B\u4E4B\u524D\u8BE5\u89D2\u8272\u5C06\u4E0D\u518D\u6388\u4E88\u6743\u9650\u3002",
|
|
289
|
+
successMessage: "\u89D2\u8272\u5DF2\u505C\u7528"
|
|
290
|
+
},
|
|
291
|
+
set_default_role: {
|
|
292
|
+
label: "\u8BBE\u4E3A\u9ED8\u8BA4",
|
|
293
|
+
confirmText: "\u5C06\u6B64\u89D2\u8272\u8BBE\u4E3A\u65B0\u7528\u6237\u7684\u9ED8\u8BA4\u89D2\u8272\u5417\uFF1F\u73B0\u6709\u7528\u6237\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
294
|
+
successMessage: "\u5DF2\u66F4\u65B0\u9ED8\u8BA4\u89D2\u8272"
|
|
295
|
+
},
|
|
296
|
+
clone_role: {
|
|
297
|
+
label: "\u514B\u9686\u89D2\u8272",
|
|
298
|
+
successMessage: "\u5DF2\u514B\u9686\u89D2\u8272"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
sys_permission_set: {
|
|
303
|
+
label: "\u6743\u9650\u96C6",
|
|
304
|
+
pluralLabel: "\u6743\u9650\u96C6",
|
|
305
|
+
description: "\u7528\u4E8E\u7CBE\u7EC6\u5316\u8BBF\u95EE\u63A7\u5236\u7684\u547D\u540D\u6743\u9650\u5206\u7EC4",
|
|
306
|
+
fields: {
|
|
307
|
+
label: {
|
|
308
|
+
label: "\u663E\u793A\u540D\u79F0"
|
|
309
|
+
},
|
|
310
|
+
name: {
|
|
311
|
+
label: "API \u540D\u79F0",
|
|
312
|
+
help: "\u6743\u9650\u96C6\u7684\u552F\u4E00\u673A\u5668\u540D\u79F0"
|
|
313
|
+
},
|
|
314
|
+
description: {
|
|
315
|
+
label: "\u63CF\u8FF0"
|
|
316
|
+
},
|
|
317
|
+
object_permissions: {
|
|
318
|
+
label: "\u5BF9\u8C61\u6743\u9650",
|
|
319
|
+
help: "\u5BF9\u8C61\u7EA7 CRUD \u6743\u9650\u7684 JSON \u5E8F\u5217\u5316\u5185\u5BB9"
|
|
320
|
+
},
|
|
321
|
+
field_permissions: {
|
|
322
|
+
label: "\u5B57\u6BB5\u6743\u9650",
|
|
323
|
+
help: "\u5B57\u6BB5\u7EA7\u8BFB\u5199\u6743\u9650\u7684 JSON \u5E8F\u5217\u5316\u5185\u5BB9"
|
|
324
|
+
},
|
|
325
|
+
system_permissions: {
|
|
326
|
+
label: "\u7CFB\u7EDF\u6743\u9650",
|
|
327
|
+
help: '\u7CFB\u7EDF\u80FD\u529B\u540D\u79F0\u7684 JSON \u5E8F\u5217\u5316\u6570\u7EC4\uFF08\u4F8B\u5982 ["setup.access","studio.access","manage_users"]\uFF09'
|
|
328
|
+
},
|
|
329
|
+
row_level_security: {
|
|
330
|
+
label: "\u884C\u7EA7\u5B89\u5168",
|
|
331
|
+
help: "\u884C\u7EA7\u5B89\u5168\u7B56\u7565\u7684 JSON \u5E8F\u5217\u5316\u6570\u7EC4\uFF08USING/CHECK \u5B50\u53E5\uFF09"
|
|
332
|
+
},
|
|
333
|
+
tab_permissions: {
|
|
334
|
+
label: "\u6807\u7B7E\u9875\u6743\u9650",
|
|
335
|
+
help: "\u5E94\u7528\u6807\u7B7E\u9875\u53EF\u89C1\u6027\u7684 JSON \u5E8F\u5217\u5316\u6620\u5C04\uFF08visible | hidden | default_on | default_off\uFF09"
|
|
336
|
+
},
|
|
337
|
+
active: {
|
|
338
|
+
label: "\u542F\u7528"
|
|
339
|
+
},
|
|
340
|
+
id: {
|
|
341
|
+
label: "\u6743\u9650\u96C6 ID"
|
|
342
|
+
},
|
|
343
|
+
created_at: {
|
|
344
|
+
label: "\u521B\u5EFA\u65F6\u95F4"
|
|
345
|
+
},
|
|
346
|
+
updated_at: {
|
|
347
|
+
label: "\u66F4\u65B0\u65F6\u95F4"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
_views: {
|
|
351
|
+
active: {
|
|
352
|
+
label: "\u542F\u7528"
|
|
353
|
+
},
|
|
354
|
+
inactive: {
|
|
355
|
+
label: "\u505C\u7528"
|
|
356
|
+
},
|
|
357
|
+
all_permsets: {
|
|
358
|
+
label: "\u5168\u90E8"
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
_actions: {
|
|
362
|
+
activate_permission_set: {
|
|
363
|
+
label: "\u6FC0\u6D3B",
|
|
364
|
+
successMessage: "\u6743\u9650\u96C6\u5DF2\u6FC0\u6D3B"
|
|
365
|
+
},
|
|
366
|
+
deactivate_permission_set: {
|
|
367
|
+
label: "\u505C\u7528",
|
|
368
|
+
confirmText: "\u786E\u5B9A\u8981\u505C\u7528\u6B64\u6743\u9650\u96C6\u5417\uFF1F\u73B0\u6709\u5206\u914D\u4ECD\u5C06\u4FDD\u7559\uFF0C\u4F46\u5728\u91CD\u65B0\u6FC0\u6D3B\u4E4B\u524D\u5C06\u4E0D\u518D\u6388\u4E88\u8BBF\u95EE\u6743\u9650\u3002",
|
|
369
|
+
successMessage: "\u6743\u9650\u96C6\u5DF2\u505C\u7528"
|
|
370
|
+
},
|
|
371
|
+
clone_permission_set: {
|
|
372
|
+
label: "\u514B\u9686",
|
|
373
|
+
successMessage: "\u5DF2\u514B\u9686\u6743\u9650\u96C6"
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
sys_user_permission_set: {
|
|
378
|
+
label: "\u7528\u6237\u6743\u9650\u96C6",
|
|
379
|
+
pluralLabel: "\u7528\u6237\u6743\u9650\u96C6",
|
|
380
|
+
description: "\u5C06\u6743\u9650\u96C6\u76F4\u63A5\u5206\u914D\u7ED9\u7528\u6237\uFF08\u53EF\u6309\u7EC4\u7EC7\u8303\u56F4\u9650\u5B9A\uFF09\u3002",
|
|
381
|
+
fields: {
|
|
382
|
+
id: {
|
|
383
|
+
label: "\u5206\u914D ID",
|
|
384
|
+
help: "\u8BE5\u5206\u914D\u8BB0\u5F55\u7684 UUID\u3002"
|
|
385
|
+
},
|
|
386
|
+
user_id: {
|
|
387
|
+
label: "\u7528\u6237",
|
|
388
|
+
help: "\u6307\u5411 sys_user \u7684\u5916\u952E\u3002"
|
|
389
|
+
},
|
|
390
|
+
permission_set_id: {
|
|
391
|
+
label: "\u6743\u9650\u96C6",
|
|
392
|
+
help: "\u6307\u5411 sys_permission_set \u7684\u5916\u952E\u3002"
|
|
393
|
+
},
|
|
394
|
+
organization_id: {
|
|
395
|
+
label: "\u7EC4\u7EC7",
|
|
396
|
+
help: "\u53EF\u9009\u7684\u7EC4\u7EC7\u8303\u56F4\u3002NULL = \u5728\u6240\u6709\u7EC4\u7EC7\u4E0A\u4E0B\u6587\u4E2D\u90FD\u751F\u6548\u3002"
|
|
397
|
+
},
|
|
398
|
+
granted_by: {
|
|
399
|
+
label: "\u6388\u6743\u4EBA",
|
|
400
|
+
help: "\u6388\u4E88\u8BE5\u6743\u9650\u96C6\u7684\u7528\u6237\u3002"
|
|
401
|
+
},
|
|
402
|
+
created_at: {
|
|
403
|
+
label: "\u521B\u5EFA\u65F6\u95F4"
|
|
404
|
+
},
|
|
405
|
+
updated_at: {
|
|
406
|
+
label: "\u66F4\u65B0\u65F6\u95F4"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
sys_role_permission_set: {
|
|
411
|
+
label: "\u89D2\u8272\u6743\u9650\u96C6",
|
|
412
|
+
pluralLabel: "\u89D2\u8272\u6743\u9650\u96C6",
|
|
413
|
+
description: "\u5C06\u6743\u9650\u96C6\u7ED1\u5B9A\u5230\u89D2\u8272\u3002",
|
|
414
|
+
fields: {
|
|
415
|
+
id: {
|
|
416
|
+
label: "\u7ED1\u5B9A ID",
|
|
417
|
+
help: "\u89D2\u8272-\u6743\u9650\u96C6\u7ED1\u5B9A\u8BB0\u5F55\u7684 UUID\u3002"
|
|
418
|
+
},
|
|
419
|
+
role_id: {
|
|
420
|
+
label: "\u89D2\u8272",
|
|
421
|
+
help: "\u6307\u5411 sys_role \u7684\u5916\u952E\u3002"
|
|
422
|
+
},
|
|
423
|
+
permission_set_id: {
|
|
424
|
+
label: "\u6743\u9650\u96C6",
|
|
425
|
+
help: "\u6307\u5411 sys_permission_set \u7684\u5916\u952E\u3002"
|
|
426
|
+
},
|
|
427
|
+
created_at: {
|
|
428
|
+
label: "\u521B\u5EFA\u65F6\u95F4"
|
|
429
|
+
},
|
|
430
|
+
updated_at: {
|
|
431
|
+
label: "\u66F4\u65B0\u65F6\u95F4"
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// src/translations/ja-JP.objects.generated.ts
|
|
440
|
+
var jaJPObjects;
|
|
441
|
+
var init_ja_JP_objects_generated = __esm({
|
|
442
|
+
"src/translations/ja-JP.objects.generated.ts"() {
|
|
443
|
+
"use strict";
|
|
444
|
+
jaJPObjects = {
|
|
445
|
+
sys_role: {
|
|
446
|
+
label: "\u30ED\u30FC\u30EB",
|
|
447
|
+
pluralLabel: "\u30ED\u30FC\u30EB",
|
|
448
|
+
description: "RBAC \u30A2\u30AF\u30BB\u30B9\u5236\u5FA1\u306E\u305F\u3081\u306E\u30ED\u30FC\u30EB\u5B9A\u7FA9",
|
|
449
|
+
fields: {
|
|
450
|
+
label: {
|
|
451
|
+
label: "\u8868\u793A\u540D"
|
|
452
|
+
},
|
|
453
|
+
name: {
|
|
454
|
+
label: "API \u540D",
|
|
455
|
+
help: "\u30ED\u30FC\u30EB\u306E\u4E00\u610F\u306E\u6A5F\u68B0\u540D\uFF08\u4F8B: admin\u3001editor\u3001viewer\uFF09"
|
|
456
|
+
},
|
|
457
|
+
description: {
|
|
458
|
+
label: "\u8AAC\u660E"
|
|
459
|
+
},
|
|
460
|
+
permissions: {
|
|
461
|
+
label: "\u6A29\u9650",
|
|
462
|
+
help: "\u6A29\u9650\u6587\u5B57\u5217\u306E JSON \u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u914D\u5217"
|
|
463
|
+
},
|
|
464
|
+
active: {
|
|
465
|
+
label: "\u6709\u52B9"
|
|
466
|
+
},
|
|
467
|
+
is_default: {
|
|
468
|
+
label: "\u30C7\u30D5\u30A9\u30EB\u30C8\u30ED\u30FC\u30EB",
|
|
469
|
+
help: "\u65B0\u898F\u30E6\u30FC\u30B6\u30FC\u306B\u81EA\u52D5\u7684\u306B\u5272\u308A\u5F53\u3066\u3089\u308C\u307E\u3059"
|
|
470
|
+
},
|
|
471
|
+
id: {
|
|
472
|
+
label: "\u30ED\u30FC\u30EB ID"
|
|
473
|
+
},
|
|
474
|
+
created_at: {
|
|
475
|
+
label: "\u4F5C\u6210\u65E5\u6642"
|
|
476
|
+
},
|
|
477
|
+
updated_at: {
|
|
478
|
+
label: "\u66F4\u65B0\u65E5\u6642"
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
_views: {
|
|
482
|
+
active: {
|
|
483
|
+
label: "\u6709\u52B9"
|
|
484
|
+
},
|
|
485
|
+
default_roles: {
|
|
486
|
+
label: "\u30C7\u30D5\u30A9\u30EB\u30C8"
|
|
487
|
+
},
|
|
488
|
+
custom: {
|
|
489
|
+
label: "\u30AB\u30B9\u30BF\u30E0"
|
|
490
|
+
},
|
|
491
|
+
all_roles: {
|
|
492
|
+
label: "\u3059\u3079\u3066"
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
_actions: {
|
|
496
|
+
activate_role: {
|
|
497
|
+
label: "\u30ED\u30FC\u30EB\u3092\u6709\u52B9\u5316",
|
|
498
|
+
successMessage: "\u30ED\u30FC\u30EB\u304C\u6709\u52B9\u5316\u3055\u308C\u307E\u3057\u305F"
|
|
499
|
+
},
|
|
500
|
+
deactivate_role: {
|
|
501
|
+
label: "\u30ED\u30FC\u30EB\u3092\u7121\u52B9\u5316",
|
|
502
|
+
confirmText: "\u3053\u306E\u30ED\u30FC\u30EB\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u304B\uFF1F\u3053\u306E\u30ED\u30FC\u30EB\u3092\u6301\u3064\u30E6\u30FC\u30B6\u30FC\u306E\u5272\u308A\u5F53\u3066\u306F\u7DAD\u6301\u3055\u308C\u307E\u3059\u304C\u3001\u518D\u5EA6\u6709\u52B9\u5316\u3059\u308B\u307E\u3067\u6A29\u9650\u306E\u4ED8\u4E0E\u306F\u505C\u6B62\u3055\u308C\u307E\u3059\u3002",
|
|
503
|
+
successMessage: "\u30ED\u30FC\u30EB\u304C\u7121\u52B9\u5316\u3055\u308C\u307E\u3057\u305F"
|
|
504
|
+
},
|
|
505
|
+
set_default_role: {
|
|
506
|
+
label: "\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u8A2D\u5B9A",
|
|
507
|
+
confirmText: "\u3053\u306E\u30ED\u30FC\u30EB\u3092\u65B0\u898F\u30E6\u30FC\u30B6\u30FC\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30ED\u30FC\u30EB\u306B\u3057\u307E\u3059\u304B\uFF1F\u65E2\u5B58\u306E\u30E6\u30FC\u30B6\u30FC\u306B\u306F\u5F71\u97FF\u3057\u307E\u305B\u3093\u3002",
|
|
508
|
+
successMessage: "\u30C7\u30D5\u30A9\u30EB\u30C8\u30ED\u30FC\u30EB\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F"
|
|
509
|
+
},
|
|
510
|
+
clone_role: {
|
|
511
|
+
label: "\u30ED\u30FC\u30EB\u3092\u8907\u88FD",
|
|
512
|
+
successMessage: "\u30ED\u30FC\u30EB\u3092\u8907\u88FD\u3057\u307E\u3057\u305F"
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
sys_permission_set: {
|
|
517
|
+
label: "\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
518
|
+
pluralLabel: "\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
519
|
+
description: "\u7D30\u304B\u3044\u30A2\u30AF\u30BB\u30B9\u5236\u5FA1\u306E\u305F\u3081\u306E\u6A29\u9650\u30B0\u30EB\u30FC\u30D7",
|
|
520
|
+
fields: {
|
|
521
|
+
label: {
|
|
522
|
+
label: "\u8868\u793A\u540D"
|
|
523
|
+
},
|
|
524
|
+
name: {
|
|
525
|
+
label: "API \u540D",
|
|
526
|
+
help: "\u6A29\u9650\u30BB\u30C3\u30C8\u306E\u4E00\u610F\u306E\u6A5F\u68B0\u540D"
|
|
527
|
+
},
|
|
528
|
+
description: {
|
|
529
|
+
label: "\u8AAC\u660E"
|
|
530
|
+
},
|
|
531
|
+
object_permissions: {
|
|
532
|
+
label: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u6A29\u9650",
|
|
533
|
+
help: "JSON \u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u3055\u308C\u305F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30EC\u30D9\u30EB\u306E CRUD \u6A29\u9650"
|
|
534
|
+
},
|
|
535
|
+
field_permissions: {
|
|
536
|
+
label: "\u30D5\u30A3\u30FC\u30EB\u30C9\u6A29\u9650",
|
|
537
|
+
help: "JSON \u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30EB\u30C9\u30EC\u30D9\u30EB\u306E\u8AAD\u307F\u53D6\u308A/\u66F8\u304D\u8FBC\u307F\u6A29\u9650"
|
|
538
|
+
},
|
|
539
|
+
system_permissions: {
|
|
540
|
+
label: "\u30B7\u30B9\u30C6\u30E0\u6A29\u9650",
|
|
541
|
+
help: '\u30B7\u30B9\u30C6\u30E0\u30B1\u30FC\u30D1\u30D3\u30EA\u30C6\u30A3\u540D\u306EJSON\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u914D\u5217\uFF08\u4F8B: ["setup.access","studio.access","manage_users"]\uFF09'
|
|
542
|
+
},
|
|
543
|
+
row_level_security: {
|
|
544
|
+
label: "\u884C\u30EC\u30D9\u30EB\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3",
|
|
545
|
+
help: "\u884C\u30EC\u30D9\u30EB\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30DD\u30EA\u30B7\u30FC\u306EJSON\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u914D\u5217\uFF08USING/CHECK \u53E5\uFF09"
|
|
546
|
+
},
|
|
547
|
+
tab_permissions: {
|
|
548
|
+
label: "\u30BF\u30D6\u6A29\u9650",
|
|
549
|
+
help: "\u30A2\u30D7\u30EA\u306E\u30BF\u30D6\u8868\u793A\u306EJSON\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u30DE\u30C3\u30D7\uFF08visible | hidden | default_on | default_off\uFF09"
|
|
550
|
+
},
|
|
551
|
+
active: {
|
|
552
|
+
label: "\u6709\u52B9"
|
|
553
|
+
},
|
|
554
|
+
id: {
|
|
555
|
+
label: "\u6A29\u9650\u30BB\u30C3\u30C8 ID"
|
|
556
|
+
},
|
|
557
|
+
created_at: {
|
|
558
|
+
label: "\u4F5C\u6210\u65E5\u6642"
|
|
559
|
+
},
|
|
560
|
+
updated_at: {
|
|
561
|
+
label: "\u66F4\u65B0\u65E5\u6642"
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
_views: {
|
|
565
|
+
active: {
|
|
566
|
+
label: "\u6709\u52B9"
|
|
567
|
+
},
|
|
568
|
+
inactive: {
|
|
569
|
+
label: "\u7121\u52B9"
|
|
570
|
+
},
|
|
571
|
+
all_permsets: {
|
|
572
|
+
label: "\u3059\u3079\u3066"
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
_actions: {
|
|
576
|
+
activate_permission_set: {
|
|
577
|
+
label: "\u6709\u52B9\u5316",
|
|
578
|
+
successMessage: "\u6A29\u9650\u30BB\u30C3\u30C8\u304C\u6709\u52B9\u5316\u3055\u308C\u307E\u3057\u305F"
|
|
579
|
+
},
|
|
580
|
+
deactivate_permission_set: {
|
|
581
|
+
label: "\u7121\u52B9\u5316",
|
|
582
|
+
confirmText: "\u3053\u306E\u6A29\u9650\u30BB\u30C3\u30C8\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u304B\uFF1F\u65E2\u5B58\u306E\u5272\u308A\u5F53\u3066\u306F\u7DAD\u6301\u3055\u308C\u307E\u3059\u304C\u3001\u518D\u5EA6\u6709\u52B9\u5316\u3059\u308B\u307E\u3067\u30A2\u30AF\u30BB\u30B9\u306E\u4ED8\u4E0E\u306F\u505C\u6B62\u3055\u308C\u307E\u3059\u3002",
|
|
583
|
+
successMessage: "\u6A29\u9650\u30BB\u30C3\u30C8\u304C\u7121\u52B9\u5316\u3055\u308C\u307E\u3057\u305F"
|
|
584
|
+
},
|
|
585
|
+
clone_permission_set: {
|
|
586
|
+
label: "\u8907\u88FD",
|
|
587
|
+
successMessage: "\u6A29\u9650\u30BB\u30C3\u30C8\u3092\u8907\u88FD\u3057\u307E\u3057\u305F"
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
sys_user_permission_set: {
|
|
592
|
+
label: "\u30E6\u30FC\u30B6\u30FC\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
593
|
+
pluralLabel: "\u30E6\u30FC\u30B6\u30FC\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
594
|
+
description: "\u30E6\u30FC\u30B6\u30FC\u3078\u306E\u6A29\u9650\u30BB\u30C3\u30C8\u306E\u76F4\u63A5\u5272\u308A\u5F53\u3066\uFF08\u7D44\u7E54\u30B9\u30B3\u30FC\u30D7\u53EF\u80FD\uFF09\u3002",
|
|
595
|
+
fields: {
|
|
596
|
+
id: {
|
|
597
|
+
label: "\u5272\u308A\u5F53\u3066 ID",
|
|
598
|
+
help: "\u5272\u308A\u5F53\u3066\u306E UUID\u3002"
|
|
599
|
+
},
|
|
600
|
+
user_id: {
|
|
601
|
+
label: "\u30E6\u30FC\u30B6\u30FC",
|
|
602
|
+
help: "sys_user \u3078\u306E\u5916\u90E8\u30AD\u30FC\u3002"
|
|
603
|
+
},
|
|
604
|
+
permission_set_id: {
|
|
605
|
+
label: "\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
606
|
+
help: "sys_permission_set \u3078\u306E\u5916\u90E8\u30AD\u30FC\u3002"
|
|
607
|
+
},
|
|
608
|
+
organization_id: {
|
|
609
|
+
label: "\u7D44\u7E54",
|
|
610
|
+
help: "\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u7E54\u30B9\u30B3\u30FC\u30D7\u3002NULL = \u3059\u3079\u3066\u306E\u7D44\u7E54\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u9069\u7528\u3002"
|
|
611
|
+
},
|
|
612
|
+
granted_by: {
|
|
613
|
+
label: "\u4ED8\u4E0E\u8005",
|
|
614
|
+
help: "\u3053\u306E\u6A29\u9650\u30BB\u30C3\u30C8\u3092\u4ED8\u4E0E\u3057\u305F\u30E6\u30FC\u30B6\u30FC\u3002"
|
|
615
|
+
},
|
|
616
|
+
created_at: {
|
|
617
|
+
label: "\u4F5C\u6210\u65E5\u6642"
|
|
618
|
+
},
|
|
619
|
+
updated_at: {
|
|
620
|
+
label: "\u66F4\u65B0\u65E5\u6642"
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
sys_role_permission_set: {
|
|
625
|
+
label: "\u30ED\u30FC\u30EB\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
626
|
+
pluralLabel: "\u30ED\u30FC\u30EB\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
627
|
+
description: "\u6A29\u9650\u30BB\u30C3\u30C8\u3092\u30ED\u30FC\u30EB\u306B\u30D0\u30A4\u30F3\u30C9\u3057\u307E\u3059\u3002",
|
|
628
|
+
fields: {
|
|
629
|
+
id: {
|
|
630
|
+
label: "\u30D0\u30A4\u30F3\u30C9 ID",
|
|
631
|
+
help: "\u30ED\u30FC\u30EB\u6A29\u9650\u30BB\u30C3\u30C8\u30D0\u30A4\u30F3\u30C9\u306E UUID\u3002"
|
|
632
|
+
},
|
|
633
|
+
role_id: {
|
|
634
|
+
label: "\u30ED\u30FC\u30EB",
|
|
635
|
+
help: "sys_role \u3078\u306E\u5916\u90E8\u30AD\u30FC\u3002"
|
|
636
|
+
},
|
|
637
|
+
permission_set_id: {
|
|
638
|
+
label: "\u6A29\u9650\u30BB\u30C3\u30C8",
|
|
639
|
+
help: "sys_permission_set \u3078\u306E\u5916\u90E8\u30AD\u30FC\u3002"
|
|
640
|
+
},
|
|
641
|
+
created_at: {
|
|
642
|
+
label: "\u4F5C\u6210\u65E5\u6642"
|
|
643
|
+
},
|
|
644
|
+
updated_at: {
|
|
645
|
+
label: "\u66F4\u65B0\u65E5\u6642"
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// src/translations/es-ES.objects.generated.ts
|
|
654
|
+
var esESObjects;
|
|
655
|
+
var init_es_ES_objects_generated = __esm({
|
|
656
|
+
"src/translations/es-ES.objects.generated.ts"() {
|
|
657
|
+
"use strict";
|
|
658
|
+
esESObjects = {
|
|
659
|
+
sys_role: {
|
|
660
|
+
label: "Rol",
|
|
661
|
+
pluralLabel: "Roles",
|
|
662
|
+
description: "Definiciones de rol para el control de acceso RBAC",
|
|
663
|
+
fields: {
|
|
664
|
+
label: {
|
|
665
|
+
label: "Nombre visible"
|
|
666
|
+
},
|
|
667
|
+
name: {
|
|
668
|
+
label: "Nombre de API",
|
|
669
|
+
help: "Nombre t\xE9cnico \xFAnico del rol (p. ej. admin, editor, viewer)."
|
|
670
|
+
},
|
|
671
|
+
description: {
|
|
672
|
+
label: "Descripci\xF3n"
|
|
673
|
+
},
|
|
674
|
+
permissions: {
|
|
675
|
+
label: "Permisos",
|
|
676
|
+
help: "Matriz serializada en JSON de cadenas de permisos."
|
|
677
|
+
},
|
|
678
|
+
active: {
|
|
679
|
+
label: "Activo"
|
|
680
|
+
},
|
|
681
|
+
is_default: {
|
|
682
|
+
label: "Rol predeterminado",
|
|
683
|
+
help: "Se asigna autom\xE1ticamente a los nuevos usuarios."
|
|
684
|
+
},
|
|
685
|
+
id: {
|
|
686
|
+
label: "ID de rol"
|
|
687
|
+
},
|
|
688
|
+
created_at: {
|
|
689
|
+
label: "Creado el"
|
|
690
|
+
},
|
|
691
|
+
updated_at: {
|
|
692
|
+
label: "Actualizado el"
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
_views: {
|
|
696
|
+
active: {
|
|
697
|
+
label: "Activo"
|
|
698
|
+
},
|
|
699
|
+
default_roles: {
|
|
700
|
+
label: "Predeterminado"
|
|
701
|
+
},
|
|
702
|
+
custom: {
|
|
703
|
+
label: "Personalizado"
|
|
704
|
+
},
|
|
705
|
+
all_roles: {
|
|
706
|
+
label: "Todos"
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
_actions: {
|
|
710
|
+
activate_role: {
|
|
711
|
+
label: "Activar rol",
|
|
712
|
+
successMessage: "Rol activado"
|
|
713
|
+
},
|
|
714
|
+
deactivate_role: {
|
|
715
|
+
label: "Desactivar rol",
|
|
716
|
+
confirmText: "\xBFDesactivar este rol? Los usuarios con el rol conservan su asignaci\xF3n, pero el rol deja de otorgar permisos hasta que se vuelva a activar.",
|
|
717
|
+
successMessage: "Rol desactivado"
|
|
718
|
+
},
|
|
719
|
+
set_default_role: {
|
|
720
|
+
label: "Establecer como predeterminado",
|
|
721
|
+
confirmText: "\xBFConvertir este en el rol predeterminado para los nuevos usuarios? Los usuarios existentes no se ven afectados.",
|
|
722
|
+
successMessage: "Rol predeterminado actualizado"
|
|
723
|
+
},
|
|
724
|
+
clone_role: {
|
|
725
|
+
label: "Clonar rol",
|
|
726
|
+
successMessage: "Rol clonado"
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
sys_permission_set: {
|
|
731
|
+
label: "Conjunto de permisos",
|
|
732
|
+
pluralLabel: "Conjuntos de permisos",
|
|
733
|
+
description: "Agrupaciones de permisos con nombre para un control de acceso detallado",
|
|
734
|
+
fields: {
|
|
735
|
+
label: {
|
|
736
|
+
label: "Nombre visible"
|
|
737
|
+
},
|
|
738
|
+
name: {
|
|
739
|
+
label: "Nombre de API",
|
|
740
|
+
help: "Nombre t\xE9cnico \xFAnico del conjunto de permisos."
|
|
741
|
+
},
|
|
742
|
+
description: {
|
|
743
|
+
label: "Descripci\xF3n"
|
|
744
|
+
},
|
|
745
|
+
object_permissions: {
|
|
746
|
+
label: "Permisos de objeto",
|
|
747
|
+
help: "Permisos CRUD a nivel de objeto serializados en JSON."
|
|
748
|
+
},
|
|
749
|
+
field_permissions: {
|
|
750
|
+
label: "Permisos de campo",
|
|
751
|
+
help: "Permisos de lectura/escritura a nivel de campo serializados en JSON."
|
|
752
|
+
},
|
|
753
|
+
system_permissions: {
|
|
754
|
+
label: "Permisos del sistema",
|
|
755
|
+
help: 'Array serializado en JSON de nombres de capacidades del sistema (p. ej. ["setup.access","studio.access","manage_users"])'
|
|
756
|
+
},
|
|
757
|
+
row_level_security: {
|
|
758
|
+
label: "Seguridad a nivel de fila",
|
|
759
|
+
help: "Array serializado en JSON de pol\xEDticas de seguridad a nivel de fila (cl\xE1usulas USING/CHECK)"
|
|
760
|
+
},
|
|
761
|
+
tab_permissions: {
|
|
762
|
+
label: "Permisos de pesta\xF1as",
|
|
763
|
+
help: "Mapa serializado en JSON de la visibilidad de las pesta\xF1as de la app (visible | hidden | default_on | default_off)"
|
|
764
|
+
},
|
|
765
|
+
active: {
|
|
766
|
+
label: "Activo"
|
|
767
|
+
},
|
|
768
|
+
id: {
|
|
769
|
+
label: "ID de conjunto de permisos"
|
|
770
|
+
},
|
|
771
|
+
created_at: {
|
|
772
|
+
label: "Creado el"
|
|
773
|
+
},
|
|
774
|
+
updated_at: {
|
|
775
|
+
label: "Actualizado el"
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
_views: {
|
|
779
|
+
active: {
|
|
780
|
+
label: "Activo"
|
|
781
|
+
},
|
|
782
|
+
inactive: {
|
|
783
|
+
label: "Inactivo"
|
|
784
|
+
},
|
|
785
|
+
all_permsets: {
|
|
786
|
+
label: "Todos"
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
_actions: {
|
|
790
|
+
activate_permission_set: {
|
|
791
|
+
label: "Activar",
|
|
792
|
+
successMessage: "Conjunto de permisos activado"
|
|
793
|
+
},
|
|
794
|
+
deactivate_permission_set: {
|
|
795
|
+
label: "Desactivar",
|
|
796
|
+
confirmText: "\xBFDesactivar este conjunto de permisos? Las asignaciones existentes se mantienen, pero dejan de otorgar acceso hasta que se vuelva a activar.",
|
|
797
|
+
successMessage: "Conjunto de permisos desactivado"
|
|
798
|
+
},
|
|
799
|
+
clone_permission_set: {
|
|
800
|
+
label: "Clonar",
|
|
801
|
+
successMessage: "Conjunto de permisos clonado"
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
sys_user_permission_set: {
|
|
806
|
+
label: "Conjunto de permisos de usuario",
|
|
807
|
+
pluralLabel: "Conjuntos de permisos de usuario",
|
|
808
|
+
description: "Asignaci\xF3n directa de un conjunto de permisos a un usuario (opcionalmente con \xE1mbito de organizaci\xF3n).",
|
|
809
|
+
fields: {
|
|
810
|
+
id: {
|
|
811
|
+
label: "ID de asignaci\xF3n",
|
|
812
|
+
help: "UUID de la asignaci\xF3n."
|
|
813
|
+
},
|
|
814
|
+
user_id: {
|
|
815
|
+
label: "Usuario",
|
|
816
|
+
help: "Clave for\xE1nea a sys_user."
|
|
817
|
+
},
|
|
818
|
+
permission_set_id: {
|
|
819
|
+
label: "Conjunto de permisos",
|
|
820
|
+
help: "Clave for\xE1nea a sys_permission_set."
|
|
821
|
+
},
|
|
822
|
+
organization_id: {
|
|
823
|
+
label: "Organizaci\xF3n",
|
|
824
|
+
help: "\xC1mbito de organizaci\xF3n opcional. NULL = se aplica en cualquier contexto de organizaci\xF3n."
|
|
825
|
+
},
|
|
826
|
+
granted_by: {
|
|
827
|
+
label: "Concedido por",
|
|
828
|
+
help: "Usuario que concedi\xF3 este conjunto de permisos."
|
|
829
|
+
},
|
|
830
|
+
created_at: {
|
|
831
|
+
label: "Creado el"
|
|
832
|
+
},
|
|
833
|
+
updated_at: {
|
|
834
|
+
label: "Actualizado el"
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
sys_role_permission_set: {
|
|
839
|
+
label: "Conjunto de permisos de rol",
|
|
840
|
+
pluralLabel: "Conjuntos de permisos de rol",
|
|
841
|
+
description: "Vincula un conjunto de permisos a un rol.",
|
|
842
|
+
fields: {
|
|
843
|
+
id: {
|
|
844
|
+
label: "ID de vinculaci\xF3n",
|
|
845
|
+
help: "UUID de la vinculaci\xF3n rol-conjunto de permisos."
|
|
846
|
+
},
|
|
847
|
+
role_id: {
|
|
848
|
+
label: "Rol",
|
|
849
|
+
help: "Clave for\xE1nea a sys_role."
|
|
850
|
+
},
|
|
851
|
+
permission_set_id: {
|
|
852
|
+
label: "Conjunto de permisos",
|
|
853
|
+
help: "Clave for\xE1nea a sys_permission_set."
|
|
854
|
+
},
|
|
855
|
+
created_at: {
|
|
856
|
+
label: "Creado el"
|
|
857
|
+
},
|
|
858
|
+
updated_at: {
|
|
859
|
+
label: "Actualizado el"
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
// src/translations/index.ts
|
|
868
|
+
var translations_exports = {};
|
|
869
|
+
__export(translations_exports, {
|
|
870
|
+
SecurityTranslations: () => SecurityTranslations
|
|
871
|
+
});
|
|
872
|
+
var SecurityTranslations;
|
|
873
|
+
var init_translations = __esm({
|
|
874
|
+
"src/translations/index.ts"() {
|
|
875
|
+
"use strict";
|
|
876
|
+
init_en_objects_generated();
|
|
877
|
+
init_zh_CN_objects_generated();
|
|
878
|
+
init_ja_JP_objects_generated();
|
|
879
|
+
init_es_ES_objects_generated();
|
|
880
|
+
SecurityTranslations = {
|
|
881
|
+
en: { objects: enObjects },
|
|
882
|
+
"zh-CN": { objects: zhCNObjects },
|
|
883
|
+
"ja-JP": { objects: jaJPObjects },
|
|
884
|
+
"es-ES": { objects: esESObjects }
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
|
|
1
889
|
// src/permission-evaluator.ts
|
|
2
890
|
var OPERATION_TO_PERMISSION = {
|
|
3
891
|
find: "allowRead",
|
|
@@ -316,6 +1204,7 @@ function isPermissionDeniedError(e) {
|
|
|
316
1204
|
}
|
|
317
1205
|
|
|
318
1206
|
// src/bootstrap-platform-admin.ts
|
|
1207
|
+
import { SystemUserId } from "@objectstack/spec/system";
|
|
319
1208
|
var SYSTEM_CTX = { isSystem: true };
|
|
320
1209
|
async function tryFind(ql, object, where, limit = 100) {
|
|
321
1210
|
try {
|
|
@@ -382,17 +1271,20 @@ async function bootstrapPlatformAdmin(ql, bootstrapPermissionSets, options = {})
|
|
|
382
1271
|
ql,
|
|
383
1272
|
"sys_user_permission_set",
|
|
384
1273
|
{ permission_set_id: adminPsId },
|
|
385
|
-
|
|
1274
|
+
50
|
|
386
1275
|
);
|
|
387
|
-
if (existingAdminLinks.some((r) => !r.organization_id)) {
|
|
1276
|
+
if (existingAdminLinks.some((r) => !r.organization_id && r.user_id !== SystemUserId.SYSTEM)) {
|
|
388
1277
|
return { seeded: seededCount, adminPromoted: false, reason: "already_have_admin" };
|
|
389
1278
|
}
|
|
390
1279
|
const allUsers = await tryFind(ql, "sys_user", {}, 50);
|
|
391
|
-
|
|
392
|
-
|
|
1280
|
+
const humanUsers = allUsers.filter(
|
|
1281
|
+
(u) => u.id !== SystemUserId.SYSTEM && u.role !== "system"
|
|
1282
|
+
);
|
|
1283
|
+
if (humanUsers.length === 0) {
|
|
1284
|
+
logger?.info?.("[security] no human users yet \u2014 first sign-up will be promoted to platform admin");
|
|
393
1285
|
return { seeded: seededCount, adminPromoted: false, reason: "no_users" };
|
|
394
1286
|
}
|
|
395
|
-
const sorted = [...
|
|
1287
|
+
const sorted = [...humanUsers].sort((a, b) => {
|
|
396
1288
|
const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
|
|
397
1289
|
const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
|
|
398
1290
|
return ta - tb;
|
|
@@ -581,14 +1473,1015 @@ function extractMemberPairs(opCtx) {
|
|
|
581
1473
|
return Array.from(out.values());
|
|
582
1474
|
}
|
|
583
1475
|
|
|
1476
|
+
// src/objects/sys-role.object.ts
|
|
1477
|
+
import { ObjectSchema, Field } from "@objectstack/spec/data";
|
|
1478
|
+
var SysRole = ObjectSchema.create({
|
|
1479
|
+
name: "sys_role",
|
|
1480
|
+
label: "Role",
|
|
1481
|
+
pluralLabel: "Roles",
|
|
1482
|
+
icon: "shield",
|
|
1483
|
+
isSystem: true,
|
|
1484
|
+
managedBy: "config",
|
|
1485
|
+
// ADR-0010 §3.7 — RBAC primitive; tenants may add custom rows
|
|
1486
|
+
// (created via UI / API) but the schema itself is locked.
|
|
1487
|
+
protection: {
|
|
1488
|
+
lock: "no-overlay",
|
|
1489
|
+
reason: "RBAC schema is platform-defined \u2014 see ADR-0010.",
|
|
1490
|
+
docsUrl: "https://docs.objectstack.ai/adr/0010-metadata-protection"
|
|
1491
|
+
},
|
|
1492
|
+
description: "Role definitions for RBAC access control",
|
|
1493
|
+
displayNameField: "label",
|
|
1494
|
+
titleFormat: "{label}",
|
|
1495
|
+
compactLayout: ["label", "name", "active", "is_default"],
|
|
1496
|
+
// Custom actions — system roles drive RBAC and are edited rarely but
|
|
1497
|
+
// require the four high-frequency sysadmin affordances every IdP
|
|
1498
|
+
// (Salesforce, ServiceNow, Okta) ships: activate/deactivate (lifecycle
|
|
1499
|
+
// without losing assignments), mark default (auto-assign to new users),
|
|
1500
|
+
// and clone (template for new roles). All operations hit the generic
|
|
1501
|
+
// data CRUD endpoint exposed by `apiEnabled` — no custom server route
|
|
1502
|
+
// required because `managedBy: 'config'` allows direct mutation.
|
|
1503
|
+
actions: [
|
|
1504
|
+
{
|
|
1505
|
+
name: "activate_role",
|
|
1506
|
+
label: "Activate Role",
|
|
1507
|
+
icon: "circle-check",
|
|
1508
|
+
variant: "secondary",
|
|
1509
|
+
mode: "custom",
|
|
1510
|
+
locations: ["list_item", "record_header"],
|
|
1511
|
+
type: "api",
|
|
1512
|
+
method: "PATCH",
|
|
1513
|
+
target: "/api/v1/data/sys_role/{id}",
|
|
1514
|
+
bodyExtra: { active: true },
|
|
1515
|
+
successMessage: "Role activated",
|
|
1516
|
+
refreshAfter: true
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
name: "deactivate_role",
|
|
1520
|
+
label: "Deactivate Role",
|
|
1521
|
+
icon: "circle-off",
|
|
1522
|
+
variant: "danger",
|
|
1523
|
+
mode: "custom",
|
|
1524
|
+
locations: ["list_item", "record_header"],
|
|
1525
|
+
type: "api",
|
|
1526
|
+
method: "PATCH",
|
|
1527
|
+
target: "/api/v1/data/sys_role/{id}",
|
|
1528
|
+
bodyExtra: { active: false },
|
|
1529
|
+
confirmText: "Deactivate this role? Users with the role keep their assignment but the role stops granting permissions until re-activated.",
|
|
1530
|
+
successMessage: "Role deactivated",
|
|
1531
|
+
refreshAfter: true
|
|
1532
|
+
},
|
|
1533
|
+
{
|
|
1534
|
+
name: "set_default_role",
|
|
1535
|
+
label: "Set as Default",
|
|
1536
|
+
icon: "star",
|
|
1537
|
+
variant: "secondary",
|
|
1538
|
+
mode: "custom",
|
|
1539
|
+
locations: ["list_item", "record_header"],
|
|
1540
|
+
type: "api",
|
|
1541
|
+
method: "PATCH",
|
|
1542
|
+
target: "/api/v1/data/sys_role/{id}",
|
|
1543
|
+
bodyExtra: { is_default: true },
|
|
1544
|
+
confirmText: "Make this the default role for new users? Existing users are unaffected.",
|
|
1545
|
+
successMessage: "Default role updated",
|
|
1546
|
+
refreshAfter: true
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
// Clone — POST a new sys_role row pre-filled from the source. The
|
|
1550
|
+
// dialog asks only for the new API name / label so the operator
|
|
1551
|
+
// can rename atomically; permissions JSON is copied wholesale via
|
|
1552
|
+
// defaultFromRow.
|
|
1553
|
+
name: "clone_role",
|
|
1554
|
+
label: "Clone Role",
|
|
1555
|
+
icon: "copy",
|
|
1556
|
+
variant: "secondary",
|
|
1557
|
+
mode: "custom",
|
|
1558
|
+
locations: ["list_item", "record_header"],
|
|
1559
|
+
type: "api",
|
|
1560
|
+
method: "POST",
|
|
1561
|
+
target: "/api/v1/data/sys_role",
|
|
1562
|
+
bodyExtra: { is_default: false, active: true },
|
|
1563
|
+
successMessage: "Role cloned",
|
|
1564
|
+
refreshAfter: true,
|
|
1565
|
+
params: [
|
|
1566
|
+
{ name: "label", label: "New Display Name", type: "text", required: true },
|
|
1567
|
+
{ name: "name", label: "New API Name", type: "text", required: true, helpText: "Unique snake_case machine name" },
|
|
1568
|
+
{ field: "description", defaultFromRow: true },
|
|
1569
|
+
{ field: "permissions", defaultFromRow: true }
|
|
1570
|
+
]
|
|
1571
|
+
}
|
|
1572
|
+
],
|
|
1573
|
+
listViews: {
|
|
1574
|
+
active: {
|
|
1575
|
+
type: "grid",
|
|
1576
|
+
name: "active",
|
|
1577
|
+
label: "Active",
|
|
1578
|
+
data: { provider: "object", object: "sys_role" },
|
|
1579
|
+
columns: ["label", "name", "is_default", "updated_at"],
|
|
1580
|
+
filter: [{ field: "active", operator: "equals", value: true }],
|
|
1581
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1582
|
+
pagination: { pageSize: 50 }
|
|
1583
|
+
},
|
|
1584
|
+
default_roles: {
|
|
1585
|
+
type: "grid",
|
|
1586
|
+
name: "default_roles",
|
|
1587
|
+
label: "Default",
|
|
1588
|
+
data: { provider: "object", object: "sys_role" },
|
|
1589
|
+
columns: ["label", "name", "description", "active"],
|
|
1590
|
+
filter: [{ field: "is_default", operator: "equals", value: true }],
|
|
1591
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1592
|
+
pagination: { pageSize: 50 }
|
|
1593
|
+
},
|
|
1594
|
+
custom: {
|
|
1595
|
+
type: "grid",
|
|
1596
|
+
name: "custom",
|
|
1597
|
+
label: "Custom",
|
|
1598
|
+
data: { provider: "object", object: "sys_role" },
|
|
1599
|
+
columns: ["label", "name", "active", "updated_at"],
|
|
1600
|
+
filter: [{ field: "is_default", operator: "equals", value: false }],
|
|
1601
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1602
|
+
pagination: { pageSize: 50 }
|
|
1603
|
+
},
|
|
1604
|
+
all_roles: {
|
|
1605
|
+
type: "grid",
|
|
1606
|
+
name: "all_roles",
|
|
1607
|
+
label: "All",
|
|
1608
|
+
data: { provider: "object", object: "sys_role" },
|
|
1609
|
+
columns: ["label", "name", "active", "is_default", "updated_at"],
|
|
1610
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1611
|
+
pagination: { pageSize: 50 }
|
|
1612
|
+
}
|
|
1613
|
+
},
|
|
1614
|
+
fields: {
|
|
1615
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
1616
|
+
label: Field.text({
|
|
1617
|
+
label: "Display Name",
|
|
1618
|
+
required: true,
|
|
1619
|
+
searchable: true,
|
|
1620
|
+
maxLength: 255,
|
|
1621
|
+
group: "Identity"
|
|
1622
|
+
}),
|
|
1623
|
+
name: Field.text({
|
|
1624
|
+
label: "API Name",
|
|
1625
|
+
required: true,
|
|
1626
|
+
searchable: true,
|
|
1627
|
+
maxLength: 100,
|
|
1628
|
+
description: "Unique machine name for the role (e.g. admin, editor, viewer)",
|
|
1629
|
+
group: "Identity"
|
|
1630
|
+
}),
|
|
1631
|
+
description: Field.textarea({
|
|
1632
|
+
label: "Description",
|
|
1633
|
+
required: false,
|
|
1634
|
+
group: "Identity"
|
|
1635
|
+
}),
|
|
1636
|
+
// ── Configuration ────────────────────────────────────────────
|
|
1637
|
+
permissions: Field.textarea({
|
|
1638
|
+
label: "Permissions",
|
|
1639
|
+
required: false,
|
|
1640
|
+
description: "JSON-serialized array of permission strings",
|
|
1641
|
+
group: "Configuration"
|
|
1642
|
+
}),
|
|
1643
|
+
// ── Status ───────────────────────────────────────────────────
|
|
1644
|
+
active: Field.boolean({
|
|
1645
|
+
label: "Active",
|
|
1646
|
+
defaultValue: true,
|
|
1647
|
+
group: "Status"
|
|
1648
|
+
}),
|
|
1649
|
+
is_default: Field.boolean({
|
|
1650
|
+
label: "Default Role",
|
|
1651
|
+
defaultValue: false,
|
|
1652
|
+
description: "Automatically assigned to new users",
|
|
1653
|
+
group: "Status"
|
|
1654
|
+
}),
|
|
1655
|
+
// ── System ───────────────────────────────────────────────────
|
|
1656
|
+
id: Field.text({
|
|
1657
|
+
label: "Role ID",
|
|
1658
|
+
required: true,
|
|
1659
|
+
readonly: true,
|
|
1660
|
+
group: "System"
|
|
1661
|
+
}),
|
|
1662
|
+
created_at: Field.datetime({
|
|
1663
|
+
label: "Created At",
|
|
1664
|
+
defaultValue: "NOW()",
|
|
1665
|
+
readonly: true,
|
|
1666
|
+
group: "System"
|
|
1667
|
+
}),
|
|
1668
|
+
updated_at: Field.datetime({
|
|
1669
|
+
label: "Updated At",
|
|
1670
|
+
defaultValue: "NOW()",
|
|
1671
|
+
readonly: true,
|
|
1672
|
+
group: "System"
|
|
1673
|
+
})
|
|
1674
|
+
},
|
|
1675
|
+
indexes: [
|
|
1676
|
+
{ fields: ["name"], unique: true },
|
|
1677
|
+
{ fields: ["active"] }
|
|
1678
|
+
],
|
|
1679
|
+
enable: {
|
|
1680
|
+
trackHistory: true,
|
|
1681
|
+
searchable: true,
|
|
1682
|
+
apiEnabled: true,
|
|
1683
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1684
|
+
trash: true,
|
|
1685
|
+
mru: true
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
1688
|
+
|
|
1689
|
+
// src/objects/sys-permission-set.object.ts
|
|
1690
|
+
import { ObjectSchema as ObjectSchema2, Field as Field2 } from "@objectstack/spec/data";
|
|
1691
|
+
var SysPermissionSet = ObjectSchema2.create({
|
|
1692
|
+
name: "sys_permission_set",
|
|
1693
|
+
label: "Permission Set",
|
|
1694
|
+
pluralLabel: "Permission Sets",
|
|
1695
|
+
icon: "lock",
|
|
1696
|
+
isSystem: true,
|
|
1697
|
+
managedBy: "config",
|
|
1698
|
+
// ADR-0010 §3.7 — RBAC primitive; tenants may add custom rows
|
|
1699
|
+
// (created via UI / API) but the schema itself is locked.
|
|
1700
|
+
protection: {
|
|
1701
|
+
lock: "no-overlay",
|
|
1702
|
+
reason: "RBAC schema is platform-defined \u2014 see ADR-0010.",
|
|
1703
|
+
docsUrl: "https://docs.objectstack.ai/adr/0010-metadata-protection"
|
|
1704
|
+
},
|
|
1705
|
+
description: "Named permission groupings for fine-grained access control",
|
|
1706
|
+
displayNameField: "label",
|
|
1707
|
+
titleFormat: "{label}",
|
|
1708
|
+
compactLayout: ["label", "name", "active"],
|
|
1709
|
+
// Custom actions — permission sets are templates assigned to roles or
|
|
1710
|
+
// users (via sys_role_permission_set / sys_user_permission_set). The
|
|
1711
|
+
// sysadmin operations that don't live on the parent-detail tabs are
|
|
1712
|
+
// lifecycle (activate/deactivate without losing assignments) and
|
|
1713
|
+
// clone (build a new permset by tweaking an existing one). Both hit
|
|
1714
|
+
// the generic data CRUD endpoint — managedBy: 'config' permits it.
|
|
1715
|
+
actions: [
|
|
1716
|
+
{
|
|
1717
|
+
name: "activate_permission_set",
|
|
1718
|
+
label: "Activate",
|
|
1719
|
+
icon: "circle-check",
|
|
1720
|
+
variant: "secondary",
|
|
1721
|
+
mode: "custom",
|
|
1722
|
+
locations: ["list_item", "record_header"],
|
|
1723
|
+
type: "api",
|
|
1724
|
+
method: "PATCH",
|
|
1725
|
+
target: "/api/v1/data/sys_permission_set/{id}",
|
|
1726
|
+
bodyExtra: { active: true },
|
|
1727
|
+
successMessage: "Permission set activated",
|
|
1728
|
+
refreshAfter: true
|
|
1729
|
+
},
|
|
1730
|
+
{
|
|
1731
|
+
name: "deactivate_permission_set",
|
|
1732
|
+
label: "Deactivate",
|
|
1733
|
+
icon: "circle-off",
|
|
1734
|
+
variant: "danger",
|
|
1735
|
+
mode: "custom",
|
|
1736
|
+
locations: ["list_item", "record_header"],
|
|
1737
|
+
type: "api",
|
|
1738
|
+
method: "PATCH",
|
|
1739
|
+
target: "/api/v1/data/sys_permission_set/{id}",
|
|
1740
|
+
bodyExtra: { active: false },
|
|
1741
|
+
confirmText: "Deactivate this permission set? Existing assignments stay in place but stop granting access until re-activated.",
|
|
1742
|
+
successMessage: "Permission set deactivated",
|
|
1743
|
+
refreshAfter: true
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
name: "clone_permission_set",
|
|
1747
|
+
label: "Clone",
|
|
1748
|
+
icon: "copy",
|
|
1749
|
+
variant: "secondary",
|
|
1750
|
+
mode: "custom",
|
|
1751
|
+
locations: ["list_item", "record_header"],
|
|
1752
|
+
type: "api",
|
|
1753
|
+
method: "POST",
|
|
1754
|
+
target: "/api/v1/data/sys_permission_set",
|
|
1755
|
+
bodyExtra: { active: true },
|
|
1756
|
+
successMessage: "Permission set cloned",
|
|
1757
|
+
refreshAfter: true,
|
|
1758
|
+
params: [
|
|
1759
|
+
{ name: "label", label: "New Display Name", type: "text", required: true },
|
|
1760
|
+
{ name: "name", label: "New API Name", type: "text", required: true, helpText: "Unique snake_case machine name" },
|
|
1761
|
+
{ field: "description", defaultFromRow: true },
|
|
1762
|
+
{ field: "object_permissions", defaultFromRow: true },
|
|
1763
|
+
{ field: "field_permissions", defaultFromRow: true }
|
|
1764
|
+
]
|
|
1765
|
+
}
|
|
1766
|
+
],
|
|
1767
|
+
listViews: {
|
|
1768
|
+
active: {
|
|
1769
|
+
type: "grid",
|
|
1770
|
+
name: "active",
|
|
1771
|
+
label: "Active",
|
|
1772
|
+
data: { provider: "object", object: "sys_permission_set" },
|
|
1773
|
+
columns: ["label", "name", "description", "updated_at"],
|
|
1774
|
+
filter: [{ field: "active", operator: "equals", value: true }],
|
|
1775
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1776
|
+
pagination: { pageSize: 50 }
|
|
1777
|
+
},
|
|
1778
|
+
inactive: {
|
|
1779
|
+
type: "grid",
|
|
1780
|
+
name: "inactive",
|
|
1781
|
+
label: "Inactive",
|
|
1782
|
+
data: { provider: "object", object: "sys_permission_set" },
|
|
1783
|
+
columns: ["label", "name", "updated_at"],
|
|
1784
|
+
filter: [{ field: "active", operator: "equals", value: false }],
|
|
1785
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1786
|
+
pagination: { pageSize: 50 }
|
|
1787
|
+
},
|
|
1788
|
+
all_permsets: {
|
|
1789
|
+
type: "grid",
|
|
1790
|
+
name: "all_permsets",
|
|
1791
|
+
label: "All",
|
|
1792
|
+
data: { provider: "object", object: "sys_permission_set" },
|
|
1793
|
+
columns: ["label", "name", "active", "updated_at"],
|
|
1794
|
+
sort: [{ field: "label", order: "asc" }],
|
|
1795
|
+
pagination: { pageSize: 50 }
|
|
1796
|
+
}
|
|
1797
|
+
},
|
|
1798
|
+
fields: {
|
|
1799
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
1800
|
+
label: Field2.text({
|
|
1801
|
+
label: "Display Name",
|
|
1802
|
+
required: true,
|
|
1803
|
+
searchable: true,
|
|
1804
|
+
maxLength: 255,
|
|
1805
|
+
group: "Identity"
|
|
1806
|
+
}),
|
|
1807
|
+
name: Field2.text({
|
|
1808
|
+
label: "API Name",
|
|
1809
|
+
required: true,
|
|
1810
|
+
searchable: true,
|
|
1811
|
+
maxLength: 100,
|
|
1812
|
+
description: "Unique machine name for the permission set",
|
|
1813
|
+
group: "Identity"
|
|
1814
|
+
}),
|
|
1815
|
+
description: Field2.textarea({
|
|
1816
|
+
label: "Description",
|
|
1817
|
+
required: false,
|
|
1818
|
+
group: "Identity"
|
|
1819
|
+
}),
|
|
1820
|
+
// ── Permissions ──────────────────────────────────────────────
|
|
1821
|
+
object_permissions: Field2.textarea({
|
|
1822
|
+
label: "Object Permissions",
|
|
1823
|
+
required: false,
|
|
1824
|
+
description: "JSON-serialized object-level CRUD permissions",
|
|
1825
|
+
group: "Permissions"
|
|
1826
|
+
}),
|
|
1827
|
+
field_permissions: Field2.textarea({
|
|
1828
|
+
label: "Field Permissions",
|
|
1829
|
+
required: false,
|
|
1830
|
+
description: "JSON-serialized field-level read/write permissions",
|
|
1831
|
+
group: "Permissions"
|
|
1832
|
+
}),
|
|
1833
|
+
system_permissions: Field2.textarea({
|
|
1834
|
+
label: "System Permissions",
|
|
1835
|
+
required: false,
|
|
1836
|
+
description: 'JSON-serialized array of system capability names (e.g. ["setup.access","studio.access","manage_users"])',
|
|
1837
|
+
group: "Permissions"
|
|
1838
|
+
}),
|
|
1839
|
+
row_level_security: Field2.textarea({
|
|
1840
|
+
label: "Row-Level Security",
|
|
1841
|
+
required: false,
|
|
1842
|
+
description: "JSON-serialized array of row-level security policies (USING/CHECK clauses)",
|
|
1843
|
+
group: "Permissions"
|
|
1844
|
+
}),
|
|
1845
|
+
tab_permissions: Field2.textarea({
|
|
1846
|
+
label: "Tab Permissions",
|
|
1847
|
+
required: false,
|
|
1848
|
+
description: "JSON-serialized map of app tab visibility (visible | hidden | default_on | default_off)",
|
|
1849
|
+
group: "Permissions"
|
|
1850
|
+
}),
|
|
1851
|
+
// ── Status ───────────────────────────────────────────────────
|
|
1852
|
+
active: Field2.boolean({
|
|
1853
|
+
label: "Active",
|
|
1854
|
+
defaultValue: true,
|
|
1855
|
+
group: "Status"
|
|
1856
|
+
}),
|
|
1857
|
+
// ── System ───────────────────────────────────────────────────
|
|
1858
|
+
id: Field2.text({
|
|
1859
|
+
label: "Permission Set ID",
|
|
1860
|
+
required: true,
|
|
1861
|
+
readonly: true,
|
|
1862
|
+
group: "System"
|
|
1863
|
+
}),
|
|
1864
|
+
created_at: Field2.datetime({
|
|
1865
|
+
label: "Created At",
|
|
1866
|
+
defaultValue: "NOW()",
|
|
1867
|
+
readonly: true,
|
|
1868
|
+
group: "System"
|
|
1869
|
+
}),
|
|
1870
|
+
updated_at: Field2.datetime({
|
|
1871
|
+
label: "Updated At",
|
|
1872
|
+
defaultValue: "NOW()",
|
|
1873
|
+
readonly: true,
|
|
1874
|
+
group: "System"
|
|
1875
|
+
})
|
|
1876
|
+
},
|
|
1877
|
+
indexes: [
|
|
1878
|
+
{ fields: ["name"], unique: true },
|
|
1879
|
+
{ fields: ["active"] }
|
|
1880
|
+
],
|
|
1881
|
+
enable: {
|
|
1882
|
+
trackHistory: true,
|
|
1883
|
+
searchable: true,
|
|
1884
|
+
apiEnabled: true,
|
|
1885
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1886
|
+
trash: true,
|
|
1887
|
+
mru: true
|
|
1888
|
+
}
|
|
1889
|
+
});
|
|
1890
|
+
|
|
1891
|
+
// src/objects/sys-user-permission-set.object.ts
|
|
1892
|
+
import { ObjectSchema as ObjectSchema3, Field as Field3 } from "@objectstack/spec/data";
|
|
1893
|
+
var SysUserPermissionSet = ObjectSchema3.create({
|
|
1894
|
+
name: "sys_user_permission_set",
|
|
1895
|
+
label: "User Permission Set",
|
|
1896
|
+
pluralLabel: "User Permission Sets",
|
|
1897
|
+
icon: "user-check",
|
|
1898
|
+
isSystem: true,
|
|
1899
|
+
managedBy: "system",
|
|
1900
|
+
description: "Direct assignment of a permission set to a user (optionally scoped to an organization).",
|
|
1901
|
+
titleFormat: "{user_id} \u2192 {permission_set_id}",
|
|
1902
|
+
compactLayout: ["user_id", "permission_set_id", "organization_id"],
|
|
1903
|
+
fields: {
|
|
1904
|
+
id: Field3.text({
|
|
1905
|
+
label: "Assignment ID",
|
|
1906
|
+
required: true,
|
|
1907
|
+
readonly: true,
|
|
1908
|
+
description: "UUID of the assignment."
|
|
1909
|
+
}),
|
|
1910
|
+
user_id: Field3.lookup("sys_user", {
|
|
1911
|
+
label: "User",
|
|
1912
|
+
required: true,
|
|
1913
|
+
description: "Foreign key to sys_user."
|
|
1914
|
+
}),
|
|
1915
|
+
permission_set_id: Field3.lookup("sys_permission_set", {
|
|
1916
|
+
label: "Permission Set",
|
|
1917
|
+
required: true,
|
|
1918
|
+
description: "Foreign key to sys_permission_set."
|
|
1919
|
+
}),
|
|
1920
|
+
organization_id: Field3.lookup("sys_organization", {
|
|
1921
|
+
label: "Organization",
|
|
1922
|
+
required: false,
|
|
1923
|
+
description: "Optional organization scope. NULL = applies in every org context."
|
|
1924
|
+
}),
|
|
1925
|
+
granted_by: Field3.lookup("sys_user", {
|
|
1926
|
+
label: "Granted By",
|
|
1927
|
+
required: false,
|
|
1928
|
+
description: "User who granted this permission set."
|
|
1929
|
+
}),
|
|
1930
|
+
created_at: Field3.datetime({
|
|
1931
|
+
label: "Created At",
|
|
1932
|
+
defaultValue: "NOW()",
|
|
1933
|
+
readonly: true
|
|
1934
|
+
}),
|
|
1935
|
+
updated_at: Field3.datetime({
|
|
1936
|
+
label: "Updated At",
|
|
1937
|
+
defaultValue: "NOW()",
|
|
1938
|
+
readonly: true
|
|
1939
|
+
})
|
|
1940
|
+
},
|
|
1941
|
+
indexes: [
|
|
1942
|
+
{ fields: ["user_id", "permission_set_id", "organization_id"], unique: true },
|
|
1943
|
+
{ fields: ["user_id"] },
|
|
1944
|
+
{ fields: ["organization_id"] },
|
|
1945
|
+
{ fields: ["permission_set_id"] }
|
|
1946
|
+
],
|
|
1947
|
+
enable: {
|
|
1948
|
+
trackHistory: true,
|
|
1949
|
+
searchable: true,
|
|
1950
|
+
apiEnabled: true,
|
|
1951
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1952
|
+
trash: true,
|
|
1953
|
+
mru: false
|
|
1954
|
+
}
|
|
1955
|
+
});
|
|
1956
|
+
|
|
1957
|
+
// src/objects/sys-role-permission-set.object.ts
|
|
1958
|
+
import { ObjectSchema as ObjectSchema4, Field as Field4 } from "@objectstack/spec/data";
|
|
1959
|
+
var SysRolePermissionSet = ObjectSchema4.create({
|
|
1960
|
+
name: "sys_role_permission_set",
|
|
1961
|
+
label: "Role Permission Set",
|
|
1962
|
+
pluralLabel: "Role Permission Sets",
|
|
1963
|
+
icon: "shield-plus",
|
|
1964
|
+
isSystem: true,
|
|
1965
|
+
managedBy: "system",
|
|
1966
|
+
description: "Binds a permission set to a role.",
|
|
1967
|
+
titleFormat: "{role_id} \u2192 {permission_set_id}",
|
|
1968
|
+
compactLayout: ["role_id", "permission_set_id"],
|
|
1969
|
+
fields: {
|
|
1970
|
+
id: Field4.text({
|
|
1971
|
+
label: "Binding ID",
|
|
1972
|
+
required: true,
|
|
1973
|
+
readonly: true,
|
|
1974
|
+
description: "UUID of the role-permission-set binding."
|
|
1975
|
+
}),
|
|
1976
|
+
role_id: Field4.lookup("sys_role", {
|
|
1977
|
+
label: "Role",
|
|
1978
|
+
required: true,
|
|
1979
|
+
description: "Foreign key to sys_role."
|
|
1980
|
+
}),
|
|
1981
|
+
permission_set_id: Field4.lookup("sys_permission_set", {
|
|
1982
|
+
label: "Permission Set",
|
|
1983
|
+
required: true,
|
|
1984
|
+
description: "Foreign key to sys_permission_set."
|
|
1985
|
+
}),
|
|
1986
|
+
created_at: Field4.datetime({
|
|
1987
|
+
label: "Created At",
|
|
1988
|
+
defaultValue: "NOW()",
|
|
1989
|
+
readonly: true
|
|
1990
|
+
}),
|
|
1991
|
+
updated_at: Field4.datetime({
|
|
1992
|
+
label: "Updated At",
|
|
1993
|
+
defaultValue: "NOW()",
|
|
1994
|
+
readonly: true
|
|
1995
|
+
})
|
|
1996
|
+
},
|
|
1997
|
+
indexes: [
|
|
1998
|
+
{ fields: ["role_id", "permission_set_id"], unique: true },
|
|
1999
|
+
{ fields: ["role_id"] },
|
|
2000
|
+
{ fields: ["permission_set_id"] }
|
|
2001
|
+
],
|
|
2002
|
+
enable: {
|
|
2003
|
+
trackHistory: true,
|
|
2004
|
+
searchable: true,
|
|
2005
|
+
apiEnabled: true,
|
|
2006
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
2007
|
+
trash: true,
|
|
2008
|
+
mru: false
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
|
|
2012
|
+
// src/objects/default-permission-sets.ts
|
|
2013
|
+
import { PermissionSetSchema } from "@objectstack/spec/security";
|
|
2014
|
+
var BETTER_AUTH_MANAGED_OBJECTS = [
|
|
2015
|
+
"sys_user",
|
|
2016
|
+
"sys_account",
|
|
2017
|
+
"sys_session",
|
|
2018
|
+
"sys_organization",
|
|
2019
|
+
"sys_member",
|
|
2020
|
+
"sys_invitation",
|
|
2021
|
+
"sys_team",
|
|
2022
|
+
"sys_team_member",
|
|
2023
|
+
"sys_api_key",
|
|
2024
|
+
"sys_two_factor",
|
|
2025
|
+
"sys_verification",
|
|
2026
|
+
"sys_jwks",
|
|
2027
|
+
"sys_device_code",
|
|
2028
|
+
"sys_oauth_application",
|
|
2029
|
+
"sys_oauth_access_token",
|
|
2030
|
+
"sys_oauth_refresh_token",
|
|
2031
|
+
"sys_oauth_consent"
|
|
2032
|
+
];
|
|
2033
|
+
var denyWritesOnManagedObjects = () => Object.fromEntries(
|
|
2034
|
+
BETTER_AUTH_MANAGED_OBJECTS.map((name) => [
|
|
2035
|
+
name,
|
|
2036
|
+
{ allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false }
|
|
2037
|
+
])
|
|
2038
|
+
);
|
|
2039
|
+
var defaultPermissionSets = [
|
|
2040
|
+
PermissionSetSchema.parse({
|
|
2041
|
+
name: "admin_full_access",
|
|
2042
|
+
label: "Administrator \u2014 Full Access",
|
|
2043
|
+
isProfile: true,
|
|
2044
|
+
objects: {
|
|
2045
|
+
"*": {
|
|
2046
|
+
allowRead: true,
|
|
2047
|
+
allowCreate: true,
|
|
2048
|
+
allowEdit: true,
|
|
2049
|
+
allowDelete: true,
|
|
2050
|
+
viewAllRecords: true,
|
|
2051
|
+
modifyAllRecords: true
|
|
2052
|
+
}
|
|
2053
|
+
},
|
|
2054
|
+
systemPermissions: [
|
|
2055
|
+
"manage_users",
|
|
2056
|
+
"manage_metadata",
|
|
2057
|
+
"manage_platform_settings",
|
|
2058
|
+
"setup.access",
|
|
2059
|
+
"studio.access"
|
|
2060
|
+
]
|
|
2061
|
+
}),
|
|
2062
|
+
// ── Organization Administrator ──────────────────────────────────────
|
|
2063
|
+
//
|
|
2064
|
+
// Third tier between platform admin (`admin_full_access`) and rank-and-file
|
|
2065
|
+
// member. Lives at the *organization* scope: full CRUD on business
|
|
2066
|
+
// objects within their org (governed by `tenant_isolation` RLS), plus
|
|
2067
|
+
// `setup.access` so the Setup app shell is reachable.
|
|
2068
|
+
//
|
|
2069
|
+
// **Deliberately withheld** vs `admin_full_access`:
|
|
2070
|
+
// - `studio.access` — schema-design surfaces are platform-level (a
|
|
2071
|
+
// tenant cannot mutate the shared metadata) and Studio is hidden.
|
|
2072
|
+
// - `manage_metadata` — same reasoning.
|
|
2073
|
+
// - `manage_platform_settings` — global settings manifests
|
|
2074
|
+
// (mail / storage / AI / knowledge) and platform-only Setup pages
|
|
2075
|
+
// (sharing rules, audit logs, OAuth apps, JWKS, …) require this
|
|
2076
|
+
// and are hidden / 403'd for org admins. Tenant-scoped manifests
|
|
2077
|
+
// (`branding`, `feature_flags`) keep using `setup.access` so org
|
|
2078
|
+
// admins CAN configure their own org's branding.
|
|
2079
|
+
//
|
|
2080
|
+
// **Anti-escalation**: writes to the global RBAC tables
|
|
2081
|
+
// (`sys_role`, `sys_permission_set`, `sys_role_permission_set`,
|
|
2082
|
+
// `sys_user_permission_set`, `sys_user_role`) are denied. Allowing
|
|
2083
|
+
// them would let an org admin bind `admin_full_access` (which has no
|
|
2084
|
+
// RLS) to themselves and break out of tenant isolation. Reads are
|
|
2085
|
+
// permitted so the Roles / Permission Sets nav entries still render.
|
|
2086
|
+
//
|
|
2087
|
+
// Auto-granted to every `sys_member` whose role contains `owner` or
|
|
2088
|
+
// `admin` by `plugin-security/src/auto-org-admin-grant.ts`.
|
|
2089
|
+
PermissionSetSchema.parse({
|
|
2090
|
+
name: "organization_admin",
|
|
2091
|
+
label: "Organization Administrator",
|
|
2092
|
+
isProfile: true,
|
|
2093
|
+
objects: {
|
|
2094
|
+
"*": {
|
|
2095
|
+
allowRead: true,
|
|
2096
|
+
allowCreate: true,
|
|
2097
|
+
allowEdit: true,
|
|
2098
|
+
allowDelete: true,
|
|
2099
|
+
viewAllRecords: true,
|
|
2100
|
+
modifyAllRecords: true
|
|
2101
|
+
},
|
|
2102
|
+
// Identity tables — go through better-auth endpoints (invite,
|
|
2103
|
+
// accept, remove-member, transfer, …) rather than raw CRUD.
|
|
2104
|
+
...denyWritesOnManagedObjects(),
|
|
2105
|
+
// RBAC tables — read-only to prevent privilege escalation.
|
|
2106
|
+
sys_role: { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false },
|
|
2107
|
+
sys_permission_set: { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false },
|
|
2108
|
+
sys_role_permission_set: { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false },
|
|
2109
|
+
sys_user_permission_set: { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false },
|
|
2110
|
+
sys_user_role: { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false }
|
|
2111
|
+
},
|
|
2112
|
+
systemPermissions: ["manage_org_users", "setup.access"],
|
|
2113
|
+
rowLevelSecurity: [
|
|
2114
|
+
{
|
|
2115
|
+
name: "tenant_isolation",
|
|
2116
|
+
object: "*",
|
|
2117
|
+
operation: "all",
|
|
2118
|
+
using: "organization_id = current_user.organization_id"
|
|
2119
|
+
},
|
|
2120
|
+
// ── better-auth system tables that lack `organization_id` and would
|
|
2121
|
+
// otherwise be denied by the wildcard policy. Same self-only
|
|
2122
|
+
// carve-outs as `member_default` — an org admin does not get to
|
|
2123
|
+
// inspect cross-tenant identity rows.
|
|
2124
|
+
{
|
|
2125
|
+
name: "sys_organization_self",
|
|
2126
|
+
object: "sys_organization",
|
|
2127
|
+
operation: "all",
|
|
2128
|
+
using: "id = current_user.organization_id"
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
name: "sys_user_self",
|
|
2132
|
+
object: "sys_user",
|
|
2133
|
+
operation: "select",
|
|
2134
|
+
using: "id = current_user.id"
|
|
2135
|
+
},
|
|
2136
|
+
{
|
|
2137
|
+
name: "sys_user_org_members",
|
|
2138
|
+
object: "sys_user",
|
|
2139
|
+
operation: "select",
|
|
2140
|
+
using: "id IN (current_user.org_user_ids)"
|
|
2141
|
+
},
|
|
2142
|
+
{
|
|
2143
|
+
name: "sys_session_self",
|
|
2144
|
+
object: "sys_session",
|
|
2145
|
+
operation: "all",
|
|
2146
|
+
using: "user_id = current_user.id"
|
|
2147
|
+
},
|
|
2148
|
+
{
|
|
2149
|
+
name: "sys_account_self",
|
|
2150
|
+
object: "sys_account",
|
|
2151
|
+
operation: "select",
|
|
2152
|
+
using: "user_id = current_user.id"
|
|
2153
|
+
},
|
|
2154
|
+
{
|
|
2155
|
+
name: "sys_team_member_self",
|
|
2156
|
+
object: "sys_team_member",
|
|
2157
|
+
operation: "select",
|
|
2158
|
+
using: "user_id = current_user.id"
|
|
2159
|
+
},
|
|
2160
|
+
{
|
|
2161
|
+
name: "sys_two_factor_self",
|
|
2162
|
+
object: "sys_two_factor",
|
|
2163
|
+
operation: "all",
|
|
2164
|
+
using: "user_id = current_user.id"
|
|
2165
|
+
},
|
|
2166
|
+
{
|
|
2167
|
+
name: "sys_user_preference_self",
|
|
2168
|
+
object: "sys_user_preference",
|
|
2169
|
+
operation: "all",
|
|
2170
|
+
using: "user_id = current_user.id"
|
|
2171
|
+
},
|
|
2172
|
+
{
|
|
2173
|
+
name: "sys_api_key_self",
|
|
2174
|
+
object: "sys_api_key",
|
|
2175
|
+
operation: "all",
|
|
2176
|
+
using: "user_id = current_user.id"
|
|
2177
|
+
},
|
|
2178
|
+
{
|
|
2179
|
+
name: "sys_device_code_self",
|
|
2180
|
+
object: "sys_device_code",
|
|
2181
|
+
operation: "all",
|
|
2182
|
+
using: "user_id = current_user.id"
|
|
2183
|
+
},
|
|
2184
|
+
{
|
|
2185
|
+
name: "sys_oauth_access_token_self",
|
|
2186
|
+
object: "sys_oauth_access_token",
|
|
2187
|
+
operation: "select",
|
|
2188
|
+
using: "user_id = current_user.id"
|
|
2189
|
+
},
|
|
2190
|
+
{
|
|
2191
|
+
name: "sys_oauth_refresh_token_self",
|
|
2192
|
+
object: "sys_oauth_refresh_token",
|
|
2193
|
+
operation: "select",
|
|
2194
|
+
using: "user_id = current_user.id"
|
|
2195
|
+
},
|
|
2196
|
+
{
|
|
2197
|
+
name: "sys_oauth_consent_self",
|
|
2198
|
+
object: "sys_oauth_consent",
|
|
2199
|
+
operation: "all",
|
|
2200
|
+
using: "user_id = current_user.id"
|
|
2201
|
+
},
|
|
2202
|
+
// OAuth applications a user has registered themselves (self-service
|
|
2203
|
+
// developer flow exposed in the Account app's Developer section).
|
|
2204
|
+
// `sys_oauth_application` has no `organization_id` so the wildcard
|
|
2205
|
+
// `tenant_isolation` policy would otherwise deny every row.
|
|
2206
|
+
{
|
|
2207
|
+
name: "sys_oauth_application_self",
|
|
2208
|
+
object: "sys_oauth_application",
|
|
2209
|
+
operation: "all",
|
|
2210
|
+
using: "user_id = current_user.id"
|
|
2211
|
+
},
|
|
2212
|
+
// Org-scoped visibility for organization-owned identity-adjacent
|
|
2213
|
+
// tables. Org admins may inspect their own org's invitations and
|
|
2214
|
+
// memberships (read; writes still flow through better-auth).
|
|
2215
|
+
{
|
|
2216
|
+
name: "sys_member_org",
|
|
2217
|
+
object: "sys_member",
|
|
2218
|
+
operation: "select",
|
|
2219
|
+
using: "organization_id = current_user.organization_id"
|
|
2220
|
+
},
|
|
2221
|
+
{
|
|
2222
|
+
name: "sys_invitation_org",
|
|
2223
|
+
object: "sys_invitation",
|
|
2224
|
+
operation: "select",
|
|
2225
|
+
using: "organization_id = current_user.organization_id"
|
|
2226
|
+
},
|
|
2227
|
+
{
|
|
2228
|
+
name: "sys_team_org",
|
|
2229
|
+
object: "sys_team",
|
|
2230
|
+
operation: "select",
|
|
2231
|
+
using: "organization_id = current_user.organization_id"
|
|
2232
|
+
}
|
|
2233
|
+
]
|
|
2234
|
+
}),
|
|
2235
|
+
PermissionSetSchema.parse({
|
|
2236
|
+
name: "member_default",
|
|
2237
|
+
label: "Member \u2014 Standard Access",
|
|
2238
|
+
isProfile: true,
|
|
2239
|
+
objects: {
|
|
2240
|
+
"*": {
|
|
2241
|
+
allowRead: true,
|
|
2242
|
+
allowCreate: true,
|
|
2243
|
+
allowEdit: true,
|
|
2244
|
+
allowDelete: true
|
|
2245
|
+
},
|
|
2246
|
+
// Identity tables are managed by better-auth — no direct writes.
|
|
2247
|
+
...denyWritesOnManagedObjects()
|
|
2248
|
+
},
|
|
2249
|
+
rowLevelSecurity: [
|
|
2250
|
+
{
|
|
2251
|
+
name: "tenant_isolation",
|
|
2252
|
+
object: "*",
|
|
2253
|
+
operation: "all",
|
|
2254
|
+
using: "organization_id = current_user.organization_id"
|
|
2255
|
+
},
|
|
2256
|
+
{
|
|
2257
|
+
name: "owner_only_writes",
|
|
2258
|
+
object: "*",
|
|
2259
|
+
operation: "update",
|
|
2260
|
+
using: "owner_id = current_user.id"
|
|
2261
|
+
},
|
|
2262
|
+
{
|
|
2263
|
+
name: "owner_only_deletes",
|
|
2264
|
+
object: "*",
|
|
2265
|
+
operation: "delete",
|
|
2266
|
+
using: "owner_id = current_user.id"
|
|
2267
|
+
},
|
|
2268
|
+
// ── better-auth system tables that lack `organization_id` and would
|
|
2269
|
+
// otherwise be left unprotected by the wildcard rule above. ────
|
|
2270
|
+
//
|
|
2271
|
+
// The security plugin's RLS injector treats wildcard policies that
|
|
2272
|
+
// target a missing field as `RLS_DENY_FILTER` (zero rows) unless a
|
|
2273
|
+
// per-object policy contributes an alternate match. Each `*_self`
|
|
2274
|
+
// policy below restores per-user visibility on a better-auth table
|
|
2275
|
+
// that has `user_id` but no `organization_id`. Tables without
|
|
2276
|
+
// `user_id` (`sys_verification`, `sys_jwks`, empty `sys_passkey`)
|
|
2277
|
+
// stay DENY for non-admins by design — only platform admins (via
|
|
2278
|
+
// `admin_full_access`, which has no RLS) should inspect them.
|
|
2279
|
+
{
|
|
2280
|
+
name: "sys_organization_self",
|
|
2281
|
+
object: "sys_organization",
|
|
2282
|
+
operation: "all",
|
|
2283
|
+
using: "id = current_user.organization_id"
|
|
2284
|
+
},
|
|
2285
|
+
{
|
|
2286
|
+
name: "sys_user_self",
|
|
2287
|
+
object: "sys_user",
|
|
2288
|
+
operation: "select",
|
|
2289
|
+
using: "id = current_user.id"
|
|
2290
|
+
},
|
|
2291
|
+
// Org collaborators: members can see other users in the same
|
|
2292
|
+
// organization. Without this, owner/assignee lookups, @-mention
|
|
2293
|
+
// suggestions, reviewer pickers and team-roster surfaces all
|
|
2294
|
+
// collapse to just the current user. `org_user_ids` is
|
|
2295
|
+
// pre-resolved by runtime/resolve-execution-context from
|
|
2296
|
+
// `sys_member` for the active organization. Sensitive credential
|
|
2297
|
+
// tables (`sys_account`, `sys_session`, `sys_api_key`, …) keep
|
|
2298
|
+
// their stricter self-only carve-outs above.
|
|
2299
|
+
{
|
|
2300
|
+
name: "sys_user_org_members",
|
|
2301
|
+
object: "sys_user",
|
|
2302
|
+
operation: "select",
|
|
2303
|
+
using: "id IN (current_user.org_user_ids)"
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
name: "sys_session_self",
|
|
2307
|
+
object: "sys_session",
|
|
2308
|
+
operation: "all",
|
|
2309
|
+
using: "user_id = current_user.id"
|
|
2310
|
+
},
|
|
2311
|
+
{
|
|
2312
|
+
name: "sys_account_self",
|
|
2313
|
+
object: "sys_account",
|
|
2314
|
+
operation: "select",
|
|
2315
|
+
using: "user_id = current_user.id"
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
name: "sys_team_member_self",
|
|
2319
|
+
object: "sys_team_member",
|
|
2320
|
+
operation: "select",
|
|
2321
|
+
using: "user_id = current_user.id"
|
|
2322
|
+
},
|
|
2323
|
+
{
|
|
2324
|
+
name: "sys_two_factor_self",
|
|
2325
|
+
object: "sys_two_factor",
|
|
2326
|
+
operation: "all",
|
|
2327
|
+
using: "user_id = current_user.id"
|
|
2328
|
+
},
|
|
2329
|
+
{
|
|
2330
|
+
name: "sys_user_preference_self",
|
|
2331
|
+
object: "sys_user_preference",
|
|
2332
|
+
operation: "all",
|
|
2333
|
+
using: "user_id = current_user.id"
|
|
2334
|
+
},
|
|
2335
|
+
{
|
|
2336
|
+
name: "sys_api_key_self",
|
|
2337
|
+
object: "sys_api_key",
|
|
2338
|
+
operation: "all",
|
|
2339
|
+
using: "user_id = current_user.id"
|
|
2340
|
+
},
|
|
2341
|
+
{
|
|
2342
|
+
name: "sys_device_code_self",
|
|
2343
|
+
object: "sys_device_code",
|
|
2344
|
+
operation: "all",
|
|
2345
|
+
using: "user_id = current_user.id"
|
|
2346
|
+
},
|
|
2347
|
+
{
|
|
2348
|
+
name: "sys_oauth_access_token_self",
|
|
2349
|
+
object: "sys_oauth_access_token",
|
|
2350
|
+
operation: "select",
|
|
2351
|
+
using: "user_id = current_user.id"
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
name: "sys_oauth_refresh_token_self",
|
|
2355
|
+
object: "sys_oauth_refresh_token",
|
|
2356
|
+
operation: "select",
|
|
2357
|
+
using: "user_id = current_user.id"
|
|
2358
|
+
},
|
|
2359
|
+
{
|
|
2360
|
+
name: "sys_oauth_consent_self",
|
|
2361
|
+
object: "sys_oauth_consent",
|
|
2362
|
+
operation: "all",
|
|
2363
|
+
using: "user_id = current_user.id"
|
|
2364
|
+
},
|
|
2365
|
+
// OAuth applications a user has registered themselves (Account →
|
|
2366
|
+
// Developer → OAuth Applications). `sys_oauth_application` has no
|
|
2367
|
+
// `organization_id`, so without this carve-out the wildcard
|
|
2368
|
+
// `tenant_isolation` policy returns zero rows even for the owner.
|
|
2369
|
+
{
|
|
2370
|
+
name: "sys_oauth_application_self",
|
|
2371
|
+
object: "sys_oauth_application",
|
|
2372
|
+
operation: "all",
|
|
2373
|
+
using: "user_id = current_user.id"
|
|
2374
|
+
}
|
|
2375
|
+
]
|
|
2376
|
+
}),
|
|
2377
|
+
PermissionSetSchema.parse({
|
|
2378
|
+
name: "viewer_readonly",
|
|
2379
|
+
label: "Viewer \u2014 Read-Only",
|
|
2380
|
+
isProfile: true,
|
|
2381
|
+
objects: {
|
|
2382
|
+
"*": {
|
|
2383
|
+
allowRead: true,
|
|
2384
|
+
allowCreate: false,
|
|
2385
|
+
allowEdit: false,
|
|
2386
|
+
allowDelete: false
|
|
2387
|
+
},
|
|
2388
|
+
// Belt-and-suspenders: explicit deny on managed objects even though
|
|
2389
|
+
// the wildcard already denies — keeps the policy readable when
|
|
2390
|
+
// future relaxations might widen the wildcard.
|
|
2391
|
+
...denyWritesOnManagedObjects()
|
|
2392
|
+
},
|
|
2393
|
+
rowLevelSecurity: [
|
|
2394
|
+
{
|
|
2395
|
+
name: "tenant_isolation",
|
|
2396
|
+
object: "*",
|
|
2397
|
+
operation: "select",
|
|
2398
|
+
using: "organization_id = current_user.organization_id"
|
|
2399
|
+
},
|
|
2400
|
+
{
|
|
2401
|
+
name: "sys_organization_self",
|
|
2402
|
+
object: "sys_organization",
|
|
2403
|
+
operation: "select",
|
|
2404
|
+
using: "id = current_user.organization_id"
|
|
2405
|
+
},
|
|
2406
|
+
{
|
|
2407
|
+
name: "sys_user_self",
|
|
2408
|
+
object: "sys_user",
|
|
2409
|
+
operation: "select",
|
|
2410
|
+
using: "id = current_user.id"
|
|
2411
|
+
},
|
|
2412
|
+
// Org collaborators (read-only): see `sys_user_org_members` in
|
|
2413
|
+
// `member_default` for rationale.
|
|
2414
|
+
{
|
|
2415
|
+
name: "sys_user_org_members",
|
|
2416
|
+
object: "sys_user",
|
|
2417
|
+
operation: "select",
|
|
2418
|
+
using: "id IN (current_user.org_user_ids)"
|
|
2419
|
+
},
|
|
2420
|
+
{
|
|
2421
|
+
name: "sys_session_self",
|
|
2422
|
+
object: "sys_session",
|
|
2423
|
+
operation: "select",
|
|
2424
|
+
using: "user_id = current_user.id"
|
|
2425
|
+
},
|
|
2426
|
+
{
|
|
2427
|
+
name: "sys_account_self",
|
|
2428
|
+
object: "sys_account",
|
|
2429
|
+
operation: "select",
|
|
2430
|
+
using: "user_id = current_user.id"
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
name: "sys_team_member_self",
|
|
2434
|
+
object: "sys_team_member",
|
|
2435
|
+
operation: "select",
|
|
2436
|
+
using: "user_id = current_user.id"
|
|
2437
|
+
},
|
|
2438
|
+
{
|
|
2439
|
+
name: "sys_two_factor_self",
|
|
2440
|
+
object: "sys_two_factor",
|
|
2441
|
+
operation: "select",
|
|
2442
|
+
using: "user_id = current_user.id"
|
|
2443
|
+
},
|
|
2444
|
+
{
|
|
2445
|
+
name: "sys_user_preference_self",
|
|
2446
|
+
object: "sys_user_preference",
|
|
2447
|
+
operation: "select",
|
|
2448
|
+
using: "user_id = current_user.id"
|
|
2449
|
+
},
|
|
2450
|
+
{
|
|
2451
|
+
name: "sys_api_key_self",
|
|
2452
|
+
object: "sys_api_key",
|
|
2453
|
+
operation: "select",
|
|
2454
|
+
using: "user_id = current_user.id"
|
|
2455
|
+
},
|
|
2456
|
+
{
|
|
2457
|
+
name: "sys_device_code_self",
|
|
2458
|
+
object: "sys_device_code",
|
|
2459
|
+
operation: "select",
|
|
2460
|
+
using: "user_id = current_user.id"
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
name: "sys_oauth_access_token_self",
|
|
2464
|
+
object: "sys_oauth_access_token",
|
|
2465
|
+
operation: "select",
|
|
2466
|
+
using: "user_id = current_user.id"
|
|
2467
|
+
},
|
|
2468
|
+
{
|
|
2469
|
+
name: "sys_oauth_refresh_token_self",
|
|
2470
|
+
object: "sys_oauth_refresh_token",
|
|
2471
|
+
operation: "select",
|
|
2472
|
+
using: "user_id = current_user.id"
|
|
2473
|
+
},
|
|
2474
|
+
{
|
|
2475
|
+
name: "sys_oauth_consent_self",
|
|
2476
|
+
object: "sys_oauth_consent",
|
|
2477
|
+
operation: "select",
|
|
2478
|
+
using: "user_id = current_user.id"
|
|
2479
|
+
}
|
|
2480
|
+
]
|
|
2481
|
+
})
|
|
2482
|
+
];
|
|
2483
|
+
|
|
584
2484
|
// src/manifest.ts
|
|
585
|
-
import {
|
|
586
|
-
SysPermissionSet,
|
|
587
|
-
SysRole,
|
|
588
|
-
SysUserPermissionSet,
|
|
589
|
-
SysRolePermissionSet,
|
|
590
|
-
defaultPermissionSets
|
|
591
|
-
} from "@objectstack/platform-objects/security";
|
|
592
2485
|
var SECURITY_PLUGIN_ID = "com.objectstack.plugin-security";
|
|
593
2486
|
var SECURITY_PLUGIN_VERSION = "1.0.0";
|
|
594
2487
|
var securityObjects = [
|
|
@@ -663,8 +2556,36 @@ var SecurityPlugin = class {
|
|
|
663
2556
|
// Permission sets ride along on the manifest so the metadata service
|
|
664
2557
|
// can resolve them by name when SecurityPlugin middleware queries
|
|
665
2558
|
// `metadata.list('permissions')`.
|
|
666
|
-
permissions: this.bootstrapPermissionSets
|
|
2559
|
+
permissions: this.bootstrapPermissionSets,
|
|
2560
|
+
// ADR-0029 D7 — contribute the RBAC entries into the Setup app's
|
|
2561
|
+
// `group_access_control` slot. This plugin owns these objects (K2), so it
|
|
2562
|
+
// ships their menu too; when the plugin is absent the entries don't appear.
|
|
2563
|
+
navigationContributions: [
|
|
2564
|
+
{
|
|
2565
|
+
app: "setup",
|
|
2566
|
+
group: "group_access_control",
|
|
2567
|
+
priority: 100,
|
|
2568
|
+
items: [
|
|
2569
|
+
{ id: "nav_roles", type: "object", label: "Roles", objectName: "sys_role", icon: "shield-check" },
|
|
2570
|
+
{ id: "nav_permission_sets", type: "object", label: "Permission Sets", objectName: "sys_permission_set", icon: "lock" }
|
|
2571
|
+
]
|
|
2572
|
+
}
|
|
2573
|
+
]
|
|
667
2574
|
});
|
|
2575
|
+
if (typeof ctx.hook === "function") {
|
|
2576
|
+
ctx.hook("kernel:ready", async () => {
|
|
2577
|
+
try {
|
|
2578
|
+
const i18n = ctx.getService("i18n");
|
|
2579
|
+
if (i18n && typeof i18n.loadTranslations === "function") {
|
|
2580
|
+
const { SecurityTranslations: SecurityTranslations2 } = await Promise.resolve().then(() => (init_translations(), translations_exports));
|
|
2581
|
+
for (const [locale, data] of Object.entries(SecurityTranslations2)) {
|
|
2582
|
+
i18n.loadTranslations(locale, data);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
} catch {
|
|
2586
|
+
}
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
668
2589
|
ctx.logger.info("Security Plugin initialized", {
|
|
669
2590
|
defaultPermissionSets: this.bootstrapPermissionSets.map((p) => p.name)
|
|
670
2591
|
});
|