@tstdl/base 0.93.87 → 0.93.89

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 (314) hide show
  1. package/ai/genkit/helpers.d.ts +3 -1
  2. package/ai/genkit/helpers.js +3 -3
  3. package/api/server/gateway.d.ts +3 -0
  4. package/api/server/gateway.js +15 -4
  5. package/api/server/middlewares/catch-error.middleware.js +2 -4
  6. package/api/server/middlewares/cors.middleware.js +2 -3
  7. package/api/server/middlewares/csrf.middleware.d.ts +41 -0
  8. package/api/server/middlewares/csrf.middleware.js +108 -0
  9. package/api/server/middlewares/index.d.ts +1 -0
  10. package/api/server/middlewares/index.js +1 -0
  11. package/api/server/module.d.ts +8 -2
  12. package/api/server/module.js +14 -8
  13. package/api/server/tests/csrf.middleware.test.js +91 -0
  14. package/audit/drizzle/{0000_bored_stick.sql → 0000_lumpy_thunderball.sql} +3 -3
  15. package/audit/drizzle/meta/0000_snapshot.json +4 -4
  16. package/audit/drizzle/meta/_journal.json +2 -9
  17. package/audit/module.d.ts +4 -1
  18. package/audit/module.js +3 -2
  19. package/audit/schemas.d.ts +1 -1
  20. package/audit/types.d.ts +1 -1
  21. package/audit/types.js +1 -1
  22. package/authentication/client/authentication.service.d.ts +14 -1
  23. package/authentication/client/authentication.service.js +82 -23
  24. package/authentication/client/http-client.middleware.d.ts +6 -0
  25. package/authentication/client/http-client.middleware.js +36 -0
  26. package/authentication/client/module.js +8 -2
  27. package/authentication/models/service-account.model.d.ts +2 -2
  28. package/authentication/models/service-account.model.js +10 -5
  29. package/authentication/models/subject.model.d.ts +19 -5
  30. package/authentication/models/subject.model.js +25 -29
  31. package/authentication/models/system-account.model.d.ts +3 -2
  32. package/authentication/models/system-account.model.js +11 -5
  33. package/authentication/models/user.model.d.ts +2 -11
  34. package/authentication/models/user.model.js +5 -16
  35. package/authentication/server/authentication-api-request-token.provider.d.ts +0 -2
  36. package/authentication/server/authentication-api-request-token.provider.js +3 -11
  37. package/authentication/server/authentication.api-controller.d.ts +1 -2
  38. package/authentication/server/authentication.api-controller.js +8 -9
  39. package/authentication/server/authentication.audit.d.ts +3 -2
  40. package/authentication/server/authentication.service.d.ts +27 -1
  41. package/authentication/server/authentication.service.js +67 -18
  42. package/authentication/server/drizzle/{0000_normal_paper_doll.sql → 0000_soft_tag.sql} +25 -32
  43. package/authentication/server/drizzle/meta/0000_snapshot.json +180 -205
  44. package/authentication/server/drizzle/meta/_journal.json +2 -2
  45. package/authentication/server/helper.js +9 -2
  46. package/authentication/server/module.d.ts +4 -1
  47. package/authentication/server/module.js +9 -5
  48. package/authentication/server/schemas.d.ts +2 -1
  49. package/authentication/server/schemas.js +2 -2
  50. package/authentication/server/subject.service.d.ts +14 -8
  51. package/authentication/server/subject.service.js +86 -84
  52. package/authentication/tests/authentication-ancillary.service.test.d.ts +1 -0
  53. package/authentication/tests/authentication-ancillary.service.test.js +13 -0
  54. package/authentication/tests/authentication-secret-requirements.validator.test.d.ts +1 -0
  55. package/authentication/tests/authentication-secret-requirements.validator.test.js +29 -0
  56. package/authentication/tests/authentication.api-controller.test.d.ts +1 -0
  57. package/authentication/tests/authentication.api-controller.test.js +88 -0
  58. package/authentication/tests/authentication.api-request-token.provider.test.d.ts +1 -0
  59. package/authentication/tests/authentication.api-request-token.provider.test.js +48 -0
  60. package/authentication/tests/authentication.client-middleware.test.d.ts +1 -0
  61. package/authentication/tests/authentication.client-middleware.test.js +23 -0
  62. package/authentication/tests/authentication.client-service.test.d.ts +1 -0
  63. package/authentication/tests/authentication.client-service.test.js +70 -0
  64. package/authentication/tests/authentication.service.test.d.ts +1 -0
  65. package/authentication/tests/authentication.service.test.js +186 -0
  66. package/authentication/tests/authentication.test-ancillary-service.d.ts +9 -0
  67. package/authentication/tests/authentication.test-ancillary-service.js +27 -0
  68. package/authentication/tests/helper.test.d.ts +1 -0
  69. package/authentication/tests/helper.test.js +107 -0
  70. package/authentication/tests/secret-requirements.error.test.d.ts +1 -0
  71. package/authentication/tests/secret-requirements.error.test.js +14 -0
  72. package/authentication/tests/subject.service.test.d.ts +1 -0
  73. package/authentication/tests/subject.service.test.js +140 -0
  74. package/circuit-breaker/postgres/drizzle/meta/0000_snapshot.json +1 -1
  75. package/circuit-breaker/postgres/drizzle/meta/_journal.json +2 -2
  76. package/circuit-breaker/postgres/module.d.ts +7 -1
  77. package/circuit-breaker/postgres/module.js +8 -6
  78. package/circuit-breaker/tests/circuit-breaker.test.js +2 -22
  79. package/document-management/api/document-management.api.js +2 -6
  80. package/document-management/server/services/document-validation.service.js +6 -5
  81. package/document-management/server/services/document-workflow.service.js +5 -5
  82. package/document-management/service-models/document-folders.view-model.d.ts +5 -2
  83. package/document-management/service-models/document-folders.view-model.js +42 -9
  84. package/document-management/service-models/enriched/enriched-document-management-data.view.js +1 -1
  85. package/examples/document-management/main.js +4 -4
  86. package/http/client/adapters/undici.adapter.d.ts +7 -5
  87. package/http/client/adapters/undici.adapter.js +13 -10
  88. package/http/client/module.d.ts +3 -1
  89. package/http/client/module.js +8 -9
  90. package/http/server/http-server.d.ts +2 -0
  91. package/http/server/node/module.d.ts +6 -2
  92. package/http/server/node/module.js +6 -4
  93. package/http/server/node/node-http-server.d.ts +2 -0
  94. package/http/server/node/node-http-server.js +7 -0
  95. package/http/types.d.ts +1 -1
  96. package/key-value-store/postgres/module.d.ts +7 -1
  97. package/key-value-store/postgres/module.js +7 -3
  98. package/lock/postgres/lock.js +0 -1
  99. package/lock/postgres/module.d.ts +7 -1
  100. package/lock/postgres/module.js +9 -5
  101. package/logger/formatter.d.ts +2 -0
  102. package/logger/formatters/json.js +2 -2
  103. package/logger/formatters/pretty-print.js +8 -10
  104. package/logger/logger.d.ts +1 -1
  105. package/logger/logger.js +15 -12
  106. package/message-bus/local/module.d.ts +5 -2
  107. package/message-bus/local/module.js +5 -4
  108. package/module/module.d.ts +2 -1
  109. package/module/module.js +3 -0
  110. package/module/modules/web-server.module.d.ts +11 -6
  111. package/module/modules/web-server.module.js +15 -10
  112. package/orm/decorators.d.ts +24 -1
  113. package/orm/decorators.js +40 -4
  114. package/orm/query/base.d.ts +17 -17
  115. package/orm/query/base.js +1 -1
  116. package/orm/repository.types.d.ts +45 -1
  117. package/orm/schemas/tsvector.js +1 -1
  118. package/orm/server/drizzle/schema-converter.d.ts +3 -1
  119. package/orm/server/drizzle/schema-converter.js +120 -14
  120. package/orm/server/index.d.ts +1 -0
  121. package/orm/server/index.js +1 -0
  122. package/orm/server/module.d.ts +4 -2
  123. package/orm/server/module.js +6 -5
  124. package/orm/server/query-converter.d.ts +6 -3
  125. package/orm/server/query-converter.js +32 -20
  126. package/orm/server/repository-config.d.ts +8 -0
  127. package/orm/server/repository-config.js +8 -0
  128. package/orm/server/repository.d.ts +117 -43
  129. package/orm/server/repository.js +757 -253
  130. package/orm/server/transaction.d.ts +4 -2
  131. package/orm/server/transaction.js +14 -5
  132. package/orm/server/transactional.d.ts +6 -2
  133. package/orm/server/transactional.js +39 -9
  134. package/orm/server/types.d.ts +2 -0
  135. package/orm/sqls/case-when.d.ts +3 -3
  136. package/orm/sqls/case-when.js +2 -2
  137. package/orm/sqls/sqls.d.ts +31 -5
  138. package/orm/sqls/sqls.js +69 -6
  139. package/orm/tests/data-types.test.d.ts +1 -0
  140. package/orm/tests/data-types.test.js +39 -0
  141. package/orm/tests/decorators.test.d.ts +1 -0
  142. package/orm/tests/decorators.test.js +77 -0
  143. package/orm/tests/encryption.test.d.ts +1 -0
  144. package/orm/tests/encryption.test.js +34 -0
  145. package/orm/tests/query-complex.test.d.ts +1 -0
  146. package/orm/tests/query-complex.test.js +203 -0
  147. package/orm/tests/query-converter-complex.test.d.ts +1 -0
  148. package/orm/tests/query-converter-complex.test.js +126 -0
  149. package/orm/tests/query-converter.test.d.ts +1 -0
  150. package/orm/tests/query-converter.test.js +123 -0
  151. package/orm/tests/repository-advanced.test.d.ts +1 -0
  152. package/orm/tests/repository-advanced.test.js +232 -0
  153. package/orm/tests/repository-attributes.test.d.ts +1 -0
  154. package/orm/tests/repository-attributes.test.js +99 -0
  155. package/orm/tests/repository-comprehensive.test.d.ts +1 -0
  156. package/orm/tests/repository-comprehensive.test.js +187 -0
  157. package/orm/tests/repository-coverage.test.d.ts +1 -0
  158. package/orm/tests/repository-coverage.test.js +303 -0
  159. package/orm/tests/repository-cti-complex.test.d.ts +1 -0
  160. package/orm/tests/repository-cti-complex.test.js +170 -0
  161. package/orm/tests/repository-cti-embedded.test.d.ts +1 -0
  162. package/orm/tests/repository-cti-embedded.test.js +188 -0
  163. package/orm/tests/repository-cti-extensive.test.d.ts +1 -0
  164. package/orm/tests/repository-cti-extensive.test.js +308 -0
  165. package/orm/tests/repository-cti-mapping.test.d.ts +1 -0
  166. package/orm/tests/repository-cti-mapping.test.js +121 -0
  167. package/orm/tests/repository-cti-search.test.d.ts +1 -0
  168. package/orm/tests/repository-cti-search.test.js +152 -0
  169. package/orm/tests/repository-cti-soft-delete.test.d.ts +1 -0
  170. package/orm/tests/repository-cti-soft-delete.test.js +115 -0
  171. package/orm/tests/repository-cti-transactions.test.d.ts +1 -0
  172. package/orm/tests/repository-cti-transactions.test.js +126 -0
  173. package/orm/tests/repository-cti-upsert-many.test.d.ts +1 -0
  174. package/orm/tests/repository-cti-upsert-many.test.js +127 -0
  175. package/orm/tests/repository-cti.test.d.ts +1 -0
  176. package/orm/tests/repository-cti.test.js +456 -0
  177. package/orm/tests/repository-edge-cases.test.d.ts +1 -0
  178. package/orm/tests/repository-edge-cases.test.js +216 -0
  179. package/orm/tests/repository-expiration.test.d.ts +1 -0
  180. package/orm/tests/repository-expiration.test.js +153 -0
  181. package/orm/tests/repository-extra-coverage.test.d.ts +1 -0
  182. package/orm/tests/repository-extra-coverage.test.js +546 -0
  183. package/orm/tests/repository-mapping.test.d.ts +1 -0
  184. package/orm/tests/repository-mapping.test.js +71 -0
  185. package/orm/tests/repository-regression.test.d.ts +1 -0
  186. package/orm/tests/repository-regression.test.js +330 -0
  187. package/orm/tests/repository-search-coverage.test.d.ts +1 -0
  188. package/orm/tests/repository-search-coverage.test.js +129 -0
  189. package/orm/tests/repository-search.test.d.ts +1 -0
  190. package/orm/tests/repository-search.test.js +116 -0
  191. package/orm/tests/repository-soft-delete.test.d.ts +1 -0
  192. package/orm/tests/repository-soft-delete.test.js +143 -0
  193. package/orm/tests/repository-transactions-nested.test.d.ts +1 -0
  194. package/orm/tests/repository-transactions-nested.test.js +202 -0
  195. package/orm/tests/repository-types.test.d.ts +1 -0
  196. package/orm/tests/repository-types.test.js +218 -0
  197. package/orm/tests/schema-converter.test.d.ts +1 -0
  198. package/orm/tests/schema-converter.test.js +81 -0
  199. package/orm/tests/schema-generation.test.d.ts +1 -0
  200. package/orm/tests/schema-generation.test.js +127 -0
  201. package/orm/tests/sql-helpers.test.d.ts +1 -0
  202. package/orm/tests/sql-helpers.test.js +67 -0
  203. package/orm/tests/transaction-safety.test.d.ts +1 -0
  204. package/orm/tests/transaction-safety.test.js +81 -0
  205. package/orm/tests/transactional.test.d.ts +1 -0
  206. package/orm/tests/transactional.test.js +224 -0
  207. package/orm/tests/utils.test.d.ts +1 -0
  208. package/orm/tests/utils.test.js +70 -0
  209. package/orm/utils.d.ts +7 -0
  210. package/orm/utils.js +26 -6
  211. package/package.json +12 -7
  212. package/pool/pool.js +1 -1
  213. package/rate-limit/index.d.ts +2 -0
  214. package/rate-limit/index.js +2 -0
  215. package/rate-limit/postgres/drizzle/0000_watery_rage.sql +7 -0
  216. package/{queue → rate-limit}/postgres/drizzle/meta/0000_snapshot.json +14 -39
  217. package/rate-limit/postgres/drizzle/meta/_journal.json +13 -0
  218. package/{queue → rate-limit}/postgres/drizzle.config.js +1 -1
  219. package/rate-limit/postgres/index.d.ts +4 -0
  220. package/rate-limit/postgres/index.js +4 -0
  221. package/rate-limit/postgres/module.d.ts +12 -0
  222. package/rate-limit/postgres/module.js +28 -0
  223. package/rate-limit/postgres/postgres-rate-limiter.d.ts +9 -0
  224. package/rate-limit/postgres/postgres-rate-limiter.js +56 -0
  225. package/rate-limit/postgres/rate-limit.model.d.ts +8 -0
  226. package/rate-limit/postgres/rate-limit.model.js +35 -0
  227. package/rate-limit/postgres/rate-limiter.provider.d.ts +6 -0
  228. package/rate-limit/postgres/rate-limiter.provider.js +21 -0
  229. package/rate-limit/postgres/schemas.d.ts +3 -0
  230. package/rate-limit/postgres/schemas.js +4 -0
  231. package/rate-limit/provider.d.ts +9 -0
  232. package/rate-limit/provider.js +2 -0
  233. package/rate-limit/rate-limiter.d.ts +35 -0
  234. package/rate-limit/rate-limiter.js +3 -0
  235. package/rate-limit/tests/postgres-rate-limiter.test.d.ts +1 -0
  236. package/rate-limit/tests/postgres-rate-limiter.test.js +92 -0
  237. package/signals/implementation/configure.d.ts +3 -0
  238. package/signals/implementation/configure.js +3 -0
  239. package/sse/data-stream-source.d.ts +1 -1
  240. package/sse/data-stream-source.js +6 -6
  241. package/task-queue/enqueue-batch.d.ts +17 -0
  242. package/task-queue/enqueue-batch.js +24 -0
  243. package/{queue → task-queue}/index.d.ts +1 -1
  244. package/{queue → task-queue}/index.js +1 -1
  245. package/task-queue/postgres/drizzle/0000_thin_black_panther.sql +74 -0
  246. package/task-queue/postgres/drizzle/meta/0000_snapshot.json +592 -0
  247. package/task-queue/postgres/drizzle/meta/_journal.json +13 -0
  248. package/task-queue/postgres/drizzle.config.d.ts +2 -0
  249. package/task-queue/postgres/drizzle.config.js +11 -0
  250. package/task-queue/postgres/index.d.ts +4 -0
  251. package/task-queue/postgres/index.js +4 -0
  252. package/task-queue/postgres/module.d.ts +12 -0
  253. package/task-queue/postgres/module.js +28 -0
  254. package/task-queue/postgres/schemas.d.ts +16 -0
  255. package/task-queue/postgres/schemas.js +8 -0
  256. package/task-queue/postgres/task-queue.d.ts +83 -0
  257. package/task-queue/postgres/task-queue.js +1054 -0
  258. package/task-queue/postgres/task-queue.provider.d.ts +7 -0
  259. package/{queue/postgres/queue.provider.js → task-queue/postgres/task-queue.provider.js} +8 -8
  260. package/task-queue/postgres/task.model.d.ts +39 -0
  261. package/task-queue/postgres/task.model.js +178 -0
  262. package/{queue → task-queue}/provider.d.ts +3 -3
  263. package/task-queue/provider.js +2 -0
  264. package/{queue → task-queue}/task-context.d.ts +7 -7
  265. package/{queue → task-queue}/task-context.js +8 -8
  266. package/{queue/queue.d.ts → task-queue/task-queue.d.ts} +128 -59
  267. package/task-queue/task-queue.js +200 -0
  268. package/task-queue/tests/complex.test.d.ts +1 -0
  269. package/task-queue/tests/complex.test.js +299 -0
  270. package/task-queue/tests/dependencies.test.d.ts +1 -0
  271. package/task-queue/tests/dependencies.test.js +174 -0
  272. package/task-queue/tests/queue.test.d.ts +1 -0
  273. package/task-queue/tests/queue.test.js +334 -0
  274. package/task-queue/tests/worker.test.d.ts +1 -0
  275. package/task-queue/tests/worker.test.js +163 -0
  276. package/test1.js +1 -1
  277. package/test4.js +2 -2
  278. package/unit-test/index.d.ts +1 -0
  279. package/unit-test/index.js +1 -0
  280. package/unit-test/integration-setup.d.ts +55 -0
  281. package/unit-test/integration-setup.js +182 -0
  282. package/utils/patterns.d.ts +3 -0
  283. package/utils/patterns.js +6 -1
  284. package/audit/drizzle/0001_previous_network.sql +0 -2
  285. package/audit/drizzle/meta/0001_snapshot.json +0 -195
  286. package/queue/enqueue-batch.d.ts +0 -17
  287. package/queue/enqueue-batch.js +0 -18
  288. package/queue/postgres/drizzle/0000_zippy_moondragon.sql +0 -11
  289. package/queue/postgres/drizzle/0001_certain_wild_pack.sql +0 -2
  290. package/queue/postgres/drizzle/0002_dear_meggan.sql +0 -2
  291. package/queue/postgres/drizzle/0003_tricky_venom.sql +0 -30
  292. package/queue/postgres/drizzle/meta/0001_snapshot.json +0 -103
  293. package/queue/postgres/drizzle/meta/0002_snapshot.json +0 -90
  294. package/queue/postgres/drizzle/meta/0003_snapshot.json +0 -288
  295. package/queue/postgres/drizzle/meta/_journal.json +0 -34
  296. package/queue/postgres/index.d.ts +0 -4
  297. package/queue/postgres/index.js +0 -4
  298. package/queue/postgres/module.d.ts +0 -9
  299. package/queue/postgres/module.js +0 -29
  300. package/queue/postgres/queue.d.ts +0 -60
  301. package/queue/postgres/queue.js +0 -681
  302. package/queue/postgres/queue.provider.d.ts +0 -7
  303. package/queue/postgres/schemas.d.ts +0 -14
  304. package/queue/postgres/schemas.js +0 -6
  305. package/queue/postgres/task.model.d.ts +0 -24
  306. package/queue/postgres/task.model.js +0 -115
  307. package/queue/provider.js +0 -2
  308. package/queue/queue.js +0 -131
  309. package/queue/tests/queue.test.js +0 -623
  310. package/test3.d.ts +0 -1
  311. package/test3.js +0 -47
  312. /package/{queue/tests/queue.test.d.ts → api/server/tests/csrf.middleware.test.d.ts} +0 -0
  313. /package/circuit-breaker/postgres/drizzle/{0000_hard_shocker.sql → 0000_cooing_korath.sql} +0 -0
  314. /package/{queue → rate-limit}/postgres/drizzle.config.d.ts +0 -0
