@portaidentity/server 1.7.3 → 1.9.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 (494) hide show
  1. package/CHANGELOG.md +28 -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/auth/token-repository.d.ts +9 -3
  44. package/dist/auth/token-repository.d.ts.map +1 -1
  45. package/dist/auth/token-repository.js +17 -8
  46. package/dist/auth/token-repository.js.map +1 -1
  47. package/dist/cli/commands/init.d.ts +1 -1
  48. package/dist/cli/commands/init.d.ts.map +1 -1
  49. package/dist/cli/commands/init.js +12 -12
  50. package/dist/cli/commands/init.js.map +1 -1
  51. package/dist/cli/error-handler.d.ts +3 -2
  52. package/dist/cli/error-handler.d.ts.map +1 -1
  53. package/dist/cli/error-handler.js +9 -2
  54. package/dist/cli/error-handler.js.map +1 -1
  55. package/dist/cli/index.d.ts +1 -1
  56. package/dist/cli/index.d.ts.map +1 -1
  57. package/dist/cli/index.js +1 -1
  58. package/dist/cli/index.js.map +1 -1
  59. package/dist/clients/index.d.ts +1 -1
  60. package/dist/clients/index.js +1 -1
  61. package/dist/clients/repository.d.ts +24 -0
  62. package/dist/clients/repository.d.ts.map +1 -1
  63. package/dist/clients/repository.js +39 -0
  64. package/dist/clients/repository.js.map +1 -1
  65. package/dist/clients/secret-repository.d.ts +35 -8
  66. package/dist/clients/secret-repository.d.ts.map +1 -1
  67. package/dist/clients/secret-repository.js +69 -16
  68. package/dist/clients/secret-repository.js.map +1 -1
  69. package/dist/clients/secret-service.d.ts +5 -9
  70. package/dist/clients/secret-service.d.ts.map +1 -1
  71. package/dist/clients/secret-service.js +13 -22
  72. package/dist/clients/secret-service.js.map +1 -1
  73. package/dist/clients/service.d.ts +10 -13
  74. package/dist/clients/service.d.ts.map +1 -1
  75. package/dist/clients/service.js +121 -42
  76. package/dist/clients/service.js.map +1 -1
  77. package/dist/clients/types.d.ts +14 -1
  78. package/dist/clients/types.d.ts.map +1 -1
  79. package/dist/clients/types.js +1 -0
  80. package/dist/clients/types.js.map +1 -1
  81. package/dist/clients/validators.d.ts +83 -1
  82. package/dist/clients/validators.d.ts.map +1 -1
  83. package/dist/clients/validators.js +110 -0
  84. package/dist/clients/validators.js.map +1 -1
  85. package/dist/config/index.d.ts +1 -0
  86. package/dist/config/index.d.ts.map +1 -1
  87. package/dist/config/index.js +1 -0
  88. package/dist/config/index.js.map +1 -1
  89. package/dist/config/schema.d.ts +1 -0
  90. package/dist/config/schema.d.ts.map +1 -1
  91. package/dist/config/schema.js +23 -1
  92. package/dist/config/schema.js.map +1 -1
  93. package/dist/custom-claims/repository.d.ts +14 -9
  94. package/dist/custom-claims/repository.d.ts.map +1 -1
  95. package/dist/custom-claims/repository.js +38 -11
  96. package/dist/custom-claims/repository.js.map +1 -1
  97. package/dist/custom-claims/service.d.ts +11 -6
  98. package/dist/custom-claims/service.d.ts.map +1 -1
  99. package/dist/custom-claims/service.js +43 -20
  100. package/dist/custom-claims/service.js.map +1 -1
  101. package/dist/index.js +8 -2
  102. package/dist/index.js.map +1 -1
  103. package/dist/lib/admin-permissions.d.ts +12 -7
  104. package/dist/lib/admin-permissions.d.ts.map +1 -1
  105. package/dist/lib/admin-permissions.js +26 -16
  106. package/dist/lib/admin-permissions.js.map +1 -1
  107. package/dist/lib/audit-log.d.ts +2 -2
  108. package/dist/lib/audit-log.d.ts.map +1 -1
  109. package/dist/lib/audit-log.js +1 -1
  110. package/dist/lib/audit-log.js.map +1 -1
  111. package/dist/lib/authority-revocation.d.ts +18 -0
  112. package/dist/lib/authority-revocation.d.ts.map +1 -0
  113. package/dist/lib/authority-revocation.js +37 -0
  114. package/dist/lib/authority-revocation.js.map +1 -0
  115. package/dist/lib/branding-assets.d.ts +35 -5
  116. package/dist/lib/branding-assets.d.ts.map +1 -1
  117. package/dist/lib/branding-assets.js +33 -26
  118. package/dist/lib/branding-assets.js.map +1 -1
  119. package/dist/lib/bulk-operations.d.ts +1 -1
  120. package/dist/lib/bulk-operations.d.ts.map +1 -1
  121. package/dist/lib/bulk-operations.js +1 -13
  122. package/dist/lib/bulk-operations.js.map +1 -1
  123. package/dist/lib/cursor.d.ts +2 -0
  124. package/dist/lib/cursor.d.ts.map +1 -1
  125. package/dist/lib/cursor.js +2 -7
  126. package/dist/lib/cursor.js.map +1 -1
  127. package/dist/lib/database.d.ts.map +1 -1
  128. package/dist/lib/database.js +5 -0
  129. package/dist/lib/database.js.map +1 -1
  130. package/dist/lib/deletion-cleanup.d.ts +43 -0
  131. package/dist/lib/deletion-cleanup.d.ts.map +1 -0
  132. package/dist/lib/deletion-cleanup.js +207 -0
  133. package/dist/lib/deletion-cleanup.js.map +1 -0
  134. package/dist/lib/image-validator.d.ts +3 -1
  135. package/dist/lib/image-validator.d.ts.map +1 -1
  136. package/dist/lib/image-validator.js +32 -19
  137. package/dist/lib/image-validator.js.map +1 -1
  138. package/dist/lib/log-format.d.ts +20 -0
  139. package/dist/lib/log-format.d.ts.map +1 -0
  140. package/dist/lib/log-format.js +22 -0
  141. package/dist/lib/log-format.js.map +1 -0
  142. package/dist/lib/logger.d.ts +3 -1
  143. package/dist/lib/logger.d.ts.map +1 -1
  144. package/dist/lib/logger.js +21 -4
  145. package/dist/lib/logger.js.map +1 -1
  146. package/dist/lib/redis.d.ts.map +1 -1
  147. package/dist/lib/redis.js +3 -0
  148. package/dist/lib/redis.js.map +1 -1
  149. package/dist/lib/session-tracking.d.ts +73 -11
  150. package/dist/lib/session-tracking.d.ts.map +1 -1
  151. package/dist/lib/session-tracking.js +76 -32
  152. package/dist/lib/session-tracking.js.map +1 -1
  153. package/dist/lib/signing-key-crypto.d.ts.map +1 -1
  154. package/dist/lib/signing-key-crypto.js +4 -5
  155. package/dist/lib/signing-key-crypto.js.map +1 -1
  156. package/dist/lib/signing-keys.d.ts +3 -4
  157. package/dist/lib/signing-keys.d.ts.map +1 -1
  158. package/dist/lib/signing-keys.js +66 -41
  159. package/dist/lib/signing-keys.js.map +1 -1
  160. package/dist/lib/super-admin-protection.d.ts +5 -5
  161. package/dist/lib/super-admin-protection.d.ts.map +1 -1
  162. package/dist/lib/super-admin-protection.js +6 -9
  163. package/dist/lib/super-admin-protection.js.map +1 -1
  164. package/dist/lib/system-config-catalog.d.ts +268 -0
  165. package/dist/lib/system-config-catalog.d.ts.map +1 -0
  166. package/dist/lib/system-config-catalog.js +90 -0
  167. package/dist/lib/system-config-catalog.js.map +1 -0
  168. package/dist/lib/system-config.d.ts +30 -33
  169. package/dist/lib/system-config.d.ts.map +1 -1
  170. package/dist/lib/system-config.js +78 -93
  171. package/dist/lib/system-config.js.map +1 -1
  172. package/dist/lib/with-timeout.d.ts +32 -0
  173. package/dist/lib/with-timeout.d.ts.map +1 -0
  174. package/dist/lib/with-timeout.js +45 -0
  175. package/dist/lib/with-timeout.js.map +1 -0
  176. package/dist/middleware/admin-auth.d.ts +6 -5
  177. package/dist/middleware/admin-auth.d.ts.map +1 -1
  178. package/dist/middleware/admin-auth.js +30 -20
  179. package/dist/middleware/admin-auth.js.map +1 -1
  180. package/dist/middleware/admin-cors.d.ts +3 -3
  181. package/dist/middleware/admin-cors.js +3 -3
  182. package/dist/middleware/admin-mutation-audit.d.ts +3 -2
  183. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
  184. package/dist/middleware/admin-mutation-audit.js +12 -5
  185. package/dist/middleware/admin-mutation-audit.js.map +1 -1
  186. package/dist/middleware/admin-rate-limiter.d.ts +7 -8
  187. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
  188. package/dist/middleware/admin-rate-limiter.js +7 -8
  189. package/dist/middleware/admin-rate-limiter.js.map +1 -1
  190. package/dist/middleware/client-secret-hash.d.ts +10 -29
  191. package/dist/middleware/client-secret-hash.d.ts.map +1 -1
  192. package/dist/middleware/client-secret-hash.js +161 -59
  193. package/dist/middleware/client-secret-hash.js.map +1 -1
  194. package/dist/middleware/health.d.ts +17 -0
  195. package/dist/middleware/health.d.ts.map +1 -1
  196. package/dist/middleware/health.js +25 -21
  197. package/dist/middleware/health.js.map +1 -1
  198. package/dist/middleware/ready.d.ts.map +1 -1
  199. package/dist/middleware/ready.js +1 -12
  200. package/dist/middleware/ready.js.map +1 -1
  201. package/dist/middleware/require-existing-organization.d.ts +18 -0
  202. package/dist/middleware/require-existing-organization.d.ts.map +1 -0
  203. package/dist/middleware/require-existing-organization.js +38 -0
  204. package/dist/middleware/require-existing-organization.js.map +1 -0
  205. package/dist/middleware/require-permission.d.ts.map +1 -1
  206. package/dist/middleware/require-permission.js +35 -1
  207. package/dist/middleware/require-permission.js.map +1 -1
  208. package/dist/middleware/require-user-organization.d.ts.map +1 -1
  209. package/dist/middleware/require-user-organization.js +4 -2
  210. package/dist/middleware/require-user-organization.js.map +1 -1
  211. package/dist/middleware/security-headers.d.ts +18 -0
  212. package/dist/middleware/security-headers.d.ts.map +1 -1
  213. package/dist/middleware/security-headers.js +32 -1
  214. package/dist/middleware/security-headers.js.map +1 -1
  215. package/dist/middleware/tenant-resolver.d.ts +1 -2
  216. package/dist/middleware/tenant-resolver.d.ts.map +1 -1
  217. package/dist/middleware/tenant-resolver.js +1 -5
  218. package/dist/middleware/tenant-resolver.js.map +1 -1
  219. package/dist/middleware/token-rate-limiter.d.ts +37 -16
  220. package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
  221. package/dist/middleware/token-rate-limiter.js +126 -54
  222. package/dist/middleware/token-rate-limiter.js.map +1 -1
  223. package/dist/oidc/account-finder.d.ts +5 -5
  224. package/dist/oidc/account-finder.d.ts.map +1 -1
  225. package/dist/oidc/account-finder.js +31 -23
  226. package/dist/oidc/account-finder.js.map +1 -1
  227. package/dist/oidc/adapter-factory.d.ts.map +1 -1
  228. package/dist/oidc/adapter-factory.js +83 -3
  229. package/dist/oidc/adapter-factory.js.map +1 -1
  230. package/dist/oidc/configuration.d.ts +3 -8
  231. package/dist/oidc/configuration.d.ts.map +1 -1
  232. package/dist/oidc/configuration.js +67 -50
  233. package/dist/oidc/configuration.js.map +1 -1
  234. package/dist/oidc/provider.d.ts.map +1 -1
  235. package/dist/oidc/provider.js +7 -0
  236. package/dist/oidc/provider.js.map +1 -1
  237. package/dist/oidc/redis-adapter.d.ts +2 -3
  238. package/dist/oidc/redis-adapter.d.ts.map +1 -1
  239. package/dist/oidc/redis-adapter.js +54 -46
  240. package/dist/oidc/redis-adapter.js.map +1 -1
  241. package/dist/organizations/branding-url.d.ts +17 -0
  242. package/dist/organizations/branding-url.d.ts.map +1 -0
  243. package/dist/organizations/branding-url.js +38 -0
  244. package/dist/organizations/branding-url.js.map +1 -0
  245. package/dist/organizations/index.d.ts +2 -2
  246. package/dist/organizations/index.d.ts.map +1 -1
  247. package/dist/organizations/index.js +1 -1
  248. package/dist/organizations/index.js.map +1 -1
  249. package/dist/organizations/repository.d.ts +22 -32
  250. package/dist/organizations/repository.d.ts.map +1 -1
  251. package/dist/organizations/repository.js +64 -45
  252. package/dist/organizations/repository.js.map +1 -1
  253. package/dist/organizations/service.d.ts +14 -46
  254. package/dist/organizations/service.d.ts.map +1 -1
  255. package/dist/organizations/service.js +60 -112
  256. package/dist/organizations/service.js.map +1 -1
  257. package/dist/organizations/types.d.ts +1 -15
  258. package/dist/organizations/types.d.ts.map +1 -1
  259. package/dist/organizations/validators.d.ts +41 -0
  260. package/dist/organizations/validators.d.ts.map +1 -0
  261. package/dist/organizations/validators.js +48 -0
  262. package/dist/organizations/validators.js.map +1 -0
  263. package/dist/portability/apply.d.ts +15 -0
  264. package/dist/portability/apply.d.ts.map +1 -0
  265. package/dist/portability/apply.js +274 -0
  266. package/dist/portability/apply.js.map +1 -0
  267. package/dist/portability/authorization.d.ts +30 -0
  268. package/dist/portability/authorization.d.ts.map +1 -0
  269. package/dist/portability/authorization.js +130 -0
  270. package/dist/portability/authorization.js.map +1 -0
  271. package/dist/portability/cleanup.d.ts +29 -0
  272. package/dist/portability/cleanup.d.ts.map +1 -0
  273. package/dist/portability/cleanup.js +167 -0
  274. package/dist/portability/cleanup.js.map +1 -0
  275. package/dist/portability/export.d.ts +18 -0
  276. package/dist/portability/export.d.ts.map +1 -0
  277. package/dist/portability/export.js +125 -0
  278. package/dist/portability/export.js.map +1 -0
  279. package/dist/portability/import-repository.d.ts +204 -0
  280. package/dist/portability/import-repository.d.ts.map +1 -0
  281. package/dist/portability/import-repository.js +348 -0
  282. package/dist/portability/import-repository.js.map +1 -0
  283. package/dist/portability/import-user-client-writers.d.ts +40 -0
  284. package/dist/portability/import-user-client-writers.d.ts.map +1 -0
  285. package/dist/portability/import-user-client-writers.js +171 -0
  286. package/dist/portability/import-user-client-writers.js.map +1 -0
  287. package/dist/portability/index.d.ts +8 -0
  288. package/dist/portability/index.d.ts.map +1 -0
  289. package/dist/portability/index.js +8 -0
  290. package/dist/portability/index.js.map +1 -0
  291. package/dist/portability/plan-support.d.ts +137 -0
  292. package/dist/portability/plan-support.d.ts.map +1 -0
  293. package/dist/portability/plan-support.js +337 -0
  294. package/dist/portability/plan-support.js.map +1 -0
  295. package/dist/portability/plan.d.ts +34 -0
  296. package/dist/portability/plan.d.ts.map +1 -0
  297. package/dist/portability/plan.js +450 -0
  298. package/dist/portability/plan.js.map +1 -0
  299. package/dist/portability/repository.d.ts +95 -0
  300. package/dist/portability/repository.d.ts.map +1 -0
  301. package/dist/portability/repository.js +390 -0
  302. package/dist/portability/repository.js.map +1 -0
  303. package/dist/portability/schema.d.ts +591 -0
  304. package/dist/portability/schema.d.ts.map +1 -0
  305. package/dist/portability/schema.js +459 -0
  306. package/dist/portability/schema.js.map +1 -0
  307. package/dist/portability/types.d.ts +382 -0
  308. package/dist/portability/types.d.ts.map +1 -0
  309. package/dist/portability/types.js +19 -0
  310. package/dist/portability/types.js.map +1 -0
  311. package/dist/rbac/errors.d.ts +4 -0
  312. package/dist/rbac/errors.d.ts.map +1 -1
  313. package/dist/rbac/errors.js +7 -0
  314. package/dist/rbac/errors.js.map +1 -1
  315. package/dist/rbac/index.d.ts +3 -3
  316. package/dist/rbac/index.d.ts.map +1 -1
  317. package/dist/rbac/index.js +3 -3
  318. package/dist/rbac/index.js.map +1 -1
  319. package/dist/rbac/mapping-repository.d.ts +84 -9
  320. package/dist/rbac/mapping-repository.d.ts.map +1 -1
  321. package/dist/rbac/mapping-repository.js +222 -55
  322. package/dist/rbac/mapping-repository.js.map +1 -1
  323. package/dist/rbac/permission-repository.d.ts +36 -19
  324. package/dist/rbac/permission-repository.d.ts.map +1 -1
  325. package/dist/rbac/permission-repository.js +93 -35
  326. package/dist/rbac/permission-repository.js.map +1 -1
  327. package/dist/rbac/permission-service.d.ts +18 -19
  328. package/dist/rbac/permission-service.d.ts.map +1 -1
  329. package/dist/rbac/permission-service.js +100 -57
  330. package/dist/rbac/permission-service.js.map +1 -1
  331. package/dist/rbac/role-repository.d.ts +29 -24
  332. package/dist/rbac/role-repository.d.ts.map +1 -1
  333. package/dist/rbac/role-repository.js +66 -43
  334. package/dist/rbac/role-repository.js.map +1 -1
  335. package/dist/rbac/role-service.d.ts +35 -32
  336. package/dist/rbac/role-service.d.ts.map +1 -1
  337. package/dist/rbac/role-service.js +210 -96
  338. package/dist/rbac/role-service.js.map +1 -1
  339. package/dist/rbac/slugs.d.ts +16 -27
  340. package/dist/rbac/slugs.d.ts.map +1 -1
  341. package/dist/rbac/slugs.js +36 -59
  342. package/dist/rbac/slugs.js.map +1 -1
  343. package/dist/rbac/types.d.ts +2 -4
  344. package/dist/rbac/types.d.ts.map +1 -1
  345. package/dist/rbac/types.js.map +1 -1
  346. package/dist/rbac/user-role-service.d.ts +23 -24
  347. package/dist/rbac/user-role-service.d.ts.map +1 -1
  348. package/dist/rbac/user-role-service.js +117 -61
  349. package/dist/rbac/user-role-service.js.map +1 -1
  350. package/dist/routes/applications.d.ts +4 -2
  351. package/dist/routes/applications.d.ts.map +1 -1
  352. package/dist/routes/applications.js +57 -19
  353. package/dist/routes/applications.js.map +1 -1
  354. package/dist/routes/audit.js +1 -1
  355. package/dist/routes/audit.js.map +1 -1
  356. package/dist/routes/branding.d.ts +3 -3
  357. package/dist/routes/branding.d.ts.map +1 -1
  358. package/dist/routes/branding.js +44 -16
  359. package/dist/routes/branding.js.map +1 -1
  360. package/dist/routes/bulk.d.ts +0 -5
  361. package/dist/routes/bulk.d.ts.map +1 -1
  362. package/dist/routes/bulk.js +3 -5
  363. package/dist/routes/bulk.js.map +1 -1
  364. package/dist/routes/clients.d.ts +4 -4
  365. package/dist/routes/clients.d.ts.map +1 -1
  366. package/dist/routes/clients.js +113 -52
  367. package/dist/routes/clients.js.map +1 -1
  368. package/dist/routes/config.d.ts +17 -12
  369. package/dist/routes/config.d.ts.map +1 -1
  370. package/dist/routes/config.js +165 -64
  371. package/dist/routes/config.js.map +1 -1
  372. package/dist/routes/custom-claims.d.ts.map +1 -1
  373. package/dist/routes/custom-claims.js +8 -2
  374. package/dist/routes/custom-claims.js.map +1 -1
  375. package/dist/routes/exports.d.ts +2 -1
  376. package/dist/routes/exports.d.ts.map +1 -1
  377. package/dist/routes/exports.js +57 -1
  378. package/dist/routes/exports.js.map +1 -1
  379. package/dist/routes/imports.d.ts +2 -2
  380. package/dist/routes/imports.d.ts.map +1 -1
  381. package/dist/routes/imports.js +95 -40
  382. package/dist/routes/imports.js.map +1 -1
  383. package/dist/routes/interactions.d.ts.map +1 -1
  384. package/dist/routes/interactions.js +113 -87
  385. package/dist/routes/interactions.js.map +1 -1
  386. package/dist/routes/invitation.d.ts.map +1 -1
  387. package/dist/routes/invitation.js +28 -27
  388. package/dist/routes/invitation.js.map +1 -1
  389. package/dist/routes/keys.d.ts.map +1 -1
  390. package/dist/routes/keys.js +26 -13
  391. package/dist/routes/keys.js.map +1 -1
  392. package/dist/routes/magic-link.d.ts.map +1 -1
  393. package/dist/routes/magic-link.js +5 -17
  394. package/dist/routes/magic-link.js.map +1 -1
  395. package/dist/routes/organizations.d.ts +1 -2
  396. package/dist/routes/organizations.d.ts.map +1 -1
  397. package/dist/routes/organizations.js +43 -104
  398. package/dist/routes/organizations.js.map +1 -1
  399. package/dist/routes/password-reset.d.ts.map +1 -1
  400. package/dist/routes/password-reset.js +13 -35
  401. package/dist/routes/password-reset.js.map +1 -1
  402. package/dist/routes/permissions.d.ts +1 -1
  403. package/dist/routes/permissions.d.ts.map +1 -1
  404. package/dist/routes/permissions.js +58 -17
  405. package/dist/routes/permissions.js.map +1 -1
  406. package/dist/routes/public-branding.d.ts +16 -0
  407. package/dist/routes/public-branding.d.ts.map +1 -0
  408. package/dist/routes/public-branding.js +52 -0
  409. package/dist/routes/public-branding.js.map +1 -0
  410. package/dist/routes/roles.d.ts +1 -1
  411. package/dist/routes/roles.d.ts.map +1 -1
  412. package/dist/routes/roles.js +63 -21
  413. package/dist/routes/roles.js.map +1 -1
  414. package/dist/routes/sessions.d.ts.map +1 -1
  415. package/dist/routes/sessions.js +23 -12
  416. package/dist/routes/sessions.js.map +1 -1
  417. package/dist/routes/two-factor.d.ts.map +1 -1
  418. package/dist/routes/two-factor.js +91 -38
  419. package/dist/routes/two-factor.js.map +1 -1
  420. package/dist/routes/user-roles.d.ts.map +1 -1
  421. package/dist/routes/user-roles.js +56 -9
  422. package/dist/routes/user-roles.js.map +1 -1
  423. package/dist/routes/users.d.ts +4 -8
  424. package/dist/routes/users.d.ts.map +1 -1
  425. package/dist/routes/users.js +108 -265
  426. package/dist/routes/users.js.map +1 -1
  427. package/dist/server.d.ts.map +1 -1
  428. package/dist/server.js +53 -37
  429. package/dist/server.js.map +1 -1
  430. package/dist/two-factor/errors.d.ts +9 -0
  431. package/dist/two-factor/errors.d.ts.map +1 -1
  432. package/dist/two-factor/errors.js +12 -0
  433. package/dist/two-factor/errors.js.map +1 -1
  434. package/dist/two-factor/index.d.ts +5 -4
  435. package/dist/two-factor/index.d.ts.map +1 -1
  436. package/dist/two-factor/index.js +4 -4
  437. package/dist/two-factor/index.js.map +1 -1
  438. package/dist/two-factor/repository.d.ts +17 -6
  439. package/dist/two-factor/repository.d.ts.map +1 -1
  440. package/dist/two-factor/repository.js +37 -9
  441. package/dist/two-factor/repository.js.map +1 -1
  442. package/dist/two-factor/service.d.ts.map +1 -1
  443. package/dist/two-factor/service.js +26 -19
  444. package/dist/two-factor/service.js.map +1 -1
  445. package/dist/two-factor/totp.d.ts +13 -2
  446. package/dist/two-factor/totp.d.ts.map +1 -1
  447. package/dist/two-factor/totp.js +20 -7
  448. package/dist/two-factor/totp.js.map +1 -1
  449. package/dist/two-factor/types.d.ts +3 -0
  450. package/dist/two-factor/types.d.ts.map +1 -1
  451. package/dist/two-factor/types.js +5 -0
  452. package/dist/two-factor/types.js.map +1 -1
  453. package/dist/users/gdpr.d.ts +2 -40
  454. package/dist/users/gdpr.d.ts.map +1 -1
  455. package/dist/users/gdpr.js +3 -110
  456. package/dist/users/gdpr.js.map +1 -1
  457. package/dist/users/index.d.ts +5 -4
  458. package/dist/users/index.d.ts.map +1 -1
  459. package/dist/users/index.js +5 -4
  460. package/dist/users/index.js.map +1 -1
  461. package/dist/users/repository.d.ts +49 -3
  462. package/dist/users/repository.d.ts.map +1 -1
  463. package/dist/users/repository.js +169 -18
  464. package/dist/users/repository.js.map +1 -1
  465. package/dist/users/service.d.ts +19 -51
  466. package/dist/users/service.d.ts.map +1 -1
  467. package/dist/users/service.js +72 -122
  468. package/dist/users/service.js.map +1 -1
  469. package/dist/users/types.d.ts +4 -5
  470. package/dist/users/types.d.ts.map +1 -1
  471. package/dist/users/types.js.map +1 -1
  472. package/dist/users/validators.d.ts +28 -0
  473. package/dist/users/validators.d.ts.map +1 -0
  474. package/dist/users/validators.js +25 -0
  475. package/dist/users/validators.js.map +1 -0
  476. package/locales/default/en/errors.json +2 -1
  477. package/migrations/024_application_client_correction.sql +39 -0
  478. package/migrations/025_record_deletion_lifecycle.sql +26 -0
  479. package/migrations/026_simplify_user_lifecycle.sql +33 -0
  480. package/migrations/027_branding_asset_size_limits.sql +19 -0
  481. package/migrations/028_totp_replay_protection.sql +17 -0
  482. package/migrations/029_public_session_identifiers.sql +16 -0
  483. package/migrations/030_global_configuration_catalog.sql +39 -0
  484. package/migrations/031_monotonic_updated_at.sql +28 -0
  485. package/migrations/032_client_require_consent.sql +15 -0
  486. package/package.json +2 -2
  487. package/dist/lib/data-import-plan.d.ts +0 -50
  488. package/dist/lib/data-import-plan.d.ts.map +0 -1
  489. package/dist/lib/data-import-plan.js +0 -235
  490. package/dist/lib/data-import-plan.js.map +0 -1
  491. package/dist/lib/data-import.d.ts +0 -276
  492. package/dist/lib/data-import.d.ts.map +0 -1
  493. package/dist/lib/data-import.js +0 -1694
  494. package/dist/lib/data-import.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"secret-repository.d.ts","sourceRoot":"","sources":["../../src/clients/secret-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AAOhE,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAWhF;AAMD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASnF;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU7E;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAa9C;AAMD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU3E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAWvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBpF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY1E"}
