@heavybit/shared-lib 2.1.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/README.md +163 -2
  2. package/dist/cjs/access/index.js +9 -1
  3. package/dist/cjs/access/index.js.map +1 -1
  4. package/dist/cjs/approvals/index.js +137 -0
  5. package/dist/cjs/approvals/index.js.map +1 -0
  6. package/dist/cjs/audit/index.js +74 -0
  7. package/dist/cjs/audit/index.js.map +1 -0
  8. package/dist/cjs/cache/index.js +90 -16
  9. package/dist/cjs/cache/index.js.map +1 -1
  10. package/dist/cjs/cache/keyspace.js +101 -0
  11. package/dist/cjs/cache/keyspace.js.map +1 -0
  12. package/dist/cjs/common/circuit-breaker.js +74 -0
  13. package/dist/cjs/common/circuit-breaker.js.map +1 -0
  14. package/dist/cjs/common/index.js +4 -0
  15. package/dist/cjs/common/index.js.map +1 -1
  16. package/dist/cjs/common/internal-client.js +177 -0
  17. package/dist/cjs/common/internal-client.js.map +1 -0
  18. package/dist/cjs/common/internal-constants.js +12 -0
  19. package/dist/cjs/common/internal-constants.js.map +1 -0
  20. package/dist/cjs/common/internal-service-auth.js +160 -0
  21. package/dist/cjs/common/internal-service-auth.js.map +1 -0
  22. package/dist/cjs/common/money.js +215 -0
  23. package/dist/cjs/common/money.js.map +1 -0
  24. package/dist/cjs/common/phone.js +41 -22
  25. package/dist/cjs/common/phone.js.map +1 -1
  26. package/dist/cjs/common/time.js +28 -2
  27. package/dist/cjs/common/time.js.map +1 -1
  28. package/dist/cjs/config/index.js +139 -19
  29. package/dist/cjs/config/index.js.map +1 -1
  30. package/dist/cjs/contracts/notification-dispatch.js +1 -1
  31. package/dist/cjs/database/db.js +37 -0
  32. package/dist/cjs/database/db.js.map +1 -0
  33. package/dist/cjs/database/index.js +22 -51
  34. package/dist/cjs/database/index.js.map +1 -1
  35. package/dist/cjs/database/pagination.js +88 -0
  36. package/dist/cjs/database/pagination.js.map +1 -0
  37. package/dist/cjs/database/pool.js +60 -0
  38. package/dist/cjs/database/pool.js.map +1 -0
  39. package/dist/cjs/database/scoped-repository.js +132 -0
  40. package/dist/cjs/database/scoped-repository.js.map +1 -0
  41. package/dist/cjs/database/scopes.js +166 -0
  42. package/dist/cjs/database/scopes.js.map +1 -0
  43. package/dist/cjs/database/table-names.js +14 -0
  44. package/dist/cjs/database/table-names.js.map +1 -0
  45. package/dist/cjs/database/tables.js +71 -0
  46. package/dist/cjs/database/tables.js.map +1 -0
  47. package/dist/cjs/express/auth.js +64 -50
  48. package/dist/cjs/express/auth.js.map +1 -1
  49. package/dist/cjs/express/index.js +2 -0
  50. package/dist/cjs/express/index.js.map +1 -1
  51. package/dist/cjs/express/internal-caller.js +52 -0
  52. package/dist/cjs/express/internal-caller.js.map +1 -0
  53. package/dist/cjs/express/step-up.js +41 -0
  54. package/dist/cjs/express/step-up.js.map +1 -0
  55. package/dist/cjs/http/index.js +3 -71
  56. package/dist/cjs/http/index.js.map +1 -1
  57. package/dist/cjs/identity/index.js +269 -67
  58. package/dist/cjs/identity/index.js.map +1 -1
  59. package/dist/cjs/identity/step-up.js +52 -0
  60. package/dist/cjs/identity/step-up.js.map +1 -0
  61. package/dist/cjs/index.js +6 -0
  62. package/dist/cjs/index.js.map +1 -1
  63. package/dist/cjs/knex/columns.js +36 -0
  64. package/dist/cjs/knex/columns.js.map +1 -0
  65. package/dist/cjs/knex/index.js +26 -43
  66. package/dist/cjs/knex/index.js.map +1 -1
  67. package/dist/cjs/knex/migration-helpers.js +57 -0
  68. package/dist/cjs/knex/migration-helpers.js.map +1 -0
  69. package/dist/cjs/logging/redact.js +6 -11
  70. package/dist/cjs/logging/redact.js.map +1 -1
  71. package/dist/cjs/messaging/base-consumer.js +36 -0
  72. package/dist/cjs/messaging/base-consumer.js.map +1 -0
  73. package/dist/cjs/messaging/consumer.js +142 -73
  74. package/dist/cjs/messaging/consumer.js.map +1 -1
  75. package/dist/cjs/messaging/envelope.js +53 -10
  76. package/dist/cjs/messaging/envelope.js.map +1 -1
  77. package/dist/cjs/messaging/idempotency.js +95 -8
  78. package/dist/cjs/messaging/idempotency.js.map +1 -1
  79. package/dist/cjs/messaging/index.js +2 -1
  80. package/dist/cjs/messaging/index.js.map +1 -1
  81. package/dist/cjs/messaging/outbox.js +97 -55
  82. package/dist/cjs/messaging/outbox.js.map +1 -1
  83. package/dist/cjs/messaging/publisher.js +86 -38
  84. package/dist/cjs/messaging/publisher.js.map +1 -1
  85. package/dist/cjs/messaging/staff-notifier.js +4 -4
  86. package/dist/cjs/messaging/staff-notifier.js.map +1 -1
  87. package/dist/cjs/messaging/topology.js +41 -5
  88. package/dist/cjs/messaging/topology.js.map +1 -1
  89. package/dist/cjs/rate-limit/index.js +57 -6
  90. package/dist/cjs/rate-limit/index.js.map +1 -1
  91. package/dist/cjs/rate-limit/keys.js +47 -0
  92. package/dist/cjs/rate-limit/keys.js.map +1 -0
  93. package/dist/cjs/socket/index.js +127 -16
  94. package/dist/cjs/socket/index.js.map +1 -1
  95. package/dist/cjs/socket/ticket.js +124 -0
  96. package/dist/cjs/socket/ticket.js.map +1 -0
  97. package/dist/cjs/testing/index.js +23 -14
  98. package/dist/cjs/testing/index.js.map +1 -1
  99. package/dist/esm/access/index.js +9 -1
  100. package/dist/esm/access/index.js.map +1 -1
  101. package/dist/esm/approvals/index.js +127 -0
  102. package/dist/esm/approvals/index.js.map +1 -0
  103. package/dist/esm/audit/index.js +70 -0
  104. package/dist/esm/audit/index.js.map +1 -0
  105. package/dist/esm/cache/index.js +70 -13
  106. package/dist/esm/cache/index.js.map +1 -1
  107. package/dist/esm/cache/keyspace.js +95 -0
  108. package/dist/esm/cache/keyspace.js.map +1 -0
  109. package/dist/esm/common/circuit-breaker.js +70 -0
  110. package/dist/esm/common/circuit-breaker.js.map +1 -0
  111. package/dist/esm/common/index.js +4 -0
  112. package/dist/esm/common/index.js.map +1 -1
  113. package/dist/esm/common/internal-client.js +173 -0
  114. package/dist/esm/common/internal-client.js.map +1 -0
  115. package/dist/esm/common/internal-constants.js +9 -0
  116. package/dist/esm/common/internal-constants.js.map +1 -0
  117. package/dist/esm/common/internal-service-auth.js +150 -0
  118. package/dist/esm/common/internal-service-auth.js.map +1 -0
  119. package/dist/esm/common/money.js +207 -0
  120. package/dist/esm/common/money.js.map +1 -0
  121. package/dist/esm/common/phone.js +41 -22
  122. package/dist/esm/common/phone.js.map +1 -1
  123. package/dist/esm/common/time.js +27 -2
  124. package/dist/esm/common/time.js.map +1 -1
  125. package/dist/esm/config/index.js +135 -18
  126. package/dist/esm/config/index.js.map +1 -1
  127. package/dist/esm/contracts/notification-dispatch.js +1 -1
  128. package/dist/esm/database/db.js +32 -0
  129. package/dist/esm/database/db.js.map +1 -0
  130. package/dist/esm/database/index.js +9 -45
  131. package/dist/esm/database/index.js.map +1 -1
  132. package/dist/esm/database/pagination.js +81 -0
  133. package/dist/esm/database/pagination.js.map +1 -0
  134. package/dist/esm/database/pool.js +51 -0
  135. package/dist/esm/database/pool.js.map +1 -0
  136. package/dist/esm/database/scoped-repository.js +128 -0
  137. package/dist/esm/database/scoped-repository.js.map +1 -0
  138. package/dist/esm/database/scopes.js +157 -0
  139. package/dist/esm/database/scopes.js.map +1 -0
  140. package/dist/esm/database/table-names.js +11 -0
  141. package/dist/esm/database/table-names.js.map +1 -0
  142. package/dist/esm/database/tables.js +61 -0
  143. package/dist/esm/database/tables.js.map +1 -0
  144. package/dist/esm/express/auth.js +62 -48
  145. package/dist/esm/express/auth.js.map +1 -1
  146. package/dist/esm/express/index.js +2 -0
  147. package/dist/esm/express/index.js.map +1 -1
  148. package/dist/esm/express/internal-caller.js +49 -0
  149. package/dist/esm/express/internal-caller.js.map +1 -0
  150. package/dist/esm/express/step-up.js +38 -0
  151. package/dist/esm/express/step-up.js.map +1 -0
  152. package/dist/esm/http/index.js +3 -70
  153. package/dist/esm/http/index.js.map +1 -1
  154. package/dist/esm/identity/index.js +246 -64
  155. package/dist/esm/identity/index.js.map +1 -1
  156. package/dist/esm/identity/step-up.js +47 -0
  157. package/dist/esm/identity/step-up.js.map +1 -0
  158. package/dist/esm/index.js +6 -0
  159. package/dist/esm/index.js.map +1 -1
  160. package/dist/esm/knex/columns.js +28 -0
  161. package/dist/esm/knex/columns.js.map +1 -0
  162. package/dist/esm/knex/index.js +8 -34
  163. package/dist/esm/knex/index.js.map +1 -1
  164. package/dist/esm/knex/migration-helpers.js +51 -0
  165. package/dist/esm/knex/migration-helpers.js.map +1 -0
  166. package/dist/esm/logging/redact.js +3 -7
  167. package/dist/esm/logging/redact.js.map +1 -1
  168. package/dist/esm/messaging/base-consumer.js +32 -0
  169. package/dist/esm/messaging/base-consumer.js.map +1 -0
  170. package/dist/esm/messaging/consumer.js +139 -71
  171. package/dist/esm/messaging/consumer.js.map +1 -1
  172. package/dist/esm/messaging/envelope.js +50 -10
  173. package/dist/esm/messaging/envelope.js.map +1 -1
  174. package/dist/esm/messaging/idempotency.js +91 -7
  175. package/dist/esm/messaging/idempotency.js.map +1 -1
  176. package/dist/esm/messaging/index.js +2 -1
  177. package/dist/esm/messaging/index.js.map +1 -1
  178. package/dist/esm/messaging/outbox.js +97 -54
  179. package/dist/esm/messaging/outbox.js.map +1 -1
  180. package/dist/esm/messaging/publisher.js +86 -38
  181. package/dist/esm/messaging/publisher.js.map +1 -1
  182. package/dist/esm/messaging/staff-notifier.js +4 -4
  183. package/dist/esm/messaging/staff-notifier.js.map +1 -1
  184. package/dist/esm/messaging/topology.js +39 -4
  185. package/dist/esm/messaging/topology.js.map +1 -1
  186. package/dist/esm/rate-limit/index.js +41 -6
  187. package/dist/esm/rate-limit/index.js.map +1 -1
  188. package/dist/esm/rate-limit/keys.js +43 -0
  189. package/dist/esm/rate-limit/keys.js.map +1 -0
  190. package/dist/esm/socket/index.js +112 -17
  191. package/dist/esm/socket/index.js.map +1 -1
  192. package/dist/esm/socket/ticket.js +117 -0
  193. package/dist/esm/socket/ticket.js.map +1 -0
  194. package/dist/esm/testing/index.js +24 -15
  195. package/dist/esm/testing/index.js.map +1 -1
  196. package/dist/types/access/index.d.ts +9 -3
  197. package/dist/types/access/index.d.ts.map +1 -1
  198. package/dist/types/approvals/index.d.ts +99 -0
  199. package/dist/types/approvals/index.d.ts.map +1 -0
  200. package/dist/types/audit/index.d.ts +82 -0
  201. package/dist/types/audit/index.d.ts.map +1 -0
  202. package/dist/types/cache/index.d.ts +64 -14
  203. package/dist/types/cache/index.d.ts.map +1 -1
  204. package/dist/types/cache/keyspace.d.ts +84 -0
  205. package/dist/types/cache/keyspace.d.ts.map +1 -0
  206. package/dist/types/common/circuit-breaker.d.ts +51 -0
  207. package/dist/types/common/circuit-breaker.d.ts.map +1 -0
  208. package/dist/types/common/index.d.ts +4 -0
  209. package/dist/types/common/index.d.ts.map +1 -1
  210. package/dist/types/common/internal-client.d.ts +116 -0
  211. package/dist/types/common/internal-client.d.ts.map +1 -0
  212. package/dist/types/common/internal-constants.d.ts +9 -0
  213. package/dist/types/common/internal-constants.d.ts.map +1 -0
  214. package/dist/types/common/internal-service-auth.d.ts +102 -0
  215. package/dist/types/common/internal-service-auth.d.ts.map +1 -0
  216. package/dist/types/common/money.d.ts +104 -0
  217. package/dist/types/common/money.d.ts.map +1 -0
  218. package/dist/types/common/phone.d.ts +25 -15
  219. package/dist/types/common/phone.d.ts.map +1 -1
  220. package/dist/types/common/time.d.ts +20 -2
  221. package/dist/types/common/time.d.ts.map +1 -1
  222. package/dist/types/config/index.d.ts +251 -27
  223. package/dist/types/config/index.d.ts.map +1 -1
  224. package/dist/types/contracts/notification-dispatch.d.ts +13 -13
  225. package/dist/types/database/db.d.ts +46 -0
  226. package/dist/types/database/db.d.ts.map +1 -0
  227. package/dist/types/database/index.d.ts +9 -22
  228. package/dist/types/database/index.d.ts.map +1 -1
  229. package/dist/types/database/pagination.d.ts +68 -0
  230. package/dist/types/database/pagination.d.ts.map +1 -0
  231. package/dist/types/database/pool.d.ts +39 -0
  232. package/dist/types/database/pool.d.ts.map +1 -0
  233. package/dist/types/database/scoped-repository.d.ts +92 -0
  234. package/dist/types/database/scoped-repository.d.ts.map +1 -0
  235. package/dist/types/database/scopes.d.ts +159 -0
  236. package/dist/types/database/scopes.d.ts.map +1 -0
  237. package/dist/types/database/table-names.d.ts +13 -0
  238. package/dist/types/database/table-names.d.ts.map +1 -0
  239. package/dist/types/database/tables.d.ts +748 -0
  240. package/dist/types/database/tables.d.ts.map +1 -0
  241. package/dist/types/express/auth.d.ts +40 -24
  242. package/dist/types/express/auth.d.ts.map +1 -1
  243. package/dist/types/express/index.d.ts +2 -0
  244. package/dist/types/express/index.d.ts.map +1 -1
  245. package/dist/types/express/internal-caller.d.ts +53 -0
  246. package/dist/types/express/internal-caller.d.ts.map +1 -0
  247. package/dist/types/express/step-up.d.ts +38 -0
  248. package/dist/types/express/step-up.d.ts.map +1 -0
  249. package/dist/types/http/index.d.ts +3 -31
  250. package/dist/types/http/index.d.ts.map +1 -1
  251. package/dist/types/identity/index.d.ts +159 -21
  252. package/dist/types/identity/index.d.ts.map +1 -1
  253. package/dist/types/identity/step-up.d.ts +41 -0
  254. package/dist/types/identity/step-up.d.ts.map +1 -0
  255. package/dist/types/index.d.ts +6 -0
  256. package/dist/types/index.d.ts.map +1 -1
  257. package/dist/types/knex/columns.d.ts +15 -0
  258. package/dist/types/knex/columns.d.ts.map +1 -0
  259. package/dist/types/knex/index.d.ts +3 -11
  260. package/dist/types/knex/index.d.ts.map +1 -1
  261. package/dist/types/knex/migration-helpers.d.ts +28 -0
  262. package/dist/types/knex/migration-helpers.d.ts.map +1 -0
  263. package/dist/types/logging/redact.d.ts +2 -2
  264. package/dist/types/logging/redact.d.ts.map +1 -1
  265. package/dist/types/messaging/base-consumer.d.ts +33 -0
  266. package/dist/types/messaging/base-consumer.d.ts.map +1 -0
  267. package/dist/types/messaging/consumer.d.ts +59 -21
  268. package/dist/types/messaging/consumer.d.ts.map +1 -1
  269. package/dist/types/messaging/envelope.d.ts +50 -11
  270. package/dist/types/messaging/envelope.d.ts.map +1 -1
  271. package/dist/types/messaging/idempotency.d.ts +60 -3
  272. package/dist/types/messaging/idempotency.d.ts.map +1 -1
  273. package/dist/types/messaging/index.d.ts +7 -0
  274. package/dist/types/messaging/index.d.ts.map +1 -1
  275. package/dist/types/messaging/outbox.d.ts +62 -22
  276. package/dist/types/messaging/outbox.d.ts.map +1 -1
  277. package/dist/types/messaging/publisher.d.ts +54 -21
  278. package/dist/types/messaging/publisher.d.ts.map +1 -1
  279. package/dist/types/messaging/staff-notifier.d.ts +9 -9
  280. package/dist/types/messaging/staff-notifier.d.ts.map +1 -1
  281. package/dist/types/messaging/staff-recipients.d.ts +1 -1
  282. package/dist/types/messaging/topology.d.ts +40 -8
  283. package/dist/types/messaging/topology.d.ts.map +1 -1
  284. package/dist/types/rate-limit/index.d.ts +40 -4
  285. package/dist/types/rate-limit/index.d.ts.map +1 -1
  286. package/dist/types/rate-limit/keys.d.ts +52 -0
  287. package/dist/types/rate-limit/keys.d.ts.map +1 -0
  288. package/dist/types/socket/index.d.ts +86 -2
  289. package/dist/types/socket/index.d.ts.map +1 -1
  290. package/dist/types/socket/ticket.d.ts +90 -0
  291. package/dist/types/socket/ticket.d.ts.map +1 -0
  292. package/dist/types/testing/index.d.ts +31 -10
  293. package/dist/types/testing/index.d.ts.map +1 -1
  294. package/dist/types/types/index.d.ts +26 -14
  295. package/dist/types/types/index.d.ts.map +1 -1
  296. package/package.json +3 -1