@@ -5,7 +5,7 @@ export type AuthenticationAuditEvents = {
5
5
  };
6
6
  'login-failure': {
7
7
  subjectInput: SubjectInput;
8
- subjectId: string | null;
8
+ resolvedSubjectId: string | null;
9
9
  };
10
10
  'logout': {
11
11
  sessionId: string;
@@ -27,11 +27,12 @@ export type AuthenticationAuditEvents = {
27
27
  'change-secret-success': {};
28
28
  'change-secret-failure': {
29
29
  subjectInput: SubjectInput;
30
- subjectId: string | null;
30
+ resolvedSubjectId: string | null;
31
31
  };
32
32
  'init-secret-reset': {};
33
33
  'reset-secret-success': {};
34
34
  'reset-secret-failure': {
35
35
  reason: string;
36
36
  };
37
+ 'invalidate-all-sessions': {};
37
38
  };
@@ -1,7 +1,7 @@
1
1
  import { Auditor } from '../../audit/index.js';
2
2
  import { afterResolve, type AfterResolve } from '../../injector/index.js';
3
3
  import type { BinaryData, Record } from '../../types/index.js';
4
- import { Subject, type RefreshToken, type SecretCheckResult, type SecretResetToken, type Token } from '../models/index.js';
4
+ import { AuthenticationSession, Subject, type RefreshToken, type SecretCheckResult, type SecretResetToken, type Token } from '../models/index.js';
5
5
  import type { SubjectInput } from '../types.js';
6
6
  import { type SecretTestResult } from './authentication-secret-requirements.validator.js';
7
7
  /**
@@ -202,6 +202,32 @@ export declare class AuthenticationService<AdditionalTokenPayload extends Record
202
202
  * @param auditor Auditor for auditing.
203
203
  */
204
204
  endSession(sessionId: string, auditor: Auditor): Promise<void>;
205
+ /**
206
+ * Invalidates all sessions for a subject.
207
+ * @param tenantId The tenant id of the subject.
208
+ * @param subjectId The id of the subject.
209
+ * @param auditor Auditor for auditing.
210
+ */
211
+ invalidateAllSessions(tenantId: string, subjectId: string, auditor: Auditor): Promise<void>;
212
+ /**
213
+ * Lists all sessions for a subject.
214
+ * @param tenantId The tenant id of the subject.
215
+ * @param subjectId The id of the subject.
216
+ * @returns List of sessions.
217
+ */
218
+ listSessions(tenantId: string, subjectId: string): Promise<AuthenticationSession[]>;
219
+ /**
220
+ * Gets a session.
221
+ * @param sessionId The id of the session.
222
+ * @returns The session.
223
+ */
224
+ getSession(sessionId: string): Promise<AuthenticationSession>;
225
+ /**
226
+ * Tries to get a session.
227
+ * @param sessionId The id of the session.
228
+ * @returns The session or undefined if not found.
229
+ */
230
+ tryGetSession(sessionId: string): Promise<AuthenticationSession | undefined>;
205
231
  /**
206
232
  * Refreshes a token.
207
233
  * @param refreshToken The refresh token to use.
@@ -15,8 +15,8 @@ import { NotImplementedError } from '../../errors/not-implemented.error.js';
15
15
  import { afterResolve, inject, provide, Singleton } from '../../injector/index.js';
16
16
  import { KeyValueStore } from '../../key-value-store/key-value.store.js';
17
17
  import { Logger } from '../../logger/logger.js';
18
+ import { TRANSACTION_TIMESTAMP } from '../../orm/index.js';
18
19
  import { DatabaseConfig, injectRepository } from '../../orm/server/index.js';
19
- import { getEntityIds } from '../../orm/utils.js';
20
20
  import { Alphabet } from '../../utils/alphabet.js';
21
21
  import { asyncHook } from '../../utils/async-hook/async-hook.js';
22
22
  import { decodeBase64, encodeBase64 } from '../../utils/base64.js';
@@ -24,6 +24,7 @@ import { deriveBytesMultiple, importPbkdf2Key } from '../../utils/cryptography.j
24
24
  import { currentTimestamp, timestampToTimestampSeconds } from '../../utils/date-time.js';
25
25
  import { timingSafeBinaryEquals } from '../../utils/equals.js';
26
26
  import { createJwtTokenString } from '../../utils/jwt.js';
27
+ import { isUuid } from '../../utils/patterns.js';
27
28
  import { getRandomBytes, getRandomString } from '../../utils/random.js';
28
29
  import { isBinaryData, isDefined, isString, isUndefined } from '../../utils/type-guards.js';
29
30
  import { millisecondsPerDay, millisecondsPerMinute } from '../../utils/units.js';
@@ -227,10 +228,11 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
227
228
  if (!authenticationResult.success) {
228
229
  const actualSubject = await this.tryResolveSubject(subjectInput);
229
230
  await authAuditor.warn('login-failure', {
231
+ actorType: ActorType.Anonymous,
230
232
  tenantId: actualSubject?.tenantId ?? subjectInput.tenantId,
231
233
  targetId: actualSubject?.id ?? NIL_UUID,
232
234
  targetType: 'User',
233
- details: { subjectInput, subjectId: actualSubject?.id ?? null },
235
+ details: { subjectInput, resolvedSubjectId: actualSubject?.id ?? null },
234
236
  });
235
237
  throw new InvalidCredentialsError();
236
238
  }
@@ -241,7 +243,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
241
243
  await authAuditor.info('login-success', {
242
244
  tenantId: authenticationResult.subject.tenantId,
243
245
  actor: authenticationResult.subject.id,
244
- actorType: ActorType.User,
246
+ actorType: ActorType.Subject,
245
247
  targetId: authenticationResult.subject.id,
246
248
  targetType: 'User',
247
249
  network: { sessionId },
@@ -266,12 +268,54 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
266
268
  await authAuditor.info('logout', {
267
269
  tenantId: session.tenantId,
268
270
  actor: session.subjectId,
269
- actorType: ActorType.User,
271
+ actorType: ActorType.Subject,
270
272
  targetId: session.subjectId,
271
273
  targetType: 'User',
272
274
  details: { sessionId },
273
275
  });
274
276
  }
277
+ /**
278
+ * Invalidates all sessions for a subject.
279
+ * @param tenantId The tenant id of the subject.
280
+ * @param subjectId The id of the subject.
281
+ * @param auditor Auditor for auditing.
282
+ */
283
+ async invalidateAllSessions(tenantId, subjectId, auditor) {
284
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
285
+ await this.#sessionRepository.updateManyByQuery({ tenantId, subjectId, end: { $gt: TRANSACTION_TIMESTAMP } }, { end: TRANSACTION_TIMESTAMP });
286
+ await authAuditor.info('invalidate-all-sessions', {
287
+ tenantId,
288
+ actor: subjectId,
289
+ actorType: ActorType.Subject,
290
+ targetId: subjectId,
291
+ targetType: 'User',
292
+ });
293
+ }
294
+ /**
295
+ * Lists all sessions for a subject.
296
+ * @param tenantId The tenant id of the subject.
297
+ * @param subjectId The id of the subject.
298
+ * @returns List of sessions.
299
+ */
300
+ async listSessions(tenantId, subjectId) {
301
+ return await this.#sessionRepository.loadManyByQuery({ tenantId, subjectId });
302
+ }
303
+ /**
304
+ * Gets a session.
305
+ * @param sessionId The id of the session.
306
+ * @returns The session.
307
+ */
308
+ async getSession(sessionId) {
309
+ return await this.#sessionRepository.load(sessionId);
310
+ }
311
+ /**
312
+ * Tries to get a session.
313
+ * @param sessionId The id of the session.
314
+ * @returns The session or undefined if not found.
315
+ */
316
+ async tryGetSession(sessionId) {
317
+ return await this.#sessionRepository.tryLoad(sessionId);
318
+ }
275
319
  /**
276
320
  * Refreshes a token.
277
321
  * @param refreshToken The refresh token to use.
@@ -283,10 +327,11 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
283
327
  */
284
328
  async refresh(refreshToken, authenticationData, options = {}, auditor) {
285
329
  const authAuditor = auditor.fork(AuthenticationService_1.name);
330
+ let session;
286
331
  try {
287
332
  const validatedRefreshToken = await this.validateRefreshToken(refreshToken);
288
333
  const sessionId = validatedRefreshToken.payload.session;
289
- const session = await this.#sessionRepository.load(sessionId);
334
+ session = await this.#sessionRepository.load(sessionId);
290
335
  const hash = await this.getHash(validatedRefreshToken.payload.secret, session.refreshTokenSalt);
291
336
  if (session.end <= currentTimestamp()) {
292
337
  throw new InvalidTokenError('Session is expired.');
@@ -294,7 +339,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
294
339
  if (!timingSafeBinaryEquals(hash, session.refreshTokenHash)) {
295
340
  await this.endSession(sessionId, auditor);
296
341
  await authAuditor.warn('refresh-failure', {
297
- targetId: session.tenantId,
342
+ actorType: ActorType.Anonymous,
343
+ tenantId: session.tenantId,
344
+ targetId: session.subjectId,
298
345
  targetType: 'User',
299
346
  details: { sessionId, reason: 'Token reuse detected. Session revoked.' },
300
347
  });
@@ -316,7 +363,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
316
363
  await authAuditor.info('refresh-success', {
317
364
  tenantId: session.tenantId,
318
365
  actor: session.subjectId,
319
- actorType: ActorType.User,
366
+ actorType: ActorType.Subject,
320
367
  targetId: session.subjectId,
321
368
  targetType: 'User',
322
369
  details: { sessionId },
@@ -325,7 +372,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
325
372
  }
326
373
  catch (error) {
327
374
  await authAuditor.warn('refresh-failure', {
328
- targetId: NIL_UUID,
375
+ actorType: ActorType.Anonymous,
376
+ targetId: session?.subjectId ?? NIL_UUID,
329
377
  targetType: 'User',
330
378
  details: { sessionId: null, reason: error.message },
331
379
  });
@@ -353,7 +401,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
353
401
  outcome: AuditOutcome.Denied,
354
402
  tenantId: impersonatorSubject.tenantId,
355
403
  actor: impersonatorSubject.id,
356
- actorType: ActorType.User,
404
+ actorType: ActorType.Subject,
357
405
  targetId: subjectId,
358
406
  targetType: 'User',
359
407
  details: { impersonatedSubjectId: subjectId },
@@ -365,9 +413,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
365
413
  await authAuditor.info('impersonate-success', {
366
414
  tenantId: subject.tenantId,
367
415
  actor: validatedImpersonatorToken.payload.subject,
368
- actorType: ActorType.User,
416
+ actorType: ActorType.Subject,
369
417
  impersonator: validatedImpersonatorToken.payload.subject,
370
- impersonatorType: ActorType.User,
418
+ impersonatorType: ActorType.Subject,
371
419
  targetId: tokenResult.jsonToken.payload.subject,
372
420
  targetType: 'User',
373
421
  details: { impersonatedSubjectId: subjectId },
@@ -391,9 +439,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
391
439
  await authAuditor.info('unimpersonate-success', {
392
440
  tenantId: tokenResult.jsonToken.payload.tenant,
393
441
  actor: tokenResult.jsonToken.payload.subject,
394
- actorType: ActorType.User,
442
+ actorType: ActorType.Subject,
395
443
  targetId: tokenResult.jsonToken.payload.subject,
396
- impersonatorType: ActorType.User,
444
+ impersonatorType: ActorType.Subject,
397
445
  impersonator: tokenResult.jsonToken.payload.impersonator,
398
446
  targetType: 'User',
399
447
  });
@@ -447,10 +495,11 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
447
495
  if (!authenticationResult.success) {
448
496
  const resolvedSubject = await this.tryResolveSubject(subjectInput);
449
497
  await authAuditor.warn('change-secret-failure', {
498
+ actorType: ActorType.Anonymous,
450
499
  tenantId: resolvedSubject?.tenantId,
451
500
  targetId: resolvedSubject?.id ?? NIL_UUID,
452
501
  targetType: 'User',
453
- details: { subjectInput, subjectId: resolvedSubject?.id ?? null },
502
+ details: { subjectInput, resolvedSubjectId: resolvedSubject?.id ?? null },
454
503
  });
455
504
  throw new InvalidCredentialsError();
456
505
  }
@@ -459,6 +508,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
459
508
  await this.hooks.afterChangeSecret.trigger({ subject: authenticationResult.subject });
460
509
  await authAuditor.info('change-secret-success', {
461
510
  tenantId: authenticationResult.subject.tenantId,
511
+ actor: authenticationResult.subject.id,
512
+ actorType: ActorType.Subject,
462
513
  targetId: authenticationResult.subject.id,
463
514
  targetType: 'User',
464
515
  });
@@ -660,12 +711,10 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
660
711
  }
661
712
  async defaultResolveSubjects({ tenantId, subject }) {
662
713
  const [subjectsById, usersByMail] = await Promise.all([
663
- this.#subjectRepository.loadManyByQuery({ tenantId, id: subject }),
714
+ isUuid(subject) ? this.#subjectRepository.loadManyByQuery({ tenantId, id: subject }) : Promise.resolve([]),
664
715
  this.#userRepository.loadManyByQuery({ tenantId, email: subject }),
665
716
  ]);
666
- const userIds = getEntityIds(usersByMail);
667
- const subjectsByUser = (userIds.length == 0) ? [] : await this.#subjectRepository.loadManyByQuery({ tenantId, userId: { $in: userIds } });
668
- return [...subjectsById, ...subjectsByUser];
717
+ return [...subjectsById, ...usersByMail];
669
718
  }
670
719
  async defaultResolveSubject({ tenantId, subject }) {
671
720
  const subjects = await this.defaultResolveSubjects({ tenantId, subject });
@@ -1,5 +1,5 @@
1
+ CREATE TYPE "authentication"."subject_status" AS ENUM('active', 'inactive', 'suspended', 'pending-approval', 'invited');--> statement-breakpoint
1
2
  CREATE TYPE "authentication"."subject_type" AS ENUM('system', 'user', 'service-account');--> statement-breakpoint
2
- CREATE TYPE "authentication"."user_status" AS ENUM('active', 'suspended', 'pending-approval', 'invited');--> statement-breakpoint
3
3
  CREATE TABLE "authentication"."credentials" (
4
4
  "id" uuid DEFAULT gen_random_uuid() NOT NULL,
5
5
  "tenant_id" uuid NOT NULL,
@@ -36,69 +36,62 @@ CREATE TABLE "authentication"."session" (
36
36
  CREATE TABLE "authentication"."service_account" (
37
37
  "id" uuid DEFAULT gen_random_uuid() NOT NULL,
38
38
  "tenant_id" uuid NOT NULL,
39
+ "type" "authentication"."subject_type" NOT NULL,
40
+ "display_name" text NOT NULL,
39
41
  "description" text NOT NULL,
40
42
  "parent" uuid,
41
- "revision" integer NOT NULL,
42
- "revision_timestamp" timestamp with time zone NOT NULL,
43
- "create_timestamp" timestamp with time zone NOT NULL,
44
- "delete_timestamp" timestamp with time zone,
45
- "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
46
- CONSTRAINT "service_account_tenant_id_id_pk" PRIMARY KEY("tenant_id","id")
43
+ CONSTRAINT "service_account_tenant_id_id_pk" PRIMARY KEY("tenant_id","id"),
44
+ CONSTRAINT "service_account_tenant_id_type_id_unique" UNIQUE("tenant_id","type","id"),
45
+ CONSTRAINT "service_account_id_unique" UNIQUE("id"),
46
+ CONSTRAINT "service_account_type_check" CHECK ("authentication"."service_account"."type" = 'service-account')
47
47
  );
48
48
  --> statement-breakpoint
49
49
  CREATE TABLE "authentication"."subject" (
50
50
  "id" uuid DEFAULT gen_random_uuid() NOT NULL,
51
51
  "tenant_id" uuid NOT NULL,
52
52
  "type" "authentication"."subject_type" NOT NULL,
53
- "display_name" text NOT NULL,
54
- "system_account_id" uuid,
55
- "user_id" uuid,
56
- "service_account_id" uuid,
53
+ "status" "authentication"."subject_status" NOT NULL,
54
+ "last_activity_timestamp" timestamp with time zone,
57
55
  "revision" integer NOT NULL,
58
56
  "revision_timestamp" timestamp with time zone NOT NULL,
59
57
  "create_timestamp" timestamp with time zone NOT NULL,
60
58
  "delete_timestamp" timestamp with time zone,
61
59
  "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
62
60
  CONSTRAINT "subject_tenant_id_id_pk" PRIMARY KEY("tenant_id","id"),
63
- CONSTRAINT "subject_tenant_id_service_account_id_unique" UNIQUE("tenant_id","service_account_id"),
64
- CONSTRAINT "subject_tenant_id_user_id_unique" UNIQUE("tenant_id","user_id"),
65
- CONSTRAINT "subject_tenant_id_system_account_id_unique" UNIQUE("tenant_id","system_account_id"),
66
- CONSTRAINT "subject_id_unique" UNIQUE("id"),
67
- CONSTRAINT "authentication_subject_reference_check" CHECK (num_nonnulls("authentication"."subject"."system_account_id", "authentication"."subject"."user_id", "authentication"."subject"."service_account_id") = 1)
61
+ CONSTRAINT "subject_tenant_id_type_id_unique" UNIQUE("tenant_id","type","id"),
62
+ CONSTRAINT "subject_id_unique" UNIQUE("id")
68
63
  );
69
64
  --> statement-breakpoint
70
65
  CREATE TABLE "authentication"."system_account" (
71
66
  "id" uuid DEFAULT gen_random_uuid() NOT NULL,
72
67
  "tenant_id" uuid NOT NULL,
68
+ "type" "authentication"."subject_type" NOT NULL,
73
69
  "identifier" text NOT NULL,
74
- "revision" integer NOT NULL,
75
- "revision_timestamp" timestamp with time zone NOT NULL,
76
- "create_timestamp" timestamp with time zone NOT NULL,
77
- "delete_timestamp" timestamp with time zone,
78
- "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
70
+ "display_name" text NOT NULL,
79
71
  CONSTRAINT "system_account_tenant_id_id_pk" PRIMARY KEY("tenant_id","id"),
80
- CONSTRAINT "system_account_identifier_unique" UNIQUE("identifier")
72
+ CONSTRAINT "system_account_tenant_id_type_id_unique" UNIQUE("tenant_id","type","id"),
73
+ CONSTRAINT "system_account_tenant_id_identifier_unique" UNIQUE("tenant_id","identifier"),
74
+ CONSTRAINT "system_account_id_unique" UNIQUE("id"),
75
+ CONSTRAINT "system_account_type_check" CHECK ("authentication"."system_account"."type" = 'system')
81
76
  );
82
77
  --> statement-breakpoint
83
78
  CREATE TABLE "authentication"."user" (
84
79
  "id" uuid DEFAULT gen_random_uuid() NOT NULL,
85
80
  "tenant_id" uuid NOT NULL,
86
- "status" "authentication"."user_status" NOT NULL,
81
+ "type" "authentication"."subject_type" NOT NULL,
87
82
  "email" text NOT NULL,
88
83
  "first_name" text NOT NULL,
89
84
  "last_name" text NOT NULL,
90
- "revision" integer NOT NULL,
91
- "revision_timestamp" timestamp with time zone NOT NULL,
92
- "create_timestamp" timestamp with time zone NOT NULL,
93
- "delete_timestamp" timestamp with time zone,
94
- "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
95
85
  CONSTRAINT "user_tenant_id_id_pk" PRIMARY KEY("tenant_id","id"),
96
- CONSTRAINT "user_tenant_id_email_unique" UNIQUE("tenant_id","email")
86
+ CONSTRAINT "user_tenant_id_type_id_unique" UNIQUE("tenant_id","type","id"),
87
+ CONSTRAINT "user_tenant_id_email_unique" UNIQUE("tenant_id","email"),
88
+ CONSTRAINT "user_id_unique" UNIQUE("id"),
89
+ CONSTRAINT "user_type_check" CHECK ("authentication"."user"."type" = 'user')
97
90
  );
98
91
  --> statement-breakpoint
99
92
  ALTER TABLE "authentication"."credentials" ADD CONSTRAINT "credentials_id_subject_fkey" FOREIGN KEY ("tenant_id","subject_id") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
100
93
  ALTER TABLE "authentication"."session" ADD CONSTRAINT "session_id_subject_fkey" FOREIGN KEY ("tenant_id","subject_id") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
94
+ ALTER TABLE "authentication"."service_account" ADD CONSTRAINT "service_account_tenantId_type_id_subject_fkey" FOREIGN KEY ("tenant_id","type","id") REFERENCES "authentication"."subject"("tenant_id","type","id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
101
95
  ALTER TABLE "authentication"."service_account" ADD CONSTRAINT "service_account_id_subject_fkey" FOREIGN KEY ("tenant_id","parent") REFERENCES "authentication"."subject"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
102
- ALTER TABLE "authentication"."subject" ADD CONSTRAINT "subject_id_system_account_fkey" FOREIGN KEY ("tenant_id","system_account_id") REFERENCES "authentication"."system_account"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
103
- ALTER TABLE "authentication"."subject" ADD CONSTRAINT "subject_id_user_fkey" FOREIGN KEY ("tenant_id","user_id") REFERENCES "authentication"."user"("tenant_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
104
- ALTER TABLE "authentication"."subject" ADD CONSTRAINT "subject_id_service_account_fkey" FOREIGN KEY ("tenant_id","service_account_id") REFERENCES "authentication"."service_account"("tenant_id","id") ON DELETE no action ON UPDATE no action;
96
+ ALTER TABLE "authentication"."system_account" ADD CONSTRAINT "system_account_tenantId_type_id_subject_fkey" FOREIGN KEY ("tenant_id","type","id") REFERENCES "authentication"."subject"("tenant_id","type","id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
97
+ ALTER TABLE "authentication"."user" ADD CONSTRAINT "user_tenantId_type_id_subject_fkey" FOREIGN KEY ("tenant_id","type","id") REFERENCES "authentication"."subject"("tenant_id","type","id") ON DELETE cascade ON UPDATE no action;