1
+ {"version":3,"file":"secret-repository.d.ts","sourceRoot":"","sources":["../../src/clients/secret-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AAOhE,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uEAAuE;IACvE,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CA6BhF;AAMD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASnF;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU/F;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAa9C;AAMD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAY7F;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAWvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBpF;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAY9C;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY1E"}
@@ -10,26 +10,45 @@
10
10
  * - Insert hashed secret
11
11
  * - List secrets (metadata only, no hashes)
12
12
  * - Find active secrets with hashes (for verification only)
13
- * - Revoke secrets
13
+ * - Permanently delete secrets
14
14
  * - Update last_used_at timestamp
15
15
  * - Cleanup expired secrets
16
16
  */
17
- import { getPool } from '../lib/database.js';
17
+ import { getPool, runDatabaseTransaction } from '../lib/database.js';
18
+ import { ClientNotFoundError, ClientValidationError } from './errors.js';
18
19
  import { mapRowToClientSecret } from './types.js';
19
20
  /**
20
21
  * Insert a new client secret.
21
22
  *
22
- * Stores the Argon2id hash — never the plaintext.
23
+ * Stores the Argon2id hash — never the plaintext. The client row is locked while
24
+ * counting and inserting so concurrent callers cannot exceed ten active,
25
+ * unexpired secrets.
23
26
  *
24
27
  * @param data - Secret data including the hash
25
28
  * @returns The created secret metadata (without hash)
29
+ * @throws ClientNotFoundError when the client is absent or public
30
+ * @throws ClientValidationError when the client already has ten active secrets
26
31
  */
27
32
  export async function insertSecret(data) {
28
- const pool = getPool();
29
- const result = await pool.query(`INSERT INTO client_secrets (client_id, secret_hash, secret_sha256, label, expires_at)
30
- VALUES ($1, $2, $3, $4, $5)
31
- RETURNING *`, [data.clientId, data.secretHash, data.secretSha256, data.label, data.expiresAt]);
32
- return mapRowToClientSecret(result.rows[0]);
33
+ return runDatabaseTransaction(async () => {
34
+ const db = getPool();
35
+ const parent = await db.query('SELECT id, client_type, status FROM clients WHERE id = $1 FOR UPDATE', [data.clientId]);
36
+ const eligible = parent.rows[0];
37
+ if (eligible === undefined || eligible.client_type !== 'confidential') {
38
+ throw new ClientNotFoundError(data.clientId);
39
+ }
40
+ const active = await db.query(`SELECT COUNT(*)::text AS count FROM client_secrets
41
+ WHERE client_id = $1
42
+ AND status = 'active'
43
+ AND (expires_at IS NULL OR expires_at > NOW())`, [data.clientId]);
44
+ if (Number(active.rows[0]?.count ?? '0') >= 10) {
45
+ throw new ClientValidationError('Client secret active limit reached');
46
+ }
47
+ const result = await db.query(`INSERT INTO client_secrets (client_id, secret_hash, secret_sha256, label, expires_at)
48
+ VALUES ($1, $2, $3, $4, $5)
49
+ RETURNING *`, [data.clientId, data.secretHash, data.secretSha256, data.label, data.expiresAt]);
50
+ return mapRowToClientSecret(result.rows[0]);
51
+ });
33
52
  }
34
53
  // ===========================================================================
35
54
  // Find / List
@@ -48,12 +67,13 @@ export async function listSecretsByClient(clientId) {
48
67
  /**
49
68
  * Find a specific secret by ID.
50
69
  *
70
+ * @param clientId - Authoritative parent client UUID
51
71
  * @param id - Secret UUID
52
72
  * @returns Secret metadata or null
53
73
  */
54
- export async function findSecretById(id) {
74
+ export async function findSecretById(clientId, id) {
55
75
  const pool = getPool();
56
- const result = await pool.query('SELECT * FROM client_secrets WHERE id = $1', [id]);
76
+ const result = await pool.query('SELECT * FROM client_secrets WHERE client_id = $1 AND id = $2', [clientId, id]);
57
77
  if (result.rows.length === 0)
58
78
  return null;
59
79
  return mapRowToClientSecret(result.rows[0]);
@@ -81,16 +101,17 @@ export async function getActiveSecretHashes(clientId) {
81
101
  // Update
82
102
  // ===========================================================================
83
103
  /**
84
- * Revoke a secret (set status = 'revoked').
85
- *
86
- * This is a permanent operation — revoked secrets cannot be reactivated.
104
+ * Permanently delete a secret.
87
105
  *
106
+ * @param clientId - Authoritative parent client UUID
88
107
  * @param id - Secret UUID
89
- * @returns Updated secret metadata, or null if not found
108
+ * @returns Deleted secret metadata, or null if absent or owned by another client
90
109
  */
91
- export async function revokeSecret(id) {
110
+ export async function revokeSecret(clientId, id) {
92
111
  const pool = getPool();
93
- const result = await pool.query(`UPDATE client_secrets SET status = 'revoked' WHERE id = $1 RETURNING *`, [id]);
112
+ const result = await pool.query(`DELETE FROM client_secrets
113
+ WHERE client_id = $1 AND id = $2
114
+ RETURNING *`, [clientId, id]);
94
115
  if (result.rows.length === 0)
95
116
  return null;
96
117
  return mapRowToClientSecret(result.rows[0]);
@@ -149,6 +170,38 @@ export async function getLatestActiveSha256(clientId) {
149
170
  return null;
150
171
  return result.rows[0].secret_sha256;
151
172
  }
173
+ /**
174
+ * Find an active modern secret by its indexed SHA-256 value.
175
+ *
176
+ * @param clientId - Parent client UUID
177
+ * @param secretSha256 - SHA-256 digest of the presented credential
178
+ * @returns Matching secret ID, or null when no active credential matches
179
+ */
180
+ export async function findActiveSecretIdBySha256(clientId, secretSha256) {
181
+ const result = await getPool().query(`SELECT id FROM client_secrets
182
+ WHERE client_id = $1
183
+ AND secret_sha256 = $2
184
+ AND status = 'active'
185
+ AND (expires_at IS NULL OR expires_at > NOW())
186
+ LIMIT 1`, [clientId, secretSha256]);
187
+ return result.rows[0]?.id ?? null;
188
+ }
189
+ /**
190
+ * Load at most eleven active Argon2-only credentials so callers can reject over-limit data.
191
+ *
192
+ * @param clientId - Parent client UUID
193
+ * @returns Active legacy secret identifiers and hashes, newest first
194
+ */
195
+ export async function getActiveLegacySecretHashes(clientId) {
196
+ const result = await getPool().query(`SELECT id, secret_hash FROM client_secrets
197
+ WHERE client_id = $1
198
+ AND secret_sha256 IS NULL
199
+ AND status = 'active'
200
+ AND (expires_at IS NULL OR expires_at > NOW())
201
+ ORDER BY created_at DESC
202
+ LIMIT 11`, [clientId]);
203
+ return result.rows.map((row) => ({ id: row.id, hash: row.secret_hash }));
204
+ }
152
205
  /**
153
206
  * Count active secrets for a client.
154
207
  *
@@ -1 +1 @@
1
- {"version":3,"file":"secret-repository.js","sourceRoot":"","sources":["../../src/clients/secret-repository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secret-repository.js","sourceRoot":"","sources":["../../src/clients/secret-repository.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * Handles the full lifecycle of OIDC client secrets:
5
5
  * - Generate and store new secrets (Argon2id hashed)
6
6
  * - Verify secrets during token endpoint authentication
7
- * - Revoke secrets permanently
7
+ * - Delete secrets permanently
8
8
  * - List secrets (metadata only, never hashes)
9
9
  * - Cleanup expired secrets
10
10
  *
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * This service is consumed by:
19
19
  * - The client service (initial secret on confidential client creation)
20
- * - The API routes (secret rotation, revocation)
20
+ * - The API routes (secret creation and deletion)
21
21
  * - The OIDC token endpoint (secret verification via admin API)
22
22
  */
23
23
  import type { ClientSecret, SecretWithPlaintext, CreateSecretInput } from './types.js';
@@ -55,18 +55,14 @@ export declare function generateAndStore(clientDbId: string, input?: CreateSecre
55
55
  */
56
56
  export declare function verify(clientDbId: string, plaintext: string): Promise<boolean>;
57
57
  /**
58
- * Revoke a client secret permanently.
59
- *
60
- * Revocation is irreversible — once revoked, a secret cannot be
61
- * reactivated. The revoked secret remains in the database for
62
- * audit trail purposes until cleanup removes it.
58
+ * Permanently delete a client secret.
63
59
  *
60
+ * @param clientDbId - Authoritative parent client UUID
64
61
  * @param secretId - Secret UUID
65
62
  * @param actorId - UUID of the user performing the action
66
63
  * @throws ClientNotFoundError if secret not found
67
- * @throws ClientValidationError if secret already revoked
68
64
  */
69
- export declare function revoke(secretId: string, actorId?: string): Promise<void>;
65
+ export declare function revoke(clientDbId: string, secretId: string, actorId?: string): Promise<void>;
70
66
  /**
71
67
  * List all secrets for a client (metadata only, never hashes).
72
68
  *
@@ -1 +1 @@
1
- {"version":3,"file":"secret-service.d.ts","sourceRoot":"","sources":["../../src/clients/secret-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAmBvF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,iBAAsB,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAyC9B;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAyClB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAE9E;AAMD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E"}
1
+ {"version":3,"file":"secret-service.d.ts","sourceRoot":"","sources":["../../src/clients/secret-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAmBvF;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,iBAAsB,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAyC9B;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyCpF;AAMD;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAiBf;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAE9E;AAMD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E"}
@@ -4,7 +4,7 @@
4
4
  * Handles the full lifecycle of OIDC client secrets:
5
5
  * - Generate and store new secrets (Argon2id hashed)
6
6
  * - Verify secrets during token endpoint authentication
7
- * - Revoke secrets permanently
7
+ * - Delete secrets permanently
8
8
  * - List secrets (metadata only, never hashes)
9
9
  * - Cleanup expired secrets
10
10
  *
@@ -17,14 +17,14 @@
17
17
  *
18
18
  * This service is consumed by:
19
19
  * - The client service (initial secret on confidential client creation)
20
- * - The API routes (secret rotation, revocation)
20
+ * - The API routes (secret creation and deletion)
21
21
  * - The OIDC token endpoint (secret verification via admin API)
22
22
  */
23
23
  import { insertSecret, listSecretsByClient, findSecretById, getActiveSecretHashes, revokeSecret as repoRevokeSecret, updateLastUsedAt, cleanupExpiredSecrets, } from './secret-repository.js';
24
24
  import { generateSecret, hashSecret, sha256Secret, verifySecretHash } from './crypto.js';
25
25
  import { writeAuditLog } from '../lib/audit-log.js';
26
26
  import { logger } from '../lib/logger.js';
27
- import { ClientNotFoundError, ClientValidationError } from './errors.js';
27
+ import { ClientNotFoundError } from './errors.js';
28
28
  // ===========================================================================
29
29
  // Secret generation
30
30
  // ===========================================================================
@@ -136,35 +136,26 @@ export async function verify(clientDbId, plaintext) {
136
136
  }
137
137
  }
138
138
  // ===========================================================================
139
- // Secret revocation
139
+ // Secret deletion
140
140
  // ===========================================================================
141
141
  /**
142
- * Revoke a client secret permanently.
143
- *
144
- * Revocation is irreversible — once revoked, a secret cannot be
145
- * reactivated. The revoked secret remains in the database for
146
- * audit trail purposes until cleanup removes it.
142
+ * Permanently delete a client secret.
147
143
  *
144
+ * @param clientDbId - Authoritative parent client UUID
148
145
  * @param secretId - Secret UUID
149
146
  * @param actorId - UUID of the user performing the action
150
147
  * @throws ClientNotFoundError if secret not found
151
- * @throws ClientValidationError if secret already revoked
152
148
  */
153
- export async function revoke(secretId, actorId) {
154
- // Validate secret exists
155
- const secret = await findSecretById(secretId);
156
- if (!secret) {
149
+ export async function revoke(clientDbId, secretId, actorId) {
150
+ const existing = await findSecretById(clientDbId, secretId);
151
+ if (!existing || existing.clientId !== clientDbId)
152
+ throw new ClientNotFoundError(secretId);
153
+ const secret = await repoRevokeSecret(clientDbId, secretId);
154
+ if (!secret)
157
155
  throw new ClientNotFoundError(secretId);
158
- }
159
- // Validate secret is not already revoked
160
- if (secret.status === 'revoked') {
161
- throw new ClientValidationError('Secret is already revoked');
162
- }
163
- // Revoke in database
164
- await repoRevokeSecret(secretId);
165
156
  // Audit log (fire-and-forget)
166
157
  await writeAuditLog({
167
- eventType: 'client.secret.revoked',
158
+ eventType: 'client.secret.deleted',
168
159
  eventCategory: 'admin',
169
160
  actorId,
170
161
  metadata: {
@@ -1 +1 @@
1
- {"version":3,"file":"secret-service.js","sourceRoot":"","sources":["../../src/clients/secret-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secret-service.js","sourceRoot":"","sources":["../../src/clients/secret-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,YAAY,IAAI,gBAAgB,EAChC,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,UAAkB,EAClB,KAAK,GAAsB,EAAE,EAC7B,OAAgB;IAEhB,4BAA4B;IAC5B,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC;IAEnC,+CAA+C;IAC/C,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;IAE/C,0DAA0D;IAC1D,MAAM,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAE7C,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,QAAQ,EAAE,UAAU;QACpB,UAAU;QACV,YAAY;QACZ,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;KACnC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,aAAa,CAAC;QAClB,SAAS,EAAE,yBAAyB;QACpC,aAAa,EAAE,OAAO;QACtB,OAAO;QACP,QAAQ,EAAE;YACR,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,IAAI;SACnD;KACF,CAAC,CAAC;IAEH,+DAA+D;IAC/D,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS;QACT,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,UAAkB,EAAE,SAAiB;IAChE,IAAI,CAAC;QACH,6CAA6C;QAC7C,MAAM,aAAa,GAAG,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAE9D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qEAAqE;QACrE,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAE/D,IAAI,OAAO,EAAE,CAAC;gBACZ,kDAAkD;gBAClD,MAAM,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAElC,qCAAqC;gBACrC,MAAM,aAAa,CAAC;oBAClB,SAAS,EAAE,wBAAwB;oBACnC,aAAa,EAAE,gBAAgB;oBAC/B,QAAQ,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE;iBACxD,CAAC,CAAC;gBAEH,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,MAAM,aAAa,CAAC;YAClB,SAAS,EAAE,sBAAsB;YACjC,aAAa,EAAE,UAAU;YACzB,QAAQ,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,CAAC,MAAM,EAAE;SAC5E,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mEAAmE;QACnE,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,kCAAkC,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,UAAkB,EAClB,QAAgB,EAChB,OAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,UAAU;QAAE,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAErD,8BAA8B;IAC9B,MAAM,aAAa,CAAC;QAClB,SAAS,EAAE,uBAAuB;QAClC,aAAa,EAAE,OAAO;QACtB,OAAO;QACP,QAAQ,EAAE;YACR,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB;KACF,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB;IACnD,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,aAAsB;IACzD,OAAO,qBAAqB,CAAC,aAAa,CAAC,CAAC;AAC9C,CAAC"}
@@ -19,7 +19,7 @@
19
19
  * metadata format, used by the adapter factory during OIDC operations.
20
20
  */
21
21
  import type { Client, ClientWithSecret, CreateClientInput, UpdateClientInput, ListClientsOptions, PaginatedResult } from './types.js';
22
- import type { ListClientsCursorOptions } from './repository.js';
22
+ import type { ClientDeletionCapture, ListClientsCursorOptions } from './repository.js';
23
23
  import type { CursorPaginatedResult } from '../lib/cursor.js';
24
24
  /**
25
25
  * Create a new OIDC client.
@@ -114,18 +114,6 @@ export declare function deactivateClient(id: string, actorId?: string): Promise<
114
114
  * @throws ClientValidationError if not currently inactive
115
115
  */
116
116
  export declare function activateClient(id: string, actorId?: string): Promise<void>;
117
- /**
118
- * Revoke a client (active or inactive → revoked).
119
- *
120
- * Revocation is permanent — revoked clients cannot be reactivated.
121
- * This effectively disables the client for all OIDC operations.
122
- *
123
- * @param id - Client internal UUID
124
- * @param actorId - UUID of the user performing the action
125
- * @throws ClientNotFoundError if not found
126
- * @throws ClientValidationError if already revoked
127
- */
128
- export declare function revokeClient(id: string, actorId?: string): Promise<void>;
129
117
  /**
130
118
  * Find a client by OIDC client_id and return oidc-provider metadata format.
131
119
  *
@@ -155,4 +143,13 @@ export declare function findForOidc(clientId: string): Promise<Record<string, un
155
143
  * @returns true if secret matches any active hash, false otherwise
156
144
  */
157
145
  export declare function verifyClientSecret(clientId: string, plaintext: string): Promise<boolean>;
146
+ /**
147
+ * Physically delete an OIDC client after capturing its protocol authority.
148
+ *
149
+ * @param id - Internal client UUID.
150
+ * @param actorId - Actor identifier available for audit attribution.
151
+ * @returns The graph captured before PostgreSQL applied its cascade.
152
+ * @throws ClientNotFoundError when the client does not exist.
153
+ */
154
+ export declare function deleteClient(id: string, actorId?: string): Promise<ClientDeletionCapture>;
158
155
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/clients/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EAEjB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAUpB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AA4E9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CA2F3B;AAOD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWtE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWlF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CA6EjB;AAOD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,GAClD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,GACjD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAExC;AAgBD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAqBf;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAoD9C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAWlB"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/clients/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EAEjB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAYpB,OAAO,KAAK,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAsG9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAsG3B;AAMD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWtE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWlF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAsGjB;AAMD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,GAClD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,GACjD,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAElC;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAExC;AAgBD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlF;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhF;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CA6DhG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW9F;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsC/F"}
@@ -19,17 +19,20 @@
19
19
  * metadata format, used by the adapter factory during OIDC operations.
20
20
  */
21
21
  import { LOGIN_METHODS } from './types.js';
22
- import { insertClient, findClientById, findClientByClientId, updateClient as repoUpdateClient, listClients as repoListClients, listClientsCursor as repoListClientsCursor, } from './repository.js';
22
+ import { insertClient, findClientById, findClientByClientId, updateClient as repoUpdateClient, listClients as repoListClients, listClientsCursor as repoListClientsCursor, captureClientForDeletion, deleteCapturedClient, } from './repository.js';
23
23
  import { getLatestActiveSha256 } from './secret-repository.js';
24
24
  import { getCachedClientByClientId, getCachedClientById, cacheClient, invalidateClientCache, } from './cache.js';
25
25
  import { generateClientId } from './crypto.js';
26
- import { validateRedirectUris, getDefaultGrantTypes, getDefaultTokenEndpointAuthMethod, getDefaultResponseTypes, getDefaultScope, } from './validators.js';
26
+ import { validateRedirectUris, getDefaultGrantTypes, getDefaultTokenEndpointAuthMethod, getDefaultResponseTypes, getDefaultScope, validateClientProtocolCompatibility, } from './validators.js';
27
27
  import { normalizeLoginMethods } from './resolve-login-methods.js';
28
28
  import { verify } from './secret-service.js';
29
29
  import { writeAuditLog } from '../lib/audit-log.js';
30
30
  import { ClientNotFoundError, ClientValidationError } from './errors.js';
31
31
  import { getApplicationById } from '../applications/service.js';
32
32
  import { getOrganizationById } from '../organizations/service.js';
33
+ import { getDatabaseTransactionClient } from '../lib/database.js';
34
+ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
35
+ import { registerDeletionCleanup } from '../lib/deletion-cleanup.js';
33
36
  // ===========================================================================
34
37
  // Validation helpers (private)
35
38
  // ===========================================================================
@@ -67,6 +70,21 @@ function validateClientLoginMethods(methods) {
67
70
  }
68
71
  return normalizeLoginMethods(methods);
69
72
  }
73
+ /** Validate a complete protocol configuration and map failures to the client domain error. */
74
+ function requireCompatibleProtocol(configuration) {
75
+ if (configuration.tokenEndpointAuthMethod !== 'client_secret_basic' &&
76
+ configuration.tokenEndpointAuthMethod !== 'client_secret_post' &&
77
+ configuration.tokenEndpointAuthMethod !== 'none') {
78
+ throw new ClientValidationError('Unsupported token endpoint authentication method');
79
+ }
80
+ const result = validateClientProtocolCompatibility({
81
+ ...configuration,
82
+ tokenEndpointAuthMethod: configuration.tokenEndpointAuthMethod,
83
+ });
84
+ if (!result.isValid) {
85
+ throw new ClientValidationError(result.errors.join('; '));
86
+ }
87
+ }
70
88
  // ===========================================================================
71
89
  // Client CRUD
72
90
  // ===========================================================================
@@ -119,13 +137,22 @@ export async function createClient(input, actorId) {
119
137
  throw new ClientValidationError(`Invalid redirect URIs: ${uriValidation.errors.join('; ')}`);
120
138
  }
121
139
  // Apply defaults for optional fields
122
- const grantTypes = input.grantTypes ??
123
- getDefaultGrantTypes(input.clientType, input.applicationType);
140
+ const grantTypes = input.grantTypes ?? getDefaultGrantTypes(input.clientType, input.applicationType);
124
141
  const responseTypes = input.responseTypes ?? getDefaultResponseTypes();
125
142
  const scope = input.scope ?? getDefaultScope();
126
- const tokenEndpointAuthMethod = input.tokenEndpointAuthMethod ??
127
- getDefaultTokenEndpointAuthMethod(input.clientType);
143
+ const tokenEndpointAuthMethod = input.tokenEndpointAuthMethod ?? getDefaultTokenEndpointAuthMethod(input.clientType);
128
144
  const requirePkce = input.requirePkce ?? true;
145
+ const requireConsent = input.requireConsent ?? false;
146
+ requireCompatibleProtocol({
147
+ clientType: input.clientType,
148
+ redirectUris: input.redirectUris,
149
+ postLogoutRedirectUris: input.postLogoutRedirectUris ?? [],
150
+ grantTypes,
151
+ responseTypes,
152
+ tokenEndpointAuthMethod,
153
+ requirePkce,
154
+ allowedOrigins: input.allowedOrigins ?? [],
155
+ });
129
156
  // Validate + normalize the login-method override (may throw). Three-state
130
157
  // input: undefined → column omitted → DB DEFAULT NULL → inherit.
131
158
  // null → inherit explicitly. Array → override with validated methods.
@@ -148,6 +175,7 @@ export async function createClient(input, actorId) {
148
175
  tokenEndpointAuthMethod,
149
176
  allowedOrigins: input.allowedOrigins ?? [],
150
177
  requirePkce,
178
+ requireConsent,
151
179
  // Pass through validated value as-is: `undefined` triggers column
152
180
  // omission (DB default), `null` inserts NULL explicitly, array inserts
153
181
  // the validated methods. The repo honors all three states.
@@ -239,6 +267,30 @@ export async function updateClient(id, input, actorId) {
239
267
  throw new ClientValidationError(`Invalid redirect URIs: ${uriValidation.errors.join('; ')}`);
240
268
  }
241
269
  }
270
+ const changesProtocol = [
271
+ input.redirectUris,
272
+ input.postLogoutRedirectUris,
273
+ input.grantTypes,
274
+ input.responseTypes,
275
+ input.tokenEndpointAuthMethod,
276
+ input.allowedOrigins,
277
+ input.requirePkce,
278
+ ].some((value) => value !== undefined);
279
+ if (changesProtocol) {
280
+ const existing = await getClientById(id);
281
+ if (!existing)
282
+ throw new ClientNotFoundError(id);
283
+ requireCompatibleProtocol({
284
+ clientType: existing.clientType,
285
+ redirectUris: input.redirectUris ?? existing.redirectUris,
286
+ postLogoutRedirectUris: input.postLogoutRedirectUris ?? existing.postLogoutRedirectUris,
287
+ grantTypes: input.grantTypes ?? existing.grantTypes,
288
+ responseTypes: input.responseTypes ?? existing.responseTypes,
289
+ tokenEndpointAuthMethod: input.tokenEndpointAuthMethod ?? existing.tokenEndpointAuthMethod,
290
+ requirePkce: input.requirePkce ?? existing.requirePkce,
291
+ allowedOrigins: input.allowedOrigins ?? existing.allowedOrigins,
292
+ });
293
+ }
242
294
  // Build update data from input
243
295
  const updateData = {};
244
296
  if (input.clientName !== undefined)
@@ -259,6 +311,8 @@ export async function updateClient(id, input, actorId) {
259
311
  updateData.allowedOrigins = input.allowedOrigins;
260
312
  if (input.requirePkce !== undefined)
261
313
  updateData.requirePkce = input.requirePkce;
314
+ if (input.requireConsent !== undefined)
315
+ updateData.requireConsent = input.requireConsent;
262
316
  // Validate + normalize the login-method override if the caller passed the
263
317
  // key (including `null` = clear). Capture the previous value first for the
264
318
  // audit log diff — we use the cache-aware accessor so stale reads don't
@@ -401,36 +455,6 @@ export async function activateClient(id, actorId) {
401
455
  metadata: { clientDbId: client.id, clientId: client.clientId },
402
456
  });
403
457
  }
404
- /**
405
- * Revoke a client (active or inactive → revoked).
406
- *
407
- * Revocation is permanent — revoked clients cannot be reactivated.
408
- * This effectively disables the client for all OIDC operations.
409
- *
410
- * @param id - Client internal UUID
411
- * @param actorId - UUID of the user performing the action
412
- * @throws ClientNotFoundError if not found
413
- * @throws ClientValidationError if already revoked
414
- */
415
- export async function revokeClient(id, actorId) {
416
- const client = await loadClientForStatusChange(id);
417
- if (client.status === 'revoked') {
418
- throw new ClientValidationError('Client is already revoked');
419
- }
420
- await repoUpdateClient(id, { status: 'revoked' });
421
- await invalidateClientCache(client.clientId, client.id);
422
- await writeAuditLog({
423
- organizationId: client.organizationId,
424
- eventType: 'client.revoked',
425
- eventCategory: 'admin',
426
- actorId,
427
- metadata: {
428
- clientDbId: client.id,
429
- clientId: client.clientId,
430
- previousStatus: client.status,
431
- },
432
- });
433
- }
434
458
  // ===========================================================================
435
459
  // OIDC integration
436
460
  // ===========================================================================
@@ -448,7 +472,9 @@ export async function revokeClient(id, actorId) {
448
472
  * @returns OIDC client metadata object, or undefined if not found/inactive
449
473
  */
450
474
  export async function findForOidc(clientId) {
451
- const client = await getClientByClientId(clientId);
475
+ // Protocol authority must come from PostgreSQL. Administrative cache reads
476
+ // remain useful elsewhere, but stale metadata cannot authorize an OIDC flow.
477
+ const client = await findClientByClientId(clientId);
452
478
  // Client must exist and be active for OIDC operations
453
479
  if (!client || client.status !== 'active') {
454
480
  return undefined;
@@ -463,9 +489,7 @@ export async function findForOidc(clientId) {
463
489
  grant_types: client.grantTypes,
464
490
  response_types: client.responseTypes,
465
491
  scope: client.scope,
466
- token_endpoint_auth_method: client.clientType === 'public'
467
- ? 'none'
468
- : client.tokenEndpointAuthMethod,
492
+ token_endpoint_auth_method: client.clientType === 'public' ? 'none' : client.tokenEndpointAuthMethod,
469
493
  // Porta uses ES256 signing keys — must declare this explicitly
470
494
  // or oidc-provider defaults to RS256 and rejects the client.
471
495
  id_token_signed_response_alg: 'ES256',
@@ -473,6 +497,9 @@ export async function findForOidc(clientId) {
473
497
  'urn:porta:allowed_origins': client.allowedOrigins,
474
498
  // Client type for internal use
475
499
  'urn:porta:client_type': client.clientType,
500
+ // Public authorization-code clients always require PKCE. Confidential clients preserve the
501
+ // administrator's persisted choice and the provider reads it through registered metadata.
502
+ 'urn:porta:require_pkce': client.requirePkce,
476
503
  // Per-client login-methods override. Null means "inherit org default";
477
504
  // a non-null array is the validated override. The OIDC configuration
478
505
  // layer registers this URN under `extraClientMetadata.properties` so
@@ -480,9 +507,15 @@ export async function findForOidc(clientId) {
480
507
  // the interaction handlers — where `resolveLoginMethodsFromOidcClient()`
481
508
  // combines it with the org default to compute the effective methods.
482
509
  'urn:porta:login_methods': client.loginMethods,
483
- // Organization ID — used by auto-consent logic in showConsent() to
484
- // identify first-party clients (same org → skip consent screen)
510
+ // Internal authority boundary consumed only while building this client's claims.
511
+ // Keeping the value in provider metadata avoids a database lookup on every claim request.
512
+ 'urn:porta:internal_application_id': client.applicationId,
513
+ // Organization ID — the tenant that owns the client.
485
514
  organizationId: client.organizationId,
515
+ // Whether the client must ask the end user for consent. The consent gate
516
+ // in showConsent() renders the consent page when this is true and a
517
+ // requested scope has not already been granted.
518
+ requireConsent: client.requireConsent,
486
519
  };
487
520
  // For confidential clients, include the SHA-256 hash as client_secret.
488
521
  // oidc-provider will compare this against the SHA-256 of the presented
@@ -520,4 +553,50 @@ export async function verifyClientSecret(clientId, plaintext) {
520
553
  // Delegate to secret-service which checks all active, non-expired hashes
521
554
  return verify(client.id, plaintext);
522
555
  }
556
+ /**
557
+ * Physically delete an OIDC client after capturing its protocol authority.
558
+ *
559
+ * @param id - Internal client UUID.
560
+ * @param actorId - Actor identifier available for audit attribution.
561
+ * @returns The graph captured before PostgreSQL applied its cascade.
562
+ * @throws ClientNotFoundError when the client does not exist.
563
+ */
564
+ export async function deleteClient(id, actorId) {
565
+ const transaction = getDatabaseTransactionClient();
566
+ if (!transaction)
567
+ throw new Error('Client deletion requires an active database transaction');
568
+ const capture = await captureClientForDeletion(id);
569
+ if (!capture)
570
+ throw new ClientNotFoundError(id);
571
+ await transaction.query(`DELETE FROM oidc_payloads
572
+ WHERE id = ANY($1::varchar[]) OR grant_id = ANY($1::varchar[])
573
+ OR payload->>'clientId' = ANY($2::text[])`, [capture.grantIds, capture.publicClientIds]);
574
+ await writeAuditLogInTransaction(transaction, {
575
+ organizationId: capture.client.organizationId,
576
+ actorId,
577
+ eventType: 'client.deleted',
578
+ eventCategory: 'admin',
579
+ metadata: {
580
+ clientDbId: capture.client.id,
581
+ clientId: capture.client.clientId,
582
+ applicationId: capture.client.applicationId,
583
+ status: capture.client.status,
584
+ },
585
+ });
586
+ await deleteCapturedClient(id);
587
+ await registerDeletionCleanup({
588
+ resource: 'client',
589
+ targetId: id,
590
+ parentId: capture.client.applicationId,
591
+ userIds: [],
592
+ clientIds: capture.clientIds,
593
+ publicClientIds: capture.publicClientIds,
594
+ grantIds: capture.grantIds,
595
+ roleIds: [],
596
+ permissionIds: [],
597
+ claimIds: [],
598
+ applicationIds: [capture.client.applicationId],
599
+ });
600
+ return capture;
601
+ }
523
602
  //# sourceMappingURL=service.js.map