@objectstack/platform-objects 0.1.0 → 4.0.5

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.
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var data = require('@objectstack/spec/data');
4
+ var security = require('@objectstack/spec/security');
4
5
 
5
6
  // src/security/sys-role.object.ts
6
7
  var SysRole = data.ObjectSchema.create({
@@ -171,8 +172,253 @@ var SysPermissionSet = data.ObjectSchema.create({
171
172
  mru: true
172
173
  }
173
174
  });
175
+ var SysUserPermissionSet = data.ObjectSchema.create({
176
+ name: "sys_user_permission_set",
177
+ label: "User Permission Set",
178
+ pluralLabel: "User Permission Sets",
179
+ icon: "user-check",
180
+ isSystem: true,
181
+ description: "Direct assignment of a permission set to a user (optionally scoped to an organization).",
182
+ titleFormat: "{user_id} \u2192 {permission_set_id}",
183
+ compactLayout: ["user_id", "permission_set_id", "organization_id"],
184
+ fields: {
185
+ id: data.Field.text({
186
+ label: "Assignment ID",
187
+ required: true,
188
+ readonly: true,
189
+ description: "UUID of the assignment."
190
+ }),
191
+ user_id: data.Field.lookup("sys_user", {
192
+ label: "User",
193
+ required: true,
194
+ description: "Foreign key to sys_user."
195
+ }),
196
+ permission_set_id: data.Field.lookup("sys_permission_set", {
197
+ label: "Permission Set",
198
+ required: true,
199
+ description: "Foreign key to sys_permission_set."
200
+ }),
201
+ organization_id: data.Field.lookup("sys_organization", {
202
+ label: "Organization",
203
+ required: false,
204
+ description: "Optional organization scope. NULL = applies in every org context."
205
+ }),
206
+ granted_by: data.Field.lookup("sys_user", {
207
+ label: "Granted By",
208
+ required: false,
209
+ description: "User who granted this permission set."
210
+ }),
211
+ created_at: data.Field.datetime({
212
+ label: "Created At",
213
+ defaultValue: "NOW()",
214
+ readonly: true
215
+ }),
216
+ updated_at: data.Field.datetime({
217
+ label: "Updated At",
218
+ defaultValue: "NOW()",
219
+ readonly: true
220
+ })
221
+ },
222
+ indexes: [
223
+ { fields: ["user_id", "permission_set_id", "organization_id"], unique: true },
224
+ { fields: ["user_id"] },
225
+ { fields: ["organization_id"] },
226
+ { fields: ["permission_set_id"] }
227
+ ],
228
+ enable: {
229
+ trackHistory: true,
230
+ searchable: true,
231
+ apiEnabled: true,
232
+ apiMethods: ["get", "list", "create", "update", "delete"],
233
+ trash: true,
234
+ mru: false
235
+ }
236
+ });
237
+ var SysRolePermissionSet = data.ObjectSchema.create({
238
+ name: "sys_role_permission_set",
239
+ label: "Role Permission Set",
240
+ pluralLabel: "Role Permission Sets",
241
+ icon: "shield-plus",
242
+ isSystem: true,
243
+ description: "Binds a permission set to a role.",
244
+ titleFormat: "{role_id} \u2192 {permission_set_id}",
245
+ compactLayout: ["role_id", "permission_set_id"],
246
+ fields: {
247
+ id: data.Field.text({
248
+ label: "Binding ID",
249
+ required: true,
250
+ readonly: true,
251
+ description: "UUID of the role-permission-set binding."
252
+ }),
253
+ role_id: data.Field.lookup("sys_role", {
254
+ label: "Role",
255
+ required: true,
256
+ description: "Foreign key to sys_role."
257
+ }),
258
+ permission_set_id: data.Field.lookup("sys_permission_set", {
259
+ label: "Permission Set",
260
+ required: true,
261
+ description: "Foreign key to sys_permission_set."
262
+ }),
263
+ created_at: data.Field.datetime({
264
+ label: "Created At",
265
+ defaultValue: "NOW()",
266
+ readonly: true
267
+ }),
268
+ updated_at: data.Field.datetime({
269
+ label: "Updated At",
270
+ defaultValue: "NOW()",
271
+ readonly: true
272
+ })
273
+ },
274
+ indexes: [
275
+ { fields: ["role_id", "permission_set_id"], unique: true },
276
+ { fields: ["role_id"] },
277
+ { fields: ["permission_set_id"] }
278
+ ],
279
+ enable: {
280
+ trackHistory: true,
281
+ searchable: true,
282
+ apiEnabled: true,
283
+ apiMethods: ["get", "list", "create", "update", "delete"],
284
+ trash: true,
285
+ mru: false
286
+ }
287
+ });
288
+ var BETTER_AUTH_MANAGED_OBJECTS = [
289
+ "sys_user",
290
+ "sys_account",
291
+ "sys_session",
292
+ "sys_organization",
293
+ "sys_member",
294
+ "sys_invitation",
295
+ "sys_team",
296
+ "sys_team_member",
297
+ "sys_api_key",
298
+ "sys_two_factor",
299
+ "sys_verification",
300
+ "sys_jwks",
301
+ "sys_device_code",
302
+ "sys_oauth_application",
303
+ "sys_oauth_access_token",
304
+ "sys_oauth_refresh_token",
305
+ "sys_oauth_consent"
306
+ ];
307
+ var denyWritesOnManagedObjects = () => Object.fromEntries(
308
+ BETTER_AUTH_MANAGED_OBJECTS.map((name) => [
309
+ name,
310
+ { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false }
311
+ ])
312
+ );
313
+ var defaultPermissionSets = [
314
+ security.PermissionSetSchema.parse({
315
+ name: "admin_full_access",
316
+ label: "Administrator \u2014 Full Access",
317
+ isProfile: true,
318
+ objects: {
319
+ "*": {
320
+ allowRead: true,
321
+ allowCreate: true,
322
+ allowEdit: true,
323
+ allowDelete: true,
324
+ viewAllRecords: true,
325
+ modifyAllRecords: true
326
+ }
327
+ },
328
+ systemPermissions: ["manage_users", "manage_metadata", "setup.access"]
329
+ }),
330
+ security.PermissionSetSchema.parse({
331
+ name: "member_default",
332
+ label: "Member \u2014 Standard Access",
333
+ isProfile: true,
334
+ objects: {
335
+ "*": {
336
+ allowRead: true,
337
+ allowCreate: true,
338
+ allowEdit: true,
339
+ allowDelete: true
340
+ },
341
+ // Identity tables are managed by better-auth — no direct writes.
342
+ ...denyWritesOnManagedObjects()
343
+ },
344
+ rowLevelSecurity: [
345
+ {
346
+ name: "tenant_isolation",
347
+ object: "*",
348
+ operation: "all",
349
+ using: "organization_id = current_user.organization_id"
350
+ },
351
+ {
352
+ name: "owner_only_writes",
353
+ object: "*",
354
+ operation: "update",
355
+ using: "owner_id = current_user.id"
356
+ },
357
+ {
358
+ name: "owner_only_deletes",
359
+ object: "*",
360
+ operation: "delete",
361
+ using: "owner_id = current_user.id"
362
+ },
363
+ // ── better-auth system tables that lack `organization_id` and would
364
+ // otherwise be left unprotected by the wildcard rule above. ────
365
+ {
366
+ name: "sys_organization_self",
367
+ object: "sys_organization",
368
+ operation: "all",
369
+ using: "id = current_user.organization_id"
370
+ },
371
+ {
372
+ name: "sys_user_self",
373
+ object: "sys_user",
374
+ operation: "select",
375
+ using: "id = current_user.id"
376
+ }
377
+ ]
378
+ }),
379
+ security.PermissionSetSchema.parse({
380
+ name: "viewer_readonly",
381
+ label: "Viewer \u2014 Read-Only",
382
+ isProfile: true,
383
+ objects: {
384
+ "*": {
385
+ allowRead: true,
386
+ allowCreate: false,
387
+ allowEdit: false,
388
+ allowDelete: false
389
+ },
390
+ // Belt-and-suspenders: explicit deny on managed objects even though
391
+ // the wildcard already denies — keeps the policy readable when
392
+ // future relaxations might widen the wildcard.
393
+ ...denyWritesOnManagedObjects()
394
+ },
395
+ rowLevelSecurity: [
396
+ {
397
+ name: "tenant_isolation",
398
+ object: "*",
399
+ operation: "select",
400
+ using: "organization_id = current_user.organization_id"
401
+ },
402
+ {
403
+ name: "sys_organization_self",
404
+ object: "sys_organization",
405
+ operation: "select",
406
+ using: "id = current_user.organization_id"
407
+ },
408
+ {
409
+ name: "sys_user_self",
410
+ object: "sys_user",
411
+ operation: "select",
412
+ using: "id = current_user.id"
413
+ }
414
+ ]
415
+ })
416
+ ];
174
417
 
175
418
  exports.SysPermissionSet = SysPermissionSet;
176
419
  exports.SysRole = SysRole;
420
+ exports.SysRolePermissionSet = SysRolePermissionSet;
421
+ exports.SysUserPermissionSet = SysUserPermissionSet;
422
+ exports.defaultPermissionSets = defaultPermissionSets;
177
423
  //# sourceMappingURL=index.js.map
178
424
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/security/sys-role.object.ts","../../src/security/sys-permission-set.object.ts"],"names":["ObjectSchema","Field"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_role — System Role Object\n *\n * RBAC role definition for the ObjectStack platform.\n * Roles group permissions and are assigned to users or members.\n *\n * @namespace sys\n */\nexport const SysRole = ObjectSchema.create({\n name: 'sys_role',\n label: 'Role',\n pluralLabel: 'Roles',\n icon: 'shield',\n isSystem: true,\n description: 'Role definitions for RBAC access control',\n displayNameField: 'label',\n titleFormat: '{label}',\n compactLayout: ['label', 'name', 'active', 'is_default'],\n\n fields: {\n // ── Identity ─────────────────────────────────────────────────\n label: Field.text({\n label: 'Display Name',\n required: true,\n searchable: true,\n maxLength: 255,\n group: 'Identity',\n }),\n\n name: Field.text({\n label: 'API Name',\n required: true,\n searchable: true,\n maxLength: 100,\n description: 'Unique machine name for the role (e.g. admin, editor, viewer)',\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n // ── Configuration ────────────────────────────────────────────\n permissions: Field.textarea({\n label: 'Permissions',\n required: false,\n description: 'JSON-serialized array of permission strings',\n group: 'Configuration',\n }),\n\n // ── Status ───────────────────────────────────────────────────\n active: Field.boolean({\n label: 'Active',\n defaultValue: true,\n group: 'Status',\n }),\n\n is_default: Field.boolean({\n label: 'Default Role',\n defaultValue: false,\n description: 'Automatically assigned to new users',\n group: 'Status',\n }),\n\n // ── System ───────────────────────────────────────────────────\n id: Field.text({\n label: 'Role ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['active'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: true,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_permission_set — System Permission Set Object\n *\n * Named groupings of fine-grained permissions.\n * Permission sets can be assigned to roles or directly to users\n * for granular access control.\n *\n * @namespace sys\n */\nexport const SysPermissionSet = ObjectSchema.create({\n name: 'sys_permission_set',\n label: 'Permission Set',\n pluralLabel: 'Permission Sets',\n icon: 'lock',\n isSystem: true,\n description: 'Named permission groupings for fine-grained access control',\n displayNameField: 'label',\n titleFormat: '{label}',\n compactLayout: ['label', 'name', 'active'],\n\n fields: {\n // ── Identity ─────────────────────────────────────────────────\n label: Field.text({\n label: 'Display Name',\n required: true,\n searchable: true,\n maxLength: 255,\n group: 'Identity',\n }),\n\n name: Field.text({\n label: 'API Name',\n required: true,\n searchable: true,\n maxLength: 100,\n description: 'Unique machine name for the permission set',\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n // ── Permissions ──────────────────────────────────────────────\n object_permissions: Field.textarea({\n label: 'Object Permissions',\n required: false,\n description: 'JSON-serialized object-level CRUD permissions',\n group: 'Permissions',\n }),\n\n field_permissions: Field.textarea({\n label: 'Field Permissions',\n required: false,\n description: 'JSON-serialized field-level read/write permissions',\n group: 'Permissions',\n }),\n\n // ── Status ───────────────────────────────────────────────────\n active: Field.boolean({\n label: 'Active',\n defaultValue: true,\n group: 'Status',\n }),\n\n // ── System ───────────────────────────────────────────────────\n id: Field.text({\n label: 'Permission Set ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['active'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: true,\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/security/sys-role.object.ts","../../src/security/sys-permission-set.object.ts","../../src/security/sys-user-permission-set.object.ts","../../src/security/sys-role-permission-set.object.ts","../../src/security/default-permission-sets.ts"],"names":["ObjectSchema","Field","PermissionSetSchema"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_role — System Role Object\n *\n * RBAC role definition for the ObjectStack platform.\n * Roles group permissions and are assigned to users or members.\n *\n * @namespace sys\n */\nexport const SysRole = ObjectSchema.create({\n name: 'sys_role',\n label: 'Role',\n pluralLabel: 'Roles',\n icon: 'shield',\n isSystem: true,\n description: 'Role definitions for RBAC access control',\n displayNameField: 'label',\n titleFormat: '{label}',\n compactLayout: ['label', 'name', 'active', 'is_default'],\n\n fields: {\n // ── Identity ─────────────────────────────────────────────────\n label: Field.text({\n label: 'Display Name',\n required: true,\n searchable: true,\n maxLength: 255,\n group: 'Identity',\n }),\n\n name: Field.text({\n label: 'API Name',\n required: true,\n searchable: true,\n maxLength: 100,\n description: 'Unique machine name for the role (e.g. admin, editor, viewer)',\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n // ── Configuration ────────────────────────────────────────────\n permissions: Field.textarea({\n label: 'Permissions',\n required: false,\n description: 'JSON-serialized array of permission strings',\n group: 'Configuration',\n }),\n\n // ── Status ───────────────────────────────────────────────────\n active: Field.boolean({\n label: 'Active',\n defaultValue: true,\n group: 'Status',\n }),\n\n is_default: Field.boolean({\n label: 'Default Role',\n defaultValue: false,\n description: 'Automatically assigned to new users',\n group: 'Status',\n }),\n\n // ── System ───────────────────────────────────────────────────\n id: Field.text({\n label: 'Role ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['active'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: true,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_permission_set — System Permission Set Object\n *\n * Named groupings of fine-grained permissions.\n * Permission sets can be assigned to roles or directly to users\n * for granular access control.\n *\n * @namespace sys\n */\nexport const SysPermissionSet = ObjectSchema.create({\n name: 'sys_permission_set',\n label: 'Permission Set',\n pluralLabel: 'Permission Sets',\n icon: 'lock',\n isSystem: true,\n description: 'Named permission groupings for fine-grained access control',\n displayNameField: 'label',\n titleFormat: '{label}',\n compactLayout: ['label', 'name', 'active'],\n\n fields: {\n // ── Identity ─────────────────────────────────────────────────\n label: Field.text({\n label: 'Display Name',\n required: true,\n searchable: true,\n maxLength: 255,\n group: 'Identity',\n }),\n\n name: Field.text({\n label: 'API Name',\n required: true,\n searchable: true,\n maxLength: 100,\n description: 'Unique machine name for the permission set',\n group: 'Identity',\n }),\n\n description: Field.textarea({\n label: 'Description',\n required: false,\n group: 'Identity',\n }),\n\n // ── Permissions ──────────────────────────────────────────────\n object_permissions: Field.textarea({\n label: 'Object Permissions',\n required: false,\n description: 'JSON-serialized object-level CRUD permissions',\n group: 'Permissions',\n }),\n\n field_permissions: Field.textarea({\n label: 'Field Permissions',\n required: false,\n description: 'JSON-serialized field-level read/write permissions',\n group: 'Permissions',\n }),\n\n // ── Status ───────────────────────────────────────────────────\n active: Field.boolean({\n label: 'Active',\n defaultValue: true,\n group: 'Status',\n }),\n\n // ── System ───────────────────────────────────────────────────\n id: Field.text({\n label: 'Permission Set ID',\n required: true,\n readonly: true,\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['active'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: true,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_user_permission_set — User ↔ PermissionSet assignment.\n *\n * Salesforce-style additive permission grant: a user may be assigned any\n * number of `sys_permission_set` rows, optionally scoped to a specific\n * organization. The runtime resolver (`resolveExecutionContext` in\n * `@objectstack/runtime`) reads this table when building the per-request\n * `ExecutionContext.permissions[]`.\n *\n * Uniqueness is `(user_id, permission_set_id, organization_id)` so the\n * same permission set can be granted independently in each org context\n * the user belongs to.\n *\n * @namespace sys\n */\nexport const SysUserPermissionSet = ObjectSchema.create({\n name: 'sys_user_permission_set',\n label: 'User Permission Set',\n pluralLabel: 'User Permission Sets',\n icon: 'user-check',\n isSystem: true,\n description: 'Direct assignment of a permission set to a user (optionally scoped to an organization).',\n titleFormat: '{user_id} → {permission_set_id}',\n compactLayout: ['user_id', 'permission_set_id', 'organization_id'],\n\n fields: {\n id: Field.text({\n label: 'Assignment ID',\n required: true,\n readonly: true,\n description: 'UUID of the assignment.',\n }),\n\n user_id: Field.lookup('sys_user', {\n label: 'User',\n required: true,\n description: 'Foreign key to sys_user.',\n }),\n\n permission_set_id: Field.lookup('sys_permission_set', {\n label: 'Permission Set',\n required: true,\n description: 'Foreign key to sys_permission_set.',\n }),\n\n organization_id: Field.lookup('sys_organization', {\n label: 'Organization',\n required: false,\n description: 'Optional organization scope. NULL = applies in every org context.',\n }),\n\n granted_by: Field.lookup('sys_user', {\n label: 'Granted By',\n required: false,\n description: 'User who granted this permission set.',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n }),\n },\n\n indexes: [\n { fields: ['user_id', 'permission_set_id', 'organization_id'], unique: true },\n { fields: ['user_id'] },\n { fields: ['organization_id'] },\n { fields: ['permission_set_id'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: false,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_role_permission_set — Role ↔ PermissionSet binding.\n *\n * Allows administrators to compose a `sys_role` from one or more\n * `sys_permission_set` rows. At request time, the runtime resolver\n * (`resolveExecutionContext`) collects every permission set bound to\n * the user's roles via this table and injects their names into\n * `ExecutionContext.permissions[]` for downstream RBAC evaluation.\n *\n * @namespace sys\n */\nexport const SysRolePermissionSet = ObjectSchema.create({\n name: 'sys_role_permission_set',\n label: 'Role Permission Set',\n pluralLabel: 'Role Permission Sets',\n icon: 'shield-plus',\n isSystem: true,\n description: 'Binds a permission set to a role.',\n titleFormat: '{role_id} → {permission_set_id}',\n compactLayout: ['role_id', 'permission_set_id'],\n\n fields: {\n id: Field.text({\n label: 'Binding ID',\n required: true,\n readonly: true,\n description: 'UUID of the role-permission-set binding.',\n }),\n\n role_id: Field.lookup('sys_role', {\n label: 'Role',\n required: true,\n description: 'Foreign key to sys_role.',\n }),\n\n permission_set_id: Field.lookup('sys_permission_set', {\n label: 'Permission Set',\n required: true,\n description: 'Foreign key to sys_permission_set.',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n defaultValue: 'NOW()',\n readonly: true,\n }),\n\n updated_at: Field.datetime({\n label: 'Updated At',\n defaultValue: 'NOW()',\n readonly: true,\n }),\n },\n\n indexes: [\n { fields: ['role_id', 'permission_set_id'], unique: true },\n { fields: ['role_id'] },\n { fields: ['permission_set_id'] },\n ],\n\n enable: {\n trackHistory: true,\n searchable: true,\n apiEnabled: true,\n apiMethods: ['get', 'list', 'create', 'update', 'delete'],\n trash: true,\n mru: false,\n },\n});\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { PermissionSetSchema, type PermissionSet } from '@objectstack/spec/security';\n\n/**\n * Identity tables managed by the better-auth plugin (see\n * `packages/platform-objects/src/identity/`). Mutations to these tables\n * MUST flow through the better-auth API endpoints (sign-up, password\n * reset, organization invite/remove-member, api-key/create, …) rather\n * than the generic CRUD pipeline so that password hashing, token\n * signing, email verification, invitation flows and scope hashing all\n * fire correctly.\n *\n * The default member/viewer permission sets therefore explicitly DENY\n * `allowCreate / allowEdit / allowDelete` on these objects while still\n * permitting reads (subject to the rest of the RLS chain). Admin\n * permission sets keep their `*` wildcard so they can rescue data\n * directly when needed.\n *\n * Each entry mirrors the `managedBy: 'better-auth'` flag declared on\n * the corresponding object schema in `packages/platform-objects/src/identity/`.\n */\nconst BETTER_AUTH_MANAGED_OBJECTS = [\n 'sys_user',\n 'sys_account',\n 'sys_session',\n 'sys_organization',\n 'sys_member',\n 'sys_invitation',\n 'sys_team',\n 'sys_team_member',\n 'sys_api_key',\n 'sys_two_factor',\n 'sys_verification',\n 'sys_jwks',\n 'sys_device_code',\n 'sys_oauth_application',\n 'sys_oauth_access_token',\n 'sys_oauth_refresh_token',\n 'sys_oauth_consent',\n] as const;\n\nconst denyWritesOnManagedObjects = (): Record<string, {\n allowRead: boolean;\n allowCreate: boolean;\n allowEdit: boolean;\n allowDelete: boolean;\n}> => Object.fromEntries(\n BETTER_AUTH_MANAGED_OBJECTS.map((name) => [\n name,\n { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false },\n ]),\n);\n\n/**\n * Default permission sets seeded by the platform.\n *\n * These are referenced by name (`admin_full_access`, `member_default`,\n * `viewer_readonly`) from `sys_role_permission_set` rows or assigned\n * directly to users via `sys_user_permission_set`.\n *\n * The runtime SecurityPlugin reads these via the metadata service when a\n * permission set name appears in the request `ExecutionContext.permissions[]`.\n *\n * Each entry is run through `PermissionSetSchema.parse(...)` so Zod fills\n * in the boolean/`priority`/`enabled` defaults — keeping the literal\n * source readable while still satisfying the strict output type.\n *\n * `objects: { '*': … }` uses the wildcard sentinel honoured by\n * `PermissionEvaluator` — admins do not need an explicit row per object.\n * Per-object entries fully override the wildcard for that object (see\n * `PermissionEvaluator.checkObjectPermission` — lookup, not merge).\n *\n * RLS policies use the canonical `current_user.*` placeholders compiled\n * by `RLSCompiler`. The active organization is exposed under\n * `current_user.organization_id` (sourced from\n * `ExecutionContext.tenantId` at request time) — there is no rewrite\n * step or `tenantField` indirection in SecurityPlugin. Schemas with a\n * different physical tenant column should fork these defaults.\n */\nexport const defaultPermissionSets: PermissionSet[] = [\n PermissionSetSchema.parse({\n name: 'admin_full_access',\n label: 'Administrator — Full Access',\n isProfile: true,\n objects: {\n '*': {\n allowRead: true,\n allowCreate: true,\n allowEdit: true,\n allowDelete: true,\n viewAllRecords: true,\n modifyAllRecords: true,\n },\n },\n systemPermissions: ['manage_users', 'manage_metadata', 'setup.access'],\n }),\n PermissionSetSchema.parse({\n name: 'member_default',\n label: 'Member — Standard Access',\n isProfile: true,\n objects: {\n '*': {\n allowRead: true,\n allowCreate: true,\n allowEdit: true,\n allowDelete: true,\n },\n // Identity tables are managed by better-auth — no direct writes.\n ...denyWritesOnManagedObjects(),\n },\n rowLevelSecurity: [\n {\n name: 'tenant_isolation',\n object: '*',\n operation: 'all',\n using: 'organization_id = current_user.organization_id',\n },\n {\n name: 'owner_only_writes',\n object: '*',\n operation: 'update',\n using: 'owner_id = current_user.id',\n },\n {\n name: 'owner_only_deletes',\n object: '*',\n operation: 'delete',\n using: 'owner_id = current_user.id',\n },\n // ── better-auth system tables that lack `organization_id` and would\n // otherwise be left unprotected by the wildcard rule above. ────\n {\n name: 'sys_organization_self',\n object: 'sys_organization',\n operation: 'all',\n using: 'id = current_user.organization_id',\n },\n {\n name: 'sys_user_self',\n object: 'sys_user',\n operation: 'select',\n using: 'id = current_user.id',\n },\n ],\n }),\n PermissionSetSchema.parse({\n name: 'viewer_readonly',\n label: 'Viewer — Read-Only',\n isProfile: true,\n objects: {\n '*': {\n allowRead: true,\n allowCreate: false,\n allowEdit: false,\n allowDelete: false,\n },\n // Belt-and-suspenders: explicit deny on managed objects even though\n // the wildcard already denies — keeps the policy readable when\n // future relaxations might widen the wildcard.\n ...denyWritesOnManagedObjects(),\n },\n rowLevelSecurity: [\n {\n name: 'tenant_isolation',\n object: '*',\n operation: 'select',\n using: 'organization_id = current_user.organization_id',\n },\n {\n name: 'sys_organization_self',\n object: 'sys_organization',\n operation: 'select',\n using: 'id = current_user.organization_id',\n },\n {\n name: 'sys_user_self',\n object: 'sys_user',\n operation: 'select',\n using: 'id = current_user.id',\n },\n ],\n }),\n];\n"]}
@@ -1,4 +1,5 @@
1
1
  import { ObjectSchema, Field } from '@objectstack/spec/data';
2
+ import { PermissionSetSchema } from '@objectstack/spec/security';
2
3
 
3
4
  // src/security/sys-role.object.ts
4
5
  var SysRole = ObjectSchema.create({
@@ -169,7 +170,249 @@ var SysPermissionSet = ObjectSchema.create({
169
170
  mru: true
170
171
  }
171
172
  });
173
+ var SysUserPermissionSet = ObjectSchema.create({
174
+ name: "sys_user_permission_set",
175
+ label: "User Permission Set",
176
+ pluralLabel: "User Permission Sets",
177
+ icon: "user-check",
178
+ isSystem: true,
179
+ description: "Direct assignment of a permission set to a user (optionally scoped to an organization).",
180
+ titleFormat: "{user_id} \u2192 {permission_set_id}",
181
+ compactLayout: ["user_id", "permission_set_id", "organization_id"],
182
+ fields: {
183
+ id: Field.text({
184
+ label: "Assignment ID",
185
+ required: true,
186
+ readonly: true,
187
+ description: "UUID of the assignment."
188
+ }),
189
+ user_id: Field.lookup("sys_user", {
190
+ label: "User",
191
+ required: true,
192
+ description: "Foreign key to sys_user."
193
+ }),
194
+ permission_set_id: Field.lookup("sys_permission_set", {
195
+ label: "Permission Set",
196
+ required: true,
197
+ description: "Foreign key to sys_permission_set."
198
+ }),
199
+ organization_id: Field.lookup("sys_organization", {
200
+ label: "Organization",
201
+ required: false,
202
+ description: "Optional organization scope. NULL = applies in every org context."
203
+ }),
204
+ granted_by: Field.lookup("sys_user", {
205
+ label: "Granted By",
206
+ required: false,
207
+ description: "User who granted this permission set."
208
+ }),
209
+ created_at: Field.datetime({
210
+ label: "Created At",
211
+ defaultValue: "NOW()",
212
+ readonly: true
213
+ }),
214
+ updated_at: Field.datetime({
215
+ label: "Updated At",
216
+ defaultValue: "NOW()",
217
+ readonly: true
218
+ })
219
+ },
220
+ indexes: [
221
+ { fields: ["user_id", "permission_set_id", "organization_id"], unique: true },
222
+ { fields: ["user_id"] },
223
+ { fields: ["organization_id"] },
224
+ { fields: ["permission_set_id"] }
225
+ ],
226
+ enable: {
227
+ trackHistory: true,
228
+ searchable: true,
229
+ apiEnabled: true,
230
+ apiMethods: ["get", "list", "create", "update", "delete"],
231
+ trash: true,
232
+ mru: false
233
+ }
234
+ });
235
+ var SysRolePermissionSet = ObjectSchema.create({
236
+ name: "sys_role_permission_set",
237
+ label: "Role Permission Set",
238
+ pluralLabel: "Role Permission Sets",
239
+ icon: "shield-plus",
240
+ isSystem: true,
241
+ description: "Binds a permission set to a role.",
242
+ titleFormat: "{role_id} \u2192 {permission_set_id}",
243
+ compactLayout: ["role_id", "permission_set_id"],
244
+ fields: {
245
+ id: Field.text({
246
+ label: "Binding ID",
247
+ required: true,
248
+ readonly: true,
249
+ description: "UUID of the role-permission-set binding."
250
+ }),
251
+ role_id: Field.lookup("sys_role", {
252
+ label: "Role",
253
+ required: true,
254
+ description: "Foreign key to sys_role."
255
+ }),
256
+ permission_set_id: Field.lookup("sys_permission_set", {
257
+ label: "Permission Set",
258
+ required: true,
259
+ description: "Foreign key to sys_permission_set."
260
+ }),
261
+ created_at: Field.datetime({
262
+ label: "Created At",
263
+ defaultValue: "NOW()",
264
+ readonly: true
265
+ }),
266
+ updated_at: Field.datetime({
267
+ label: "Updated At",
268
+ defaultValue: "NOW()",
269
+ readonly: true
270
+ })
271
+ },
272
+ indexes: [
273
+ { fields: ["role_id", "permission_set_id"], unique: true },
274
+ { fields: ["role_id"] },
275
+ { fields: ["permission_set_id"] }
276
+ ],
277
+ enable: {
278
+ trackHistory: true,
279
+ searchable: true,
280
+ apiEnabled: true,
281
+ apiMethods: ["get", "list", "create", "update", "delete"],
282
+ trash: true,
283
+ mru: false
284
+ }
285
+ });
286
+ var BETTER_AUTH_MANAGED_OBJECTS = [
287
+ "sys_user",
288
+ "sys_account",
289
+ "sys_session",
290
+ "sys_organization",
291
+ "sys_member",
292
+ "sys_invitation",
293
+ "sys_team",
294
+ "sys_team_member",
295
+ "sys_api_key",
296
+ "sys_two_factor",
297
+ "sys_verification",
298
+ "sys_jwks",
299
+ "sys_device_code",
300
+ "sys_oauth_application",
301
+ "sys_oauth_access_token",
302
+ "sys_oauth_refresh_token",
303
+ "sys_oauth_consent"
304
+ ];
305
+ var denyWritesOnManagedObjects = () => Object.fromEntries(
306
+ BETTER_AUTH_MANAGED_OBJECTS.map((name) => [
307
+ name,
308
+ { allowRead: true, allowCreate: false, allowEdit: false, allowDelete: false }
309
+ ])
310
+ );
311
+ var defaultPermissionSets = [
312
+ PermissionSetSchema.parse({
313
+ name: "admin_full_access",
314
+ label: "Administrator \u2014 Full Access",
315
+ isProfile: true,
316
+ objects: {
317
+ "*": {
318
+ allowRead: true,
319
+ allowCreate: true,
320
+ allowEdit: true,
321
+ allowDelete: true,
322
+ viewAllRecords: true,
323
+ modifyAllRecords: true
324
+ }
325
+ },
326
+ systemPermissions: ["manage_users", "manage_metadata", "setup.access"]
327
+ }),
328
+ PermissionSetSchema.parse({
329
+ name: "member_default",
330
+ label: "Member \u2014 Standard Access",
331
+ isProfile: true,
332
+ objects: {
333
+ "*": {
334
+ allowRead: true,
335
+ allowCreate: true,
336
+ allowEdit: true,
337
+ allowDelete: true
338
+ },
339
+ // Identity tables are managed by better-auth — no direct writes.
340
+ ...denyWritesOnManagedObjects()
341
+ },
342
+ rowLevelSecurity: [
343
+ {
344
+ name: "tenant_isolation",
345
+ object: "*",
346
+ operation: "all",
347
+ using: "organization_id = current_user.organization_id"
348
+ },
349
+ {
350
+ name: "owner_only_writes",
351
+ object: "*",
352
+ operation: "update",
353
+ using: "owner_id = current_user.id"
354
+ },
355
+ {
356
+ name: "owner_only_deletes",
357
+ object: "*",
358
+ operation: "delete",
359
+ using: "owner_id = current_user.id"
360
+ },
361
+ // ── better-auth system tables that lack `organization_id` and would
362
+ // otherwise be left unprotected by the wildcard rule above. ────
363
+ {
364
+ name: "sys_organization_self",
365
+ object: "sys_organization",
366
+ operation: "all",
367
+ using: "id = current_user.organization_id"
368
+ },
369
+ {
370
+ name: "sys_user_self",
371
+ object: "sys_user",
372
+ operation: "select",
373
+ using: "id = current_user.id"
374
+ }
375
+ ]
376
+ }),
377
+ PermissionSetSchema.parse({
378
+ name: "viewer_readonly",
379
+ label: "Viewer \u2014 Read-Only",
380
+ isProfile: true,
381
+ objects: {
382
+ "*": {
383
+ allowRead: true,
384
+ allowCreate: false,
385
+ allowEdit: false,
386
+ allowDelete: false
387
+ },
388
+ // Belt-and-suspenders: explicit deny on managed objects even though
389
+ // the wildcard already denies — keeps the policy readable when
390
+ // future relaxations might widen the wildcard.
391
+ ...denyWritesOnManagedObjects()
392
+ },
393
+ rowLevelSecurity: [
394
+ {
395
+ name: "tenant_isolation",
396
+ object: "*",
397
+ operation: "select",
398
+ using: "organization_id = current_user.organization_id"
399
+ },
400
+ {
401
+ name: "sys_organization_self",
402
+ object: "sys_organization",
403
+ operation: "select",
404
+ using: "id = current_user.organization_id"
405
+ },
406
+ {
407
+ name: "sys_user_self",
408
+ object: "sys_user",
409
+ operation: "select",
410
+ using: "id = current_user.id"
411
+ }
412
+ ]
413
+ })
414
+ ];
172
415
 
173
- export { SysPermissionSet, SysRole };
416
+ export { SysPermissionSet, SysRole, SysRolePermissionSet, SysUserPermissionSet, defaultPermissionSets };
174
417
  //# sourceMappingURL=index.mjs.map
175
418
  //# sourceMappingURL=index.mjs.map