@simple-auth-kit/cli 1.5.1 → 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 (182) hide show
  1. package/package.json +1 -1
  2. package/registry/combos/express-drizzle/shared/src/{ability.ts → ability/ability.ts} +8 -2
  3. package/registry/combos/express-drizzle/shared/src/{permission-cache.ts → cache/permission-cache.ts} +25 -9
  4. package/registry/combos/express-drizzle/shared/src/{rate-limit.store.ts → cache/rate-limit.store.ts} +4 -1
  5. package/registry/combos/{express-prisma/shared/src → express-drizzle/shared/src/config}/auth.config.ts +1 -1
  6. package/registry/combos/express-drizzle/shared/src/{db.ts → config/db.ts} +1 -1
  7. package/registry/combos/express-drizzle/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  8. package/registry/combos/express-drizzle/shared/src/{id.helper.ts → helpers/id.helper.ts} +6 -2
  9. package/registry/combos/{nestjs-drizzle/shared/src → express-drizzle/shared/src/helpers}/pagination.ts +17 -3
  10. package/registry/combos/express-drizzle/shared/src/middleware/auth-core-error.middleware.ts +6 -8
  11. package/registry/combos/express-drizzle/shared/src/middleware/auth.middleware.ts +6 -8
  12. package/registry/combos/{express-prisma/shared/src → express-drizzle/shared/src/openapi}/openapi-fragment.ts +13 -4
  13. package/registry/combos/express-drizzle/shared/src/{openapi-spec.ts → openapi/openapi-spec.ts} +251 -52
  14. package/registry/combos/express-drizzle/shared/src/repositories/oauth.repository.ts +2 -2
  15. package/registry/combos/express-drizzle/shared/src/repositories/password-reset.repository.ts +2 -4
  16. package/registry/combos/express-drizzle/shared/src/repositories/session.repository.ts +3 -3
  17. package/registry/combos/express-drizzle/shared/src/request-context.ts +1 -1
  18. package/registry/combos/express-drizzle/shared/src/route-tiers.ts +52 -11
  19. package/registry/combos/express-drizzle/shared/src/routers/auth.router.ts +2 -2
  20. package/registry/combos/express-drizzle/test/bootstrap.ts +4 -2
  21. package/registry/combos/express-drizzle/test/prove-cycle.ts +1095 -308
  22. package/registry/combos/express-drizzle/variants/base/src/create-auth-app.ts +5 -5
  23. package/registry/combos/express-drizzle/variants/base/src/index.ts +8 -0
  24. package/registry/combos/express-drizzle/variants/base/src/middleware/authz.middleware.ts +2 -2
  25. package/registry/combos/express-drizzle/variants/base/src/openapi/openapi-admin.ts +1082 -0
  26. package/registry/combos/express-drizzle/variants/base/src/rbac.defaults.ts +60 -17
  27. package/registry/combos/express-drizzle/variants/base/src/repositories/audit-log.repository.ts +2 -2
  28. package/registry/combos/express-drizzle/variants/base/src/repositories/rbac.repository.ts +5 -5
  29. package/registry/combos/express-drizzle/variants/base/src/routers/admin.router.ts +18 -22
  30. package/registry/combos/express-drizzle/variants/base/src/seed.ts +76 -17
  31. package/registry/combos/express-drizzle/variants/base/src/services/auth.service.ts +7 -9
  32. package/registry/combos/express-drizzle/variants/base/test/variant-hooks.ts +167 -45
  33. package/registry/combos/express-drizzle/variants/workspaces/src/create-auth-app.ts +5 -5
  34. package/registry/combos/express-drizzle/variants/workspaces/src/index.ts +8 -0
  35. package/registry/combos/express-drizzle/variants/workspaces/src/middleware/authz.middleware.ts +3 -3
  36. package/registry/combos/express-drizzle/variants/workspaces/src/openapi/openapi-admin.ts +1176 -0
  37. package/registry/combos/express-drizzle/variants/workspaces/src/openapi-workspace.ts +1 -1
  38. package/registry/combos/express-drizzle/variants/workspaces/src/rbac.defaults.ts +66 -19
  39. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  40. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/rbac.repository.ts +5 -5
  41. package/registry/combos/express-drizzle/variants/workspaces/src/repositories/workspace.repository.ts +9 -11
  42. package/registry/combos/express-drizzle/variants/workspaces/src/routers/admin.router.ts +18 -22
  43. package/registry/combos/express-drizzle/variants/workspaces/src/routers/workspace.router.ts +1 -1
  44. package/registry/combos/express-drizzle/variants/workspaces/src/seed.ts +168 -35
  45. package/registry/combos/express-drizzle/variants/workspaces/src/services/auth.service.ts +7 -9
  46. package/registry/combos/express-drizzle/variants/workspaces/test/variant-hooks.ts +539 -133
  47. package/registry/combos/express-prisma/shared/src/{ability.ts → ability/ability.ts} +8 -2
  48. package/registry/combos/express-prisma/shared/src/{permission-cache.ts → cache/permission-cache.ts} +25 -9
  49. package/registry/combos/express-prisma/shared/src/{rate-limit.store.ts → cache/rate-limit.store.ts} +4 -1
  50. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/config}/auth.config.ts +1 -1
  51. package/registry/combos/express-prisma/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  52. package/registry/combos/{nestjs-prisma/shared/src → express-prisma/shared/src/helpers}/id.helper.ts +6 -2
  53. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/helpers}/pagination.ts +17 -3
  54. package/registry/combos/express-prisma/shared/src/middleware/auth-core-error.middleware.ts +6 -8
  55. package/registry/combos/express-prisma/shared/src/middleware/auth.middleware.ts +6 -8
  56. package/registry/combos/{express-drizzle/shared/src → express-prisma/shared/src/openapi}/openapi-fragment.ts +13 -4
  57. package/registry/combos/express-prisma/shared/src/{openapi-spec.ts → openapi/openapi-spec.ts} +313 -55
  58. package/registry/combos/express-prisma/shared/src/repositories/oauth.repository.ts +2 -2
  59. package/registry/combos/express-prisma/shared/src/repositories/password-reset.repository.ts +2 -4
  60. package/registry/combos/express-prisma/shared/src/repositories/session.repository.ts +2 -2
  61. package/registry/combos/express-prisma/shared/src/request-context.ts +1 -1
  62. package/registry/combos/express-prisma/shared/src/route-tiers.ts +52 -11
  63. package/registry/combos/express-prisma/shared/src/routers/auth.router.ts +2 -2
  64. package/registry/combos/express-prisma/test/bootstrap.ts +7 -3
  65. package/registry/combos/express-prisma/test/prove-cycle.ts +1095 -308
  66. package/registry/combos/express-prisma/variants/base/src/create-auth-app.ts +6 -6
  67. package/registry/combos/express-prisma/variants/base/src/index.ts +8 -0
  68. package/registry/combos/express-prisma/variants/base/src/middleware/authz.middleware.ts +2 -2
  69. package/registry/combos/express-prisma/variants/base/src/openapi/openapi-admin.ts +1102 -0
  70. package/registry/combos/express-prisma/variants/base/src/rbac.defaults.ts +1 -1
  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/seed.ts +1 -1
  75. package/registry/combos/express-prisma/variants/base/src/services/auth.service.ts +6 -8
  76. package/registry/combos/express-prisma/variants/base/test/variant-hooks.ts +176 -47
  77. package/registry/combos/express-prisma/variants/workspaces/src/create-auth-app.ts +6 -6
  78. package/registry/combos/express-prisma/variants/workspaces/src/index.ts +8 -0
  79. package/registry/combos/express-prisma/variants/workspaces/src/middleware/authz.middleware.ts +3 -3
  80. package/registry/combos/express-prisma/variants/workspaces/src/openapi/openapi-admin.ts +1218 -0
  81. package/registry/combos/express-prisma/variants/workspaces/src/openapi-workspace.ts +1 -1
  82. package/registry/combos/express-prisma/variants/workspaces/src/rbac.defaults.ts +1 -1
  83. package/registry/combos/express-prisma/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  84. package/registry/combos/express-prisma/variants/workspaces/src/repositories/rbac.repository.ts +4 -4
  85. package/registry/combos/express-prisma/variants/workspaces/src/repositories/workspace.repository.ts +2 -2
  86. package/registry/combos/express-prisma/variants/workspaces/src/routers/admin.router.ts +18 -22
  87. package/registry/combos/express-prisma/variants/workspaces/src/routers/workspace.router.ts +1 -1
  88. package/registry/combos/express-prisma/variants/workspaces/src/seed.ts +1 -1
  89. package/registry/combos/express-prisma/variants/workspaces/src/services/auth.service.ts +6 -8
  90. package/registry/combos/express-prisma/variants/workspaces/test/variant-hooks.ts +538 -134
  91. package/registry/combos/nestjs-drizzle/shared/src/{guards → ability}/ability.guard.ts +1 -1
  92. package/registry/combos/nestjs-drizzle/shared/src/{ability.ts → ability/ability.ts} +8 -2
  93. package/registry/combos/nestjs-drizzle/shared/src/{permission-cache.ts → cache/permission-cache.ts} +27 -10
  94. package/registry/combos/{nestjs-prisma/shared/src → nestjs-drizzle/shared/src/cache}/rate-limit.store.ts +4 -1
  95. package/registry/combos/nestjs-drizzle/shared/src/{auth.config.ts → config/auth.config.ts} +1 -1
  96. package/registry/combos/nestjs-drizzle/shared/src/{db.ts → config/db.ts} +1 -1
  97. package/registry/combos/nestjs-drizzle/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  98. package/registry/combos/nestjs-drizzle/shared/src/controllers/auth.controller.ts +1 -1
  99. package/registry/combos/nestjs-drizzle/shared/src/guards/auth.guard.ts +1 -1
  100. package/registry/combos/nestjs-drizzle/shared/src/{id.helper.ts → helpers/id.helper.ts} +6 -2
  101. package/registry/combos/{express-prisma/shared/src → nestjs-drizzle/shared/src/helpers}/pagination.ts +17 -3
  102. package/registry/combos/nestjs-drizzle/shared/src/repositories/oauth.repository.ts +2 -2
  103. package/registry/combos/nestjs-drizzle/shared/src/repositories/password-reset.repository.ts +8 -12
  104. package/registry/combos/nestjs-drizzle/shared/src/repositories/session.repository.ts +3 -3
  105. package/registry/combos/nestjs-drizzle/shared/src/repositories/two-factor.repository.ts +1 -1
  106. package/registry/combos/nestjs-drizzle/shared/src/request-context.ts +1 -1
  107. package/registry/combos/nestjs-drizzle/test/bootstrap.ts +1 -1
  108. package/registry/combos/nestjs-drizzle/test/prove-cycle.ts +1 -1
  109. package/registry/combos/nestjs-drizzle/variants/base/src/auth.module.ts +10 -6
  110. package/registry/combos/nestjs-drizzle/variants/base/src/controllers/admin.controller.ts +1 -1
  111. package/registry/combos/nestjs-drizzle/variants/base/src/guards/authz.guard.ts +2 -2
  112. package/registry/combos/nestjs-drizzle/variants/base/src/index.ts +9 -0
  113. package/registry/combos/nestjs-drizzle/variants/base/src/rbac.defaults.ts +58 -16
  114. package/registry/combos/nestjs-drizzle/variants/base/src/repositories/audit-log.repository.ts +3 -3
  115. package/registry/combos/nestjs-drizzle/variants/base/src/repositories/rbac.repository.ts +4 -4
  116. package/registry/combos/nestjs-drizzle/variants/base/src/seed.ts +76 -17
  117. package/registry/combos/nestjs-drizzle/variants/base/src/services/auth.service.ts +7 -9
  118. package/registry/combos/nestjs-drizzle/variants/base/test/variant-hooks.ts +167 -45
  119. package/registry/combos/nestjs-drizzle/variants/workspaces/src/auth.module.ts +10 -6
  120. package/registry/combos/nestjs-drizzle/variants/workspaces/src/controllers/admin.controller.ts +1 -1
  121. package/registry/combos/nestjs-drizzle/variants/workspaces/src/controllers/workspace.controller.ts +1 -1
  122. package/registry/combos/nestjs-drizzle/variants/workspaces/src/guards/authz.guard.ts +2 -2
  123. package/registry/combos/nestjs-drizzle/variants/workspaces/src/index.ts +9 -0
  124. package/registry/combos/nestjs-drizzle/variants/workspaces/src/rbac.defaults.ts +64 -18
  125. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/audit-log.repository.ts +3 -3
  126. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/rbac.repository.ts +4 -4
  127. package/registry/combos/nestjs-drizzle/variants/workspaces/src/repositories/workspace.repository.ts +8 -10
  128. package/registry/combos/nestjs-drizzle/variants/workspaces/src/seed.ts +171 -36
  129. package/registry/combos/nestjs-drizzle/variants/workspaces/src/services/auth.service.ts +7 -9
  130. package/registry/combos/nestjs-drizzle/variants/workspaces/test/variant-hooks.ts +539 -133
  131. package/registry/combos/nestjs-prisma/shared/src/{guards → ability}/ability.guard.ts +1 -1
  132. package/registry/combos/nestjs-prisma/shared/src/{ability.ts → ability/ability.ts} +8 -2
  133. package/registry/combos/nestjs-prisma/shared/src/{permission-cache.ts → cache/permission-cache.ts} +27 -10
  134. package/registry/combos/{nestjs-drizzle/shared/src → nestjs-prisma/shared/src/cache}/rate-limit.store.ts +4 -1
  135. package/registry/combos/nestjs-prisma/shared/src/{auth.config.ts → config/auth.config.ts} +1 -1
  136. package/registry/combos/nestjs-prisma/shared/src/{key-provider.ts → config/key-provider.ts} +6 -2
  137. package/registry/combos/nestjs-prisma/shared/src/controllers/auth.controller.ts +1 -1
  138. package/registry/combos/nestjs-prisma/shared/src/guards/auth.guard.ts +1 -1
  139. package/registry/combos/{express-prisma/shared/src → nestjs-prisma/shared/src/helpers}/id.helper.ts +6 -2
  140. package/registry/combos/nestjs-prisma/shared/src/{pagination.ts → helpers/pagination.ts} +17 -3
  141. package/registry/combos/nestjs-prisma/shared/src/repositories/oauth.repository.ts +1 -1
  142. package/registry/combos/nestjs-prisma/shared/src/repositories/password-reset.repository.ts +2 -4
  143. package/registry/combos/nestjs-prisma/shared/src/repositories/session.repository.ts +2 -2
  144. package/registry/combos/nestjs-prisma/shared/src/request-context.ts +1 -1
  145. package/registry/combos/nestjs-prisma/test/bootstrap.ts +1 -1
  146. package/registry/combos/nestjs-prisma/test/prove-cycle.ts +1 -1
  147. package/registry/combos/nestjs-prisma/variants/base/src/auth.module.ts +10 -6
  148. package/registry/combos/nestjs-prisma/variants/base/src/controllers/admin.controller.ts +1 -1
  149. package/registry/combos/nestjs-prisma/variants/base/src/gateways/audit-log.gateway.ts +1 -1
  150. package/registry/combos/nestjs-prisma/variants/base/src/guards/authz.guard.ts +2 -2
  151. package/registry/combos/nestjs-prisma/variants/base/src/index.ts +9 -0
  152. package/registry/combos/nestjs-prisma/variants/base/src/{docs.ts → openapi/docs.ts} +23 -6
  153. package/registry/combos/nestjs-prisma/variants/base/src/rbac.defaults.ts +1 -1
  154. package/registry/combos/nestjs-prisma/variants/base/src/repositories/audit-log.repository.ts +2 -2
  155. package/registry/combos/nestjs-prisma/variants/base/src/repositories/country.repository.ts +2 -2
  156. package/registry/combos/nestjs-prisma/variants/base/src/repositories/customer.repository.ts +6 -5
  157. package/registry/combos/nestjs-prisma/variants/base/src/repositories/language.repository.ts +2 -2
  158. package/registry/combos/nestjs-prisma/variants/base/src/repositories/rbac.repository.ts +3 -3
  159. package/registry/combos/nestjs-prisma/variants/base/src/seed.ts +1 -1
  160. package/registry/combos/nestjs-prisma/variants/base/src/services/auth.service.ts +6 -8
  161. package/registry/combos/nestjs-prisma/variants/base/test/variant-hooks.ts +176 -47
  162. package/registry/combos/nestjs-prisma/variants/workspaces/src/auth.module.ts +10 -6
  163. package/registry/combos/nestjs-prisma/variants/workspaces/src/controllers/admin.controller.ts +1 -1
  164. package/registry/combos/nestjs-prisma/variants/workspaces/src/controllers/workspace.controller.ts +1 -1
  165. package/registry/combos/nestjs-prisma/variants/workspaces/src/guards/authz.guard.ts +2 -2
  166. package/registry/combos/nestjs-prisma/variants/workspaces/src/index.ts +9 -0
  167. package/registry/combos/nestjs-prisma/variants/workspaces/src/rbac.defaults.ts +1 -1
  168. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/audit-log.repository.ts +2 -2
  169. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/country.repository.ts +2 -2
  170. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/customer.repository.ts +6 -5
  171. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/language.repository.ts +2 -2
  172. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/rbac.repository.ts +3 -3
  173. package/registry/combos/nestjs-prisma/variants/workspaces/src/repositories/workspace.repository.ts +1 -1
  174. package/registry/combos/nestjs-prisma/variants/workspaces/src/seed.ts +1 -1
  175. package/registry/combos/nestjs-prisma/variants/workspaces/src/services/auth.service.ts +6 -8
  176. package/registry/combos/nestjs-prisma/variants/workspaces/test/variant-hooks.ts +538 -134
  177. package/registry/combos/express-drizzle/variants/base/src/openapi-admin.ts +0 -565
  178. package/registry/combos/express-drizzle/variants/workspaces/src/openapi-admin.ts +0 -596
  179. package/registry/combos/express-prisma/variants/base/src/openapi-admin.ts +0 -569
  180. package/registry/combos/express-prisma/variants/workspaces/src/openapi-admin.ts +0 -601
  181. /package/registry/combos/express-drizzle/shared/src/{http-error.ts → errors/http-error.ts} +0 -0
  182. /package/registry/combos/express-prisma/shared/src/{http-error.ts → errors/http-error.ts} +0 -0
