@objectstack/platform-objects 12.5.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,13 +37,14 @@ var SysUser = data.ObjectSchema.create({
37
37
  locations: ["list_toolbar"],
38
38
  type: "api",
39
39
  target: "/api/v1/auth/organization/invite-member",
40
- // Org invitations are a multi-org-only flow (the endpoint resolves
41
- // an active org that does not exist in single-org mode). Hide the
42
- // affordance unless multi-org is enabled matching the
43
- // `create_organization` gate on sys_organization. This action is the
44
- // most exposed of the set because the Users list is always reachable
45
- // in single-org, unlike the org/membership lists.
46
- visible: "features.multiOrgEnabled != false",
40
+ // Gated on the org CAPABILITY, not multi-org (ADR-0081 D1): the
41
+ // better-auth organization plugin is always mounted, and single-org
42
+ // mode now bootstraps a Default Organization (plugin-auth) so the
43
+ // endpoint's active-org resolution works there too. This is THE
44
+ // "add a teammate" affordance the Users list is always reachable
45
+ // and every add flows through better-auth invitations, never bespoke
46
+ // sys_user CRUD.
47
+ visible: "features.organization != false",
47
48
  successMessage: "Invitation sent",
48
49
  refreshAfter: true,
49
50
  params: [
@@ -932,6 +933,12 @@ var SysVerification = data.ObjectSchema.create({
932
933
  icon: "shield-check",
933
934
  isSystem: true,
934
935
  managedBy: "better-auth",
936
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE one-time credentials
937
+ // (email/phone verification + password-reset tokens) — reading one is
938
+ // account takeover. Not covered by the wildcard `'*'` grant; admins retain
939
+ // access via the superuser bypass; better-auth reads via its adapter
940
+ // (system context), so verification flows are unaffected.
941
+ access: { default: "private" },
935
942
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
936
943
  // but may add overlay row-level config. Use `no-overlay` if you need to
937
944
  // forbid sys_metadata overlays entirely.
@@ -1265,11 +1272,11 @@ var SysMember = data.ObjectSchema.create({
1265
1272
  locations: ["list_toolbar"],
1266
1273
  type: "api",
1267
1274
  target: "/api/v1/auth/organization/add-member",
1268
- // Org-membership mutations are multi-org-only: the better-auth
1269
- // endpoints resolve an active org that does not exist in single-org
1270
- // mode, so these actions would fail at the API. Gate every one on
1271
- // the multi-org flag (mirrors sys_organization.create_organization).
1272
- visible: "features.multiOrgEnabled != false",
1275
+ // Gated on the org CAPABILITY, not multi-org (ADR-0081 D1): the
1276
+ // better-auth endpoints resolve the session's active org, which
1277
+ // single-org mode now guarantees via plugin-auth's default-org
1278
+ // bootstrap. Same gate on every membership mutation below.
1279
+ visible: "features.organization != false",
1273
1280
  successMessage: "Member added",
1274
1281
  refreshAfter: true,
1275
1282
  params: [
@@ -1287,7 +1294,7 @@ var SysMember = data.ObjectSchema.create({
1287
1294
  type: "api",
1288
1295
  target: "/api/v1/auth/organization/update-member-role",
1289
1296
  recordIdParam: "memberId",
1290
- visible: "features.multiOrgEnabled != false",
1297
+ visible: "features.organization != false",
1291
1298
  successMessage: "Member role updated",
1292
1299
  refreshAfter: true,
1293
1300
  params: [
@@ -1304,7 +1311,7 @@ var SysMember = data.ObjectSchema.create({
1304
1311
  type: "api",
1305
1312
  target: "/api/v1/auth/organization/remove-member",
1306
1313
  recordIdParam: "memberIdOrEmail",
1307
- visible: "features.multiOrgEnabled != false",
1314
+ visible: "features.organization != false",
1308
1315
  confirmText: "Remove this member from the organization? They will lose access to all org resources.",
1309
1316
  successMessage: "Member removed",
1310
1317
  refreshAfter: true
@@ -1326,7 +1333,7 @@ var SysMember = data.ObjectSchema.create({
1326
1333
  target: "/api/v1/auth/organization/update-member-role",
1327
1334
  recordIdParam: "memberId",
1328
1335
  bodyExtra: { role: "owner" },
1329
- visible: "record.role != 'owner' && features.multiOrgEnabled != false",
1336
+ visible: "record.role != 'owner' && features.organization != false",
1330
1337
  confirmText: "Transfer ownership of this organization to the selected member? You will be demoted to admin and lose owner-only privileges.",
1331
1338
  successMessage: "Ownership transferred",
1332
1339
  refreshAfter: true
@@ -1434,7 +1441,7 @@ var SysInvitation = data.ObjectSchema.create({
1434
1441
  // sys_organization.create_organization). The recipient-side
1435
1442
  // accept/reject actions below stay record-gated — they are
1436
1443
  // unreachable in single-org anyway (no invitation rows exist).
1437
- visible: "features.multiOrgEnabled != false",
1444
+ visible: "features.organization != false",
1438
1445
  successMessage: "Invitation sent",
1439
1446
  refreshAfter: true,
1440
1447
  params: [
@@ -1452,7 +1459,7 @@ var SysInvitation = data.ObjectSchema.create({
1452
1459
  type: "api",
1453
1460
  target: "/api/v1/auth/organization/cancel-invitation",
1454
1461
  recordIdParam: "invitationId",
1455
- visible: "features.multiOrgEnabled != false",
1462
+ visible: "features.organization != false",
1456
1463
  confirmText: "Cancel this invitation? The recipient will no longer be able to accept it.",
1457
1464
  successMessage: "Invitation canceled",
1458
1465
  refreshAfter: true
@@ -1466,7 +1473,7 @@ var SysInvitation = data.ObjectSchema.create({
1466
1473
  type: "api",
1467
1474
  target: "/api/v1/auth/organization/invite-member",
1468
1475
  bodyExtra: { resend: true },
1469
- visible: "features.multiOrgEnabled != false",
1476
+ visible: "features.organization != false",
1470
1477
  successMessage: "Invitation resent",
1471
1478
  refreshAfter: true,
1472
1479
  params: [
@@ -1656,7 +1663,7 @@ var SysTeam = data.ObjectSchema.create({
1656
1663
  // Teams are nested inside organizations — a multi-org-only concept.
1657
1664
  // Gate every team mutation on the multi-org flag so the affordances
1658
1665
  // disappear in single-org (mirrors sys_organization.create_organization).
1659
- visible: "features.multiOrgEnabled != false",
1666
+ visible: "features.organization != false",
1660
1667
  successMessage: "Team created",
1661
1668
  refreshAfter: true,
1662
1669
  params: [
@@ -1677,7 +1684,7 @@ var SysTeam = data.ObjectSchema.create({
1677
1684
  target: "/api/v1/auth/organization/update-team",
1678
1685
  recordIdParam: "teamId",
1679
1686
  bodyShape: { wrap: "data" },
1680
- visible: "features.multiOrgEnabled != false",
1687
+ visible: "features.organization != false",
1681
1688
  successMessage: "Team updated",
1682
1689
  refreshAfter: true,
1683
1690
  params: [
@@ -1696,7 +1703,7 @@ var SysTeam = data.ObjectSchema.create({
1696
1703
  type: "api",
1697
1704
  target: "/api/v1/auth/organization/remove-team",
1698
1705
  recordIdParam: "teamId",
1699
- visible: "features.multiOrgEnabled != false",
1706
+ visible: "features.organization != false",
1700
1707
  confirmText: "Delete this team? Members will lose any team-scoped access. This cannot be undone.",
1701
1708
  successMessage: "Team deleted",
1702
1709
  refreshAfter: true
@@ -1810,7 +1817,7 @@ var SysTeamMember = data.ObjectSchema.create({
1810
1817
  // Team membership lives under organizations — multi-org-only. Gate
1811
1818
  // both mutations so they vanish in single-org (mirrors
1812
1819
  // sys_organization.create_organization).
1813
- visible: "features.multiOrgEnabled != false",
1820
+ visible: "features.organization != false",
1814
1821
  successMessage: "Team member added",
1815
1822
  refreshAfter: true,
1816
1823
  params: [
@@ -1831,7 +1838,7 @@ var SysTeamMember = data.ObjectSchema.create({
1831
1838
  locations: ["list_item"],
1832
1839
  type: "api",
1833
1840
  target: "/api/v1/auth/organization/remove-team-member",
1834
- visible: "features.multiOrgEnabled != false",
1841
+ visible: "features.organization != false",
1835
1842
  confirmText: "Remove this user from the team? They will lose any team-scoped access.",
1836
1843
  successMessage: "Team member removed",
1837
1844
  refreshAfter: true,
@@ -2069,7 +2076,7 @@ var SysBusinessUnitMember = data.ObjectSchema.create({
2069
2076
  managedBy: "platform",
2070
2077
  description: "User assignment to a business unit (matrix-org friendly, effective-dated).",
2071
2078
  titleFormat: "{user_id} in {business_unit_id}",
2072
- highlightFields: ["user_id", "business_unit_id", "role_in_business_unit", "is_primary"],
2079
+ highlightFields: ["user_id", "business_unit_id", "function_in_business_unit", "is_primary"],
2073
2080
  fields: {
2074
2081
  id: data.Field.text({
2075
2082
  label: "Member ID",
@@ -2087,10 +2094,10 @@ var SysBusinessUnitMember = data.ObjectSchema.create({
2087
2094
  required: true,
2088
2095
  group: "Assignment"
2089
2096
  }),
2090
- role_in_business_unit: data.Field.select(
2097
+ function_in_business_unit: data.Field.select(
2091
2098
  ["member", "lead", "deputy"],
2092
2099
  {
2093
- label: "Role in Business Unit",
2100
+ label: "Function in Business Unit",
2094
2101
  required: false,
2095
2102
  defaultValue: "member",
2096
2103
  description: "`lead` is the day-to-day head; `deputy` may stand in for the lead in approval routing.",
@@ -2494,6 +2501,12 @@ var SysDeviceCode = data.ObjectSchema.create({
2494
2501
  icon: "key-round",
2495
2502
  isSystem: true,
2496
2503
  managedBy: "better-auth",
2504
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE pending device-grant
2505
+ // codes — reading `user_code`/`device_code` lets an attacker hijack a
2506
+ // pending CLI login. Not covered by the wildcard `'*'` grant; admins retain
2507
+ // access via the superuser bypass; better-auth reads via its adapter
2508
+ // (system context), so the device-grant flow is unaffected.
2509
+ access: { default: "private" },
2497
2510
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
2498
2511
  // but may add overlay row-level config. Use `no-overlay` if you need to
2499
2512
  // forbid sys_metadata overlays entirely.
@@ -3089,6 +3102,11 @@ var SysOauthAccessToken = data.ObjectSchema.create({
3089
3102
  icon: "ticket",
3090
3103
  isSystem: true,
3091
3104
  managedBy: "better-auth",
3105
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE bearer credentials —
3106
+ // reading one is session hijack. Not covered by the wildcard `'*'` grant;
3107
+ // admins retain access via the superuser bypass; better-auth reads via its
3108
+ // adapter (system context), so OAuth flows are unaffected.
3109
+ access: { default: "private" },
3092
3110
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3093
3111
  // but may add overlay row-level config. Use `no-overlay` if you need to
3094
3112
  // forbid sys_metadata overlays entirely.
@@ -3175,6 +3193,11 @@ var SysOauthRefreshToken = data.ObjectSchema.create({
3175
3193
  icon: "refresh-cw",
3176
3194
  isSystem: true,
3177
3195
  managedBy: "better-auth",
3196
+ // [ADR-0066 D2/④] Secure-by-default: rows are LIVE long-lived credentials —
3197
+ // a refresh token mints new access tokens. Not covered by the wildcard `'*'`
3198
+ // grant; admins retain access via the superuser bypass; better-auth reads
3199
+ // via its adapter (system context), so OAuth flows are unaffected.
3200
+ access: { default: "private" },
3178
3201
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3179
3202
  // but may add overlay row-level config. Use `no-overlay` if you need to
3180
3203
  // forbid sys_metadata overlays entirely.
@@ -3333,6 +3356,13 @@ var SysJwks = data.ObjectSchema.create({
3333
3356
  icon: "key",
3334
3357
  isSystem: true,
3335
3358
  managedBy: "better-auth",
3359
+ // [ADR-0066 D2/④] Secure-by-default: rows are the environment's JWT SIGNING
3360
+ // KEYS (private key material). Not covered by the wildcard `'*'` grant — an
3361
+ // ordinary member gets 403 from the generic data layer. Platform admins
3362
+ // (viewAllRecords/modifyAllRecords) retain access via the posture-gated
3363
+ // superuser bypass; better-auth itself reads via its adapter (system
3364
+ // context), so token signing/verification is unaffected.
3365
+ access: { default: "private" },
3336
3366
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema,
3337
3367
  // but may add overlay row-level config. Use `no-overlay` if you need to
3338
3368
  // forbid sys_metadata overlays entirely.
@@ -3646,6 +3676,14 @@ var SysScimProvider = data.ObjectSchema.create({
3646
3676
  icon: "users",
3647
3677
  isSystem: true,
3648
3678
  managedBy: "better-auth",
3679
+ // [ADR-0066 D3/④] Admin-only identity config carrying a live credential
3680
+ // (`scim_token` — the bearer external IdPs authenticate provisioning calls
3681
+ // with). Object-level capability gate, mirroring the sibling
3682
+ // `sys_sso_provider`: ordinary members are denied entirely (without it, the
3683
+ // `member_default` wildcard `'*': allowRead` would expose SCIM connections
3684
+ // to every authenticated user). better-auth's own endpoints read via a
3685
+ // system context, so SCIM provisioning is unaffected.
3686
+ requiredPermissions: ["manage_platform_settings"],
3649
3687
  // ADR-0010 §3.7 — managed by better-auth; tenants may not edit schema.
3650
3688
  protection: {
3651
3689
  lock: "full",