@@ -1,111 +1,293 @@
1
1
  import { hmacSha256, safeEqual } from '../common/crypto.js';
2
2
  /**
3
- * Header contract between the gateway and downstream services.
3
+ * Gateway identity protocol, version 2.
4
4
  *
5
- * The gateway strips any client-supplied identity headers, then writes these and signs them with
6
- * `x-gateway-auth` = HMAC-SHA256(secret, canonical string). Services verify the signature and
7
- * timestamp before trusting anything, so a request that bypasses the gateway on the internal
8
- * network cannot forge an identity.
5
+ * The gateway strips every client-supplied identity header, writes the headers below for the
6
+ * authenticated caller and signs them with `x-gateway-signature: v2=<hex>`. The signature is an
7
+ * HMAC-SHA256 over an app-chosen domain separator, the HTTP method, the canonical path (no query),
8
+ * the gateway timestamp and every identity header in a fixed order. A request that bypasses the
9
+ * gateway, is replayed later, or is replayed against another route cannot carry a forged identity.
10
+ *
11
+ * App-specific identity fields (for example a tenant id) travel in their own headers through an
12
+ * {@link IdentityProtocol} mapping, so this module never names an app concept.
9
13
  */
10
14
  export const IDENTITY_HEADERS = {
11
15
  USER_ID: 'x-user-id',
12
16
  USER_EMAIL: 'x-user-email',
13
17
  USER_ROLES: 'x-user-roles',
14
18
  USER_PERMISSIONS: 'x-user-permissions',
19
+ SUPER_ADMIN: 'x-is-superadmin',
20
+ OTP_VERIFIED: 'x-otp-verified',
21
+ STEP_UP_AT: 'x-step-up-at',
22
+ SESSION_ID: 'x-session-id',
15
23
  USER_SCOPES: 'x-user-scopes',
16
24
  USER_ATTRS: 'x-user-attrs',
17
- SESSION_ID: 'x-session-id',
18
25
  TIMESTAMP: 'x-gateway-ts',
19
- SIGNATURE: 'x-gateway-auth',
26
+ SIGNATURE: 'x-gateway-signature',
20
27
  };
