@checkstack/auth-backend 0.1.0 → 0.2.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.
@@ -29,6 +29,13 @@
29
29
  "when": 1768332454744,
30
30
  "tag": "0003_tranquil_sally_floyd",
31
31
  "breakpoints": true
32
+ },
33
+ {
34
+ "idx": 4,
35
+ "version": "7",
36
+ "when": 1768390244988,
37
+ "tag": "0004_lucky_power_man",
38
+ "breakpoints": true
32
39
  }
33
40
  ]
34
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/auth-backend",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
package/src/index.ts CHANGED
@@ -10,10 +10,10 @@ import {
10
10
  } from "@checkstack/backend-api";
11
11
  import {
12
12
  pluginMetadata,
13
- permissionList,
13
+ authAccessRules,
14
+ authAccess,
14
15
  authContract,
15
16
  authRoutes,
16
- permissions,
17
17
  } from "@checkstack/auth-common";
18
18
  import { NotificationApi } from "@checkstack/notification-common";
19
19
  import * as schema from "./schema";
@@ -47,145 +47,148 @@ export const betterAuthExtensionPoint =
47
47
  );
48
48
 
49
49
  /**
50
- * Sync permissions to database and assign to admin role.
50
+ * Sync access rules to database and assign to admin role.
51
51
  * @param fullSync - If true, also performs orphan cleanup and default role sync.
52
- * Should only be true when syncing ALL permissions (not per-plugin hooks).
52
+ * Should only be true when syncing ALL access rules (not per-plugin hooks).
53
53
  */
