@simple-auth-kit/cli 1.5.0 → 1.6.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.
Files changed (176) hide show
  1. package/lib/copy.ts +1 -1
  2. package/package.json +1 -1
  3. package/registry/combos/express-drizzle/shared/src/{ability.ts → ability/ability.ts} +8 -2
  4. package/registry/combos/express-drizzle/shared/src/{permission-cache.ts → cache/permission-cache.ts} +25 -9
  5. package/registry/combos/express-drizzle/shared/src/{rate-limit.store.ts → cache/rate-limit.store.ts} +4 -1
  6. package/registry/combos/{express-prisma/shared/src → express-drizzle/shared/src/config}/auth.config.ts +1 -1
  7. package/registry/combos/express-drizzle/shared/src/{db.ts → config/db.ts} +1 -1
  8. package/registry/combos/express-drizzle/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  9. package/registry/combos/express-drizzle/shared/src/{id.helper.ts → helpers/id.helper.ts} +6 -2
  10. package/registry/combos/{nestjs-drizzle/shared/src → express-drizzle/shared/src/helpers}/pagination.ts +17 -3
  11. package/registry/combos/express-drizzle/shared/src/middleware/auth-core-error.middleware.ts +6 -8
  12. package/registry/combos/express-drizzle/shared/src/middleware/auth.middleware.ts +6 -8
  13. package/registry/combos/{express-prisma/shared/src → express-drizzle/shared/src/openapi}/openapi-fragment.ts +13 -4
  14. package/registry/combos/express-drizzle/shared/src/{openapi-spec.ts → openapi/openapi-spec.ts} +251 -52
  15. package/registry/combos/express-drizzle/shared/src/repositories/oauth.repository.ts +2 -2
  16. package/registry/combos/express-drizzle/shared/src/repositories/password-reset.repository.ts +2 -4
  17. package/registry/combos/express-drizzle/shared/src/repositories/session.repository.ts +3 -3
  18. package/registry/combos/express-drizzle/shared/src/request-context.ts +1 -1
  19. package/registry/combos/express-drizzle/shared/src/route-tiers.ts +52 -11
  20. package/registry/combos/express-drizzle/shared/src/routers/auth.router.ts +2 -2
  21. package/registry/combos/express-drizzle/test/bootstrap.ts +4 -2
  22. package/registry/combos/express-drizzle/test/prove-cycle.ts +1095 -308
  23. package/registry/combos/express-drizzle/variants/base/src/create-auth-app.ts +5 -5
  24. package/registry/combos/express-drizzle/variants/base/src/index.ts +8 -0
  25. package/registry/combos/express-drizzle/variants/base/src/middleware/authz.middleware.ts +2 -2
  26. package/registry/combos/express-drizzle/variants/base/src/openapi/openapi-admin.ts +1082 -0
  27. package/registry/combos/express-drizzle/variants/base/src/rbac.defaults.ts +60 -17
  28. package/registry/combos/express-drizzle/variants/base/src/repositories/audit-log.repository.ts +2 -2
  29. package/registry/combos/express-drizzle/variants/base/src/repositories/rbac.repository.ts +5 -5
  30. package/registry/combos/express-drizzle/variants/base/src/routers/admin.router.ts +18 -22
  31. package/registry/combos/express-drizzle/variants/base/src/seed.ts +76 -17
  32. package/registry/combos/express-drizzle/variants/base/src/services/auth.service.ts +7 -9
  33. package/registry/combos/express-drizzle/variants/base/test/variant-hooks.ts +167 -45
  34. package/registry/combos/express-drizzle/variants/workspaces/src/create-auth-app.ts +5 -5
  35. package/registry/combos/express-drizzle/variants/workspaces/src/index.ts +8 -0
  36. package/registry/combos/express-drizzle/variants/workspaces/src/middleware/authz.middleware.ts +3 -3
  37. package/registry/combos/express-drizzle/variants/workspaces/src/openapi/openapi-admin.ts +1176 -0
  38. package/registry/combos/express-drizzle/variants/workspaces/src/openapi-workspace.ts +1 -1
  39. package/registry/combos/express-drizzle/variants/workspaces/src/rbac.defaults.ts +66 -19
  40. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  41. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/rbac.repository.ts +5 -5
  42. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/workspace.repository.ts +9 -11
  43. package/registry/combos/express-drizzle/variants/workspaces/src/routers/admin.router.ts +18 -22
  44. package/registry/combos/express-drizzle/variants/workspaces/src/routers/workspace.router.ts +1 -1
  45. package/registry/combos/express-drizzle/variants/workspaces/src/seed.ts +168 -35
  46. package/registry/combos/express-drizzle/variants/workspaces/src/services/auth.service.ts +7 -9
  47. package/registry/combos/express-drizzle/variants/workspaces/test/variant-hooks.ts +539 -133
  48. package/registry/combos/express-prisma/shared/src/{ability.ts → ability/ability.ts} +8 -2
  49. package/registry/combos/express-prisma/shared/src/{permission-cache.ts → cache/permission-cache.ts} +25 -9
  50. package/registry/combos/express-prisma/shared/src/{rate-limit.store.ts → cache/rate-limit.store.ts} +4 -1
  51. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/config}/auth.config.ts +1 -1
  52. package/registry/combos/express-prisma/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  53. package/registry/combos/{nestjs-prisma/shared/src → express-prisma/shared/src/helpers}/id.helper.ts +6 -2
  54. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/helpers}/pagination.ts +17 -3
  55. package/registry/combos/express-prisma/shared/src/middleware/auth-core-error.middleware.ts +6 -8
  56. package/registry/combos/express-prisma/shared/src/middleware/auth.middleware.ts +6 -8
  57. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/openapi}/openapi-fragment.ts +13 -4
  58. package/registry/combos/express-prisma/shared/src/{openapi-spec.ts → openapi/openapi-spec.ts} +313 -55
  59. package/registry/combos/express-prisma/shared/src/repositories/oauth.repository.ts +2 -2
  60. package/registry/combos/express-prisma/shared/src/repositories/password-reset.repository.ts +2 -4
  61. package/registry/combos/express-prisma/shared/src/repositories/session.repository.ts +2 -2
  62. package/registry/combos/express-prisma/shared/src/request-context.ts +1 -1
  63. package/registry/combos/express-prisma/shared/src/route-tiers.ts +52 -11
  64. package/registry/combos/express-prisma/shared/src/routers/auth.router.ts +2 -2
  65. package/registry/combos/express-prisma/test/bootstrap.ts +7 -3
  66. package/registry/combos/express-prisma/test/prove-cycle.ts +1095 -308
  67. package/registry/combos/express-prisma/variants/base/src/create-auth-app.ts +5 -5
  68. package/registry/combos/express-prisma/variants/base/src/index.ts +8 -0
  69. package/registry/combos/express-prisma/variants/base/src/middleware/authz.middleware.ts +2 -2
  70. package/registry/combos/express-prisma/variants/base/src/openapi/openapi-admin.ts +1102 -0
  71. package/registry/combos/express-prisma/variants/base/src/repositories/audit-log.repository.ts +2 -2
  72. package/registry/combos/express-prisma/variants/base/src/repositories/rbac.repository.ts +4 -4
  73. package/registry/combos/express-prisma/variants/base/src/routers/admin.router.ts +18 -22
  74. package/registry/combos/express-prisma/variants/base/src/services/auth.service.ts +6 -8
  75. package/registry/combos/express-prisma/variants/base/test/variant-hooks.ts +176 -47
  76. package/registry/combos/express-prisma/variants/workspaces/src/create-auth-app.ts +5 -5
  77. package/registry/combos/express-prisma/variants/workspaces/src/index.ts +8 -0
  78. package/registry/combos/express-prisma/variants/workspaces/src/middleware/authz.middleware.ts +3 -3
  79. package/registry/combos/express-prisma/variants/workspaces/src/openapi/openapi-admin.ts +1218 -0
  80. package/registry/combos/express-prisma/variants/workspaces/src/openapi-workspace.ts +1 -1
  81. package/registry/combos/express-prisma/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  82. package/registry/combos/express-prisma/variants/workspaces/src/repositories/rbac.repository.ts +4 -4
  83. package/registry/combos/express-prisma/variants/workspaces/src/repositories/workspace.repository.ts +2 -2
  84. package/registry/combos/express-prisma/variants/workspaces/src/routers/admin.router.ts +18 -22
  85. package/registry/combos/express-prisma/variants/workspaces/src/routers/workspace.router.ts +1 -1
  86. package/registry/combos/express-prisma/variants/workspaces/src/services/auth.service.ts +6 -8
  87. package/registry/combos/express-prisma/variants/workspaces/test/variant-hooks.ts +538 -134
  88. package/registry/combos/nestjs-drizzle/shared/src/{guards → ability}/ability.guard.ts +1 -1
  89. package/registry/combos/nestjs-drizzle/shared/src/{ability.ts → ability/ability.ts} +8 -2
  90. package/registry/combos/nestjs-drizzle/shared/src/{permission-cache.ts → cache/permission-cache.ts} +27 -10
  91. package/registry/combos/{nestjs-prisma/shared/src → nestjs-drizzle/shared/src/cache}/rate-limit.store.ts +4 -1
  92. package/registry/combos/nestjs-drizzle/shared/src/{auth.config.ts → config/auth.config.ts} +1 -1
  93. package/registry/combos/nestjs-drizzle/shared/src/{db.ts → config/db.ts} +1 -1
  94. package/registry/combos/nestjs-drizzle/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  95. package/registry/combos/nestjs-drizzle/shared/src/controllers/auth.controller.ts +1 -1
  96. package/registry/combos/nestjs-drizzle/shared/src/guards/auth.guard.ts +1 -1
  97. package/registry/combos/nestjs-drizzle/shared/src/{id.helper.ts → helpers/id.helper.ts} +6 -2
  98. package/registry/combos/{express-prisma/shared/src → nestjs-drizzle/shared/src/helpers}/pagination.ts +17 -3
  99. package/registry/combos/nestjs-drizzle/shared/src/repositories/oauth.repository.ts +2 -2
  100. package/registry/combos/nestjs-drizzle/shared/src/repositories/password-reset.repository.ts +8 -12
  101. package/registry/combos/nestjs-drizzle/shared/src/repositories/session.repository.ts +3 -3
  102. package/registry/combos/nestjs-drizzle/shared/src/repositories/two-factor.repository.ts +1 -1
  103. package/registry/combos/nestjs-drizzle/shared/src/request-context.ts +1 -1
  104. package/registry/combos/nestjs-drizzle/test/bootstrap.ts +1 -1
  105. package/registry/combos/nestjs-drizzle/test/prove-cycle.ts +1 -1
  106. package/registry/combos/nestjs-drizzle/variants/base/src/auth.module.ts +10 -6
  107. package/registry/combos/nestjs-drizzle/variants/base/src/controllers/admin.controller.ts +1 -1
  108. package/registry/combos/nestjs-drizzle/variants/base/src/guards/authz.guard.ts +2 -2
  109. package/registry/combos/nestjs-drizzle/variants/base/src/index.ts +9 -0
  110. package/registry/combos/nestjs-drizzle/variants/base/src/rbac.defaults.ts +58 -16
  111. package/registry/combos/nestjs-drizzle/variants/base/src/repositories/audit-log.repository.ts +3 -3
  112. package/registry/combos/nestjs-drizzle/variants/base/src/repositories/rbac.repository.ts +4 -4
  113. package/registry/combos/nestjs-drizzle/variants/base/src/seed.ts +76 -17
  114. package/registry/combos/nestjs-drizzle/variants/base/src/services/auth.service.ts +7 -9
  115. package/registry/combos/nestjs-drizzle/variants/base/test/variant-hooks.ts +167 -45
  116. package/registry/combos/nestjs-drizzle/variants/workspaces/src/auth.module.ts +10 -6
  117. package/registry/combos/nestjs-drizzle/variants/workspaces/src/controllers/admin.controller.ts +1 -1
  118. package/registry/combos/nestjs-drizzle/variants/workspaces/src/controllers/workspace.controller.ts +1 -1
  119. package/registry/combos/nestjs-drizzle/variants/workspaces/src/guards/authz.guard.ts +2 -2
  120. package/registry/combos/nestjs-drizzle/variants/workspaces/src/index.ts +9 -0
  121. package/registry/combos/nestjs-drizzle/variants/workspaces/src/rbac.defaults.ts +64 -18
  122. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/audit-log.repository.ts +3 -3
  123. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/rbac.repository.ts +4 -4
  124. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/workspace.repository.ts +8 -10
  125. package/registry/combos/nestjs-drizzle/variants/workspaces/src/seed.ts +171 -36
  126. package/registry/combos/nestjs-drizzle/variants/workspaces/src/services/auth.service.ts +7 -9
  127. package/registry/combos/nestjs-drizzle/variants/workspaces/test/variant-hooks.ts +539 -133
  128. package/registry/combos/nestjs-prisma/shared/src/{guards → ability}/ability.guard.ts +1 -1
  129. package/registry/combos/nestjs-prisma/shared/src/{ability.ts → ability/ability.ts} +8 -2
  130. package/registry/combos/nestjs-prisma/shared/src/{permission-cache.ts → cache/permission-cache.ts} +27 -10
  131. package/registry/combos/{nestjs-drizzle/shared/src → nestjs-prisma/shared/src/cache}/rate-limit.store.ts +4 -1
  132. package/registry/combos/nestjs-prisma/shared/src/{auth.config.ts → config/auth.config.ts} +1 -1
  133. package/registry/combos/nestjs-prisma/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  134. package/registry/combos/nestjs-prisma/shared/src/controllers/auth.controller.ts +1 -1
  135. package/registry/combos/nestjs-prisma/shared/src/guards/auth.guard.ts +1 -1
  136. package/registry/combos/{express-prisma/shared/src → nestjs-prisma/shared/src/helpers}/id.helper.ts +6 -2
  137. package/registry/combos/nestjs-prisma/shared/src/{pagination.ts → helpers/pagination.ts} +17 -3
  138. package/registry/combos/nestjs-prisma/shared/src/repositories/oauth.repository.ts +1 -1
  139. package/registry/combos/nestjs-prisma/shared/src/repositories/password-reset.repository.ts +2 -4
  140. package/registry/combos/nestjs-prisma/shared/src/repositories/session.repository.ts +2 -2
  141. package/registry/combos/nestjs-prisma/shared/src/request-context.ts +1 -1
  142. package/registry/combos/nestjs-prisma/test/bootstrap.ts +1 -1
  143. package/registry/combos/nestjs-prisma/test/prove-cycle.ts +1 -1
  144. package/registry/combos/nestjs-prisma/variants/base/src/auth.module.ts +9 -5
  145. package/registry/combos/nestjs-prisma/variants/base/src/controllers/admin.controller.ts +1 -1
  146. package/registry/combos/nestjs-prisma/variants/base/src/gateways/audit-log.gateway.ts +1 -1
  147. package/registry/combos/nestjs-prisma/variants/base/src/guards/authz.guard.ts +2 -2
  148. package/registry/combos/nestjs-prisma/variants/base/src/index.ts +9 -0
  149. package/registry/combos/nestjs-prisma/variants/base/src/{docs.ts → openapi/docs.ts} +23 -6
  150. package/registry/combos/nestjs-prisma/variants/base/src/repositories/audit-log.repository.ts +2 -2
  151. package/registry/combos/nestjs-prisma/variants/base/src/repositories/country.repository.ts +2 -2
  152. package/registry/combos/nestjs-prisma/variants/base/src/repositories/customer.repository.ts +6 -5
  153. package/registry/combos/nestjs-prisma/variants/base/src/repositories/language.repository.ts +2 -2
  154. package/registry/combos/nestjs-prisma/variants/base/src/repositories/rbac.repository.ts +3 -3
  155. package/registry/combos/nestjs-prisma/variants/base/src/services/auth.service.ts +6 -8
  156. package/registry/combos/nestjs-prisma/variants/base/test/variant-hooks.ts +176 -47
  157. package/registry/combos/nestjs-prisma/variants/workspaces/src/auth.module.ts +9 -5
  158. package/registry/combos/nestjs-prisma/variants/workspaces/src/controllers/admin.controller.ts +1 -1
  159. package/registry/combos/nestjs-prisma/variants/workspaces/src/controllers/workspace.controller.ts +1 -1
  160. package/registry/combos/nestjs-prisma/variants/workspaces/src/guards/authz.guard.ts +2 -2
  161. package/registry/combos/nestjs-prisma/variants/workspaces/src/index.ts +9 -0
  162. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  163. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/country.repository.ts +2 -2
  164. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/customer.repository.ts +6 -5
  165. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/language.repository.ts +2 -2
  166. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/rbac.repository.ts +3 -3
  167. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/workspace.repository.ts +1 -1
  168. package/registry/combos/nestjs-prisma/variants/workspaces/src/services/auth.service.ts +6 -8
  169. package/registry/combos/nestjs-prisma/variants/workspaces/test/variant-hooks.ts +538 -134
  170. package/simple-auth-kit.ts +13 -9
  171. package/registry/combos/express-drizzle/variants/base/src/openapi-admin.ts +0 -565
  172. package/registry/combos/express-drizzle/variants/workspaces/src/openapi-admin.ts +0 -596
  173. package/registry/combos/express-prisma/variants/base/src/openapi-admin.ts +0 -569
  174. package/registry/combos/express-prisma/variants/workspaces/src/openapi-admin.ts +0 -601
  175. /package/registry/combos/express-drizzle/shared/src/{http-error.ts → errors/http-error.ts} +0 -0
  176. /package/registry/combos/express-prisma/shared/src/{http-error.ts → errors/http-error.ts} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  missingPermission,