28
+ /** Non-identity request headers shared by the gateway and services (correlation, client hints, internal auth). */
21
29
  export const CONTEXT_HEADERS = {
22
30
  CORRELATION_ID: 'x-correlation-id',
23
31
  ANON_ID: 'x-anon-id',
24
32
  TIMEZONE: 'x-timezone',
25
33
  CLIENT_IP: 'x-client-ip',
26
34
  INTERNAL_SECRET: 'x-internal-service-secret',
27
- CALLER_SERVICE: 'x-caller-service',
35
+ INTERNAL_SERVICE_NAME: 'x-internal-service-name',
36
+ IDEMPOTENCY_KEY: 'idempotency-key',
28
37
  };
29
- /** Every header a client must never be allowed to set. */
30
- export const PROTECTED_HEADERS = [...Object.values(IDENTITY_HEADERS), CONTEXT_HEADERS.INTERNAL_SECRET, CONTEXT_HEADERS.CLIENT_IP];
31
- const DEFAULT_MAX_SKEW_MS = 5 * 60_000;
38
+ /** Signature version prefix: `x-gateway-signature: v2=<hex>`. */
39
+ export const GATEWAY_SIGNATURE_VERSION = 'v2';
40
+ /** Default maximum age of a gateway timestamp (replay window). */
41
+ export const DEFAULT_IDENTITY_MAX_AGE_MS = 30_000;
42
+ /** Default allowance for a gateway clock that runs ahead of the service clock. */
43
+ export const DEFAULT_IDENTITY_MAX_FUTURE_MS = 5_000;
44
+ /** Minimum length of the shared gateway signing secret. */
45
+ export const MIN_GATEWAY_SECRET_LENGTH = 32;
46
+ const BASE_HEAD = [IDENTITY_HEADERS.USER_ID, IDENTITY_HEADERS.USER_EMAIL];
47
+ const BASE_TAIL = [
48
+ IDENTITY_HEADERS.USER_ROLES,
49
+ IDENTITY_HEADERS.USER_PERMISSIONS,
50
+ IDENTITY_HEADERS.SUPER_ADMIN,
51
+ IDENTITY_HEADERS.OTP_VERIFIED,
52
+ IDENTITY_HEADERS.STEP_UP_AT,
53
+ IDENTITY_HEADERS.SESSION_ID,
54
+ IDENTITY_HEADERS.USER_SCOPES,
55
+ IDENTITY_HEADERS.USER_ATTRS,
56
+ ];
57
+ const HEADER_NAME = /^x-[a-z0-9-]+$/;
58
+ const RESERVED_HEADERS = new Set([...Object.values(IDENTITY_HEADERS), ...Object.values(CONTEXT_HEADERS)]);
59
+ /**
60
+ * Validates and freezes an app's identity protocol. Throws at startup on a bad binding so a
61
+ * misconfiguration can never weaken verification at runtime.
62
+ *
63
+ * @param input Domain separator and optional scope/attr header mappings.
64
+ * @returns The frozen protocol, including the signing order.
65
+ * @example const protocol = defineIdentityProtocol({ domain: 'shop-gateway-identity:v2', scopeHeaders: { tenant: 'x-tenant-id' } });
66
+ */
67
+ export function defineIdentityProtocol(input) {
68
+ if (!input.domain?.trim())
69
+ throw new Error('defineIdentityProtocol: domain separator is required');
70
+ const scopeHeaders = { ...(input.scopeHeaders ?? {}) };
71
+ const attrHeaders = { ...(input.attrHeaders ?? {}) };
72
+ const mapped = [...Object.values(scopeHeaders), ...Object.values(attrHeaders)];
73
+ const seen = new Set();
74
+ for (const name of mapped) {
75
+ if (!HEADER_NAME.test(name))
76
+ throw new Error(`defineIdentityProtocol: "${name}" must be a lower-case x- header`);
77
+ if (RESERVED_HEADERS.has(name) || seen.has(name))
78
+ throw new Error(`defineIdentityProtocol: header "${name}" is reserved or duplicated`);
79
+ seen.add(name);
80
+ }
81
+ return Object.freeze({
82
+ domain: input.domain,
83
+ scopeHeaders: Object.freeze(scopeHeaders),
84
+ attrHeaders: Object.freeze(attrHeaders),
85
+ headerOrder: Object.freeze([...BASE_HEAD, ...mapped, ...BASE_TAIL]),
86
+ });
87
+ }
88
+ /**
89
+ * Every header a client must never be allowed to set, for a given protocol: identity headers, the gateway
90
+ * timestamp and signature, both internal-service headers and the client IP.
91
+ *
92
+ * @param protocol The app's identity protocol.
93
+ * @returns Lower-case header names.
94
+ * @example const blocked = new Set(protectedHeaders(protocol));
95
+ */
96
+ export function protectedHeaders(protocol) {
97
+ return [...protocol.headerOrder, IDENTITY_HEADERS.TIMESTAMP, IDENTITY_HEADERS.SIGNATURE, CONTEXT_HEADERS.INTERNAL_SECRET, CONTEXT_HEADERS.INTERNAL_SERVICE_NAME, CONTEXT_HEADERS.CLIENT_IP];
98
+ }
99
+ /**
100
+ * Removes every protected header in place (gateway ingress), so clients can't forge identity or internal auth.
101
+ *
102
+ * @param headers Incoming request headers (mutated).
103
+ * @param protocol The app's identity protocol.
104
+ * @example stripProtectedHeaders(req.headers, protocol);
105
+ */
106
+ export function stripProtectedHeaders(headers, protocol) {
107
+ for (const name of protectedHeaders(protocol))
108
+ delete headers[name];
109
+ }
32
110
  function header(headers, name) {
33
111
  const value = headers[name];
34
112
  return Array.isArray(value) ? value[0] : value;
35
113
  }