@@ -19,7 +19,8 @@ export const openApiSpec: Record<string, unknown> = {
19
19
  openapi: "3.0.3",
20
20
  info: {
21
21
  title: "simple-auth-kit API",
22
- description: "express-drizzle combo — signup/login, sessions, TOTP 2FA, OAuth, password reset, RBAC, audit log",
22
+ description:
23
+ "express-drizzle combo — signup/login, sessions, TOTP 2FA, OAuth, password reset, RBAC, audit log",
23
24
  version: "1.0",
24
25
  },
25
26
  servers: [{ url: "/" }],
@@ -39,18 +40,37 @@ export const openApiSpec: Record<string, unknown> = {
39
40
  properties: {
40
41
  email: { type: "string", example: "alice@example.com" },
41
42
  password: { type: "string", example: "correct-horse-battery-staple" },
42
- firstName: { type: "string", description: "Unique across the deployment.", example: "Alice" },
43
- lastName: { type: "string", description: "Unique across the deployment.", example: "Nguyen" },
43
+ firstName: {
44
+ type: "string",
45
+ description: "Unique across the deployment.",
46
+ example: "Alice",
47
+ },
48
+ lastName: {
49
+ type: "string",
50
+ description: "Unique across the deployment.",
51
+ example: "Nguyen",
52
+ },
44
53
  displayName: { type: "string", example: "Alice Nguyen" },
45
- phone: { type: "string", description: "Unique across the deployment." },
46
- username: { type: "string", description: "Unique across the deployment." },
54
+ phone: {
55
+ type: "string",
56
+ description: "Unique across the deployment.",
57
+ },
58
+ username: {
59
+ type: "string",
60
+ description: "Unique across the deployment.",
61
+ },
47
62
  },
48
63
  },
49
64
  LoginDto: {
50
65
  type: "object",
51
66
  required: ["identifier", "password"],
52
67
  properties: {
53
- identifier: { type: "string", description: "Email, username, or phone — whichever the account has set.", example: "alice@example.com" },
68
+ identifier: {
69
+ type: "string",
70
+ description:
71
+ "Email, username, or phone — whichever the account has set.",
72
+ example: "alice@example.com",
73
+ },
54
74
  password: { type: "string", example: "correct-horse-battery-staple" },
55
75
  },
56
76
  },
@@ -58,8 +78,16 @@ export const openApiSpec: Record<string, unknown> = {
58
78
  type: "object",
59
79
  required: ["challengeToken", "code"],
60
80
  properties: {
61
- challengeToken: { type: "string", description: "Returned by POST /auth/login when the account has 2FA enabled" },
62
- code: { type: "string", description: "6-digit TOTP code, or an unused backup code", example: "123456" },
81
+ challengeToken: {
82
+ type: "string",
83
+ description:
84
+ "Returned by POST /auth/login when the account has 2FA enabled",
85
+ },
86
+ code: {
87
+ type: "string",
88
+ description: "6-digit TOTP code, or an unused backup code",
89
+ example: "123456",
90
+ },
63
91
  },
64
92
  },
65
93
  RefreshDto: {
@@ -87,7 +115,10 @@ export const openApiSpec: Record<string, unknown> = {
87
115
  type: "object",
88
116
  required: ["token", "newPassword"],
89
117
  properties: {
90
- token: { type: "string", description: "Raw token from the sendPasswordResetEmail hook" },
118
+ token: {
119
+ type: "string",
120
+ description: "Raw token from the sendPasswordResetEmail hook",
121
+ },
91
122
  newPassword: { type: "string" },
92
123
  },
93
124
  },
@@ -95,7 +126,11 @@ export const openApiSpec: Record<string, unknown> = {
95
126
  type: "object",
96
127
  required: ["currentPassword", "newPassword"],
97
128
  properties: {
98
- currentPassword: { type: "string", description: "The caller's current password, re-checked server-side before anything changes." },
129
+ currentPassword: {
130
+ type: "string",
131
+ description:
132
+ "The caller's current password, re-checked server-side before anything changes.",
133
+ },
99
134
  newPassword: { type: "string" },
100
135
  },
101
136
  },
@@ -135,7 +170,12 @@ export const openApiSpec: Record<string, unknown> = {
135
170
  displayName: { type: "string", nullable: true },
136
171
  phone: { type: "string", nullable: true },
137
172
  username: { type: "string", nullable: true },
138
- photo: { type: "string", nullable: true, description: "A data URI or an externally-hosted URL — stored as-is, never processed server-side." },
173
+ photo: {
174
+ type: "string",
175
+ nullable: true,
176
+ description:
177
+ "A data URI or an externally-hosted URL — stored as-is, never processed server-side.",
178
+ },
139
179
  },
140
180
  },
141
181
  SelfProfileDto: {
@@ -148,7 +188,12 @@ export const openApiSpec: Record<string, unknown> = {
148
188
  displayName: { type: "string", nullable: true },
149
189
  phone: { type: "string", nullable: true },
150
190
  username: { type: "string", nullable: true },
151
- photo: { type: "string", nullable: true, description: "A data URI or an externally-hosted URL — stored as-is, never processed server-side." },
191
+ photo: {
192
+ type: "string",
193
+ nullable: true,
194
+ description:
195
+ "A data URI or an externally-hosted URL — stored as-is, never processed server-side.",
196
+ },
152
197
  createdAt: { type: "string", format: "date-time" },
153
198
  },
154
199
  },
@@ -171,19 +216,30 @@ export const openApiSpec: Record<string, unknown> = {
171
216
  type: "object",
172
217
  properties: {
173
218
  secret: { type: "string", description: "Base32 TOTP secret" },
174
- provisioningUri: { type: "string", description: "otpauth:// provisioning URI, render as a QR code" },
219
+ provisioningUri: {
220
+ type: "string",
221
+ description: "otpauth:// provisioning URI, render as a QR code",
222
+ },
175
223
  },
176
224
  },
177
225
  ConfirmTwoFactorResponseDto: {
178
226
  type: "object",
179
227
  properties: {
180
- backupCodes: { type: "array", items: { type: "string" }, description: "One-time recovery codes — shown once" },
228
+ backupCodes: {
229
+ type: "array",
230
+ items: { type: "string" },
231
+ description: "One-time recovery codes — shown once",
232
+ },
181
233
  },
182
234
  },
183
235
  OAuthStartResponseDto: {
184
236
  type: "object",
185
237
  properties: {
186
- url: { type: "string", description: "Redirect the user/webview to this URL to start the OAuth flow" },
238
+ url: {
239
+ type: "string",
240
+ description:
241
+ "Redirect the user/webview to this URL to start the OAuth flow",
242
+ },
187
243
  },
188
244
  },
189
245
  RoleSummaryDto: {
@@ -203,12 +259,20 @@ export const openApiSpec: Record<string, unknown> = {
203
259
  summary: "Create a user and issue a session",
204
260
  requestBody: {
205
261
  required: true,
206
- content: { "application/json": { schema: { $ref: "#/components/schemas/SignupDto" } } },
262
+ content: {
263
+ "application/json": {
264
+ schema: { $ref: "#/components/schemas/SignupDto" },
265
+ },
266
+ },
207
267
  },
208
268
  responses: {
209
269
  "201": {
210
270
  description: "Session created",
211
- content: { "application/json": { schema: { $ref: "#/components/schemas/AuthTokensDto" } } },
271
+ content: {
272
+ "application/json": {
273
+ schema: { $ref: "#/components/schemas/AuthTokensDto" },
274
+ },
275
+ },
212
276
  },
213
277
  },
214
278
  },
@@ -221,7 +285,11 @@ export const openApiSpec: Record<string, unknown> = {
221
285
  "identifier is matched against email, username, and phone, in that order. Returns tokens directly, or a 2FA challenge if the account has 2FA enabled.",
222
286
  requestBody: {
223
287
  required: true,
224
- content: { "application/json": { schema: { $ref: "#/components/schemas/LoginDto" } } },
288
+ content: {
289
+ "application/json": {
290
+ schema: { $ref: "#/components/schemas/LoginDto" },
291
+ },
292
+ },
225
293
  },
226
294
  responses: {
227
295
  "200": {
@@ -246,12 +314,20 @@ export const openApiSpec: Record<string, unknown> = {
246
314
  summary: "Complete the 2FA challenge from POST /auth/login",
247
315
  requestBody: {
248
316
  required: true,
249
- content: { "application/json": { schema: { $ref: "#/components/schemas/LoginTwoFactorDto" } } },
317
+ content: {
318
+ "application/json": {
319
+ schema: { $ref: "#/components/schemas/LoginTwoFactorDto" },
320
+ },
321
+ },
250
322
  },
251
323
  responses: {
252
324
  "200": {
253
325
  description: "Session created",
254
- content: { "application/json": { schema: { $ref: "#/components/schemas/AuthTokensDto" } } },
326
+ content: {
327
+ "application/json": {
328
+ schema: { $ref: "#/components/schemas/AuthTokensDto" },
329
+ },
330
+ },
255
331
  },
256
332
  },
257
333
  },
@@ -262,12 +338,20 @@ export const openApiSpec: Record<string, unknown> = {
262
338
  summary: "Rotate a refresh token for a new access+refresh pair",
263
339
  requestBody: {
264
340
  required: true,
265
- content: { "application/json": { schema: { $ref: "#/components/schemas/RefreshDto" } } },
341
+ content: {
342
+ "application/json": {
343
+ schema: { $ref: "#/components/schemas/RefreshDto" },
344
+ },
345
+ },
266
346
  },
267
347
  responses: {
268
348
  "200": {
269
349
  description: "New token pair",
270
- content: { "application/json": { schema: { $ref: "#/components/schemas/RefreshResponseDto" } } },
350
+ content: {
351
+ "application/json": {
352
+ schema: { $ref: "#/components/schemas/RefreshResponseDto" },
353
+ },
354
+ },
271
355
  },
272
356
  },
273
357
  },
@@ -276,29 +360,43 @@ export const openApiSpec: Record<string, unknown> = {
276
360
  get: {
277
361
  tags: ["auth"],
278
362
  summary: "Current session's identity",
279
- description: "`roles` and `permissions` are whatever applies to this request — see authz.middleware.ts for how they are resolved.",
363
+ description:
364
+ "`roles` and `permissions` are whatever applies to this request — see authz.middleware.ts for how they are resolved.",
280
365
  security: [{ bearerAuth: [] }],
281
366
  parameters: adminSpec.scopeParameters,
282
367
  responses: {
283
368
  "200": {
284
369
  description: "Current user",
285
- content: { "application/json": { schema: { $ref: "#/components/schemas/CurrentUserDto" } } },
370
+ content: {
371
+ "application/json": {
372
+ schema: { $ref: "#/components/schemas/CurrentUserDto" },
373
+ },
374
+ },
286
375
  },
287
376
  },
288
377
  },
289
378
  patch: {
290
379
  tags: ["auth"],
291
380
  summary: "Update the current user's own profile",
292
- description: "Self-service — no admin permission required. Updates the caller's own row directly; unrelated to any workspace.",
381
+ description:
382
+ "Self-service — no admin permission required. Updates the caller's own row directly; unrelated to any workspace.",
293
383
  security: [{ bearerAuth: [] }],
294
384
  requestBody: {
295
385
  required: true,
296
- content: { "application/json": { schema: { $ref: "#/components/schemas/UpdateUserRequest" } } },
386
+ content: {
387
+ "application/json": {
388
+ schema: { $ref: "#/components/schemas/UpdateUserRequest" },
389
+ },
390
+ },
297
391
  },
298
392
  responses: {
299
393
  "200": {
300
394
  description: "Updated profile",
301
- content: { "application/json": { schema: { $ref: "#/components/schemas/SelfProfileDto" } } },
395
+ content: {
396
+ "application/json": {
397
+ schema: { $ref: "#/components/schemas/SelfProfileDto" },
398
+ },
399
+ },
302
400
  },
303
401
  "401": { description: "Missing or invalid access token" },
304
402
  },
@@ -312,7 +410,14 @@ export const openApiSpec: Record<string, unknown> = {
312
410
  responses: {
313
411
  "200": {
314
412
  description: "Active sessions",
315
- content: { "application/json": { schema: { type: "array", items: { $ref: "#/components/schemas/SessionSummaryDto" } } } },
413
+ content: {
414
+ "application/json": {
415
+ schema: {
416
+ type: "array",
417
+ items: { $ref: "#/components/schemas/SessionSummaryDto" },
418
+ },
419
+ },
420
+ },
316
421
  },
317
422
  },
318
423
  },
@@ -325,7 +430,11 @@ export const openApiSpec: Record<string, unknown> = {
325
430
  responses: {
326
431
  "200": {
327
432
  description: "OK",
328
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
433
+ content: {
434
+ "application/json": {
435
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
436
+ },
437
+ },
329
438
  },
330
439
  },
331
440
  },
@@ -338,7 +447,11 @@ export const openApiSpec: Record<string, unknown> = {
338
447
  responses: {
339
448
  "200": {
340
449
  description: "OK",
341
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
450
+ content: {
451
+ "application/json": {
452
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
453
+ },
454
+ },
342
455
  },
343
456
  },
344
457
  },
@@ -351,7 +464,11 @@ export const openApiSpec: Record<string, unknown> = {
351
464
  responses: {
352
465
  "200": {
353
466
  description: "OK",
354
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
467
+ content: {
468
+ "application/json": {
469
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
470
+ },
471
+ },
355
472
  },
356
473
  },
357
474
  },
@@ -365,7 +482,13 @@ export const openApiSpec: Record<string, unknown> = {
365
482
  responses: {
366
483
  "200": {
367
484
  description: "TOTP secret + provisioning URI",
368
- content: { "application/json": { schema: { $ref: "#/components/schemas/EnrollTwoFactorResponseDto" } } },
485
+ content: {
486
+ "application/json": {
487
+ schema: {
488
+ $ref: "#/components/schemas/EnrollTwoFactorResponseDto",
489
+ },
490
+ },
491
+ },
369
492
  },
370
493
  },
371
494
  },
@@ -374,16 +497,27 @@ export const openApiSpec: Record<string, unknown> = {
374
497
  post: {
375
498
  tags: ["auth"],
376
499
  summary: "Confirm TOTP enrollment with a code",
377
- description: "Enables 2FA and returns one-time backup codes, shown only here.",
500
+ description:
501
+ "Enables 2FA and returns one-time backup codes, shown only here.",
378
502
  security: [{ bearerAuth: [] }],
379
503
  requestBody: {
380
504
  required: true,
381
- content: { "application/json": { schema: { $ref: "#/components/schemas/TwoFactorCodeDto" } } },
505
+ content: {
506
+ "application/json": {
507
+ schema: { $ref: "#/components/schemas/TwoFactorCodeDto" },
508
+ },
509
+ },
382
510
  },
383
511
  responses: {
384
512
  "200": {
385
513
  description: "Backup codes",
386
- content: { "application/json": { schema: { $ref: "#/components/schemas/ConfirmTwoFactorResponseDto" } } },
514
+ content: {
515
+ "application/json": {
516
+ schema: {
517
+ $ref: "#/components/schemas/ConfirmTwoFactorResponseDto",
518
+ },
519
+ },
520
+ },
387
521
  },
388
522
  },
389
523
  },
@@ -396,12 +530,20 @@ export const openApiSpec: Record<string, unknown> = {
396
530
  security: [{ bearerAuth: [] }],
397
531
  requestBody: {
398
532
  required: true,
399
- content: { "application/json": { schema: { $ref: "#/components/schemas/TwoFactorCodeDto" } } },
533
+ content: {
534
+ "application/json": {
535
+ schema: { $ref: "#/components/schemas/TwoFactorCodeDto" },
536
+ },
537
+ },
400
538
  },
401
539
  responses: {
402
540
  "200": {
403
541
  description: "OK",
404
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
542
+ content: {
543
+ "application/json": {
544
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
545
+ },
546
+ },
405
547
  },
406
548
  },
407
549
  },
@@ -410,15 +552,24 @@ export const openApiSpec: Record<string, unknown> = {
410
552
  post: {
411
553
  tags: ["auth"],
412
554
  summary: "Request a password reset",
413
- description: "Always reports success, whether or not the email exists — avoids account enumeration.",
555
+ description:
556
+ "Always reports success, whether or not the email exists — avoids account enumeration.",
414
557
  requestBody: {
415
558
  required: true,
416
- content: { "application/json": { schema: { $ref: "#/components/schemas/ForgotPasswordDto" } } },
559
+ content: {
560
+ "application/json": {
561
+ schema: { $ref: "#/components/schemas/ForgotPasswordDto" },
562
+ },
563
+ },
417
564
  },
418
565
  responses: {
419
566
  "200": {
420
567
  description: "OK",
421
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
568
+ content: {
569
+ "application/json": {
570
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
571
+ },
572
+ },
422
573
  },
423
574
  },
424
575
  },
@@ -430,12 +581,20 @@ export const openApiSpec: Record<string, unknown> = {
430
581
  description: "Revokes every existing session for the user on success.",
431
582
  requestBody: {
432
583
  required: true,
433
- content: { "application/json": { schema: { $ref: "#/components/schemas/ResetPasswordDto" } } },
584
+ content: {
585
+ "application/json": {
586
+ schema: { $ref: "#/components/schemas/ResetPasswordDto" },
587
+ },
588
+ },
434
589
  },
435
590
  responses: {
436
591
  "200": {
437
592
  description: "OK",
438
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
593
+ content: {
594
+ "application/json": {
595
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
596
+ },
597
+ },
439
598
  },
440
599
  },
441
600
  },
@@ -444,16 +603,25 @@ export const openApiSpec: Record<string, unknown> = {
444
603
  post: {
445
604
  tags: ["auth"],
446
605
  summary: "Change the current user's password",
447
- description: "Verifies currentPassword server-side, then revokes every other session for the user — the calling session is left alone.",
606
+ description:
607
+ "Verifies currentPassword server-side, then revokes every other session for the user — the calling session is left alone.",
448
608
  security: [{ bearerAuth: [] }],
449
609
  requestBody: {
450
610
  required: true,
451
- content: { "application/json": { schema: { $ref: "#/components/schemas/ChangePasswordDto" } } },
611
+ content: {
612
+ "application/json": {
613
+ schema: { $ref: "#/components/schemas/ChangePasswordDto" },
614
+ },
615
+ },
452
616
  },
453
617
  responses: {
454
618
  "200": {
455
619
  description: "OK",
456
- content: { "application/json": { schema: { $ref: "#/components/schemas/OkResponseDto" } } },
620
+ content: {
621
+ "application/json": {
622
+ schema: { $ref: "#/components/schemas/OkResponseDto" },
623
+ },
624
+ },
457
625
  },
458
626
  },
459
627
  },
@@ -462,11 +630,22 @@ export const openApiSpec: Record<string, unknown> = {
462
630
  get: {
463
631
  tags: ["auth"],
464
632
  summary: "Get the redirect URL to start an OAuth login",
465
- parameters: [{ name: "provider", in: "path", required: true, schema: { type: "string", enum: ["google", "apple"] } }],
633
+ parameters: [
634
+ {
635
+ name: "provider",
636
+ in: "path",
637
+ required: true,
638
+ schema: { type: "string", enum: ["google", "apple"] },
639
+ },
640
+ ],
466
641
  responses: {
467
642
  "200": {
468
643
  description: "Redirect URL",
469
- content: { "application/json": { schema: { $ref: "#/components/schemas/OAuthStartResponseDto" } } },
644
+ content: {
645
+ "application/json": {
646
+ schema: { $ref: "#/components/schemas/OAuthStartResponseDto" },
647
+ },
648
+ },
470
649
  },
471
650
  },
472
651
  },
@@ -474,16 +653,36 @@ export const openApiSpec: Record<string, unknown> = {
474
653
  "/auth/oauth/{provider}/callback": {
475
654
  get: {
476
655
  tags: ["auth"],
477
- summary: "OAuth provider callback — exchanges the code and completes login",
656
+ summary:
657
+ "OAuth provider callback — exchanges the code and completes login",
478
658
  parameters: [
479
- { name: "provider", in: "path", required: true, schema: { type: "string", enum: ["google", "apple"] } },
480
- { name: "code", in: "query", required: true, schema: { type: "string" } },
481
- { name: "state", in: "query", required: true, schema: { type: "string" } },
659
+ {
660
+ name: "provider",
661
+ in: "path",
662
+ required: true,
663
+ schema: { type: "string", enum: ["google", "apple"] },
664
+ },
665
+ {
666
+ name: "code",
667
+ in: "query",
668
+ required: true,
669
+ schema: { type: "string" },
670
+ },
671
+ {
672
+ name: "state",
673
+ in: "query",
674
+ required: true,
675
+ schema: { type: "string" },
676
+ },
482
677
  ],
483
678
  responses: {
484
679
  "200": {
485
680
  description: "Session created",
486
- content: { "application/json": { schema: { $ref: "#/components/schemas/AuthTokensDto" } } },
681
+ content: {
682
+ "application/json": {
683
+ schema: { $ref: "#/components/schemas/AuthTokensDto" },
684
+ },
685
+ },
487
686
  },
488
687
  },
489
688
  },
@@ -1,9 +1,9 @@
1
1
  import { and, eq } from "drizzle-orm";
2
2
  import type { NodePgDatabase } from "drizzle-orm/node-postgres";
3
3
  import type { OAuthStoreDeps } from "@/lib/auth/core/oauth.js";
4
- import { HttpError } from "../http-error.js";
4
+ import { HttpError } from "../errors/http-error.js";
5
5
  import * as schema from "../schema.js";
6
- import { toId } from "../id.helper.js";
6
+ import { toId } from "../helpers/id.helper.js";
7
7
 
8
8
  /**
9
9
  * Plain class, no decorators — Drizzle-specific implementation of `OAuthStoreDeps`
@@ -2,7 +2,7 @@ import { eq } from "drizzle-orm";
2
2
  import type { NodePgDatabase } from "drizzle-orm/node-postgres";
3
3
  import type { PasswordResetStoreDeps } from "@/lib/auth/core/password-reset.js";
4
4
  import * as schema from "../schema.js";
5
- import { toId } from "../id.helper.js";
5
+ import { toId } from "../helpers/id.helper.js";
6
6
 
7
7
  /**
8
8
  * Plain class, no decorators — Drizzle-specific implementation of `PasswordResetStoreDeps`
@@ -23,9 +23,7 @@ export class PasswordResetRepository implements PasswordResetStoreDeps {
23
23
  });
24
24
  }
25
25
 
26
- async findValidResetToken(
27
- tokenHash: string,
28
- ): Promise<{
26
+ async findValidResetToken(tokenHash: string): Promise<{
29
27
  userId: string;
30
28
  expiresAt: string;
31
29
  consumedAt: string | null;
@@ -7,10 +7,10 @@ import type {
7
7
  SessionRecord,
8
8
  } from "@/lib/auth/core/types.js";
9
9
  import { AuditLogRepository } from "./audit-log.repository.js";
10
- import type { AuthConfig } from "../auth.config.js";
11
- import type { Database } from "../db.js";
10
+ import type { AuthConfig } from "../config/auth.config.js";
11
+ import type { Database } from "../config/db.js";
12
12
  import { denylistedAccessTokens, sessions } from "../schema.js";
13
- import { toId, toIdOrNull } from "../id.helper.js";
13
+ import { toId, toIdOrNull } from "../helpers/id.helper.js";
14
14
 
15
15
  function toSessionRecord(row: typeof sessions.$inferSelect): SessionRecord {
16
16
  return {
@@ -19,7 +19,7 @@
19
19
  // the `Express` namespace, see @types/express-serve-static-core) rather than the reference's
20
20
  // `declare module "express"`.
21
21
  import type { AccessTokenClaims } from "@/lib/auth/core/types.js";
22
- import type { AppAbility } from "./ability.js";
22
+ import type { AppAbility } from "./ability/ability.js";
23
23
  import type { AuthzContext } from "./middleware/authz.middleware.js";
24
24
 
25
25
  declare global {