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