36
- function canonical(values) {
37
- return [
38
- values[IDENTITY_HEADERS.TIMESTAMP],
39
- values[IDENTITY_HEADERS.USER_ID],
40
- values[IDENTITY_HEADERS.USER_EMAIL],
41
- values[IDENTITY_HEADERS.USER_ROLES],
42
- values[IDENTITY_HEADERS.USER_PERMISSIONS],
43
- values[IDENTITY_HEADERS.USER_SCOPES],
44
- values[IDENTITY_HEADERS.USER_ATTRS],
45
- values[IDENTITY_HEADERS.SESSION_ID],
46
- ].join('\n');
114
+ /**
115
+ * Canonical request path for signing: the path only (query and fragment dropped), always starting with `/`.
116
+ *
117
+ * @param path A path or path-plus-query such as `req.originalUrl`.
118
+ * @returns The path to sign or verify.
119
+ * @example canonicalPath('/v1/items?page=2') // '/v1/items'
120
+ */
121
+ export function canonicalPath(path) {
122
+ const bare = path.split(/[?#]/, 1)[0] ?? '';
123
+ return bare.startsWith('/') ? bare : `/${bare}`;
47
124
  }
48
- const encodeList = (items) => items.join(',');
125
+ const encodeList = (items = []) => items.join(',');
49
126
  const decodeList = (value) => (value ? value.split(',').map((s) => s.trim()).filter(Boolean) : []);
50
- const encodeJson = (value) => Buffer.from(JSON.stringify(value ?? {})).toString('base64url');
51
- function decodeJson(value, fallback) {
127
+ const encodeJson = (value) => (Object.keys(value).length ? Buffer.from(JSON.stringify(value)).toString('base64url') : '');
128
+ const omitKeys = (record, keys) => Object.fromEntries(Object.entries(record).filter(([k]) => !keys.includes(k)));
129
+ function decodeJson(value) {
52
130
  if (!value)
53
- return fallback;
131
+ return {};
54
132
  try {
55
- return JSON.parse(Buffer.from(value, 'base64url').toString('utf8'));
133
+ const parsed = JSON.parse(Buffer.from(value, 'base64url').toString('utf8'));
134
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : undefined;
56
135
  }
57
136
  catch {
58
- return fallback;
137
+ return undefined;
59
138
  }
60
139
  }
61
- /** Gateway side: headers (including signature) that represent `user`. */
62
- export function signIdentityHeaders(user, secret, now = Date.now()) {
140
+ /**
141
+ * Gateway side: the identity header values (unsigned) that represent `user` under `protocol`.
142
+ * Mapped scopes and string attrs travel in their own headers; the rest go in the JSON headers.
143
+ *
144
+ * @param user The authenticated caller.
145
+ * @param protocol The app's identity protocol.
146
+ * @returns Header name → value for every header in `protocol.headerOrder`.
147
+ * @example const identity = buildIdentityHeaders(user, protocol);
148
+ */
149
+ export function buildIdentityHeaders(user, protocol) {
150
+ const scopeKeys = Object.keys(protocol.scopeHeaders);
151
+ const attrKeys = Object.keys(protocol.attrHeaders);
63
152
  const values = {
64
- [IDENTITY_HEADERS.TIMESTAMP]: String(now),
65
153
  [IDENTITY_HEADERS.USER_ID]: user.id,
66
154
  [IDENTITY_HEADERS.USER_EMAIL]: user.email ?? '',
67
155
  [IDENTITY_HEADERS.USER_ROLES]: encodeList(user.roles),
68
156
  [IDENTITY_HEADERS.USER_PERMISSIONS]: encodeList(user.permissions),
69
- [IDENTITY_HEADERS.USER_SCOPES]: encodeJson(user.scopes),
70
- [IDENTITY_HEADERS.USER_ATTRS]: encodeJson(user.attrs),
157
+ [IDENTITY_HEADERS.SUPER_ADMIN]: user.isSuperAdmin ? 'true' : 'false',
158
+ [IDENTITY_HEADERS.OTP_VERIFIED]: user.otpVerified ? 'true' : 'false',
159
+ [IDENTITY_HEADERS.STEP_UP_AT]: user.stepUpAt !== undefined ? String(Math.trunc(user.stepUpAt)) : '',
71
160
  [IDENTITY_HEADERS.SESSION_ID]: user.sessionId ?? '',
161
+ [IDENTITY_HEADERS.USER_SCOPES]: encodeJson(omitKeys(user.scopes ?? {}, scopeKeys)),
162
+ [IDENTITY_HEADERS.USER_ATTRS]: encodeJson(omitKeys(user.attrs ?? {}, attrKeys)),
72
163
  };
73
- values[IDENTITY_HEADERS.SIGNATURE] = hmacSha256(secret, canonical(values));
164
+ for (const [key, name] of Object.entries(protocol.scopeHeaders))
165
+ values[name] = encodeList(user.scopes?.[key]);
166
+ for (const [key, name] of Object.entries(protocol.attrHeaders)) {
167
+ const attr = user.attrs?.[key];
168
+ values[name] = typeof attr === 'string' ? attr : '';
169
+ }
74
170
  return values;
75
171
  }
76
- /** Service side: verifies and decodes the gateway identity headers. */
77
- export function verifyIdentityHeaders(headers, secret, options = {}) {
78
- const userId = header(headers, IDENTITY_HEADERS.USER_ID);
79
- if (!userId)
80
- return { status: 'anonymous' };
81
- const values = {};
82
- for (const name of Object.values(IDENTITY_HEADERS))
83
- values[name] = header(headers, name) ?? '';
84
- const signature = values[IDENTITY_HEADERS.SIGNATURE];
85
- if (!signature || !safeEqual(signature, hmacSha256(secret, canonical(values)))) {
86
- return { status: 'invalid', reason: 'bad-signature' };
172
+ function canonicalString(input) {
173
+ const fields = [
174
+ input.protocol.domain,
175
+ input.method.toUpperCase(),
176
+ canonicalPath(input.path),
177
+ String(input.ts),
178
+ ...input.protocol.headerOrder.map((name) => input.identity[name] ?? ''),
179
+ ];
180
+ // JSON array encoding keeps field boundaries unambiguous whatever the values contain.
181
+ return JSON.stringify(fields);
182
+ }
183
+ /**
184
+ * Signs an identity for one request.
185
+ *
186
+ * @param input Method, path, identity headers, timestamp, secret and protocol.
187
+ * @returns The `x-gateway-signature` value, `v2=<hex>`.
188
+ * @example headers['x-gateway-signature'] = signGatewayIdentity({ method, path, identity, ts, secret, protocol });
189
+ */
190
+ export function signGatewayIdentity(input) {
191
+ return `${GATEWAY_SIGNATURE_VERSION}=${hmacSha256(input.secret, canonicalString(input))}`;
192
+ }
193
+ /**
194
+ * Gateway side convenience: every identity header plus `x-gateway-ts` and `x-gateway-signature`. Also used by a
195
+ * service acting for a user to re-sign the identity for one internal call (signatures bind method and path).
196
+ *
197
+ * @param input User, method, path, secret, protocol and optional time.
198
+ * @returns Headers to add to the outgoing request.
199
+ *
200
+ * @example Object.assign(proxyHeaders, signedIdentityHeaders({ user, method: req.method, path: upstreamPath, secret, protocol }));
201
+ */
202
+ export function signedIdentityHeaders(input) {
203
+ const ts = input.now ?? Date.now();
204
+ const identity = buildIdentityHeaders(input.user, input.protocol);
205
+ const signature = signGatewayIdentity({ method: input.method, path: input.path, identity, ts, secret: input.secret, protocol: input.protocol });
206
+ return { ...identity, [IDENTITY_HEADERS.TIMESTAMP]: String(ts), [IDENTITY_HEADERS.SIGNATURE]: signature };
207
+ }
208
+ function checkTimestamp(raw, now, maxAgeMs, maxFutureMs) {
209
+ if (!raw || !/^\d+$/.test(raw))
210
+ return 'bad-timestamp';
211
+ const ts = Number(raw);
212
+ if (now - ts > maxAgeMs)
213
+ return 'stale';
214
+ if (ts - now > maxFutureMs)
215
+ return 'future';
216
+ return null;
217
+ }
218
+ function decodeUser(values, protocol) {
219
+ const scopes = decodeJson(values[IDENTITY_HEADERS.USER_SCOPES]);
220
+ const attrs = decodeJson(values[IDENTITY_HEADERS.USER_ATTRS]);
221
+ const stepUpRaw = values[IDENTITY_HEADERS.STEP_UP_AT];
222
+ if (!scopes || !attrs || (stepUpRaw && !/^\d+$/.test(stepUpRaw)))
223
+ return null;
224
+ for (const [key, name] of Object.entries(protocol.scopeHeaders)) {
225
+ const ids = decodeList(values[name]);
226
+ if (ids.length)
227
+ scopes[key] = ids;
87
228
  }
88
- const ts = Number(values[IDENTITY_HEADERS.TIMESTAMP]);
89
- const now = options.now ?? Date.now();
90
- if (!Number.isFinite(ts) || Math.abs(now - ts) > (options.maxSkewMs ?? DEFAULT_MAX_SKEW_MS)) {
91
- return { status: 'invalid', reason: 'stale-signature' };
229
+ for (const [key, name] of Object.entries(protocol.attrHeaders)) {
230
+ if (values[name])
231
+ attrs[key] = values[name];
92
232
  }
93
- return {
94
- status: 'authenticated',
95
- user: {
96
- id: userId,
97
- email: values[IDENTITY_HEADERS.USER_EMAIL] ?? '',
98
- roles: decodeList(values[IDENTITY_HEADERS.USER_ROLES]),
99
- permissions: decodeList(values[IDENTITY_HEADERS.USER_PERMISSIONS]),
100
- scopes: decodeJson(values[IDENTITY_HEADERS.USER_SCOPES], {}),
101
- attrs: decodeJson(values[IDENTITY_HEADERS.USER_ATTRS], {}),
102
- sessionId: values[IDENTITY_HEADERS.SESSION_ID] || undefined,
103
- },
233
+ const user = {
234
+ id: values[IDENTITY_HEADERS.USER_ID] ?? '',
235
+ email: values[IDENTITY_HEADERS.USER_EMAIL] ?? '',
236
+ roles: decodeList(values[IDENTITY_HEADERS.USER_ROLES]),
237
+ permissions: decodeList(values[IDENTITY_HEADERS.USER_PERMISSIONS]),
238
+ scopes,
239
+ attrs,
240
+ isSuperAdmin: values[IDENTITY_HEADERS.SUPER_ADMIN] === 'true',
241
+ otpVerified: values[IDENTITY_HEADERS.OTP_VERIFIED] === 'true',
104
242
  };
243
+ if (values[IDENTITY_HEADERS.SESSION_ID])
244
+ user.sessionId = values[IDENTITY_HEADERS.SESSION_ID];
245
+ if (stepUpRaw)
246
+ user.stepUpAt = Number(stepUpRaw);
247
+ return user;
105
248
  }
106
- /** Removes every protected header in place (gateway ingress). */
107
- export function stripProtectedHeaders(headers) {
108
- for (const name of PROTECTED_HEADERS)
109
- delete headers[name];
249
+ /**
250
+ * Service side: verifies and decodes the gateway identity. No `x-user-id` → anonymous. Otherwise the
251
+ * request is rejected unless the signature is present, version `v2`, made for this method, path and
252
+ * protocol, and the timestamp is at most `maxAgeMs` old (default 30 s) and at most `maxFutureMs` ahead
253
+ * (default 5 s). The comparison is constant-time.
254
+ *
255
+ * @example const result = verifyGatewayIdentity({ headers: req.headers, method: req.method, path: req.originalUrl, secret, protocol });
256
+ */
257
+ export function verifyGatewayIdentity(input) {
258
+ const { headers, protocol } = input;
259
+ if (!header(headers, IDENTITY_HEADERS.USER_ID))
260
+ return { status: 'anonymous' };
261
+ const signature = header(headers, IDENTITY_HEADERS.SIGNATURE);
262
+ if (!signature)
263
+ return { status: 'invalid', reason: 'missing-signature' };
264
+ if (!signature.startsWith(`${GATEWAY_SIGNATURE_VERSION}=`))
265
+ return { status: 'invalid', reason: 'bad-version' };
266
+ const rawTs = header(headers, IDENTITY_HEADERS.TIMESTAMP);
267
+ const now = input.now ?? Date.now();
268
+ const tsProblem = checkTimestamp(rawTs, now, input.maxAgeMs ?? DEFAULT_IDENTITY_MAX_AGE_MS, input.maxFutureMs ?? DEFAULT_IDENTITY_MAX_FUTURE_MS);
269
+ if (tsProblem)
270
+ return { status: 'invalid', reason: tsProblem };
271
+ const identity = {};
272
+ for (const name of protocol.headerOrder)
273
+ identity[name] = header(headers, name) ?? '';
274
+ const expected = signGatewayIdentity({ method: input.method, path: input.path, identity, ts: Number(rawTs), secret: input.secret, protocol });
275
+ if (!safeEqual(signature, expected))
276
+ return { status: 'invalid', reason: 'bad-signature' };
277
+ const user = decodeUser(identity, protocol);
278
+ return user ? { status: 'authenticated', user } : { status: 'invalid', reason: 'bad-payload' };
279
+ }
280
+ /**
281
+ * Throws unless `secret` is long enough to sign identities. Call at startup.
282
+ *
283
+ * @param secret The shared gateway signing secret (env `GATEWAY_SIGNING_SECRET`).
284
+ * @returns The secret, unchanged.
285
+ */
286
+ export function assertGatewaySecret(secret) {
287
+ if (!secret || secret.length < MIN_GATEWAY_SECRET_LENGTH) {
288
+ throw new Error(`Gateway signing secret must be at least ${MIN_GATEWAY_SECRET_LENGTH} characters`);
289
+ }
290
+ return secret;
110
291
  }
292
+ export * from './step-up.js';
111
293
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Step-up (re-authentication) scopes. The gateway checks the client's step-up proof for the route's
3
+ * scope and forwards the verified time as the signed `x-step-up-at` header; services only check that
4
+ * the time is fresh. Scope names and their rules are app values, declared once with
5
+ * {@link defineStepUpScopes}.
6
+ */
7
+ /** Default freshness window for a step-up verification. */
8
+ export const DEFAULT_STEP_UP_WINDOW_MS = 5 * 60_000;
9
+ /** A step-up time this far ahead of the service clock is still accepted (clock skew). */
10
+ export const STEP_UP_MAX_FUTURE_MS = 5_000;
11
+ /** Error code of the 403 a service returns when a fresh step-up is required. */
12
+ export const STEP_UP_REQUIRED_CODE = 'STEP_UP_REQUIRED';
13
+ const SCOPE_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
14
+ /**
15
+ * Validates and freezes an app's step-up scope catalogue (kebab-case names). Throws at startup on a bad name.
16
+ *
17
+ * @param catalogue Scope name → rules.
18
+ * @returns The frozen catalogue; its keys type `requireStepUp`'s scope argument.
19
+ * @example export const stepUpScopes = defineStepUpScopes({ 'refund-large': {}, 'payout-destination': { singleUse: true } });
20
+ */
21
+ export function defineStepUpScopes(catalogue) {
22
+ const entries = Object.entries(catalogue);
23
+ if (!entries.length)
24
+ throw new Error('defineStepUpScopes: catalogue is empty');
25
+ for (const [name] of entries) {
26
+ if (!SCOPE_NAME.test(name))
27
+ throw new Error(`defineStepUpScopes: "${name}" must be kebab-case`);
28
+ }
29
+ return Object.freeze(Object.fromEntries(entries.map(([name, rules]) => [name, Object.freeze({ ...rules })])));
30
+ }
31
+ /**
32
+ * Whether a gateway-verified step-up time is usable now.
33
+ *
34
+ * @param stepUpAt Epoch milliseconds of the step-up, or undefined when none was made.
35
+ * @param windowMs How old the step-up may be.
36
+ * @param now Current epoch milliseconds.
37
+ * @returns `fresh` when usable; otherwise why not.
38
+ * @example stepUpStatus(req.user?.stepUpAt, DEFAULT_STEP_UP_WINDOW_MS) === 'fresh'
39
+ */
40
+ export function stepUpStatus(stepUpAt, windowMs, now = Date.now()) {
41
+ if (stepUpAt === undefined || !Number.isFinite(stepUpAt))
42
+ return 'missing';
43
+ if (stepUpAt - now > STEP_UP_MAX_FUTURE_MS)
44
+ return 'future';
45
+ return now - stepUpAt > windowMs ? 'stale' : 'fresh';
46
+ }
47
+ //# sourceMappingURL=step-up.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-up.js","sourceRoot":"","sources":["../../../src/identity/step-up.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,MAAM,CAAC;AACpD,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,gFAAgF;AAChF,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,MAAM,UAAU,GAAG,iCAAiC,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAmB,SAA2C;IAC9F,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAsC,CAAC;IAC/E,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC/E,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,sBAAsB,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAuB,CAAC;AACtI,CAAC;AAID;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,QAAgB,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;IACnG,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3E,IAAI,QAAQ,GAAG,GAAG,GAAG,qBAAqB;QAAE,OAAO,QAAQ,CAAC;IAC5D,OAAO,GAAG,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACvD,CAAC"}
package/dist/esm/index.js CHANGED
@@ -9,6 +9,12 @@ export * from './access/index.js';
9
9
  export * from './validation/index.js';
10
10
  export * from './logging/index.js';
11
11
  export * from './config/index.js';
12
+ export * from './cache/keyspace.js';
13
+ export * from './rate-limit/keys.js';
12
14
  export * from './contracts/index.js';
13
15
  export * from './alerting/index.js';
16
+ export * from './database/pagination.js';
17
+ export * from './audit/index.js';
18
+ export * from './approvals/index.js';
19
+ export * from './socket/ticket.js';
14
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8FAA8F;AAC9F,kFAAkF;AAClF,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8FAA8F;AAC9F,kFAAkF;AAClF,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** Column primitives shared by every migration helper (one definition of ULID and DATETIME(3) columns). */
2
+ /** `id CHAR(26)` primary key for ULIDs. */
3
+ export function ulidPrimary(table, name = 'id') {
4
+ table.specificType(name, 'char(26)').notNullable().primary();
5
+ }
6
+ /** `CHAR(26)` column referencing another ULID (FK constraints only within the same database). */
7
+ export function ulidColumn(table, name) {
8
+ return table.specificType(name, 'char(26)');
9
+ }
10
+ /** `created_at` / `updated_at` as `DATETIME(3)` in UTC, maintained by MySQL. */
11
+ export function timestamps(table, knex) {
12
+ createdAtColumn(table, knex);
13
+ datetime(table, 'updated_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)'));
14
+ }
15
+ /** `created_by` / `updated_by` actor columns (null for system operations). */
16
+ export function actorColumns(table) {
17
+ ulidColumn(table, 'created_by').nullable();
18
+ ulidColumn(table, 'updated_by').nullable();
19
+ }
20
+ /** Nullable `DATETIME(3)` column. */
21
+ export function datetime(table, name) {
22
+ return table.specificType(name, 'datetime(3)');
23
+ }
24
+ /** `DATETIME(3)` column defaulting to `CURRENT_TIMESTAMP(3)` (insert time, UTC). */
25
+ export function createdAtColumn(table, knex, name = 'created_at') {
26
+ return datetime(table, name).notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3)'));
27
+ }
28
+ //# sourceMappingURL=columns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../../src/knex/columns.ts"],"names":[],"mappings":"AAEA,2GAA2G;AAE3G,2CAA2C;AAC3C,MAAM,UAAU,WAAW,CAAC,KAA8B,EAAE,IAAI,GAAG,IAAI;IACrE,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;AAC/D,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,UAAU,CAAC,KAAuD,EAAE,IAAY;IAC9F,OAAO,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,KAA8B,EAAE,IAAU;IACnE,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;AACzH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,KAA8B;IACzD,UAAU,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3C,UAAU,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC7C,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,QAAQ,CAAC,KAAuD,EAAE,IAAY;IAC5F,OAAO,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,eAAe,CAAC,KAA8B,EAAE,IAAU,EAAE,IAAI,GAAG,YAAY;IAC7F,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;AACzF,CAAC"}
@@ -1,29 +1,12 @@
1
+ import { DEFAULT_OUTBOX_TABLE } from '../database/table-names.js';
2
+ import { actorColumns, timestamps, ulidColumn, ulidPrimary } from './columns.js';
3
+ import { outboxColumns } from './migration-helpers.js';
4
+ export * from './columns.js';
5
+ export * from './migration-helpers.js';
1
6
  /**
2
7
  * Migration helpers (usable from CommonJS `.cjs` migrations via `require('@heavybit/shared-lib/knex')`).
3
8
  * They keep ID, timestamp and audit column definitions identical across services.
4
9
  */
5
- /** `id CHAR(26)` primary key for ULIDs. */
6
- export function ulidPrimary(table, name = 'id') {
7
- table.specificType(name, 'char(26)').notNullable().primary();
8
- }
9
- /** `CHAR(26)` column referencing another ULID (FK constraints only within the same database). */
10
- export function ulidColumn(table, name) {
11
- return table.specificType(name, 'char(26)');
12
- }
13
- /** `created_at` / `updated_at` as `DATETIME(3)` in UTC, maintained by MySQL. */
14
- export function timestamps(table, knex) {
15
- table.specificType('created_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3)'));
16
- table.specificType('updated_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)'));
17
- }
18
- /** `created_by` / `updated_by` actor columns (null for system operations). */
19
- export function actorColumns(table) {
20
- ulidColumn(table, 'created_by').nullable();
21
- ulidColumn(table, 'updated_by').nullable();
22
- }
23
- /** Nullable `DATETIME(3)` column. */
24
- export function datetime(table, name) {
25
- return table.specificType(name, 'datetime(3)');
26
- }
27
10
  /**
28
11
  * Creates `<parent>_audits`: every parent column (defined again by `columns`) plus `parent_id`
29
12
  * and `action`. Audit rows are append-only history, so no unique constraints are copied.
@@ -42,20 +25,11 @@ export async function createAuditTable(knex, parentTable, columns) {
42
25
  table.index(['parent_id', 'created_at']);
43
26
  });
44
27
  }
45
- /** Transactional outbox table used by `OutboxRelay`. */
46
- export async function createOutboxTable(knex, name = 'event_outbox') {
28
+ /** Transactional outbox table used by `OutboxRelay` (columns from {@link outboxColumns}). */
29
+ export async function createOutboxTable(knex, name = DEFAULT_OUTBOX_TABLE) {
47
30
  if (await knex.schema.hasTable(name))
48
31
  return;
49
- await knex.schema.createTable(name, (table) => {
50
- ulidPrimary(table);
51
- table.string('routing_key', 191).notNullable();
52
- table.json('payload').notNullable();
53
- table.integer('attempts').unsigned().notNullable().defaultTo(0);
54
- table.string('last_error', 500).nullable();
55
- table.specificType('created_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3)'));
56
- datetime(table, 'published_at').nullable();
57
- table.index(['published_at', 'id']);
58
- });
32
+ await knex.schema.createTable(name, (table) => outboxColumns(table, knex));
59
33
  }
60
34
  /** Standard table options: InnoDB, utf8mb4. Call inside `createTable`. */
61
35
  export function utf8mb4(table) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/knex/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/knex/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAY,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AAEvC;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAU,EAAE,WAAmB,EAAE,OAAiD;IACvH,MAAM,IAAI,GAAG,GAAG,WAAW,SAAS,CAAC;IACrC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QAC5C,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;QACrD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxB,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAI,GAAG,oBAAoB;IAC7E,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,KAA8B;IACpD,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvB,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzB,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { OUTBOX_EXCHANGES, SCHEDULER_RUN_STATUSES } from '../database/table-names.js';
2
+ import { createdAtColumn, datetime, ulidPrimary } from './columns.js';
3
+ /**
4
+ * Outbox columns: id, routing_key, exchange, payload, correlation_id, attempts, last_error, created_at,
5
+ * published_at (+ relay index).
6
+ */
7
+ export function outboxColumns(t, knex) {
8
+ ulidPrimary(t);
9
+ t.string('routing_key', 191).notNullable();
10
+ t.enu('exchange', [...OUTBOX_EXCHANGES]).notNullable().defaultTo('events');
11
+ t.json('payload').notNullable();
12
+ t.string('correlation_id', 64).nullable();
13
+ t.integer('attempts').unsigned().notNullable().defaultTo(0);
14
+ t.string('last_error', 500).nullable();
15
+ createdAtColumn(t, knex, 'created_at');
16
+ datetime(t, 'published_at').nullable();
17
+ t.index(['published_at', 'id']);
18
+ }
19
+ /** Consumer idempotency columns: id, consumer, event_id (unique together), processed_at. */
20
+ export function processedEventsColumns(t, knex) {
21
+ ulidPrimary(t);
22
+ t.string('consumer', 191).notNullable();
23
+ t.string('event_id', 64).notNullable();
24
+ createdAtColumn(t, knex, 'processed_at');
25
+ t.unique(['consumer', 'event_id']);
26
+ t.index(['processed_at']);
27
+ }
28
+ /** Scheduler run columns: id, job, run_key (unique together), status, error, started_at, finished_at. */
29
+ export function schedulerRunsColumns(t, knex) {
30
+ ulidPrimary(t);
31
+ t.string('job', 191).notNullable();
32
+ t.string('run_key', 191).notNullable();
33
+ t.enu('status', [...SCHEDULER_RUN_STATUSES]).notNullable().defaultTo('running');
34
+ t.string('error', 500).nullable();
35
+ createdAtColumn(t, knex, 'started_at');
36
+ datetime(t, 'finished_at').nullable();
37
+ t.unique(['job', 'run_key']);
38
+ t.index(['job', 'started_at']);
39
+ }
40
+ /**
41
+ * Index that always leads with the scope column (TEN-4); `columns` follow in order, duplicates of
42
+ * the scope column are dropped.
43
+ *
44
+ * @example scopedIndex(t, 'workspace_id', ['status', 'created_at'])
45
+ */
46
+ export function scopedIndex(t, scopeColumn, columns = [], indexName) {
47
+ if (!scopeColumn)
48
+ throw new Error('scopedIndex needs a scope column');
49
+ t.index([scopeColumn, ...columns.filter((c) => c !== scopeColumn)], indexName);
50
+ }
51
+ //# sourceMappingURL=migration-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-helpers.js","sourceRoot":"","sources":["../../../src/knex/migration-helpers.ts"],"names":[],"mappings":"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"}