7
7
  requiresPermission,
8
8
  type OpenApiFragment,
9
- } from "./openapi-fragment.js";
9
+ } from "./openapi/openapi-fragment.js";
10
10
  import { WORKSPACE_HEADER } from "./middleware/authz.middleware.js";
11
11
 
12
12
  /** Every route that acts *inside* a workspace names it with this header, never a path segment. */
@@ -29,7 +29,7 @@
29
29
  // same transaction that creates it, so its creator is never locked out of a workspace they just
30
30
  // made).
31
31
  import { and, eq, inArray } from "drizzle-orm";
32
- import type { Database } from "./db.js";
32
+ import type { Database } from "./config/db.js";
33
33
  import { permissionRole, permissions, roles } from "./schema.js";
34
34
 
35
35
  /** The display metadata a seeded permission carries. `group`/`order` exist so an admin console can render a stable matrix. */
@@ -55,11 +55,22 @@ export interface PermissionSeed {
55
55
  * evaluate.
56
56
  */
57
57
  export const PERMISSION_CATALOG = {
58
- "users:read": { displayName: "List members", description: "GET /auth/admin/users", group: "Users", order: 1 },
59
- "users:block": { displayName: "Block and unblock members", description: "POST /auth/admin/users/:userId/block, .../unblock", group: "Users", order: 2 },
58
+ "users:read": {
59
+ displayName: "List members",
60
+ description: "GET /auth/admin/users",
61
+ group: "Users",
62
+ order: 1,
63
+ },
64
+ "users:block": {
65
+ displayName: "Block and unblock members",
66
+ description: "POST /auth/admin/users/:userId/block, .../unblock",
67
+ group: "Users",
68
+ order: 2,
69
+ },
60
70
  "users:manage": {
61
71
  displayName: "Edit and delete members",
62
- description: "Edit a member's profile or delete their account — PATCH /auth/admin/users/:userId, DELETE /auth/admin/users/:userId",
72
+ description:
73
+ "Edit a member's profile or delete their account — PATCH /auth/admin/users/:userId, DELETE /auth/admin/users/:userId",
63
74
  group: "Users",
64
75
  order: 3,
65
76
  },
@@ -72,30 +83,44 @@ export const PERMISSION_CATALOG = {
72
83
  },
73
84
  "roles:assign": {
74
85
  displayName: "Assign roles",
75
- description: "Assign and revoke a member's roles — POST /auth/admin/users/:userId/roles, .../roles/:roleSlug/revoke, PUT /workspaces/members/:memberId/roles",
86
+ description:
87
+ "Assign and revoke a member's roles — POST /auth/admin/users/:userId/roles, .../roles/:roleSlug/revoke, PUT /workspaces/members/:memberId/roles",
76
88
  group: "Roles",
77
89
  order: 2,
78
90
  },
79
- "permissions:read": { displayName: "Read the permission catalog", description: "GET /auth/admin/permissions", group: "Permissions", order: 1 },
91
+ "permissions:read": {
92
+ displayName: "Read the permission catalog",
93
+ description: "GET /auth/admin/permissions",
94
+ group: "Permissions",
95
+ order: 1,
96
+ },
80
97
  "permissions:define": {
81
98
  displayName: "Define permissions",
82
- description: "Create a permission, rename it, or deactivate it — POST /auth/admin/permissions. The authority that defines all the others.",
99
+ description:
100
+ "Create a permission, rename it, or deactivate it — POST /auth/admin/permissions. The authority that defines all the others.",
83
101
  group: "Permissions",
84
102
  order: 2,
85
103
  },
86
104
  "permissions:grant": {
87
105
  displayName: "Grant permissions directly",
88
- description: "Grant and revoke a permission straight to a member, bypassing roles — POST /auth/admin/users/:userId/permissions, .../permissions/:slug/revoke",
106
+ description:
107
+ "Grant and revoke a permission straight to a member, bypassing roles — POST /auth/admin/users/:userId/permissions, .../permissions/:slug/revoke",
89
108
  group: "Permissions",
90
109
  order: 3,
91
110
  },
92
111
  "members:manage": {
93
112
  displayName: "Add and remove members",
94
- description: "POST /workspaces/members, DELETE /workspaces/members/:memberId",
113
+ description:
114
+ "POST /workspaces/members, DELETE /workspaces/members/:memberId",
95
115
  group: "Members",
96
116
  order: 1,
97
117
  },
98
- "audit-log:read": { displayName: "Read the audit log", description: "GET /auth/admin/audit-log", group: "Audit", order: 1 },
118
+ "audit-log:read": {
119
+ displayName: "Read the audit log",
120
+ description: "GET /auth/admin/audit-log",
121
+ group: "Audit",
122
+ order: 1,
123
+ },
99
124
  } as const satisfies Record<string, PermissionSeed>;
100
125
 
101
126
  /**
@@ -107,10 +132,14 @@ export const PERMISSION_CATALOG = {
107
132
  */
108
133
  export type PermissionSlug = keyof typeof PERMISSION_CATALOG;
109
134
 
110
- export const PERMISSION_SLUGS = Object.keys(PERMISSION_CATALOG) as PermissionSlug[];
135
+ export const PERMISSION_SLUGS = Object.keys(
136
+ PERMISSION_CATALOG,
137
+ ) as PermissionSlug[];
111
138
 
112
139
  /** Groups, in the order an admin console should render them. Derived from the catalog so it cannot drift from it. */
113
- export const PERMISSION_GROUP_ORDER: string[] = [...new Set(PERMISSION_SLUGS.map((slug) => PERMISSION_CATALOG[slug].group))];
140
+ export const PERMISSION_GROUP_ORDER: string[] = [
141
+ ...new Set(PERMISSION_SLUGS.map((slug) => PERMISSION_CATALOG[slug].group)),
142
+ ];
114
143
 
115
144
  /** The display metadata a seeded role carries, plus what it starts out granting. */
116
145
  export interface RoleSeed {
@@ -146,7 +175,8 @@ export const DEFAULT_ROLES: readonly RoleSeed[] = [
146
175
  {
147
176
  slug: "superadmin",
148
177
  displayName: "Super Admin",
149
- description: "Carries every permission in the catalog — same authority as admin, held by the seeded super_admin account's membership (see SEED_SUPERADMIN_* in seed.ts).",
178
+ description:
179
+ "Carries every permission in the catalog — same authority as admin, held by the seeded super_admin account's membership (see SEED_SUPERADMIN_* in seed.ts).",
150
180
  isDefault: false,
151
181
  order: 1,
152
182
  permissions: PERMISSION_SLUGS,
@@ -154,7 +184,8 @@ export const DEFAULT_ROLES: readonly RoleSeed[] = [
154
184
  {
155
185
  slug: "member",
156
186
  displayName: "Member",
157
- description: "The default for a new membership. Carries no administrative permission.",
187
+ description:
188
+ "The default for a new membership. Carries no administrative permission.",
158
189
  isDefault: true,
159
190
  order: 2,
160
191
  permissions: [],
@@ -191,7 +222,10 @@ export type RbacWriter = Pick<Database, "insert" | "select">;
191
222
  */
192
223
  // Takes bigint directly: both callers (`WorkspaceRepository.create`, `seed.ts`) already have the
193
224
  // workspace row's id in hand from their own database call.
194
- export async function provisionDefaultRoles(db: RbacWriter, workspaceId: bigint): Promise<void> {
225
+ export async function provisionDefaultRoles(
226
+ db: RbacWriter,
227
+ workspaceId: bigint,
228
+ ): Promise<void> {
195
229
  // Insert-then-read rather than `.returning()`: ON CONFLICT DO NOTHING returns no row for the
196
230
  // slugs that already existed, and the ids of *those* are exactly the ones a re-run needs.
197
231
  await db
@@ -203,12 +237,17 @@ export async function provisionDefaultRoles(db: RbacWriter, workspaceId: bigint)
203
237
  displayName: PERMISSION_CATALOG[slug].displayName,
204
238
  description: PERMISSION_CATALOG[slug].description,
205
239
  group: PERMISSION_CATALOG[slug].group,
206
- groupOrder: PERMISSION_GROUP_ORDER.indexOf(PERMISSION_CATALOG[slug].group),
240
+ groupOrder: PERMISSION_GROUP_ORDER.indexOf(
241
+ PERMISSION_CATALOG[slug].group,
242
+ ),
207
243
  order: PERMISSION_CATALOG[slug].order,
208
244
  })),
209
245
  )
210
246
  .onConflictDoNothing({ target: permissions.slug });
211
- const permissionRows = await db.select({ id: permissions.id, slug: permissions.slug }).from(permissions).where(inArray(permissions.slug, PERMISSION_SLUGS));
247
+ const permissionRows = await db
248
+ .select({ id: permissions.id, slug: permissions.slug })
249
+ .from(permissions)
250
+ .where(inArray(permissions.slug, PERMISSION_SLUGS));
212
251
  const permissionId = new Map(permissionRows.map((p) => [p.slug, p.id]));
213
252
 
214
253
  await db
@@ -240,9 +279,17 @@ export async function provisionDefaultRoles(db: RbacWriter, workspaceId: bigint)
240
279
  const seedBySlug = new Map(DEFAULT_ROLES.map((role) => [role.slug, role]));
241
280
 
242
281
  const pairs = roleRows.flatMap((role) =>
243
- (seedBySlug.get(role.slug)?.permissions ?? []).map((slug) => ({ roleId: role.id, permissionId: permissionId.get(slug)! })),
282
+ (seedBySlug.get(role.slug)?.permissions ?? []).map((slug) => ({
283
+ roleId: role.id,
284
+ permissionId: permissionId.get(slug)!,
285
+ })),
244
286
  );
245
287
  if (pairs.length) {
246
- await db.insert(permissionRole).values(pairs).onConflictDoNothing({ target: [permissionRole.permissionId, permissionRole.roleId] });
288
+ await db
289
+ .insert(permissionRole)
290
+ .values(pairs)
291
+ .onConflictDoNothing({
292
+ target: [permissionRole.permissionId, permissionRole.roleId],
293
+ });
247
294
  }
248
295
  }
@@ -6,9 +6,9 @@ import {
6
6
  normalizeLimit,
7
7
  normalizePage,
8
8
  type Paginated,
9
- } from "../pagination.js";
9
+ } from "../helpers/pagination.js";
10
10
  import * as schema from "../schema.js";
11
- import { toIdOrNull, toIdOrUndefined } from "../id.helper.js";
11
+ import { toIdOrNull, toIdOrUndefined } from "../helpers/id.helper.js";
12
12
 
13
13
  export interface AuditLogEntry {
14
14
  id: string;
@@ -10,14 +10,14 @@ import {
10
10
  } from "drizzle-orm";
11
11
  import { resolvePermissions } from "@/lib/auth/core/rbac.js";
12
12
  import type { AuthzContext } from "../middleware/authz.middleware.js";
13
- import type { Database } from "../db.js";
13
+ import type { Database } from "../config/db.js";
14
14
  import {
15
15
  buildPageMeta,
16
16
  normalizeLimit,
17
17
  normalizePage,
18
18
  type Paginated,
19
- } from "../pagination.js";
20
- import { PermissionCache } from "../permission-cache.js";
19
+ } from "../helpers/pagination.js";
20
+ import { PermissionCache } from "../cache/permission-cache.js";
21
21
  import {
22
22
  permissionMember,
23
23
  permissionRole,
@@ -27,8 +27,8 @@ import {
27
27
  users,
28
28
  workspaceMembers,
29
29
  } from "../schema.js";
30
- import { HttpError } from "../http-error.js";
31
- import { toId, toIdOrNull } from "../id.helper.js";
30
+ import { HttpError } from "../errors/http-error.js";
31
+ import { toId, toIdOrNull } from "../helpers/id.helper.js";
32
32
 
33
33
  /**
34
34
  * Every column the `users` table has (plus the membership's own `memberId`/`createdAt`), except
@@ -1,5 +1,5 @@
1
1
  import { and, asc, eq, inArray } from "drizzle-orm";
2
- import type { Database } from "../db.js";
2
+ import type { Database } from "../config/db.js";
3
3
  import {
4
4
  provisionDefaultRoles,
5
5
  WORKSPACE_CREATOR_ROLES,
@@ -12,8 +12,8 @@ import {
12
12
  workspaceMembers,
13
13
  workspaces,
14
14
  } from "../schema.js";
15
- import { HttpError } from "../http-error.js";
16
- import { toId } from "../id.helper.js";
15
+ import { HttpError } from "../errors/http-error.js";
16
+ import { toId } from "../helpers/id.helper.js";
17
17
 
18
18
  export interface WorkspaceSummary {
19
19
  id: string;
@@ -71,14 +71,12 @@ export class WorkspaceRepository {
71
71
  .values({ workspaceId: created.id, userId: userIdBig })
72
72
  .returning({ id: workspaceMembers.id });
73
73
  if (creatorRoles.length) {
74
- await tx
75
- .insert(roleMember)
76
- .values(
77
- creatorRoles.map((role) => ({
78
- memberId: member.id,
79
- roleId: role.id,
80
- })),
81
- );
74
+ await tx.insert(roleMember).values(
75
+ creatorRoles.map((role) => ({
76
+ memberId: member.id,
77
+ roleId: role.id,
78
+ })),
79
+ );
82
80
  }
83
81
  return created;
84
82
  });
@@ -1,7 +1,7 @@
1
1
  import type { NextFunction, Request, RequestHandler, Response } from "express";
2
2
  import { hashPassword } from "@/lib/auth/core/crypto.js";
3
3
  import { AuthService } from "../services/auth.service.js";
4
- import { HttpError } from "../http-error.js";
4
+ import { HttpError } from "../errors/http-error.js";
5
5
  import { ability, createTieredRouter } from "../route-tiers.js";
6
6
  import { WorkspaceRepository } from "../repositories/workspace.repository.js";
7
7
  import "../request-context.js";
@@ -65,15 +65,13 @@ export function createAdminRouter(deps: AdminRouterDeps): RequestHandler {
65
65
  string,
66
66
  string | undefined
67
67
  >;
68
- res
69
- .status(200)
70
- .json(
71
- await auth.listUsers(req.authz!, {
72
- search,
73
- page: page ? Number(page) : undefined,
74
- limit: limit ? Number(limit) : undefined,
75
- }),
76
- );
68
+ res.status(200).json(
69
+ await auth.listUsers(req.authz!, {
70
+ search,
71
+ page: page ? Number(page) : undefined,
72
+ limit: limit ? Number(limit) : undefined,
73
+ }),
74
+ );
77
75
  } catch (err) {
78
76
  next(err);
79
77
  }
@@ -200,18 +198,16 @@ export function createAdminRouter(deps: AdminRouterDeps): RequestHandler {
200
198
  try {
201
199
  const { userId, action, since, until, page, limit } =
202
200
  req.query as Record<string, string | undefined>;
203
- res
204
- .status(200)
205
- .json(
206
- await auth.listAuditLog(req.authz!, {
207
- userId,
208
- action,
209
- since,
210
- until,
211
- page: page ? Number(page) : undefined,
212
- limit: limit ? Number(limit) : undefined,
213
- }),
214
- );
201
+ res.status(200).json(
202
+ await auth.listAuditLog(req.authz!, {
203
+ userId,
204
+ action,
205
+ since,
206
+ until,
207
+ page: page ? Number(page) : undefined,
208
+ limit: limit ? Number(limit) : undefined,
209
+ }),
210
+ );
215
211
  } catch (err) {
216
212
  next(err);
217
213
  }
@@ -1,6 +1,6 @@
1
1
  import { Router } from "express";
2
2
  import type { NextFunction, Request, RequestHandler, Response } from "express";
3
- import { HttpError } from "../http-error.js";
3
+ import { HttpError } from "../errors/http-error.js";
4
4
  import { RbacRepository } from "../repositories/rbac.repository.js";
5
5
  import { ability, authenticated, createTieredRouter } from "../route-tiers.js";
6
6
  import { WorkspaceRepository } from "../repositories/workspace.repository.js";
@@ -31,23 +31,46 @@ import { and, asc, eq, inArray, notInArray } from "drizzle-orm";
31
31
  import { drizzle } from "drizzle-orm/node-postgres";
32
32
  import { Pool } from "pg";
33
33
  import { hashPassword } from "@/lib/auth/core/crypto.js";
34
- import type { Database } from "./db.js";
35
- import { DEFAULT_ROLES, PERMISSION_SLUGS, SEED_SUPERADMIN_ROLES, WORKSPACE_CREATOR_ROLES, provisionDefaultRoles } from "./rbac.defaults.js";
34
+ import type { Database } from "./config/db.js";
35
+ import {
36
+ DEFAULT_ROLES,
37
+ PERMISSION_SLUGS,
38
+ SEED_SUPERADMIN_ROLES,
39
+ WORKSPACE_CREATOR_ROLES,
40
+ provisionDefaultRoles,
41
+ } from "./rbac.defaults.js";
36
42
  import * as schema from "./schema.js";
37
- import { permissions, roleMember, roles, users, workspaceMembers, workspaces } from "./schema.js";
43
+ import {
44
+ permissions,
45
+ roleMember,
46
+ roles,
47
+ users,
48
+ workspaceMembers,
49
+ workspaces,
50
+ } from "./schema.js";
38
51
 
39
52
  const DEFAULT_WORKSPACE_NAME = "Default workspace";
40
53
 
41
54
  function requireEnv(name: string): string {
42
55
  const value = process.env[name];
43
- if (!value) throw new Error(`${name} is not set — the seeder cannot reach the database without it`);
56
+ if (!value)
57
+ throw new Error(
58
+ `${name} is not set — the seeder cannot reach the database without it`,
59
+ );
44
60
  return value;
45
61
  }
46
62
 
47
63
  /** Workspace names are not unique in the schema, so re-running adopts the one it made last time rather than making another. */
48
- async function seedWorkspace(db: Database): Promise<{ id: bigint; name: string }> {
64
+ async function seedWorkspace(
65
+ db: Database,
66
+ ): Promise<{ id: bigint; name: string }> {
49
67
  const name = process.env["SEED_WORKSPACE_NAME"] || DEFAULT_WORKSPACE_NAME;
50
- const [existing] = await db.select().from(workspaces).where(eq(workspaces.name, name)).orderBy(asc(workspaces.createdAt)).limit(1);
68
+ const [existing] = await db
69
+ .select()
70
+ .from(workspaces)
71
+ .where(eq(workspaces.name, name))
72
+ .orderBy(asc(workspaces.createdAt))
73
+ .limit(1);
51
74
  if (existing) {
52
75
  console.log(`workspace: "${name}" already exists (${existing.id})`);
53
76
  return existing;
@@ -58,91 +81,201 @@ async function seedWorkspace(db: Database): Promise<{ id: bigint; name: string }
58
81
  }
59
82
 
60
83
  /** The catalog and this workspace's roles come from rbac.defaults.ts; this only reports what it wrote. */
61
- async function seedRbacDefaults(db: Database, workspaceId: bigint): Promise<void> {
84
+ async function seedRbacDefaults(
85
+ db: Database,
86
+ workspaceId: bigint,
87
+ ): Promise<void> {
62
88
  await provisionDefaultRoles(db, workspaceId);
63
89
  console.log(`permissions: ${PERMISSION_SLUGS.length} slug(s) in the catalog`);
64
- for (const role of DEFAULT_ROLES) console.log(`role "${role.slug}": ${role.permissions.length} permission(s)${role.isDefault ? " (new-member default)" : ""}`);
90
+ for (const role of DEFAULT_ROLES)
91
+ console.log(
92
+ `role "${role.slug}": ${role.permissions.length} permission(s)${role.isDefault ? " (new-member default)" : ""}`,
93
+ );
65
94
 
66
95
  // Slugs that exist in the database but not in this build's catalog. They are not an error —
67
96
  // `POST /auth/admin/permissions` exists so a deployment can define its own, and a grant can
68
97
  // create one — but a slug no route names grants nothing, so a typo would otherwise be a
69
98
  // permission that mysteriously never works. Printing them is what makes it visible.
70
- const unknown = await db.select({ slug: permissions.slug }).from(permissions).where(notInArray(permissions.slug, PERMISSION_SLUGS));
71
- if (unknown.length) console.log(`permissions: ${unknown.length} slug(s) outside this build's catalog (no route names them): ${unknown.map((r) => r.slug).join(", ")}`);
72
- const inactive = await db.select({ slug: permissions.slug }).from(permissions).where(eq(permissions.isActive, false));
73
- if (inactive.length) console.log(`permissions: ${inactive.length} deactivated, granting nothing: ${inactive.map((r) => r.slug).join(", ")}`);
99
+ const unknown = await db
100
+ .select({ slug: permissions.slug })
101
+ .from(permissions)
102
+ .where(notInArray(permissions.slug, PERMISSION_SLUGS));
103
+ if (unknown.length)
104
+ console.log(
105
+ `permissions: ${unknown.length} slug(s) outside this build's catalog (no route names them): ${unknown.map((r) => r.slug).join(", ")}`,
106
+ );
107
+ const inactive = await db
108
+ .select({ slug: permissions.slug })
109
+ .from(permissions)
110
+ .where(eq(permissions.isActive, false));
111
+ if (inactive.length)
112
+ console.log(
113
+ `permissions: ${inactive.length} deactivated, granting nothing: ${inactive.map((r) => r.slug).join(", ")}`,
114
+ );
74
115
  }
75
116
 
76
117
  /** The user is the authentication principal; the membership below is the authorization one. */
77
- async function seedAdminUser(db: Database, workspace: { id: bigint; name: string }): Promise<void> {
118
+ async function seedAdminUser(
119
+ db: Database,
120
+ workspace: { id: bigint; name: string },
121
+ ): Promise<void> {
78
122
  const email = process.env["SEED_ADMIN_EMAIL"];
79
123
  const password = process.env["SEED_ADMIN_PASSWORD"];
80
124
  if (!email || !password) {
81
- console.log(`admin: skipped — set SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD to create one (there is no default password)`);
82
- console.log(`admin: "${workspace.name}" has no members until you re-run with them set`);
125
+ console.log(
126
+ `admin: skipped set SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD to create one (there is no default password)`,
127
+ );
128
+ console.log(
129
+ `admin: "${workspace.name}" has no members until you re-run with them set`,
130
+ );
83
131
  return;
84
132
  }
85
133
 
86
134
  // Their password may have been changed since; rewriting it here would silently reset it.
87
- const [existing] = await db.select({ id: users.id }).from(users).where(eq(users.email, email)).limit(1);
88
- const user = existing ?? (await db.insert(users).values({ email, passwordHash: await hashPassword(password) }).returning({ id: users.id }))[0];
89
- console.log(existing ? `admin: ${email} already exists — password left unchanged` : `admin: created ${email}`);
135
+ const [existing] = await db
136
+ .select({ id: users.id })
137
+ .from(users)
138
+ .where(eq(users.email, email))
139
+ .limit(1);
140
+ const user =
141
+ existing ??
142
+ (
143
+ await db
144
+ .insert(users)
145
+ .values({ email, passwordHash: await hashPassword(password) })
146
+ .returning({ id: users.id })
147
+ )[0];
148
+ console.log(
149
+ existing
150
+ ? `admin: ${email} already exists — password left unchanged`
151
+ : `admin: created ${email}`,
152
+ );
90
153
 
91
154
  const [existingMembership] = await db
92
155
  .select({ id: workspaceMembers.id })
93
156
  .from(workspaceMembers)
94
- .where(and(eq(workspaceMembers.userId, user.id), eq(workspaceMembers.workspaceId, workspace.id)))
157
+ .where(
158
+ and(
159
+ eq(workspaceMembers.userId, user.id),
160
+ eq(workspaceMembers.workspaceId, workspace.id),
161
+ ),
162
+ )
95
163
  .limit(1);
96
164
  const membership =
97
- existingMembership ?? (await db.insert(workspaceMembers).values({ userId: user.id, workspaceId: workspace.id }).returning({ id: workspaceMembers.id }))[0];
165
+ existingMembership ??
166
+ (
167
+ await db
168
+ .insert(workspaceMembers)
169
+ .values({ userId: user.id, workspaceId: workspace.id })
170
+ .returning({ id: workspaceMembers.id })
171
+ )[0];
98
172
 
99
173
  const adminRoles = await db
100
174
  .select({ id: roles.id, slug: roles.slug })
101
175
  .from(roles)
102
- .where(and(eq(roles.workspaceId, workspace.id), inArray(roles.slug, WORKSPACE_CREATOR_ROLES)));
176
+ .where(
177
+ and(
178
+ eq(roles.workspaceId, workspace.id),
179
+ inArray(roles.slug, WORKSPACE_CREATOR_ROLES),
180
+ ),
181
+ );
103
182
  if (adminRoles.length) {
104
183
  await db
105
184
  .insert(roleMember)
106
- .values(adminRoles.map((role) => ({ memberId: membership.id, roleId: role.id })))
107
- .onConflictDoNothing({ target: [roleMember.memberId, roleMember.roleId] });
185
+ .values(
186
+ adminRoles.map((role) => ({
187
+ memberId: membership.id,
188
+ roleId: role.id,
189
+ })),
190
+ )
191
+ .onConflictDoNothing({
192
+ target: [roleMember.memberId, roleMember.roleId],
193
+ });
108
194
  }
109
- console.log(`admin: member of "${workspace.name}" with roles ${adminRoles.map((r) => r.slug).join(", ")}`);
195
+ console.log(
196
+ `admin: member of "${workspace.name}" with roles ${adminRoles.map((r) => r.slug).join(", ")}`,
197
+ );
110
198
  }
111
199
 
112
200
  /** Same shape as seedAdminUser, for the seeded super_admin account — a distinct account and membership holding the "superadmin" role. */
113
- async function seedSuperAdminUser(db: Database, workspace: { id: bigint; name: string }): Promise<void> {
201
+ async function seedSuperAdminUser(
202
+ db: Database,
203
+ workspace: { id: bigint; name: string },
204
+ ): Promise<void> {
114
205
  const email = process.env["SEED_SUPERADMIN_EMAIL"];
115
206
  const password = process.env["SEED_SUPERADMIN_PASSWORD"];
116
207
  if (!email || !password) {
117
- console.log(`super admin: skipped — set SEED_SUPERADMIN_EMAIL and SEED_SUPERADMIN_PASSWORD to create one (there is no default password)`);
208
+ console.log(
209
+ `super admin: skipped — set SEED_SUPERADMIN_EMAIL and SEED_SUPERADMIN_PASSWORD to create one (there is no default password)`,
210
+ );
118
211
  return;
119
212
  }
120
213
  const username = process.env["SEED_SUPERADMIN_USERNAME"] || undefined;
121
214
 
122
215
  // Their password may have been changed since; rewriting it here would silently reset it.
123
- const [existing] = await db.select({ id: users.id }).from(users).where(eq(users.email, email)).limit(1);
124
- const user = existing ?? (await db.insert(users).values({ email, username, passwordHash: await hashPassword(password) }).returning({ id: users.id }))[0];
125
- console.log(existing ? `super admin: ${email} already exists — password left unchanged` : `super admin: created ${email}${username ? ` (username ${username})` : ""}`);
216
+ const [existing] = await db
217
+ .select({ id: users.id })
218
+ .from(users)
219
+ .where(eq(users.email, email))
220
+ .limit(1);
221
+ const user =
222
+ existing ??
223
+ (
224
+ await db
225
+ .insert(users)
226
+ .values({ email, username, passwordHash: await hashPassword(password) })
227
+ .returning({ id: users.id })
228
+ )[0];
229
+ console.log(
230
+ existing
231
+ ? `super admin: ${email} already exists — password left unchanged`
232
+ : `super admin: created ${email}${username ? ` (username ${username})` : ""}`,
233
+ );
126
234
 
127
235
  const [existingMembership] = await db
128
236
  .select({ id: workspaceMembers.id })
129
237
  .from(workspaceMembers)
130
- .where(and(eq(workspaceMembers.userId, user.id), eq(workspaceMembers.workspaceId, workspace.id)))
238
+ .where(
239
+ and(
240
+ eq(workspaceMembers.userId, user.id),
241
+ eq(workspaceMembers.workspaceId, workspace.id),
242
+ ),
243
+ )
131
244
  .limit(1);
132
245
  const membership =
133
- existingMembership ?? (await db.insert(workspaceMembers).values({ userId: user.id, workspaceId: workspace.id }).returning({ id: workspaceMembers.id }))[0];
246
+ existingMembership ??
247
+ (
248
+ await db
249
+ .insert(workspaceMembers)
250
+ .values({ userId: user.id, workspaceId: workspace.id })
251
+ .returning({ id: workspaceMembers.id })
252
+ )[0];
134
253
 
135
254
  const superAdminRoles = await db
136
255
  .select({ id: roles.id, slug: roles.slug })
137
256
  .from(roles)
138
- .where(and(eq(roles.workspaceId, workspace.id), inArray(roles.slug, SEED_SUPERADMIN_ROLES)));
257
+ .where(
258
+ and(
259
+ eq(roles.workspaceId, workspace.id),
260
+ inArray(roles.slug, SEED_SUPERADMIN_ROLES),
261
+ ),
262
+ );
139
263
  if (superAdminRoles.length) {
140
264
  await db
141
265
  .insert(roleMember)
142
- .values(superAdminRoles.map((role) => ({ memberId: membership.id, roleId: role.id })))
143
- .onConflictDoNothing({ target: [roleMember.memberId, roleMember.roleId] });
266
+ .values(
267
+ superAdminRoles.map((role) => ({
268
+ memberId: membership.id,
269
+ roleId: role.id,
270
+ })),
271
+ )
272
+ .onConflictDoNothing({
273
+ target: [roleMember.memberId, roleMember.roleId],
274
+ });
144
275
  }
145
- console.log(`super admin: member of "${workspace.name}" with roles ${superAdminRoles.map((r) => r.slug).join(", ")}`);
276
+ console.log(
277
+ `super admin: member of "${workspace.name}" with roles ${superAdminRoles.map((r) => r.slug).join(", ")}`,
278
+ );
146
279
  }
147
280
 
148
281
  async function main(): Promise<void> {
@@ -42,17 +42,17 @@ import {
42
42
  generateTotpSecret,
43
43
  verifyTotpCode,
44
44
  } from "@/lib/auth/core/two-factor.js";
45
- import type { AuthConfig } from "../auth.config.js";
46
- import { HttpError } from "../http-error.js";
45
+ import type { AuthConfig } from "../config/auth.config.js";
46
+ import { HttpError } from "../errors/http-error.js";
47
47
  import {
48
48
  AuditLogEntry,
49
49
  AuditLogListFilter,
50
50
  AuditLogRepository,
51
51
  toAuditLogEntry,
52
52
  } from "../repositories/audit-log.repository.js";
53
- import type { Paginated } from "../pagination.js";
54
- import type { Database } from "../db.js";
55
- import { KeyProviderService } from "../key-provider.js";
53
+ import type { Paginated } from "../helpers/pagination.js";
54
+ import type { Database } from "../config/db.js";
55
+ import { KeyProviderService } from "../config/key-provider.js";
56
56
  import { OAuthRepository } from "../repositories/oauth.repository.js";
57
57
  import { PasswordResetRepository } from "../repositories/password-reset.repository.js";
58
58
  import type { Revoker } from "@/lib/auth/core/types.js";
@@ -70,7 +70,7 @@ import {
70
70
  import { sessions, users } from "../schema.js";
71
71
  import { SessionRepository } from "../repositories/session.repository.js";
72
72
  import { TwoFactorRepository } from "../repositories/two-factor.repository.js";
73
- import { toId, toIdOrNull } from "../id.helper.js";
73
+ import { toId, toIdOrNull } from "../helpers/id.helper.js";
74
74
 
75
75
  export interface AuthTokens {
76
76
  accessToken: string;
@@ -470,9 +470,7 @@ export class AuthService {
470
470
  return { twoFactorEnabled: user.twoFactorEnabled };
471
471
  }
472
472
 
473
- async listActiveSessions(
474
- userId: string,
475
- ): Promise<
473
+ async listActiveSessions(userId: string): Promise<
476
474
  Array<{
477
475
  id: string;
478
476
  createdAt: string;