@portaidentity/server 1.7.3 → 1.8.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 (487) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/applications/index.d.ts +2 -2
  3. package/dist/applications/index.d.ts.map +1 -1
  4. package/dist/applications/index.js +2 -2
  5. package/dist/applications/index.js.map +1 -1
  6. package/dist/applications/repository.d.ts +49 -4
  7. package/dist/applications/repository.d.ts.map +1 -1
  8. package/dist/applications/repository.js +148 -10
  9. package/dist/applications/repository.js.map +1 -1
  10. package/dist/applications/service.d.ts +35 -17
  11. package/dist/applications/service.d.ts.map +1 -1
  12. package/dist/applications/service.js +144 -35
  13. package/dist/applications/service.js.map +1 -1
  14. package/dist/applications/types.d.ts +1 -1
  15. package/dist/applications/types.d.ts.map +1 -1
  16. package/dist/applications/validators.d.ts +14 -0
  17. package/dist/applications/validators.d.ts.map +1 -0
  18. package/dist/applications/validators.js +14 -0
  19. package/dist/applications/validators.js.map +1 -0
  20. package/dist/auth/effective-branding.d.ts +35 -0
  21. package/dist/auth/effective-branding.d.ts.map +1 -0
  22. package/dist/auth/effective-branding.js +81 -0
  23. package/dist/auth/effective-branding.js.map +1 -0
  24. package/dist/auth/email-service.d.ts +3 -8
  25. package/dist/auth/email-service.d.ts.map +1 -1
  26. package/dist/auth/email-service.js +22 -30
  27. package/dist/auth/email-service.js.map +1 -1
  28. package/dist/auth/i18n.d.ts +5 -0
  29. package/dist/auth/i18n.d.ts.map +1 -1
  30. package/dist/auth/i18n.js +6 -5
  31. package/dist/auth/i18n.js.map +1 -1
  32. package/dist/auth/rate-limiter.d.ts +6 -10
  33. package/dist/auth/rate-limiter.d.ts.map +1 -1
  34. package/dist/auth/rate-limiter.js +12 -16
  35. package/dist/auth/rate-limiter.js.map +1 -1
  36. package/dist/auth/recovery-job-processor.d.ts.map +1 -1
  37. package/dist/auth/recovery-job-processor.js +1 -1
  38. package/dist/auth/recovery-job-processor.js.map +1 -1
  39. package/dist/auth/template-engine.d.ts +3 -1
  40. package/dist/auth/template-engine.d.ts.map +1 -1
  41. package/dist/auth/template-engine.js +1 -1
  42. package/dist/auth/template-engine.js.map +1 -1
  43. package/dist/cli/commands/init.d.ts +1 -1
  44. package/dist/cli/commands/init.d.ts.map +1 -1
  45. package/dist/cli/commands/init.js +12 -12
  46. package/dist/cli/commands/init.js.map +1 -1
  47. package/dist/cli/error-handler.d.ts +3 -2
  48. package/dist/cli/error-handler.d.ts.map +1 -1
  49. package/dist/cli/error-handler.js +9 -2
  50. package/dist/cli/error-handler.js.map +1 -1
  51. package/dist/cli/index.d.ts +1 -1
  52. package/dist/cli/index.d.ts.map +1 -1
  53. package/dist/cli/index.js +1 -1
  54. package/dist/cli/index.js.map +1 -1
  55. package/dist/clients/index.d.ts +1 -1
  56. package/dist/clients/index.js +1 -1
  57. package/dist/clients/repository.d.ts +18 -0
  58. package/dist/clients/repository.d.ts.map +1 -1
  59. package/dist/clients/repository.js +36 -0
  60. package/dist/clients/repository.js.map +1 -1
  61. package/dist/clients/secret-repository.d.ts +35 -8
  62. package/dist/clients/secret-repository.d.ts.map +1 -1
  63. package/dist/clients/secret-repository.js +69 -16
  64. package/dist/clients/secret-repository.js.map +1 -1
  65. package/dist/clients/secret-service.d.ts +5 -9
  66. package/dist/clients/secret-service.d.ts.map +1 -1
  67. package/dist/clients/secret-service.js +13 -22
  68. package/dist/clients/secret-service.js.map +1 -1
  69. package/dist/clients/service.d.ts +10 -13
  70. package/dist/clients/service.d.ts.map +1 -1
  71. package/dist/clients/service.js +112 -40
  72. package/dist/clients/service.js.map +1 -1
  73. package/dist/clients/types.d.ts +1 -1
  74. package/dist/clients/types.d.ts.map +1 -1
  75. package/dist/clients/validators.d.ts +83 -1
  76. package/dist/clients/validators.d.ts.map +1 -1
  77. package/dist/clients/validators.js +110 -0
  78. package/dist/clients/validators.js.map +1 -1
  79. package/dist/config/index.d.ts +1 -0
  80. package/dist/config/index.d.ts.map +1 -1
  81. package/dist/config/index.js +1 -0
  82. package/dist/config/index.js.map +1 -1
  83. package/dist/config/schema.d.ts +1 -0
  84. package/dist/config/schema.d.ts.map +1 -1
  85. package/dist/config/schema.js +23 -1
  86. package/dist/config/schema.js.map +1 -1
  87. package/dist/custom-claims/repository.d.ts +14 -9
  88. package/dist/custom-claims/repository.d.ts.map +1 -1
  89. package/dist/custom-claims/repository.js +38 -11
  90. package/dist/custom-claims/repository.js.map +1 -1
  91. package/dist/custom-claims/service.d.ts +11 -6
  92. package/dist/custom-claims/service.d.ts.map +1 -1
  93. package/dist/custom-claims/service.js +43 -20
  94. package/dist/custom-claims/service.js.map +1 -1
  95. package/dist/index.js +8 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/lib/admin-permissions.d.ts +12 -7
  98. package/dist/lib/admin-permissions.d.ts.map +1 -1
  99. package/dist/lib/admin-permissions.js +26 -16
  100. package/dist/lib/admin-permissions.js.map +1 -1
  101. package/dist/lib/audit-log.d.ts +2 -2
  102. package/dist/lib/audit-log.d.ts.map +1 -1
  103. package/dist/lib/audit-log.js +1 -1
  104. package/dist/lib/audit-log.js.map +1 -1
  105. package/dist/lib/authority-revocation.d.ts +18 -0
  106. package/dist/lib/authority-revocation.d.ts.map +1 -0
  107. package/dist/lib/authority-revocation.js +37 -0
  108. package/dist/lib/authority-revocation.js.map +1 -0
  109. package/dist/lib/branding-assets.d.ts +35 -5
  110. package/dist/lib/branding-assets.d.ts.map +1 -1
  111. package/dist/lib/branding-assets.js +33 -26
  112. package/dist/lib/branding-assets.js.map +1 -1
  113. package/dist/lib/bulk-operations.d.ts +1 -1
  114. package/dist/lib/bulk-operations.d.ts.map +1 -1
  115. package/dist/lib/bulk-operations.js +1 -13
  116. package/dist/lib/bulk-operations.js.map +1 -1
  117. package/dist/lib/cursor.d.ts +2 -0
  118. package/dist/lib/cursor.d.ts.map +1 -1
  119. package/dist/lib/cursor.js +2 -7
  120. package/dist/lib/cursor.js.map +1 -1
  121. package/dist/lib/database.d.ts.map +1 -1
  122. package/dist/lib/database.js +5 -0
  123. package/dist/lib/database.js.map +1 -1
  124. package/dist/lib/deletion-cleanup.d.ts +43 -0
  125. package/dist/lib/deletion-cleanup.d.ts.map +1 -0
  126. package/dist/lib/deletion-cleanup.js +207 -0
  127. package/dist/lib/deletion-cleanup.js.map +1 -0
  128. package/dist/lib/image-validator.d.ts +3 -1
  129. package/dist/lib/image-validator.d.ts.map +1 -1
  130. package/dist/lib/image-validator.js +32 -19
  131. package/dist/lib/image-validator.js.map +1 -1
  132. package/dist/lib/log-format.d.ts +20 -0
  133. package/dist/lib/log-format.d.ts.map +1 -0
  134. package/dist/lib/log-format.js +22 -0
  135. package/dist/lib/log-format.js.map +1 -0
  136. package/dist/lib/logger.d.ts +3 -1
  137. package/dist/lib/logger.d.ts.map +1 -1
  138. package/dist/lib/logger.js +21 -4
  139. package/dist/lib/logger.js.map +1 -1
  140. package/dist/lib/redis.d.ts.map +1 -1
  141. package/dist/lib/redis.js +3 -0
  142. package/dist/lib/redis.js.map +1 -1
  143. package/dist/lib/session-tracking.d.ts +73 -11
  144. package/dist/lib/session-tracking.d.ts.map +1 -1
  145. package/dist/lib/session-tracking.js +76 -32
  146. package/dist/lib/session-tracking.js.map +1 -1
  147. package/dist/lib/signing-key-crypto.d.ts.map +1 -1
  148. package/dist/lib/signing-key-crypto.js +4 -5
  149. package/dist/lib/signing-key-crypto.js.map +1 -1
  150. package/dist/lib/signing-keys.d.ts +3 -4
  151. package/dist/lib/signing-keys.d.ts.map +1 -1
  152. package/dist/lib/signing-keys.js +66 -41
  153. package/dist/lib/signing-keys.js.map +1 -1
  154. package/dist/lib/super-admin-protection.d.ts +5 -5
  155. package/dist/lib/super-admin-protection.d.ts.map +1 -1
  156. package/dist/lib/super-admin-protection.js +6 -9
  157. package/dist/lib/super-admin-protection.js.map +1 -1
  158. package/dist/lib/system-config-catalog.d.ts +268 -0
  159. package/dist/lib/system-config-catalog.d.ts.map +1 -0
  160. package/dist/lib/system-config-catalog.js +90 -0
  161. package/dist/lib/system-config-catalog.js.map +1 -0
  162. package/dist/lib/system-config.d.ts +30 -33
  163. package/dist/lib/system-config.d.ts.map +1 -1
  164. package/dist/lib/system-config.js +78 -93
  165. package/dist/lib/system-config.js.map +1 -1
  166. package/dist/lib/with-timeout.d.ts +32 -0
  167. package/dist/lib/with-timeout.d.ts.map +1 -0
  168. package/dist/lib/with-timeout.js +45 -0
  169. package/dist/lib/with-timeout.js.map +1 -0
  170. package/dist/middleware/admin-auth.d.ts +6 -5
  171. package/dist/middleware/admin-auth.d.ts.map +1 -1
  172. package/dist/middleware/admin-auth.js +30 -20
  173. package/dist/middleware/admin-auth.js.map +1 -1
  174. package/dist/middleware/admin-cors.d.ts +3 -3
  175. package/dist/middleware/admin-cors.js +3 -3
  176. package/dist/middleware/admin-mutation-audit.d.ts +3 -2
  177. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
  178. package/dist/middleware/admin-mutation-audit.js +12 -5
  179. package/dist/middleware/admin-mutation-audit.js.map +1 -1
  180. package/dist/middleware/admin-rate-limiter.d.ts +7 -8
  181. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
  182. package/dist/middleware/admin-rate-limiter.js +7 -8
  183. package/dist/middleware/admin-rate-limiter.js.map +1 -1
  184. package/dist/middleware/client-secret-hash.d.ts +10 -29
  185. package/dist/middleware/client-secret-hash.d.ts.map +1 -1
  186. package/dist/middleware/client-secret-hash.js +161 -59
  187. package/dist/middleware/client-secret-hash.js.map +1 -1
  188. package/dist/middleware/health.d.ts +17 -0
  189. package/dist/middleware/health.d.ts.map +1 -1
  190. package/dist/middleware/health.js +25 -21
  191. package/dist/middleware/health.js.map +1 -1
  192. package/dist/middleware/ready.d.ts.map +1 -1
  193. package/dist/middleware/ready.js +1 -12
  194. package/dist/middleware/ready.js.map +1 -1
  195. package/dist/middleware/require-existing-organization.d.ts +18 -0
  196. package/dist/middleware/require-existing-organization.d.ts.map +1 -0
  197. package/dist/middleware/require-existing-organization.js +38 -0
  198. package/dist/middleware/require-existing-organization.js.map +1 -0
  199. package/dist/middleware/require-permission.d.ts.map +1 -1
  200. package/dist/middleware/require-permission.js +35 -1
  201. package/dist/middleware/require-permission.js.map +1 -1
  202. package/dist/middleware/require-user-organization.d.ts.map +1 -1
  203. package/dist/middleware/require-user-organization.js +4 -2
  204. package/dist/middleware/require-user-organization.js.map +1 -1
  205. package/dist/middleware/security-headers.d.ts +18 -0
  206. package/dist/middleware/security-headers.d.ts.map +1 -1
  207. package/dist/middleware/security-headers.js +32 -1
  208. package/dist/middleware/security-headers.js.map +1 -1
  209. package/dist/middleware/tenant-resolver.d.ts +1 -2
  210. package/dist/middleware/tenant-resolver.d.ts.map +1 -1
  211. package/dist/middleware/tenant-resolver.js +1 -5
  212. package/dist/middleware/tenant-resolver.js.map +1 -1
  213. package/dist/middleware/token-rate-limiter.d.ts +37 -16
  214. package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
  215. package/dist/middleware/token-rate-limiter.js +126 -54
  216. package/dist/middleware/token-rate-limiter.js.map +1 -1
  217. package/dist/oidc/account-finder.d.ts +5 -5
  218. package/dist/oidc/account-finder.d.ts.map +1 -1
  219. package/dist/oidc/account-finder.js +31 -23
  220. package/dist/oidc/account-finder.js.map +1 -1
  221. package/dist/oidc/adapter-factory.d.ts.map +1 -1
  222. package/dist/oidc/adapter-factory.js +83 -3
  223. package/dist/oidc/adapter-factory.js.map +1 -1
  224. package/dist/oidc/configuration.d.ts +3 -8
  225. package/dist/oidc/configuration.d.ts.map +1 -1
  226. package/dist/oidc/configuration.js +64 -50
  227. package/dist/oidc/configuration.js.map +1 -1
  228. package/dist/oidc/provider.d.ts.map +1 -1
  229. package/dist/oidc/provider.js +7 -0
  230. package/dist/oidc/provider.js.map +1 -1
  231. package/dist/oidc/redis-adapter.d.ts +2 -3
  232. package/dist/oidc/redis-adapter.d.ts.map +1 -1
  233. package/dist/oidc/redis-adapter.js +54 -46
  234. package/dist/oidc/redis-adapter.js.map +1 -1
  235. package/dist/organizations/branding-url.d.ts +17 -0
  236. package/dist/organizations/branding-url.d.ts.map +1 -0
  237. package/dist/organizations/branding-url.js +38 -0
  238. package/dist/organizations/branding-url.js.map +1 -0
  239. package/dist/organizations/index.d.ts +2 -2
  240. package/dist/organizations/index.d.ts.map +1 -1
  241. package/dist/organizations/index.js +1 -1
  242. package/dist/organizations/index.js.map +1 -1
  243. package/dist/organizations/repository.d.ts +22 -32
  244. package/dist/organizations/repository.d.ts.map +1 -1
  245. package/dist/organizations/repository.js +64 -45
  246. package/dist/organizations/repository.js.map +1 -1
  247. package/dist/organizations/service.d.ts +14 -46
  248. package/dist/organizations/service.d.ts.map +1 -1
  249. package/dist/organizations/service.js +60 -112
  250. package/dist/organizations/service.js.map +1 -1
  251. package/dist/organizations/types.d.ts +1 -15
  252. package/dist/organizations/types.d.ts.map +1 -1
  253. package/dist/organizations/validators.d.ts +41 -0
  254. package/dist/organizations/validators.d.ts.map +1 -0
  255. package/dist/organizations/validators.js +48 -0
  256. package/dist/organizations/validators.js.map +1 -0
  257. package/dist/portability/apply.d.ts +15 -0
  258. package/dist/portability/apply.d.ts.map +1 -0
  259. package/dist/portability/apply.js +274 -0
  260. package/dist/portability/apply.js.map +1 -0
  261. package/dist/portability/authorization.d.ts +30 -0
  262. package/dist/portability/authorization.d.ts.map +1 -0
  263. package/dist/portability/authorization.js +130 -0
  264. package/dist/portability/authorization.js.map +1 -0
  265. package/dist/portability/cleanup.d.ts +29 -0
  266. package/dist/portability/cleanup.d.ts.map +1 -0
  267. package/dist/portability/cleanup.js +167 -0
  268. package/dist/portability/cleanup.js.map +1 -0
  269. package/dist/portability/export.d.ts +18 -0
  270. package/dist/portability/export.d.ts.map +1 -0
  271. package/dist/portability/export.js +125 -0
  272. package/dist/portability/export.js.map +1 -0
  273. package/dist/portability/import-repository.d.ts +204 -0
  274. package/dist/portability/import-repository.d.ts.map +1 -0
  275. package/dist/portability/import-repository.js +347 -0
  276. package/dist/portability/import-repository.js.map +1 -0
  277. package/dist/portability/import-user-client-writers.d.ts +40 -0
  278. package/dist/portability/import-user-client-writers.d.ts.map +1 -0
  279. package/dist/portability/import-user-client-writers.js +168 -0
  280. package/dist/portability/import-user-client-writers.js.map +1 -0
  281. package/dist/portability/index.d.ts +8 -0
  282. package/dist/portability/index.d.ts.map +1 -0
  283. package/dist/portability/index.js +8 -0
  284. package/dist/portability/index.js.map +1 -0
  285. package/dist/portability/plan-support.d.ts +137 -0
  286. package/dist/portability/plan-support.d.ts.map +1 -0
  287. package/dist/portability/plan-support.js +336 -0
  288. package/dist/portability/plan-support.js.map +1 -0
  289. package/dist/portability/plan.d.ts +34 -0
  290. package/dist/portability/plan.d.ts.map +1 -0
  291. package/dist/portability/plan.js +450 -0
  292. package/dist/portability/plan.js.map +1 -0
  293. package/dist/portability/repository.d.ts +95 -0
  294. package/dist/portability/repository.d.ts.map +1 -0
  295. package/dist/portability/repository.js +388 -0
  296. package/dist/portability/repository.js.map +1 -0
  297. package/dist/portability/schema.d.ts +589 -0
  298. package/dist/portability/schema.d.ts.map +1 -0
  299. package/dist/portability/schema.js +458 -0
  300. package/dist/portability/schema.js.map +1 -0
  301. package/dist/portability/types.d.ts +381 -0
  302. package/dist/portability/types.d.ts.map +1 -0
  303. package/dist/portability/types.js +19 -0
  304. package/dist/portability/types.js.map +1 -0
  305. package/dist/rbac/errors.d.ts +4 -0
  306. package/dist/rbac/errors.d.ts.map +1 -1
  307. package/dist/rbac/errors.js +7 -0
  308. package/dist/rbac/errors.js.map +1 -1
  309. package/dist/rbac/index.d.ts +3 -3
  310. package/dist/rbac/index.d.ts.map +1 -1
  311. package/dist/rbac/index.js +3 -3
  312. package/dist/rbac/index.js.map +1 -1
  313. package/dist/rbac/mapping-repository.d.ts +84 -9
  314. package/dist/rbac/mapping-repository.d.ts.map +1 -1
  315. package/dist/rbac/mapping-repository.js +222 -55
  316. package/dist/rbac/mapping-repository.js.map +1 -1
  317. package/dist/rbac/permission-repository.d.ts +36 -19
  318. package/dist/rbac/permission-repository.d.ts.map +1 -1
  319. package/dist/rbac/permission-repository.js +93 -35
  320. package/dist/rbac/permission-repository.js.map +1 -1
  321. package/dist/rbac/permission-service.d.ts +18 -19
  322. package/dist/rbac/permission-service.d.ts.map +1 -1
  323. package/dist/rbac/permission-service.js +100 -57
  324. package/dist/rbac/permission-service.js.map +1 -1
  325. package/dist/rbac/role-repository.d.ts +29 -24
  326. package/dist/rbac/role-repository.d.ts.map +1 -1
  327. package/dist/rbac/role-repository.js +66 -43
  328. package/dist/rbac/role-repository.js.map +1 -1
  329. package/dist/rbac/role-service.d.ts +35 -32
  330. package/dist/rbac/role-service.d.ts.map +1 -1
  331. package/dist/rbac/role-service.js +210 -96
  332. package/dist/rbac/role-service.js.map +1 -1
  333. package/dist/rbac/slugs.d.ts +16 -27
  334. package/dist/rbac/slugs.d.ts.map +1 -1
  335. package/dist/rbac/slugs.js +36 -59
  336. package/dist/rbac/slugs.js.map +1 -1
  337. package/dist/rbac/types.d.ts +2 -4
  338. package/dist/rbac/types.d.ts.map +1 -1
  339. package/dist/rbac/types.js.map +1 -1
  340. package/dist/rbac/user-role-service.d.ts +23 -24
  341. package/dist/rbac/user-role-service.d.ts.map +1 -1
  342. package/dist/rbac/user-role-service.js +117 -61
  343. package/dist/rbac/user-role-service.js.map +1 -1
  344. package/dist/routes/applications.d.ts +4 -2
  345. package/dist/routes/applications.d.ts.map +1 -1
  346. package/dist/routes/applications.js +57 -19
  347. package/dist/routes/applications.js.map +1 -1
  348. package/dist/routes/audit.js +1 -1
  349. package/dist/routes/audit.js.map +1 -1
  350. package/dist/routes/branding.d.ts +3 -3
  351. package/dist/routes/branding.d.ts.map +1 -1
  352. package/dist/routes/branding.js +44 -16
  353. package/dist/routes/branding.js.map +1 -1
  354. package/dist/routes/bulk.d.ts +0 -5
  355. package/dist/routes/bulk.d.ts.map +1 -1
  356. package/dist/routes/bulk.js +3 -5
  357. package/dist/routes/bulk.js.map +1 -1
  358. package/dist/routes/clients.d.ts +4 -4
  359. package/dist/routes/clients.d.ts.map +1 -1
  360. package/dist/routes/clients.js +111 -52
  361. package/dist/routes/clients.js.map +1 -1
  362. package/dist/routes/config.d.ts +17 -12
  363. package/dist/routes/config.d.ts.map +1 -1
  364. package/dist/routes/config.js +165 -64
  365. package/dist/routes/config.js.map +1 -1
  366. package/dist/routes/custom-claims.d.ts.map +1 -1
  367. package/dist/routes/custom-claims.js +8 -2
  368. package/dist/routes/custom-claims.js.map +1 -1
  369. package/dist/routes/exports.d.ts +2 -1
  370. package/dist/routes/exports.d.ts.map +1 -1
  371. package/dist/routes/exports.js +57 -1
  372. package/dist/routes/exports.js.map +1 -1
  373. package/dist/routes/imports.d.ts +2 -2
  374. package/dist/routes/imports.d.ts.map +1 -1
  375. package/dist/routes/imports.js +95 -40
  376. package/dist/routes/imports.js.map +1 -1
  377. package/dist/routes/interactions.d.ts.map +1 -1
  378. package/dist/routes/interactions.js +16 -34
  379. package/dist/routes/interactions.js.map +1 -1
  380. package/dist/routes/invitation.d.ts.map +1 -1
  381. package/dist/routes/invitation.js +10 -23
  382. package/dist/routes/invitation.js.map +1 -1
  383. package/dist/routes/keys.d.ts.map +1 -1
  384. package/dist/routes/keys.js +26 -13
  385. package/dist/routes/keys.js.map +1 -1
  386. package/dist/routes/magic-link.d.ts.map +1 -1
  387. package/dist/routes/magic-link.js +5 -17
  388. package/dist/routes/magic-link.js.map +1 -1
  389. package/dist/routes/organizations.d.ts +1 -2
  390. package/dist/routes/organizations.d.ts.map +1 -1
  391. package/dist/routes/organizations.js +43 -104
  392. package/dist/routes/organizations.js.map +1 -1
  393. package/dist/routes/password-reset.d.ts.map +1 -1
  394. package/dist/routes/password-reset.js +13 -35
  395. package/dist/routes/password-reset.js.map +1 -1
  396. package/dist/routes/permissions.d.ts +1 -1
  397. package/dist/routes/permissions.d.ts.map +1 -1
  398. package/dist/routes/permissions.js +58 -17
  399. package/dist/routes/permissions.js.map +1 -1
  400. package/dist/routes/public-branding.d.ts +16 -0
  401. package/dist/routes/public-branding.d.ts.map +1 -0
  402. package/dist/routes/public-branding.js +52 -0
  403. package/dist/routes/public-branding.js.map +1 -0
  404. package/dist/routes/roles.d.ts +1 -1
  405. package/dist/routes/roles.d.ts.map +1 -1
  406. package/dist/routes/roles.js +63 -21
  407. package/dist/routes/roles.js.map +1 -1
  408. package/dist/routes/sessions.d.ts.map +1 -1
  409. package/dist/routes/sessions.js +23 -12
  410. package/dist/routes/sessions.js.map +1 -1
  411. package/dist/routes/two-factor.d.ts.map +1 -1
  412. package/dist/routes/two-factor.js +91 -38
  413. package/dist/routes/two-factor.js.map +1 -1
  414. package/dist/routes/user-roles.d.ts.map +1 -1
  415. package/dist/routes/user-roles.js +56 -9
  416. package/dist/routes/user-roles.js.map +1 -1
  417. package/dist/routes/users.d.ts +4 -8
  418. package/dist/routes/users.d.ts.map +1 -1
  419. package/dist/routes/users.js +108 -265
  420. package/dist/routes/users.js.map +1 -1
  421. package/dist/server.d.ts.map +1 -1
  422. package/dist/server.js +53 -37
  423. package/dist/server.js.map +1 -1
  424. package/dist/two-factor/errors.d.ts +9 -0
  425. package/dist/two-factor/errors.d.ts.map +1 -1
  426. package/dist/two-factor/errors.js +12 -0
  427. package/dist/two-factor/errors.js.map +1 -1
  428. package/dist/two-factor/index.d.ts +5 -4
  429. package/dist/two-factor/index.d.ts.map +1 -1
  430. package/dist/two-factor/index.js +4 -4
  431. package/dist/two-factor/index.js.map +1 -1
  432. package/dist/two-factor/repository.d.ts +17 -6
  433. package/dist/two-factor/repository.d.ts.map +1 -1
  434. package/dist/two-factor/repository.js +37 -9
  435. package/dist/two-factor/repository.js.map +1 -1
  436. package/dist/two-factor/service.d.ts.map +1 -1
  437. package/dist/two-factor/service.js +26 -19
  438. package/dist/two-factor/service.js.map +1 -1
  439. package/dist/two-factor/totp.d.ts +13 -2
  440. package/dist/two-factor/totp.d.ts.map +1 -1
  441. package/dist/two-factor/totp.js +20 -7
  442. package/dist/two-factor/totp.js.map +1 -1
  443. package/dist/two-factor/types.d.ts +3 -0
  444. package/dist/two-factor/types.d.ts.map +1 -1
  445. package/dist/two-factor/types.js +5 -0
  446. package/dist/two-factor/types.js.map +1 -1
  447. package/dist/users/gdpr.d.ts +2 -40
  448. package/dist/users/gdpr.d.ts.map +1 -1
  449. package/dist/users/gdpr.js +3 -110
  450. package/dist/users/gdpr.js.map +1 -1
  451. package/dist/users/index.d.ts +5 -4
  452. package/dist/users/index.d.ts.map +1 -1
  453. package/dist/users/index.js +5 -4
  454. package/dist/users/index.js.map +1 -1
  455. package/dist/users/repository.d.ts +49 -3
  456. package/dist/users/repository.d.ts.map +1 -1
  457. package/dist/users/repository.js +169 -18
  458. package/dist/users/repository.js.map +1 -1
  459. package/dist/users/service.d.ts +19 -51
  460. package/dist/users/service.d.ts.map +1 -1
  461. package/dist/users/service.js +72 -122
  462. package/dist/users/service.js.map +1 -1
  463. package/dist/users/types.d.ts +4 -5
  464. package/dist/users/types.d.ts.map +1 -1
  465. package/dist/users/types.js.map +1 -1
  466. package/dist/users/validators.d.ts +28 -0
  467. package/dist/users/validators.d.ts.map +1 -0
  468. package/dist/users/validators.js +25 -0
  469. package/dist/users/validators.js.map +1 -0
  470. package/locales/default/en/errors.json +2 -1
  471. package/migrations/024_application_client_correction.sql +39 -0
  472. package/migrations/025_record_deletion_lifecycle.sql +26 -0
  473. package/migrations/026_simplify_user_lifecycle.sql +33 -0
  474. package/migrations/027_branding_asset_size_limits.sql +19 -0
  475. package/migrations/028_totp_replay_protection.sql +17 -0
  476. package/migrations/029_public_session_identifiers.sql +16 -0
  477. package/migrations/030_global_configuration_catalog.sql +39 -0
  478. package/migrations/031_monotonic_updated_at.sql +28 -0
  479. package/package.json +2 -2
  480. package/dist/lib/data-import-plan.d.ts +0 -50
  481. package/dist/lib/data-import-plan.d.ts.map +0 -1
  482. package/dist/lib/data-import-plan.js +0 -235
  483. package/dist/lib/data-import-plan.js.map +0 -1
  484. package/dist/lib/data-import.d.ts +0 -276
  485. package/dist/lib/data-import.d.ts.map +0 -1
  486. package/dist/lib/data-import.js +0 -1694
  487. package/dist/lib/data-import.js.map +0 -1
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * Validates Bearer access tokens against Porta's own OIDC provider
5
5
  * using opaque token lookup (provider.AccessToken.find()). Verifies