54
- async function syncPermissionsToDb({
54
+ async function syncAccessRulesToDb({
55
55
  database,
56
56
  logger,
57
- permissions,
57
+ accessRules,
58
58
  fullSync = false,
59
59
  }: {
60
60
  database: NodePgDatabase<typeof schema>;
61
61
  logger: { debug: (msg: string) => void };
62
- permissions: {
62
+ accessRules: {
63
63
  id: string;
64
64
  description?: string;
65
- isAuthenticatedDefault?: boolean;
66
- isPublicDefault?: boolean;
65
+ isDefault?: boolean;
66
+ isPublic?: boolean;
67
67
  }[];
68
68
  fullSync?: boolean;
69
69
  }) {
70
- logger.debug(`🔑 Syncing ${permissions.length} permissions to database...`);
71
-
72
- for (const perm of permissions) {
70
+ logger.debug(`🔑 Syncing ${accessRules.length} access rules to database...`);
71
+
72
+ for (const rule of accessRules) {
73
+ // Map AccessRule fields to DB fields
74
+ const dbRecord = {
75
+ id: rule.id,
76
+ description: rule.description,
77
+ isAuthenticatedDefault: rule.isDefault,
78
+ isPublicDefault: rule.isPublic,
79
+ };
73
80
  const existing = await database
74
81
  .select()
75
- .from(schema.permission)
76
- .where(eq(schema.permission.id, perm.id));
82
+ .from(schema.accessRule)
83
+ .where(eq(schema.accessRule.id, rule.id));
77
84
 
78
85
  if (existing.length === 0) {
79
- await database.insert(schema.permission).values(perm);
80
- logger.debug(` -> Created permission: ${perm.id}`);
86
+ await database.insert(schema.accessRule).values(dbRecord);
87
+ logger.debug(` -> Created access rule: ${rule.id}`);
81
88
  } else {
82
89
  await database
83
- .update(schema.permission)
84
- .set({ description: perm.description })
85
- .where(eq(schema.permission.id, perm.id));
90
+ .update(schema.accessRule)
91
+ .set({ description: rule.description })
92
+ .where(eq(schema.accessRule.id, rule.id));
86
93
  }
87
94
  }
88
95
 
89
- // Assign all permissions to admin role
90
- const adminRolePermissions = await database
96
+ // Assign all access rules to admin role
97
+ const adminRoleAccessRules = await database
91
98
  .select()
92
- .from(schema.rolePermission)
93
- .where(eq(schema.rolePermission.roleId, "admin"));
99
+ .from(schema.roleAccessRule)
100
+ .where(eq(schema.roleAccessRule.roleId, "admin"));
94
101
 
95
- for (const perm of permissions) {
96
- const hasPermission = adminRolePermissions.some(
97
- (rp) => rp.permissionId === perm.id
102
+ for (const rule of accessRules) {
103
+ const hasAccess = adminRoleAccessRules.some(
104
+ (rp) => rp.accessRuleId === rule.id
98
105
  );
99
106
 
100
- if (!hasPermission) {
107
+ if (!hasAccess) {
101
108
  await database
102
- .insert(schema.rolePermission)
109
+ .insert(schema.roleAccessRule)
103
110
  .values({
104
111
  roleId: "admin",
105
- permissionId: perm.id,
112
+ accessRuleId: rule.id,
106
113
  })
107
114
  .onConflictDoNothing();
108
- logger.debug(` -> Assigned permission ${perm.id} to admin role`);
115
+ logger.debug(` -> Assigned access rule ${rule.id} to admin role`);
109
116
  }
110
117
  }
111
118
 
112
119
  // Only perform orphan cleanup and default sync when doing a full sync
113
- // (i.e., when we have ALL permissions, not just one plugin's permissions from a hook)
120
+ // (i.e., when we have ALL access rules, not just one plugin's access rules from a hook)
114
121
  if (!fullSync) {
115
122
  return;
116
123
  }
117
124
 
118
- // Cleanup orphan permissions (no longer registered by any plugin)
119
- const registeredIds = new Set(permissions.map((p) => p.id));
120
- const allDbPermissions = await database.select().from(schema.permission);
121
- const orphanPermissions = allDbPermissions.filter(
125
+ // Cleanup orphan access rules (no longer registered by any plugin)
126
+ const registeredIds = new Set(accessRules.map((r) => r.id));
127
+ const allDbAccessRules = await database.select().from(schema.accessRule);
128
+ const orphanAccessRules = allDbAccessRules.filter(
122
129
  (p) => !registeredIds.has(p.id)
123
130
  );
124
131
 
125
- if (orphanPermissions.length > 0) {
132
+ if (orphanAccessRules.length > 0) {
126
133
  logger.debug(
127
- `🧹 Removing ${orphanPermissions.length} orphan permission(s)...`
134
+ `🧹 Removing ${orphanAccessRules.length} orphan access rule(s)...`
128
135
  );
129
- for (const orphan of orphanPermissions) {
130
- // Delete role_permission entries first (FK doesn't cascade)
136
+ for (const orphan of orphanAccessRules) {
137
+ // Delete role_access_rule entries first (FK doesn't cascade)
131
138
  await database
132
- .delete(schema.rolePermission)
133
- .where(eq(schema.rolePermission.permissionId, orphan.id));
134
- // Then delete the permission itself
139
+ .delete(schema.roleAccessRule)
140
+ .where(eq(schema.roleAccessRule.accessRuleId, orphan.id));
141
+ // Then delete the access rule itself
135
142
  await database
136
- .delete(schema.permission)
137
- .where(eq(schema.permission.id, orphan.id));
138
- logger.debug(` -> Removed orphan permission: ${orphan.id}`);
143
+ .delete(schema.accessRule)
144
+ .where(eq(schema.accessRule.id, orphan.id));
145
+ logger.debug(` -> Removed orphan access rule: ${orphan.id}`);
139
146
  }
140
147
  }
141
148
 
142
- // Sync authenticated default permissions to users role
143
- await syncAuthenticatedDefaultPermissionsToUsersRole({
149
+ // Sync authenticated default access rules to users role
150
+ await syncAuthenticatedDefaultAccessRulesToUsersRole({
144
151
  database,
145
152
  logger,
146
- permissions,
153
+ accessRules,
147
154
  });
148
155
 
149
- // Sync public default permissions to anonymous role
150
- await syncPublicDefaultPermissionsToAnonymousRole({
156
+ // Sync public default access rules to anonymous role
157
+ await syncPublicDefaultAccessRulesToAnonymousRole({
151
158
  database,
152
159
  logger,
153
- permissions,
160
+ accessRules,
154
161
  });
155
162
  }
156
163
 
157
164
  /**
158
- * Sync authenticated default permissions (isAuthenticatedDefault=true) to the "users" role.
159
- * Respects admin-disabled defaults stored in disabled_default_permission table.
165
+ * Sync authenticated default access rules (isAuthenticatedDefault=true) to the "users" role.
166
+ * Respects admin-disabled defaults stored in disabled_default_access_rule table.
160
167
  */
161
- async function syncAuthenticatedDefaultPermissionsToUsersRole({
168
+ async function syncAuthenticatedDefaultAccessRulesToUsersRole({
162
169
  database,
163
170
  logger,
164
- permissions,
171
+ accessRules,
165
172
  }: {
166
173
  database: NodePgDatabase<typeof schema>;
167
174
  logger: { debug: (msg: string) => void };
168
- permissions: { id: string; isAuthenticatedDefault?: boolean }[];
175
+ accessRules: { id: string; isDefault?: boolean }[];
169
176
  }) {
170
- // Debug: log all permissions with their isAuthenticatedDefault status
177
+ // Debug: log all access rules with their isDefault status
171
178
  logger.debug(
172
- `[DEBUG] All permissions received (${permissions.length} total):`
179
+ `[DEBUG] All access rules received (${accessRules.length} total):`
173
180
  );
174
- for (const p of permissions) {
175
- logger.debug(
176
- ` -> ${p.id}: isAuthenticatedDefault=${p.isAuthenticatedDefault}`
177
- );
181
+ for (const r of accessRules) {
182
+ logger.debug(` -> ${r.id}: isDefault=${r.isDefault}`);
178
183
  }
179
184
 
180
- const defaultPermissions = permissions.filter(
181
- (p) => p.isAuthenticatedDefault
182
- );
185
+ const defaultRules = accessRules.filter((r) => r.isDefault);
183
186
  logger.debug(
184
- `👥 Found ${defaultPermissions.length} authenticated default permissions to sync to users role`
187
+ `👥 Found ${defaultRules.length} authenticated default access rules to sync to users role`
185
188
  );
186
- if (defaultPermissions.length === 0) {
189
+ if (defaultRules.length === 0) {
187
190
  logger.debug(
188
- ` -> No authenticated default permissions found, skipping sync`
191
+ ` -> No authenticated default access rules found, skipping sync`
189
192
  );
190
193
  return;
191
194
  }
@@ -193,90 +196,90 @@ async function syncAuthenticatedDefaultPermissionsToUsersRole({
193
196
  // Get already disabled defaults (admin has removed them)
194
197
  const disabledDefaults = await database
195
198
  .select()
196
- .from(schema.disabledDefaultPermission);
197
- const disabledIds = new Set(disabledDefaults.map((d) => d.permissionId));
199
+ .from(schema.disabledDefaultAccessRule);
200
+ const disabledIds = new Set(disabledDefaults.map((d) => d.accessRuleId));
198
201
 
199
- // Get current users role permissions
200
- const usersRolePermissions = await database
202
+ // Get current users role access rules
203
+ const usersRoleAccessRules = await database
201
204
  .select()
202
- .from(schema.rolePermission)
203
- .where(eq(schema.rolePermission.roleId, "users"));
205
+ .from(schema.roleAccessRule)
206
+ .where(eq(schema.roleAccessRule.roleId, "users"));
204
207
 
205
- for (const perm of defaultPermissions) {
208
+ for (const rule of defaultRules) {
206
209
  // Skip if admin has disabled this default
207
- if (disabledIds.has(perm.id)) {
208
- logger.debug(` -> Skipping disabled authenticated default: ${perm.id}`);
210
+ if (disabledIds.has(rule.id)) {
211
+ logger.debug(` -> Skipping disabled authenticated default: ${rule.id}`);
209
212
  continue;
210
213
  }
211
214
 
212
- const hasPermission = usersRolePermissions.some(
213
- (rp) => rp.permissionId === perm.id
215
+ const hasAccess = usersRoleAccessRules.some(
216
+ (rp) => rp.accessRuleId === rule.id
214
217
  );
215
218
 
216
- if (!hasPermission) {
217
- await database.insert(schema.rolePermission).values({
219
+ if (!hasAccess) {
220
+ await database.insert(schema.roleAccessRule).values({
218
221
  roleId: "users",
219
- permissionId: perm.id,
222
+ accessRuleId: rule.id,
220
223
  });
221
224
  logger.debug(
222
- ` -> Assigned authenticated default permission ${perm.id} to users role`
225
+ ` -> Assigned authenticated default access rule ${rule.id} to users role`
223
226
  );
224
227
  }
225
228
  }
226
229
  }
227
230
 
228
231
  /**
229
- * Sync public default permissions (isPublicDefault=true) to the "anonymous" role.
230
- * Respects admin-disabled defaults stored in disabled_public_default_permission table.
232
+ * Sync public default access rules (isPublic=true) to the "anonymous" role.
233
+ * Respects admin-disabled defaults stored in disabled_public_default_access_rule table.
231
234
  */
232
- async function syncPublicDefaultPermissionsToAnonymousRole({
235
+ async function syncPublicDefaultAccessRulesToAnonymousRole({
233
236
  database,
234
237
  logger,
235
- permissions,
238
+ accessRules,
236
239
  }: {
237
240
  database: NodePgDatabase<typeof schema>;
238
241
  logger: { debug: (msg: string) => void };
239
- permissions: { id: string; isPublicDefault?: boolean }[];
242
+ accessRules: { id: string; isPublic?: boolean }[];
240
243
  }) {
241
- const publicDefaults = permissions.filter((p) => p.isPublicDefault);
244
+ const publicDefaults = accessRules.filter((r) => r.isPublic);
242
245
  logger.debug(
243
- `🌐 Found ${publicDefaults.length} public default permissions to sync to anonymous role`
246
+ `🌐 Found ${publicDefaults.length} public default access rules to sync to anonymous role`
244
247
  );
245
248
  if (publicDefaults.length === 0) {
246
- logger.debug(` -> No public default permissions found, skipping sync`);
249
+ logger.debug(` -> No public default access rules found, skipping sync`);
247
250
  return;
248
251
  }
249
252
 
250
253
  // Get already disabled public defaults (admin has removed them)
251
254
  const disabledDefaults = await database
252
255
  .select()
253
- .from(schema.disabledPublicDefaultPermission);
254
- const disabledIds = new Set(disabledDefaults.map((d) => d.permissionId));
256
+ .from(schema.disabledPublicDefaultAccessRule);
257
+ const disabledIds = new Set(disabledDefaults.map((d) => d.accessRuleId));
255
258
 
256
- // Get current anonymous role permissions
257
- const anonymousRolePermissions = await database
259
+ // Get current anonymous role access rules
260
+ const anonymousRoleAccessRules = await database
258
261
  .select()
259
- .from(schema.rolePermission)
260
- .where(eq(schema.rolePermission.roleId, "anonymous"));
262
+ .from(schema.roleAccessRule)
263
+ .where(eq(schema.roleAccessRule.roleId, "anonymous"));
261
264
 
262
- for (const perm of publicDefaults) {
265
+ for (const rule of publicDefaults) {
263
266
  // Skip if admin has disabled this public default
264
- if (disabledIds.has(perm.id)) {
265
- logger.debug(` -> Skipping disabled public default: ${perm.id}`);
267
+ if (disabledIds.has(rule.id)) {
268
+ logger.debug(` -> Skipping disabled public default: ${rule.id}`);
266
269
  continue;
267
270
  }
268
271
 
269
- const hasPermission = anonymousRolePermissions.some(
270
- (rp) => rp.permissionId === perm.id
272
+ const hasAccess = anonymousRoleAccessRules.some(
273
+ (rp) => rp.accessRuleId === rule.id
271
274
  );
272
275
 
273
- if (!hasPermission) {
274
- await database.insert(schema.rolePermission).values({
276
+ if (!hasAccess) {
277
+ await database.insert(schema.roleAccessRule).values({
275
278
  roleId: "anonymous",
276
- permissionId: perm.id,
279
+ accessRuleId: rule.id,
277
280
  });
278
281
  logger.debug(
279
- ` -> Assigned public default permission ${perm.id} to anonymous role`
282
+ ` -> Assigned public default access rule ${rule.id} to anonymous role`
280
283
  );
281
284
  }
282
285
  }
@@ -295,15 +298,15 @@ export default createBackendPlugin({
295
298
  getStrategies: () => strategies,
296
299
  };
297
300
 
298
- // Permission registry - gets all permissions from PluginManager
299
- const permissionRegistry = {
300
- getPermissions: () => {
301
- // Get all permissions from the central PluginManager registry
302
- return env.pluginManager.getAllPermissions();
301
+ // Access rule registry - gets all access rules from PluginManager
302
+ const accessRuleRegistry = {
303
+ getAccessRules: () => {
304
+ // Get all access rules from the central PluginManager registry
305
+ return env.pluginManager.getAllAccessRules();
303
306
  },
304
307
  };
305
308
 
306
- env.registerPermissions(permissionList);
309
+ env.registerAccessRules(authAccessRules);
307
310
 
308
311
  env.registerExtensionPoint(betterAuthExtensionPoint, {
309
312
  addStrategy: (s) => {
@@ -321,7 +324,7 @@ export default createBackendPlugin({
321
324
  },
322
325
  });
323
326
 
324
- // Helper to fetch permissions
327
+ // Helper to fetch access rules
325
328
  const enrichUserLocal = async (user: User) => {
326
329
  if (!db) return user;
327
330
  return enrichUser(user, db);
@@ -377,7 +380,7 @@ export default createBackendPlugin({
377
380
  // Ignore errors from lastUsedAt update
378
381
  });
379
382
 
380
- // Fetch roles and compute permissions for the application
383
+ // Fetch roles and compute access rules for the application
381
384
  const appRoles = await db
382
385
  .select({ roleId: schema.applicationRole.roleId })
383
386
  .from(schema.applicationRole)
@@ -387,18 +390,18 @@ export default createBackendPlugin({
387
390
 
388
391
  const roleIds = appRoles.map((r) => r.roleId);
389
392
 
390
- // Get permissions for these roles
391
- let permissions: string[] = [];
393
+ // Get access rules for these roles
394
+ let accessRulesArray: string[] = [];
392
395
  if (roleIds.length > 0) {
393
396
  const rolePerms = await db
394
397
  .select({
395
- permissionId: schema.rolePermission.permissionId,
398
+ accessRuleId: schema.roleAccessRule.accessRuleId,
396
399
  })
397
- .from(schema.rolePermission)
398
- .where(inArray(schema.rolePermission.roleId, roleIds));
400
+ .from(schema.roleAccessRule)
401
+ .where(inArray(schema.roleAccessRule.roleId, roleIds));
399
402
 
400
- permissions = [
401
- ...new Set(rolePerms.map((rp) => rp.permissionId)),
403
+ accessRulesArray = [
404
+ ...new Set(rolePerms.map((rp) => rp.accessRuleId)),
402
405
  ];
403
406
  }
404
407
 
@@ -417,7 +420,7 @@ export default createBackendPlugin({
417
420
  id: app.id,
418
421
  name: app.name,
419
422
  roles: roleIds,
420
- permissions,
423
+ accessRulesArray,
421
424
  teamIds,
422
425
  };
423
426
  }
@@ -549,6 +552,7 @@ export default createBackendPlugin({
549
552
  }),
550
553
  emailAndPassword: {
551
554
  enabled: credentialEnabled,
555
+ autoSignIn: true, // Log in user immediately after successful registration
552
556
  disableSignUp: !registrationAllowed,
553
557
  minPasswordLength: 8,
554
558
  maxPasswordLength: 128,
@@ -634,7 +638,7 @@ export default createBackendPlugin({
634
638
  logger.info("[auth-backend] ✅ Authentication reloaded successfully");
635
639
  };
636
640
 
637
- // IMPORTANT: Seed roles BEFORE syncing permissions so default perms can be assigned
641
+ // IMPORTANT: Seed roles BEFORE syncing access rules so default perms can be assigned
638
642
  logger.debug("🌱 Checking for initial roles...");
639
643
  const adminRole = await database
640
644
  .select()
@@ -649,7 +653,7 @@ export default createBackendPlugin({
649
653
  logger.info(" -> Created 'admin' role.");
650
654
  }
651
655
 
652
- // Seed "users" role for default permissions
656
+ // Seed "users" role for default access rules
653
657
  const usersRole = await database
654
658
  .select()
655
659
  .from(schema.role)
@@ -673,7 +677,7 @@ export default createBackendPlugin({
673
677
  await database.insert(schema.role).values({
674
678
  id: "anonymous",
675
679
  name: "Anonymous Users",
676
- description: "Permissions for unauthenticated (anonymous) users",
680
+ description: "Access rules for unauthenticated (anonymous) users",
677
681
  isSystem: true,
678
682
  });
679
683
  logger.info(" -> Created 'anonymous' role.");
@@ -694,7 +698,7 @@ export default createBackendPlugin({
694
698
  logger.info(" -> Created 'applications' role.");
695
699
  }
696
700
 
697
- // Note: Permission sync happens in afterPluginsReady (when all plugins have registered)
701
+ // Note: Access rule sync happens in afterPluginsReady (when all plugins have registered)
698
702
 
699
703
  // 4. Register oRPC router
700
704
  const authRouter = createAuthRouter(
@@ -702,7 +706,7 @@ export default createBackendPlugin({
702
706
  strategyRegistry,
703
707
  reloadAuth,
704
708
  config,
705
- permissionRegistry
709
+ accessRuleRegistry
706
710
  );
707
711
  rpc.registerRouter(authRouter, authContract);
708
712
 
@@ -766,7 +770,7 @@ export default createBackendPlugin({
766
770
  iconName: "Users",
767
771
  shortcuts: ["meta+shift+u", "ctrl+shift+u"],
768
772
  route: resolveRoute(authRoutes.routes.settings) + "?tab=users",
769
- requiredPermissions: [permissions.usersRead],
773
+ requiredAccessRules: [authAccess.users.read],
770
774
  },
771
775
  {
772
776
  id: "createUser",
@@ -776,15 +780,15 @@ export default createBackendPlugin({
776
780
  route:
777
781
  resolveRoute(authRoutes.routes.settings) +
778
782
  "?tab=users&action=create",
779
- requiredPermissions: [permissions.usersCreate],
783
+ requiredAccessRules: [authAccess.users.create],
780
784
  },
781
785
  {
782
786
  id: "roles",
783
787
  title: "Manage Roles",
784
- subtitle: "Manage roles and permissions",
788
+ subtitle: "Manage roles and access rules",
785
789
  iconName: "Shield",
786
790
  route: resolveRoute(authRoutes.routes.settings) + "?tab=roles",
787
- requiredPermissions: [permissions.rolesRead],
791
+ requiredAccessRules: [authAccess.roles.read],
788
792
  },
789
793
  {
790
794
  id: "applications",
@@ -793,82 +797,82 @@ export default createBackendPlugin({
793
797
  iconName: "Key",
794
798
  route:
795
799
  resolveRoute(authRoutes.routes.settings) + "?tab=applications",
796
- requiredPermissions: [permissions.applicationsManage],
800
+ requiredAccessRules: [authAccess.applications],
797
801
  },
798
802
  ],
799
803
  });
800
804
 
801
805
  logger.debug("✅ Auth Backend initialized.");
802
806
  },
803
- // Phase 3: After all plugins are ready - sync all permissions including defaults
807
+ // Phase 3: After all plugins are ready - sync all access rules including defaults
804
808
  afterPluginsReady: async ({ database, logger, onHook }) => {
805
- // Now that all plugins are ready, sync permissions including defaults
809
+ // Now that all plugins are ready, sync access rules including defaults
806
810
  // This is critical because during init, other plugins haven't registered yet
807
- const allPermissions = permissionRegistry.getPermissions();
811
+ const allAccessRules = accessRuleRegistry.getAccessRules();
808
812
  logger.debug(
809
- `[auth-backend] afterPluginsReady: syncing ${allPermissions.length} permissions from all plugins`
813
+ `[auth-backend] afterPluginsReady: syncing ${allAccessRules.length} access rules from all plugins`
810
814
  );
811
- await syncPermissionsToDb({
815
+ await syncAccessRulesToDb({
812
816
  database: database as NodePgDatabase<typeof schema>,
813
817
  logger,
814
- permissions: allPermissions,
818
+ accessRules: allAccessRules,
815
819
  fullSync: true,
816
820
  });
817
821
 
818
- // Subscribe to permission registration hook for future registrations
819
- // This syncs new permissions when other plugins register them dynamically
822
+ // Subscribe to access rule registration hook for future registrations
823
+ // This syncs new access rules when other plugins register them dynamically
820
824
  onHook(
821
- coreHooks.permissionsRegistered,
822
- async ({ permissions }) => {
823
- await syncPermissionsToDb({
825
+ coreHooks.accessRulesRegistered,
826
+ async ({ accessRules }) => {
827
+ await syncAccessRulesToDb({
824
828
  database: database as NodePgDatabase<typeof schema>,
825
829
  logger,
826
- permissions,
830
+ accessRules,
827
831
  });
828
832
  },
829
833
  {
830
834
  mode: "work-queue",
831
- workerGroup: "permission-db-sync",
835
+ workerGroup: "access-rule-db-sync",
832
836
  maxRetries: 5,
833
837
  }
834
838
  );
835
839
 
836
- // Subscribe to plugin deregistered hook for permission cleanup
837
- // When a plugin is removed at runtime, delete its permissions from DB
840
+ // Subscribe to plugin deregistered hook for access rule cleanup
841
+ // When a plugin is removed at runtime, delete its access rules from DB
838
842
  onHook(
839
843
  coreHooks.pluginDeregistered,
840
844
  async ({ pluginId }) => {
841
845
  logger.debug(
842
- `[auth-backend] Cleaning up permissions for deregistered plugin: ${pluginId}`
846
+ `[auth-backend] Cleaning up access rules for deregistered plugin: ${pluginId}`
843
847
  );
844
848
 
845
- // Delete all permissions with this plugin's prefix
846
- const allDbPermissions = await database
849
+ // Delete all access rules with this plugin's prefix
850
+ const allDbAccessRules = await database
847
851
  .select()
848
- .from(schema.permission);
849
- const pluginPermissions = allDbPermissions.filter((p) =>
852
+ .from(schema.accessRule);
853
+ const pluginAccessRules = allDbAccessRules.filter((p) =>
850
854
  p.id.startsWith(`${pluginId}.`)
851
855
  );
852
856
 
853
- for (const perm of pluginPermissions) {
854
- // Delete role_permission entries first
857
+ for (const perm of pluginAccessRules) {
858
+ // Delete role_access_rule entries first
855
859
  await database
856
- .delete(schema.rolePermission)
857
- .where(eq(schema.rolePermission.permissionId, perm.id));
858
- // Then delete the permission itself
860
+ .delete(schema.roleAccessRule)
861
+ .where(eq(schema.roleAccessRule.accessRuleId, perm.id));
862
+ // Then delete the access rule itself
859
863
  await database
860
- .delete(schema.permission)
861
- .where(eq(schema.permission.id, perm.id));
862
- logger.debug(` -> Removed permission: ${perm.id}`);
864
+ .delete(schema.accessRule)
865
+ .where(eq(schema.accessRule.id, perm.id));
866
+ logger.debug(` -> Removed access rule: ${perm.id}`);
863
867
  }
864
868
 
865
869
  logger.debug(
866
- `[auth-backend] Cleaned up ${pluginPermissions.length} permissions for ${pluginId}`
870
+ `[auth-backend] Cleaned up ${pluginAccessRules.length} access rules for ${pluginId}`
867
871
  );
868
872
  },
869
873
  {
870
874
  mode: "work-queue",
871
- workerGroup: "permission-cleanup",
875
+ workerGroup: "access-rule-cleanup",
872
876
  maxRetries: 3,
873
877
  }
874
878
  );