6
- * the user belongs to the super-admin organization and has the
7
- * porta-admin role. Sets ctx.state.adminUser for downstream handlers
8
- * and audit logging.
6
+ * the user belongs to the super-admin organization and has a recognized
7
+ * built-in role owned by the canonical Porta Admin application. Sets
8
+ * ctx.state.adminUser for downstream handlers and audit logging.
9
9
  *
10
10
  * This middleware replaces the old requireSuperAdmin() that checked
11
11
  * ctx.state.organization.isSuperAdmin (which required tenant-resolver
@@ -17,7 +17,7 @@
17
17
  * 3. Resolve super-admin organization
18
18
  * 4. Look up user — must be active
19
19
  * 5. Verify user belongs to the super-admin organization
20
- * 6. Verify user has the porta-admin role
20
+ * 6. Verify the user has a recognized role from the canonical Admin application
21
21
  * 7. Set ctx.state.adminUser and proceed
22
22
  *
23
23
  * Response codes:
@@ -27,9 +27,10 @@
27
27
  */
28
28
  import { findUserForOidc } from '../users/service.js';
29
29
  import { findSuperAdminOrganization } from '../organizations/repository.js';
30
- import { getUserRoles } from '../rbac/user-role-service.js';
30
+ import { getUserRolesForAuthority } from '../rbac/user-role-service.js';
31
+ import { getApplicationBySlug } from '../applications/service.js';
31
32
  import { logger } from '../lib/logger.js';
32
- import { resolvePermissionsFromRoles } from '../lib/admin-permissions.js';
33
+ import { getPermissionsForAdminRole, resolvePermissionsFromRoles, } from '../lib/admin-permissions.js';
33
34
  import { recordSecurityDecision, recordSecurityReference } from '../security/decision-context.js';
34
35
  let _provider = null;
35
36
  /**
@@ -69,17 +70,15 @@ export function requireAdminOrganizationMembership(ctx, userOrganizationId, admi
69
70
  // ---------------------------------------------------------------------------
70
71
  // Admin auth middleware factory
71
72
  // ---------------------------------------------------------------------------
72
- /**
73
- * Admin role slug prefix — all admin roles start with 'porta-'.
74
- * Legacy 'porta-admin' role is treated as super-admin for backward compatibility.
75
- */
76
- const ADMIN_ROLE_PREFIX = 'porta-';
73
+ /** Immutable slug of the application that owns Porta's control-plane roles. */
74
+ const ADMIN_APPLICATION_SLUG = 'porta-admin';
77
75
  /**
78
76
  * Create middleware that requires admin authentication and authorization.
79
77
  *
80
78
  * Validates the Bearer access token in the Authorization header by looking
81
79
  * it up via the OIDC provider's opaque token store, then verifies the user
82
- * is an active member of the super-admin organization with the porta-admin role.
80
+ * is an active member of the super-admin organization with a recognized role
81
+ * owned by the canonical Porta Admin application.
83
82
  *
84
83
  * On success, sets ctx.state.adminUser with the authenticated identity.
85
84
  * On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
@@ -201,14 +200,27 @@ export function requireAdminAuth() {
201
200
  if (!requireAdminOrganizationMembership(ctx, user.organizationId, superAdminOrg.id))
202
201
  return;
203
202
  // -----------------------------------------------------------------
204
- // Step 6: Verify user has an admin role (any porta-* role)
203
+ // Step 6: Verify the user has a recognized role from the canonical Admin application.
205
204
  // -----------------------------------------------------------------
206
- // Supports both legacy porta-admin and new granular roles:
207
- // porta-super-admin, porta-org-admin, porta-user-admin, etc.
208
- const userRoles = await getUserRoles(userId);
205
+ const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
206
+ if (!adminApplication) {
207
+ logger.error('Admin auth: canonical application not found — run porta init');
208
+ recordSecurityDecision(ctx, {
209
+ decisionPoint: 'handler',
210
+ reasonCode: 'handler-failed',
211
+ outcome: 'error',
212
+ });
213
+ ctx.status = 500;
214
+ ctx.body = { error: 'Server configuration error' };
215
+ return;
216
+ }
217
+ const userRoles = await getUserRolesForAuthority(userId);
209
218
  const adminRoleSlugs = userRoles
210
- .map((role) => role.slug)
211
- .filter((slug) => slug.startsWith(ADMIN_ROLE_PREFIX));
219
+ .filter((role) => role.applicationId === adminApplication.id &&
220
+ getPermissionsForAdminRole(role.slug).length > 0)
221
+ .map((role) => role.slug);
222
+ recordSecurityReference(ctx, 'actor', userId);
223
+ recordSecurityReference(ctx, 'tenant', user.organizationId);
212
224
  if (adminRoleSlugs.length === 0) {
213
225
  recordSecurityDecision(ctx, {
214
226
  decisionPoint: 'membership',
@@ -233,8 +245,6 @@ export function requireAdminAuth() {
233
245
  roles: adminRoleSlugs,
234
246
  permissions,
235
247
  };
236
- recordSecurityReference(ctx, 'actor', userId);
237
- recordSecurityReference(ctx, 'tenant', user.organizationId);
238
248
  await next();
239
249
  };
240
250
  }
@@ -1 +1 @@
1
- {"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"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"}
@@ -12,9 +12,9 @@
12
12
  * Non-browser clients (CLI, same-origin requests) never send an `Origin`
13
13
  * header, so they pass through this middleware untouched.
14
14
  *
15
- * Placement: mount after the admin metadata router and before
16
- * `setAdminAuthProvider()` — preflight `OPTIONS` requests don't carry
17
- * an `Authorization` header, so CORS must respond before auth runs.
15
+ * Placement: mount before Admin rate limiting, body parsing, and authentication.
16
+ * Preflight `OPTIONS` requests carry no `Authorization` header, so CORS must
17
+ * respond before authentication runs.
18
18
  *
19
19
  * @module middleware/admin-cors
20
20
  */
@@ -12,9 +12,9 @@
12
12
  * Non-browser clients (CLI, same-origin requests) never send an `Origin`
13
13
  * header, so they pass through this middleware untouched.
14
14
  *
15
- * Placement: mount after the admin metadata router and before
16
- * `setAdminAuthProvider()` — preflight `OPTIONS` requests don't carry
17
- * an `Authorization` header, so CORS must respond before auth runs.
15
+ * Placement: mount before Admin rate limiting, body parsing, and authentication.
16
+ * Preflight `OPTIONS` requests carry no `Authorization` header, so CORS must
17
+ * respond before authentication runs.
18
18
  *
19
19
  * @module middleware/admin-cors
20
20
  */
@@ -2,8 +2,9 @@ import type { Middleware } from 'koa';
2
2
  /**
3
3
  * Atomically bind successful administrative mutations to one durable audit row.
4
4
  *
5
- * Bulk and import own specialized transaction/result semantics and are excluded here. Every other
6
- * state-changing admin request shares one request-local PostgreSQL client across repository calls.
5
+ * Bulk operations, portability and configuration updates own specialized transaction semantics and are
6
+ * excluded here. Every other state-changing admin request shares one request-local PostgreSQL
7
+ * client across repository calls.
7
8
  */
8
9
  export declare function adminMutationAudit(): Middleware;
9
10
  //# sourceMappingURL=admin-mutation-audit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-mutation-audit.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AA2BtC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CA2C/C"}
1
+ {"version":3,"file":"admin-mutation-audit.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAgCtC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,UAAU,CA+C/C"}
@@ -2,7 +2,12 @@ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
2
2
  import { getDatabaseTransactionClient, runDatabaseTransaction } from '../lib/database.js';
3
3
  import { normalizedRouteTemplate, recordSecurityDecision } from '../security/decision-context.js';
4
4
  const MUTATION_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
5
- const SELF_MANAGED_MUTATION_PREFIXES = ['/api/admin/bulk', '/api/admin/import'];
5
+ const SELF_MANAGED_MUTATION_PREFIXES = [
6
+ '/api/admin/bulk',
7
+ '/api/admin/import',
8
+ '/api/admin/export/manifest',
9
+ '/api/admin/config',
10
+ ];
6
11
  /** Internal signal used to roll back a handled non-success response without replacing its body. */
7
12
  class HandledMutationRejection extends Error {
8
13
  }
@@ -22,8 +27,9 @@ function ownsAdministrativeMutation(method, path) {
22
27
  /**
23
28
  * Atomically bind successful administrative mutations to one durable audit row.
24
29
  *
25
- * Bulk and import own specialized transaction/result semantics and are excluded here. Every other
26
- * state-changing admin request shares one request-local PostgreSQL client across repository calls.
30
+ * Bulk operations, portability and configuration updates own specialized transaction semantics and are
31
+ * excluded here. Every other state-changing admin request shares one request-local PostgreSQL
32
+ * client across repository calls.
27
33
  */
28
34
  export function adminMutationAudit() {
29
35
  return async (ctx, next) => {
@@ -42,9 +48,10 @@ export function adminMutationAudit() {
42
48
  const actor = ctx.state.adminUser;
43
49
  if (!actor)
44
50
  throw new Error('Administrative mutation actor is unavailable');
51
+ const liveActor = await client.query('SELECT id, organization_id FROM users WHERE id = $1', [actor.id]);
45
52
  await writeAuditLogInTransaction(client, {
46
- organizationId: actor.organizationId,
47
- actorId: actor.id,
53
+ organizationId: liveActor.rows[0]?.organization_id,
54
+ actorId: liveActor.rows[0]?.id,
48
55
  eventType: 'admin.mutation.committed',
49
56
  eventCategory: 'admin',
50
57
  metadata: {
@@ -1 +1 @@
1
- {"version":3,"file":"admin-mutation-audit.js","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-mutation-audit.js","sourceRoot":"","sources":["../../src/middleware/admin-mutation-audit.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,10 @@
5
5
  * `/api/admin/*`) against brute-force attacks and automated abuse.
6
6
  * GET requests are read-only and pass through without rate limiting.
7
7
  *
8
- * Key format: `ratelimit:admin:{ip}` — per-IP only since admin-auth
9
- * already restricts access to authenticated super-admin users. There
10
- * is no per-user key because the IP-based counter is sufficient:
11
- * legitimate admins won't make 60 write requests per minute, and
12
- * attackers from the same IP are blocked regardless of identity.
8
+ * Key format: `ratelimit:admin:{ip}`. The limiter intentionally runs before
9
+ * body parsing and authentication so rejected large requests consume minimal
10
+ * resources. A per-IP counter covers both unauthenticated abuse and legitimate
11
+ * administrators without requiring an authenticated user identifier.
13
12
  *
14
13
  * Limit: 60 requests / 60 seconds (sliding window).
15
14
  *
@@ -17,9 +16,9 @@
17
16
  * provides Redis INCR+EXPIRE sliding window and graceful degradation
18
17
  * on Redis failure (allows request + logs warning).
19
18
  *
20
- * Placement: mount as global middleware in `src/server.ts` before the
21
- * admin route routers. The path + method check ensures only write
22
- * requests to `/api/admin/*` are counted.
19
+ * Placement: mount after Admin CORS and before body parsing, authentication,
20
+ * and Admin route routers. The path + method check ensures only write requests
21
+ * to `/api/admin/*` are counted.
23
22
  *
24
23
  * @module middleware/admin-rate-limiter
25
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"admin-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAO/D,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAA8C,CAAC;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAG9B,CAAC;AAMF;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAyC7C"}
1
+ {"version":3,"file":"admin-rate-limiter.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAO/D,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAA8C,CAAC;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAG9B,CAAC;AAMF;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAyC7C"}
@@ -5,11 +5,10 @@
5
5
  * `/api/admin/*`) against brute-force attacks and automated abuse.
6
6
  * GET requests are read-only and pass through without rate limiting.
7
7
  *
8
- * Key format: `ratelimit:admin:{ip}` — per-IP only since admin-auth
9
- * already restricts access to authenticated super-admin users. There
10
- * is no per-user key because the IP-based counter is sufficient:
11
- * legitimate admins won't make 60 write requests per minute, and
12
- * attackers from the same IP are blocked regardless of identity.
8
+ * Key format: `ratelimit:admin:{ip}`. The limiter intentionally runs before
9
+ * body parsing and authentication so rejected large requests consume minimal
10
+ * resources. A per-IP counter covers both unauthenticated abuse and legitimate
11
+ * administrators without requiring an authenticated user identifier.
13
12
  *
14
13
  * Limit: 60 requests / 60 seconds (sliding window).
15
14
  *
@@ -17,9 +16,9 @@
17
16
  * provides Redis INCR+EXPIRE sliding window and graceful degradation
18
17
  * on Redis failure (allows request + logs warning).
19
18
  *
20
- * Placement: mount as global middleware in `src/server.ts` before the
21
- * admin route routers. The path + method check ensures only write
22
- * requests to `/api/admin/*` are counted.
19
+ * Placement: mount after Admin CORS and before body parsing, authentication,
20
+ * and Admin route routers. The path + method check ensures only write requests
21
+ * to `/api/admin/*` are counted.
23
22
  *
24
23
  * @module middleware/admin-rate-limiter
25
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"admin-rate-limiter.js","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,8EAA8E;AAC9E,6DAA6D;AAC7D,8EAA8E;AAE9E,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,GAAG,EAAE,EAAE;IACP,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,UAAU,0BAA0B,CAAC,GAAG,EAAE,IAAI;QACxD,8DAA8D;QAC9D,mEAAmE;QACnE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpF,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,kEAAkE;QAClE,8DAA8D;QAC9D,sDAAsD;QACtD,MAAM,GAAG,GAAG,mBAAmB,GAAG,CAAC,EAAE,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAE3D,+DAA+D;QAC/D,iDAAiD;QACjD,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CACT;gBACE,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,EACD,+BAA+B,CAChC,CAAC;YAEF,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,GAAG;gBACT,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,wDAAwD;gBACjE,WAAW,EAAE,MAAM,CAAC,UAAU;aAC/B,CAAC;YACF,OAAO;QACT,CAAC;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"admin-rate-limiter.js","sourceRoot":"","sources":["../../src/middleware/admin-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,8EAA8E;AAC9E,6DAA6D;AAC7D,8EAA8E;AAE9E,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,GAAG,EAAE,EAAE;IACP,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,UAAU,0BAA0B,CAAC,GAAG,EAAE,IAAI;QACxD,8DAA8D;QAC9D,mEAAmE;QACnE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpF,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,kEAAkE;QAClE,8DAA8D;QAC9D,sDAAsD;QACtD,MAAM,GAAG,GAAG,mBAAmB,GAAG,CAAC,EAAE,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAE3D,+DAA+D;QAC/D,iDAAiD;QACjD,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CACT;gBACE,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,EACD,+BAA+B,CAChC,CAAC;YAEF,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,GAAG;gBACT,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,wDAAwD;gBACjE,WAAW,EAAE,MAAM,CAAC,UAAU;aAC/B,CAAC;YACF,OAAO;QACT,CAAC;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -1,34 +1,15 @@
1
- /**
2
- * SHA-256 client secret pre-hashing middleware.
3
- *
4
- * Transforms client_secret values in incoming requests by replacing
5
- * the plaintext with its SHA-256 hash BEFORE oidc-provider processes them.
6
- *
7
- * Supports:
8
- * - client_secret_basic: Authorization: Basic base64(client_id:secret)
9
- * - client_secret_post: client_secret in POST body
10
- *
11
- * This allows oidc-provider's built-in string comparison to work
12
- * with our SHA-256-hashed secret storage — no monkey-patching needed.
13
- *
14
- * How it works:
15
- * 1. At secret generation: SHA-256(secret) is stored in the DB
16
- * 2. At request time: This middleware hashes the presented secret
17
- * 3. In the adapter: findForOidc() returns SHA-256 hash as client_secret
18
- * 4. oidc-provider compares: SHA-256(presented) === SHA-256(stored) → ✅ MATCH
19
- *
20
- * Security: SHA-256 is appropriate for machine-generated, high-entropy
21
- * client secrets (48 bytes / 384 bits of randomness).
22
- */
1
+ /** Confidential-client active-secret bridge for oidc-provider. */
23
2
  import type { Middleware } from 'koa';
3
+ /** Optional controls for the active-secret bridge. */
4
+ export interface ClientSecretBridgeOptions {
5
+ /** Credential-free test hook awaited after validation and immediately before provider handoff. */
6
+ afterCredentialValidation?: () => Promise<void>;
7
+ }
24
8
  /**
25
- * Create middleware that pre-hashes client secrets with SHA-256.
26
- *
27
- * Must be mounted BEFORE oidc-provider's callback handler on the
28
- * OIDC router. Transparently transforms secrets so oidc-provider
29
- * can compare them against stored SHA-256 hashes.
9
+ * Create the bounded active-secret bridge mounted immediately before oidc-provider.
30
10
  *
31
- * @returns Koa middleware function
11
+ * @param options - Optional credential-free validation/handoff test hook
12
+ * @returns Koa middleware
32
13
  */
33
- export declare function clientSecretHash(): Middleware;
14
+ export declare function clientSecretHash(options?: ClientSecretBridgeOptions): Middleware;
34
15
  //# sourceMappingURL=client-secret-hash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-secret-hash.d.ts","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAStC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAqC7C"}
1
+ {"version":3,"file":"client-secret-hash.d.ts","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAiBtC,sDAAsD;AACtD,MAAM,WAAW,yBAAyB;IACxC,kGAAkG;IAClG,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AA6HD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,yBAA8B,GAAG,UAAU,CAoEpF"}
@@ -1,74 +1,176 @@
1
- /**
2
- * SHA-256 client secret pre-hashing middleware.
3
- *
4
- * Transforms client_secret values in incoming requests by replacing
5
- * the plaintext with its SHA-256 hash BEFORE oidc-provider processes them.
6
- *
7
- * Supports:
8
- * - client_secret_basic: Authorization: Basic base64(client_id:secret)
9
- * - client_secret_post: client_secret in POST body
10
- *
11
- * This allows oidc-provider's built-in string comparison to work
12
- * with our SHA-256-hashed secret storage — no monkey-patching needed.
13
- *
14
- * How it works:
15
- * 1. At secret generation: SHA-256(secret) is stored in the DB
16
- * 2. At request time: This middleware hashes the presented secret
17
- * 3. In the adapter: findForOidc() returns SHA-256 hash as client_secret
18
- * 4. oidc-provider compares: SHA-256(presented) === SHA-256(stored) → ✅ MATCH
19
- *
20
- * Security: SHA-256 is appropriate for machine-generated, high-entropy
21
- * client secrets (48 bytes / 384 bits of randomness).
22
- */
23
- import { createHash } from 'node:crypto';
24
- /**
25
- * Compute SHA-256 hash of a string, returned as hex.
26
- */
27
- function sha256(input) {
28
- return createHash('sha256').update(input).digest('hex');
1
+ /** Confidential-client active-secret bridge for oidc-provider. */
2
+ import * as clientCrypto from '../clients/crypto.js';
3
+ import { getClientByClientId } from '../clients/service.js';
4
+ import { findActiveSecretIdBySha256, getActiveLegacySecretHashes, getLatestActiveSha256, } from '../clients/secret-repository.js';
5
+ import { checkRateLimitStrict } from '../auth/rate-limiter.js';
6
+ import { TOKEN_RATE_LIMIT } from './token-rate-limiter.js';
7
+ const MAX_CLIENT_ID_LENGTH = 255;
8
+ const MAX_SECRET_LENGTH = 512;
9
+ const BUSY_RETRY_SECONDS = 1;
10
+ let legacyBatchActive = false;
11
+ /** Identify a plain request-body record without coercing arrays or scalar values. */
12
+ function isRequestBody(value) {
13
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
14
+ }
15
+ /** Return a parsed object body without coercing arrays or scalar values. */
16
+ function requestBody(ctx) {
17
+ const body = ctx.request.body;
18
+ return isRequestBody(body) ? body : undefined;
19
+ }
20
+ /** Parse bounded HTTP Basic credentials while leaving malformed input to the provider. */
21
+ function basicCredential(ctx) {
22
+ const authorization = ctx.headers.authorization;
23
+ if (authorization === undefined || !authorization.startsWith('Basic '))
24
+ return undefined;
25
+ try {
26
+ const decoded = Buffer.from(authorization.slice(6), 'base64').toString('utf8');
27
+ const separator = decoded.indexOf(':');
28
+ const clientId = decoded.slice(0, separator);
29
+ const plaintext = decoded.slice(separator + 1);
30
+ if (separator < 1 ||
31
+ clientId.length > MAX_CLIENT_ID_LENGTH ||
32
+ plaintext.length < 1 ||
33
+ plaintext.length > MAX_SECRET_LENGTH) {
34
+ return undefined;
35
+ }
36
+ return {
37
+ clientId,
38
+ plaintext,
39
+ method: 'client_secret_basic',
40
+ replace(canonicalValue) {
41
+ const encoded = Buffer.from(`${clientId}:${canonicalValue}`).toString('base64');
42
+ ctx.headers.authorization = `Basic ${encoded}`;
43
+ ctx.req.headers.authorization = `Basic ${encoded}`;
44
+ },
45
+ };
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ }
51
+ /** Parse bounded form credentials from the body already parsed by the OIDC router. */
52
+ function postCredential(ctx) {
53
+ const body = requestBody(ctx);
54
+ const clientId = body?.client_id;
55
+ const plaintext = body?.client_secret;
56
+ if (body === undefined ||
57
+ typeof clientId !== 'string' ||
58
+ clientId.length < 1 ||
59
+ clientId.length > MAX_CLIENT_ID_LENGTH ||
60
+ typeof plaintext !== 'string' ||
61
+ plaintext.length < 1 ||
62
+ plaintext.length > MAX_SECRET_LENGTH) {
63
+ return undefined;
64
+ }
65
+ const mutableBody = body;
66
+ return {
67
+ clientId,
68
+ plaintext,
69
+ method: 'client_secret_post',
70
+ replace(canonicalValue) {
71
+ mutableBody.client_secret = canonicalValue;
72
+ const rawBody = Reflect.get(ctx.req, 'body');
73
+ if (typeof rawBody === 'object' && rawBody !== null && !Array.isArray(rawBody)) {
74
+ Reflect.set(rawBody, 'client_secret', canonicalValue);
75
+ }
76
+ },
77
+ };
78
+ }
79
+ /** Return one supported credential source and reject ambiguous dual-mechanism input. */
80
+ function presentedCredential(ctx) {
81
+ const basic = basicCredential(ctx);
82
+ const post = postCredential(ctx);
83
+ if (basic !== undefined && post !== undefined)
84
+ return undefined;
85
+ return basic ?? post;
86
+ }
87
+ /** Return the resolved tenant identifier without trusting request-controlled text. */
88
+ function organizationId(ctx) {
89
+ const organization = ctx.state?.organization;
90
+ if (typeof organization !== 'object' || organization === null || Array.isArray(organization)) {
91
+ return undefined;
92
+ }
93
+ const id = Reflect.get(organization, 'id');
94
+ return typeof id === 'string' && id.length > 0 ? id : undefined;
95
+ }
96
+ /** Emit the existing fixed token rate-limit response without credential detail. */
97
+ function denyProtectedWork(ctx, retryAfter) {
98
+ ctx.status = 429;
99
+ ctx.set('Retry-After', String(retryAfter));
100
+ ctx.body = {
101
+ error: 'rate_limit_exceeded',
102
+ error_description: 'Too many token requests. Please try again later.',
103
+ retry_after: retryAfter,
104
+ };
105
+ }
106
+ /** Rewrite a proven credential and continue to oidc-provider. */
107
+ async function handOffValidatedCredential(credential, canonicalValue, options, next) {
108
+ credential.replace(canonicalValue);
109
+ await options.afterCredentialValidation?.();
110
+ await next();
29
111
  }
30
112
  /**
31
- * Create middleware that pre-hashes client secrets with SHA-256.
113
+ * Create the bounded active-secret bridge mounted immediately before oidc-provider.
32
114
  *
33
- * Must be mounted BEFORE oidc-provider's callback handler on the
34
- * OIDC router. Transparently transforms secrets so oidc-provider
35
- * can compare them against stored SHA-256 hashes.
36
- *
37
- * @returns Koa middleware function
115
+ * @param options - Optional credential-free validation/handoff test hook
116
+ * @returns Koa middleware
38
117
  */
39
- export function clientSecretHash() {
118
+ export function clientSecretHash(options = {}) {
40
119
  return async (ctx, next) => {
41
- // Handle client_secret_basic: Authorization: Basic base64(client_id:secret)
42
- const authHeader = ctx.headers.authorization;
43
- if (authHeader && authHeader.startsWith('Basic ')) {
120
+ const credential = presentedCredential(ctx);
121
+ const tenantId = organizationId(ctx);
122
+ if (credential === undefined || tenantId === undefined)
123
+ return next();
124
+ try {
125
+ const client = await getClientByClientId(credential.clientId);
126
+ if (client === null ||
127
+ client.organizationId !== tenantId ||
128
+ client.clientType !== 'confidential' ||
129
+ client.status !== 'active' ||
130
+ client.tokenEndpointAuthMethod !== credential.method) {
131
+ return next();
132
+ }
133
+ const canonicalValue = await getLatestActiveSha256(client.id);
134
+ if (canonicalValue === null)
135
+ return next();
136
+ const presentedSha256 = clientCrypto.sha256Secret(credential.plaintext);
137
+ const modernMatchId = await findActiveSecretIdBySha256(client.id, presentedSha256);
138
+ if (modernMatchId !== null) {
139
+ return handOffValidatedCredential(credential, canonicalValue, options, next);
140
+ }
141
+ const legacySecrets = await getActiveLegacySecretHashes(client.id);
142
+ if (legacySecrets.length === 0 || legacySecrets.length > 10)
143
+ return next();
144
+ if (legacyBatchActive) {
145
+ denyProtectedWork(ctx, BUSY_RETRY_SECONDS);
146
+ return;
147
+ }
148
+ legacyBatchActive = true;
149
+ let legacyMatched = false;
44
150
  try {
45
- const encoded = authHeader.slice(6); // strip 'Basic '
46
- const decoded = Buffer.from(encoded, 'base64').toString('utf8');
47
- const colonIndex = decoded.indexOf(':');
48
- if (colonIndex !== -1) {
49
- const clientId = decoded.slice(0, colonIndex);
50
- const secret = decoded.slice(colonIndex + 1);
51
- if (secret.length > 0) {
52
- // Hash the secret and re-encode the Basic auth header
53
- const hashedSecret = sha256(secret);
54
- const newEncoded = Buffer.from(`${clientId}:${hashedSecret}`).toString('base64');
55
- ctx.headers.authorization = `Basic ${newEncoded}`;
56
- // Also update the raw request header for oidc-provider
57
- ctx.req.headers.authorization = `Basic ${newEncoded}`;
151
+ const limit = await checkRateLimitStrict(`ratelimit:client-secret-legacy:${tenantId}:${client.id}`, TOKEN_RATE_LIMIT);
152
+ if (!limit.allowed) {
153
+ denyProtectedWork(ctx, limit.retryAfter);
154
+ return;
155
+ }
156
+ for (const legacy of legacySecrets) {
157
+ if (await clientCrypto.verifySecretHash(legacy.hash, credential.plaintext)) {
158
+ legacyMatched = true;
159
+ break;
58
160
  }
59
161
  }
60
162
  }
61
- catch {
62
- // Malformed Basic auth — let oidc-provider handle the error
163
+ finally {
164
+ legacyBatchActive = false;
165
+ }
166
+ if (legacyMatched) {
167
+ return handOffValidatedCredential(credential, canonicalValue, options, next);
63
168
  }
64
169
  }
65
- // Handle client_secret_post: client_secret in POST body
66
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
- const body = ctx.request.body;
68
- if (body && typeof body.client_secret === 'string' && body.client_secret.length > 0) {
69
- body.client_secret = sha256(body.client_secret);
170
+ catch {
171
+ // Fail closed by leaving the credential untouched for the provider's minimal rejection.
70
172
  }
71
- await next();
173
+ return next();
72
174
  };
73
175
  }
74
176
  //# sourceMappingURL=client-secret-hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-secret-hash.js","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;GAEG;AACH,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,4EAA4E;QAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QAC7C,IAAI,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;gBACtD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAChE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAExC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;oBACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;oBAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;oBAE7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACtB,sDAAsD;wBACtD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;wBACpC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBACjF,GAAG,CAAC,OAAO,CAAC,aAAa,GAAG,SAAS,UAAU,EAAE,CAAC;wBAClD,uDAAuD;wBACvD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,GAAG,SAAS,UAAU,EAAE,CAAC;oBACxD,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,4DAA4D;YAC9D,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,8DAA8D;QAC9D,MAAM,IAAI,GAAI,GAAG,CAAC,OAAe,CAAC,IAAI,CAAC;QACvC,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpF,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"client-secret-hash.js","sourceRoot":"","sources":["../../src/middleware/client-secret-hash.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAIlE,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAgB9B,qFAAqF;AACrF,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,4EAA4E;AAC5E,SAAS,WAAW,CAAC,GAA8B;IACjD,MAAM,IAAI,GAAY,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;IACvC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,0FAA0F;AAC1F,SAAS,eAAe,CAAC,GAA8B;IACrD,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;IAChD,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IACzF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAC/C,IACE,SAAS,GAAG,CAAC;YACb,QAAQ,CAAC,MAAM,GAAG,oBAAoB;YACtC,SAAS,CAAC,MAAM,GAAG,CAAC;YACpB,SAAS,CAAC,MAAM,GAAG,iBAAiB,EACpC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO;YACL,QAAQ;YACR,SAAS;YACT,MAAM,EAAE,qBAAqB;YAC7B,OAAO,CAAC,cAAc;gBACpB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAChF,GAAG,CAAC,OAAO,CAAC,aAAa,GAAG,SAAS,OAAO,EAAE,CAAC;gBAC/C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,GAAG,SAAS,OAAO,EAAE,CAAC;YACrD,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,SAAS,cAAc,CAAC,GAA8B;IACpD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,EAAE,SAAS,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,EAAE,aAAa,CAAC;IACtC,IACE,IAAI,KAAK,SAAS;QAClB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,CAAC,MAAM,GAAG,CAAC;QACnB,QAAQ,CAAC,MAAM,GAAG,oBAAoB;QACtC,OAAO,SAAS,KAAK,QAAQ;QAC7B,SAAS,CAAC,MAAM,GAAG,CAAC;QACpB,SAAS,CAAC,MAAM,GAAG,iBAAiB,EACpC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC;IACzB,OAAO;QACL,QAAQ;QACR,SAAS;QACT,MAAM,EAAE,oBAAoB;QAC5B,OAAO,CAAC,cAAc;YACpB,WAAW,CAAC,aAAa,GAAG,cAAc,CAAC;YAC3C,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,SAAS,mBAAmB,CAAC,GAA8B;IACzD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED,sFAAsF;AACtF,SAAS,cAAc,CAAC,GAA8B;IACpD,MAAM,YAAY,GAAY,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC;IACtD,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7F,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,GAAY,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC;AAED,mFAAmF;AACnF,SAAS,iBAAiB,CAAC,GAA8B,EAAE,UAAkB;IAC3E,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;IACjB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3C,GAAG,CAAC,IAAI,GAAG;QACT,KAAK,EAAE,qBAAqB;QAC5B,iBAAiB,EAAE,kDAAkD;QACrE,WAAW,EAAE,UAAU;KACxB,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,KAAK,UAAU,0BAA0B,CACvC,UAA+B,EAC/B,cAAsB,EACtB,OAAkC,EAClC,IAA+B;IAE/B,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,MAAM,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC;IAC5C,MAAM,IAAI,EAAE,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAA8B,EAAE;IACtE,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,IAAI,EAAE,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC9D,IACE,MAAM,KAAK,IAAI;gBACf,MAAM,CAAC,cAAc,KAAK,QAAQ;gBAClC,MAAM,CAAC,UAAU,KAAK,cAAc;gBACpC,MAAM,CAAC,MAAM,KAAK,QAAQ;gBAC1B,MAAM,CAAC,uBAAuB,KAAK,UAAU,CAAC,MAAM,EACpD,CAAC;gBACD,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9D,IAAI,cAAc,KAAK,IAAI;gBAAE,OAAO,IAAI,EAAE,CAAC;YAE3C,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACxE,MAAM,aAAa,GAAG,MAAM,0BAA0B,CAAC,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YACnF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,0BAA0B,CAC/B,UAAU,EACV,cAAc,EACd,OAAO,EACP,IAAI,CACL,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,2BAA2B,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,EAAE;gBAAE,OAAO,IAAI,EAAE,CAAC;YAC3E,IAAI,iBAAiB,EAAE,CAAC;gBACtB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,iBAAiB,GAAG,IAAI,CAAC;YACzB,IAAI,aAAa,GAAG,KAAK,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CACtC,kCAAkC,QAAQ,IAAI,MAAM,CAAC,EAAE,EAAE,EACzD,gBAAgB,CACjB,CAAC;gBACF,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnB,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;oBACzC,OAAO;gBACT,CAAC;gBAED,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;oBACnC,IAAI,MAAM,YAAY,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC3E,aAAa,GAAG,IAAI,CAAC;wBACrB,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,iBAAiB,GAAG,KAAK,CAAC;YAC5B,CAAC;YACD,IAAI,aAAa,EAAE,CAAC;gBAClB,OAAO,0BAA0B,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wFAAwF;QAC1F,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}