@portaidentity/server 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (742) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +33 -0
  4. package/dist/applications/cache.d.ts +64 -0
  5. package/dist/applications/cache.d.ts.map +1 -0
  6. package/dist/applications/cache.js +161 -0
  7. package/dist/applications/cache.js.map +1 -0
  8. package/dist/applications/errors.d.ts +25 -0
  9. package/dist/applications/errors.d.ts.map +1 -0
  10. package/dist/applications/errors.js +31 -0
  11. package/dist/applications/errors.js.map +1 -0
  12. package/dist/applications/index.d.ts +17 -0
  13. package/dist/applications/index.d.ts.map +1 -0
  14. package/dist/applications/index.js +19 -0
  15. package/dist/applications/index.js.map +1 -0
  16. package/dist/applications/repository.d.ts +184 -0
  17. package/dist/applications/repository.d.ts.map +1 -0
  18. package/dist/applications/repository.js +367 -0
  19. package/dist/applications/repository.js.map +1 -0
  20. package/dist/applications/service.d.ts +160 -0
  21. package/dist/applications/service.d.ts.map +1 -0
  22. package/dist/applications/service.js +388 -0
  23. package/dist/applications/service.js.map +1 -0
  24. package/dist/applications/slugs.d.ts +61 -0
  25. package/dist/applications/slugs.d.ts.map +1 -0
  26. package/dist/applications/slugs.js +115 -0
  27. package/dist/applications/slugs.js.map +1 -0
  28. package/dist/applications/types.d.ts +129 -0
  29. package/dist/applications/types.d.ts.map +1 -0
  30. package/dist/applications/types.js +62 -0
  31. package/dist/applications/types.js.map +1 -0
  32. package/dist/auth/csrf.d.ts +71 -0
  33. package/dist/auth/csrf.d.ts.map +1 -0
  34. package/dist/auth/csrf.js +112 -0
  35. package/dist/auth/csrf.js.map +1 -0
  36. package/dist/auth/email-renderer.d.ts +37 -0
  37. package/dist/auth/email-renderer.d.ts.map +1 -0
  38. package/dist/auth/email-renderer.js +116 -0
  39. package/dist/auth/email-renderer.js.map +1 -0
  40. package/dist/auth/email-service.d.ts +154 -0
  41. package/dist/auth/email-service.d.ts.map +1 -0
  42. package/dist/auth/email-service.js +415 -0
  43. package/dist/auth/email-service.js.map +1 -0
  44. package/dist/auth/email-transport.d.ts +65 -0
  45. package/dist/auth/email-transport.d.ts.map +1 -0
  46. package/dist/auth/email-transport.js +82 -0
  47. package/dist/auth/email-transport.js.map +1 -0
  48. package/dist/auth/i18n.d.ts +81 -0
  49. package/dist/auth/i18n.d.ts.map +1 -0
  50. package/dist/auth/i18n.js +395 -0
  51. package/dist/auth/i18n.js.map +1 -0
  52. package/dist/auth/index.d.ts +28 -0
  53. package/dist/auth/index.d.ts.map +1 -0
  54. package/dist/auth/index.js +31 -0
  55. package/dist/auth/index.js.map +1 -0
  56. package/dist/auth/interaction-authority.d.ts +39 -0
  57. package/dist/auth/interaction-authority.d.ts.map +1 -0
  58. package/dist/auth/interaction-authority.js +30 -0
  59. package/dist/auth/interaction-authority.js.map +1 -0
  60. package/dist/auth/magic-link-session.d.ts +81 -0
  61. package/dist/auth/magic-link-session.d.ts.map +1 -0
  62. package/dist/auth/magic-link-session.js +183 -0
  63. package/dist/auth/magic-link-session.js.map +1 -0
  64. package/dist/auth/rate-limiter.d.ts +143 -0
  65. package/dist/auth/rate-limiter.d.ts.map +1 -0
  66. package/dist/auth/rate-limiter.js +220 -0
  67. package/dist/auth/rate-limiter.js.map +1 -0
  68. package/dist/auth/recovery-crypto.d.ts +34 -0
  69. package/dist/auth/recovery-crypto.d.ts.map +1 -0
  70. package/dist/auth/recovery-crypto.js +103 -0
  71. package/dist/auth/recovery-crypto.js.map +1 -0
  72. package/dist/auth/recovery-job-processor.d.ts +24 -0
  73. package/dist/auth/recovery-job-processor.d.ts.map +1 -0
  74. package/dist/auth/recovery-job-processor.js +123 -0
  75. package/dist/auth/recovery-job-processor.js.map +1 -0
  76. package/dist/auth/recovery-job-repository.d.ts +219 -0
  77. package/dist/auth/recovery-job-repository.d.ts.map +1 -0
  78. package/dist/auth/recovery-job-repository.js +340 -0
  79. package/dist/auth/recovery-job-repository.js.map +1 -0
  80. package/dist/auth/recovery-service.d.ts +27 -0
  81. package/dist/auth/recovery-service.d.ts.map +1 -0
  82. package/dist/auth/recovery-service.js +53 -0
  83. package/dist/auth/recovery-service.js.map +1 -0
  84. package/dist/auth/recovery-worker.d.ts +158 -0
  85. package/dist/auth/recovery-worker.d.ts.map +1 -0
  86. package/dist/auth/recovery-worker.js +306 -0
  87. package/dist/auth/recovery-worker.js.map +1 -0
  88. package/dist/auth/template-engine.d.ts +134 -0
  89. package/dist/auth/template-engine.d.ts.map +1 -0
  90. package/dist/auth/template-engine.js +225 -0
  91. package/dist/auth/template-engine.js.map +1 -0
  92. package/dist/auth/token-repository.d.ts +238 -0
  93. package/dist/auth/token-repository.d.ts.map +1 -0
  94. package/dist/auth/token-repository.js +475 -0
  95. package/dist/auth/token-repository.js.map +1 -0
  96. package/dist/auth/tokens.d.ts +45 -0
  97. package/dist/auth/tokens.d.ts.map +1 -0
  98. package/dist/auth/tokens.js +51 -0
  99. package/dist/auth/tokens.js.map +1 -0
  100. package/dist/cli/bootstrap.d.ts +55 -0
  101. package/dist/cli/bootstrap.d.ts.map +1 -0
  102. package/dist/cli/bootstrap.js +90 -0
  103. package/dist/cli/bootstrap.js.map +1 -0
  104. package/dist/cli/commands/health.d.ts +20 -0
  105. package/dist/cli/commands/health.d.ts.map +1 -0
  106. package/dist/cli/commands/health.js +80 -0
  107. package/dist/cli/commands/health.js.map +1 -0
  108. package/dist/cli/commands/init.d.ts +48 -0
  109. package/dist/cli/commands/init.d.ts.map +1 -0
  110. package/dist/cli/commands/init.js +349 -0
  111. package/dist/cli/commands/init.js.map +1 -0
  112. package/dist/cli/commands/migrate.d.ts +19 -0
  113. package/dist/cli/commands/migrate.d.ts.map +1 -0
  114. package/dist/cli/commands/migrate.js +88 -0
  115. package/dist/cli/commands/migrate.js.map +1 -0
  116. package/dist/cli/commands/seed.d.ts +19 -0
  117. package/dist/cli/commands/seed.d.ts.map +1 -0
  118. package/dist/cli/commands/seed.js +71 -0
  119. package/dist/cli/commands/seed.js.map +1 -0
  120. package/dist/cli/commands/user-2fa.d.ts +29 -0
  121. package/dist/cli/commands/user-2fa.d.ts.map +1 -0
  122. package/dist/cli/commands/user-2fa.js +113 -0
  123. package/dist/cli/commands/user-2fa.js.map +1 -0
  124. package/dist/cli/error-handler.d.ts +31 -0
  125. package/dist/cli/error-handler.d.ts.map +1 -0
  126. package/dist/cli/error-handler.js +65 -0
  127. package/dist/cli/error-handler.js.map +1 -0
  128. package/dist/cli/index.d.ts +48 -0
  129. package/dist/cli/index.d.ts.map +1 -0
  130. package/dist/cli/index.js +99 -0
  131. package/dist/cli/index.js.map +1 -0
  132. package/dist/cli/output.d.ts +94 -0
  133. package/dist/cli/output.d.ts.map +1 -0
  134. package/dist/cli/output.js +124 -0
  135. package/dist/cli/output.js.map +1 -0
  136. package/dist/cli/prompt.d.ts +48 -0
  137. package/dist/cli/prompt.d.ts.map +1 -0
  138. package/dist/cli/prompt.js +96 -0
  139. package/dist/cli/prompt.js.map +1 -0
  140. package/dist/clients/cache.d.ts +63 -0
  141. package/dist/clients/cache.d.ts.map +1 -0
  142. package/dist/clients/cache.js +160 -0
  143. package/dist/clients/cache.js.map +1 -0
  144. package/dist/clients/crypto.d.ts +69 -0
  145. package/dist/clients/crypto.d.ts.map +1 -0
  146. package/dist/clients/crypto.js +83 -0
  147. package/dist/clients/crypto.js.map +1 -0
  148. package/dist/clients/errors.d.ts +27 -0
  149. package/dist/clients/errors.d.ts.map +1 -0
  150. package/dist/clients/errors.js +33 -0
  151. package/dist/clients/errors.js.map +1 -0
  152. package/dist/clients/index.d.ts +19 -0
  153. package/dist/clients/index.d.ts.map +1 -0
  154. package/dist/clients/index.js +23 -0
  155. package/dist/clients/index.js.map +1 -0
  156. package/dist/clients/repository.d.ts +161 -0
  157. package/dist/clients/repository.d.ts.map +1 -0
  158. package/dist/clients/repository.js +318 -0
  159. package/dist/clients/repository.js.map +1 -0
  160. package/dist/clients/resolve-login-methods.d.ts +74 -0
  161. package/dist/clients/resolve-login-methods.d.ts.map +1 -0
  162. package/dist/clients/resolve-login-methods.js +68 -0
  163. package/dist/clients/resolve-login-methods.js.map +1 -0
  164. package/dist/clients/secret-repository.d.ts +109 -0
  165. package/dist/clients/secret-repository.d.ts.map +1 -0
  166. package/dist/clients/secret-repository.js +166 -0
  167. package/dist/clients/secret-repository.js.map +1 -0
  168. package/dist/clients/secret-service.d.ts +87 -0
  169. package/dist/clients/secret-service.d.ts.map +1 -0
  170. package/dist/clients/secret-service.js +204 -0
  171. package/dist/clients/secret-service.js.map +1 -0
  172. package/dist/clients/service.d.ts +158 -0
  173. package/dist/clients/service.d.ts.map +1 -0
  174. package/dist/clients/service.js +523 -0
  175. package/dist/clients/service.js.map +1 -0
  176. package/dist/clients/types.d.ts +214 -0
  177. package/dist/clients/types.d.ts.map +1 -0
  178. package/dist/clients/types.js +77 -0
  179. package/dist/clients/types.js.map +1 -0
  180. package/dist/clients/validators.d.ts +87 -0
  181. package/dist/clients/validators.d.ts.map +1 -0
  182. package/dist/clients/validators.js +164 -0
  183. package/dist/clients/validators.js.map +1 -0
  184. package/dist/config/index.d.ts +23 -0
  185. package/dist/config/index.d.ts.map +1 -0
  186. package/dist/config/index.js +52 -0
  187. package/dist/config/index.js.map +1 -0
  188. package/dist/config/schema.d.ts +35 -0
  189. package/dist/config/schema.d.ts.map +1 -0
  190. package/dist/config/schema.js +167 -0
  191. package/dist/config/schema.js.map +1 -0
  192. package/dist/custom-claims/cache.d.ts +48 -0
  193. package/dist/custom-claims/cache.d.ts.map +1 -0
  194. package/dist/custom-claims/cache.js +122 -0
  195. package/dist/custom-claims/cache.js.map +1 -0
  196. package/dist/custom-claims/errors.d.ts +25 -0
  197. package/dist/custom-claims/errors.d.ts.map +1 -0
  198. package/dist/custom-claims/errors.js +31 -0
  199. package/dist/custom-claims/errors.js.map +1 -0
  200. package/dist/custom-claims/index.d.ts +14 -0
  201. package/dist/custom-claims/index.d.ts.map +1 -0
  202. package/dist/custom-claims/index.js +17 -0
  203. package/dist/custom-claims/index.js.map +1 -0
  204. package/dist/custom-claims/repository.d.ts +147 -0
  205. package/dist/custom-claims/repository.d.ts.map +1 -0
  206. package/dist/custom-claims/repository.js +338 -0
  207. package/dist/custom-claims/repository.js.map +1 -0
  208. package/dist/custom-claims/service.d.ts +129 -0
  209. package/dist/custom-claims/service.d.ts.map +1 -0
  210. package/dist/custom-claims/service.js +296 -0
  211. package/dist/custom-claims/service.js.map +1 -0
  212. package/dist/custom-claims/types.d.ts +132 -0
  213. package/dist/custom-claims/types.d.ts.map +1 -0
  214. package/dist/custom-claims/types.js +61 -0
  215. package/dist/custom-claims/types.js.map +1 -0
  216. package/dist/custom-claims/validators.d.ts +61 -0
  217. package/dist/custom-claims/validators.d.ts.map +1 -0
  218. package/dist/custom-claims/validators.js +136 -0
  219. package/dist/custom-claims/validators.js.map +1 -0
  220. package/dist/index.d.ts +14 -0
  221. package/dist/index.d.ts.map +1 -0
  222. package/dist/index.js +91 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/lib/admin-permissions.d.ts +147 -0
  225. package/dist/lib/admin-permissions.d.ts.map +1 -0
  226. package/dist/lib/admin-permissions.js +261 -0
  227. package/dist/lib/admin-permissions.js.map +1 -0
  228. package/dist/lib/audit-log.d.ts +45 -0
  229. package/dist/lib/audit-log.d.ts.map +1 -0
  230. package/dist/lib/audit-log.js +79 -0
  231. package/dist/lib/audit-log.js.map +1 -0
  232. package/dist/lib/branding-assets.d.ts +47 -0
  233. package/dist/lib/branding-assets.d.ts.map +1 -0
  234. package/dist/lib/branding-assets.js +93 -0
  235. package/dist/lib/branding-assets.js.map +1 -0
  236. package/dist/lib/bulk-operations.d.ts +54 -0
  237. package/dist/lib/bulk-operations.d.ts.map +1 -0
  238. package/dist/lib/bulk-operations.js +201 -0
  239. package/dist/lib/bulk-operations.js.map +1 -0
  240. package/dist/lib/cursor.d.ts +110 -0
  241. package/dist/lib/cursor.d.ts.map +1 -0
  242. package/dist/lib/cursor.js +115 -0
  243. package/dist/lib/cursor.js.map +1 -0
  244. package/dist/lib/data-export.d.ts +67 -0
  245. package/dist/lib/data-export.d.ts.map +1 -0
  246. package/dist/lib/data-export.js +272 -0
  247. package/dist/lib/data-export.js.map +1 -0
  248. package/dist/lib/data-import-plan.d.ts +50 -0
  249. package/dist/lib/data-import-plan.d.ts.map +1 -0
  250. package/dist/lib/data-import-plan.js +235 -0
  251. package/dist/lib/data-import-plan.js.map +1 -0
  252. package/dist/lib/data-import.d.ts +276 -0
  253. package/dist/lib/data-import.d.ts.map +1 -0
  254. package/dist/lib/data-import.js +1694 -0
  255. package/dist/lib/data-import.js.map +1 -0
  256. package/dist/lib/database.d.ts +22 -0
  257. package/dist/lib/database.d.ts.map +1 -0
  258. package/dist/lib/database.js +103 -0
  259. package/dist/lib/database.js.map +1 -0
  260. package/dist/lib/entity-history.d.ts +52 -0
  261. package/dist/lib/entity-history.d.ts.map +1 -0
  262. package/dist/lib/entity-history.js +121 -0
  263. package/dist/lib/entity-history.js.map +1 -0
  264. package/dist/lib/etag.d.ts +92 -0
  265. package/dist/lib/etag.d.ts.map +1 -0
  266. package/dist/lib/etag.js +155 -0
  267. package/dist/lib/etag.js.map +1 -0
  268. package/dist/lib/image-validator.d.ts +44 -0
  269. package/dist/lib/image-validator.d.ts.map +1 -0
  270. package/dist/lib/image-validator.js +204 -0
  271. package/dist/lib/image-validator.js.map +1 -0
  272. package/dist/lib/logger.d.ts +15 -0
  273. package/dist/lib/logger.d.ts.map +1 -0
  274. package/dist/lib/logger.js +84 -0
  275. package/dist/lib/logger.js.map +1 -0
  276. package/dist/lib/migrator.d.ts +14 -0
  277. package/dist/lib/migrator.d.ts.map +1 -0
  278. package/dist/lib/migrator.js +34 -0
  279. package/dist/lib/migrator.js.map +1 -0
  280. package/dist/lib/redis.d.ts +5 -0
  281. package/dist/lib/redis.d.ts.map +1 -0
  282. package/dist/lib/redis.js +29 -0
  283. package/dist/lib/redis.js.map +1 -0
  284. package/dist/lib/runtime-paths.d.ts +38 -0
  285. package/dist/lib/runtime-paths.d.ts.map +1 -0
  286. package/dist/lib/runtime-paths.js +50 -0
  287. package/dist/lib/runtime-paths.js.map +1 -0
  288. package/dist/lib/session-tracking.d.ts +81 -0
  289. package/dist/lib/session-tracking.d.ts.map +1 -0
  290. package/dist/lib/session-tracking.js +145 -0
  291. package/dist/lib/session-tracking.js.map +1 -0
  292. package/dist/lib/signing-key-crypto.d.ts +53 -0
  293. package/dist/lib/signing-key-crypto.d.ts.map +1 -0
  294. package/dist/lib/signing-key-crypto.js +108 -0
  295. package/dist/lib/signing-key-crypto.js.map +1 -0
  296. package/dist/lib/signing-keys.d.ts +141 -0
  297. package/dist/lib/signing-keys.d.ts.map +1 -0
  298. package/dist/lib/signing-keys.js +206 -0
  299. package/dist/lib/signing-keys.js.map +1 -0
  300. package/dist/lib/stats.d.ts +83 -0
  301. package/dist/lib/stats.d.ts.map +1 -0
  302. package/dist/lib/stats.js +187 -0
  303. package/dist/lib/stats.js.map +1 -0
  304. package/dist/lib/super-admin-protection.d.ts +69 -0
  305. package/dist/lib/super-admin-protection.d.ts.map +1 -0
  306. package/dist/lib/super-admin-protection.js +102 -0
  307. package/dist/lib/super-admin-protection.js.map +1 -0
  308. package/dist/lib/system-config.d.ts +79 -0
  309. package/dist/lib/system-config.d.ts.map +1 -0
  310. package/dist/lib/system-config.js +159 -0
  311. package/dist/lib/system-config.js.map +1 -0
  312. package/dist/middleware/admin-auth.d.ts +100 -0
  313. package/dist/middleware/admin-auth.d.ts.map +1 -0
  314. package/dist/middleware/admin-auth.js +241 -0
  315. package/dist/middleware/admin-auth.js.map +1 -0
  316. package/dist/middleware/admin-cors.d.ts +41 -0
  317. package/dist/middleware/admin-cors.d.ts.map +1 -0
  318. package/dist/middleware/admin-cors.js +83 -0
  319. package/dist/middleware/admin-cors.js.map +1 -0
  320. package/dist/middleware/admin-mutation-audit.d.ts +9 -0
  321. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -0
  322. package/dist/middleware/admin-mutation-audit.js +76 -0
  323. package/dist/middleware/admin-mutation-audit.js.map +1 -0
  324. package/dist/middleware/admin-rate-limiter.d.ts +56 -0
  325. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -0
  326. package/dist/middleware/admin-rate-limiter.js +97 -0
  327. package/dist/middleware/admin-rate-limiter.js.map +1 -0
  328. package/dist/middleware/client-secret-hash.d.ts +34 -0
  329. package/dist/middleware/client-secret-hash.d.ts.map +1 -0
  330. package/dist/middleware/client-secret-hash.js +74 -0
  331. package/dist/middleware/client-secret-hash.js.map +1 -0
  332. package/dist/middleware/error-handler.d.ts +3 -0
  333. package/dist/middleware/error-handler.d.ts.map +1 -0
  334. package/dist/middleware/error-handler.js +93 -0
  335. package/dist/middleware/error-handler.js.map +1 -0
  336. package/dist/middleware/health.d.ts +3 -0
  337. package/dist/middleware/health.d.ts.map +1 -0
  338. package/dist/middleware/health.js +35 -0
  339. package/dist/middleware/health.js.map +1 -0
  340. package/dist/middleware/metrics.d.ts +40 -0
  341. package/dist/middleware/metrics.d.ts.map +1 -0
  342. package/dist/middleware/metrics.js +75 -0
  343. package/dist/middleware/metrics.js.map +1 -0
  344. package/dist/middleware/oidc-client-tenant.d.ts +37 -0
  345. package/dist/middleware/oidc-client-tenant.d.ts.map +1 -0
  346. package/dist/middleware/oidc-client-tenant.js +156 -0
  347. package/dist/middleware/oidc-client-tenant.js.map +1 -0
  348. package/dist/middleware/oidc-cors.d.ts +33 -0
  349. package/dist/middleware/oidc-cors.d.ts.map +1 -0
  350. package/dist/middleware/oidc-cors.js +68 -0
  351. package/dist/middleware/oidc-cors.js.map +1 -0
  352. package/dist/middleware/oidc-preflight-cors.d.ts +54 -0
  353. package/dist/middleware/oidc-preflight-cors.d.ts.map +1 -0
  354. package/dist/middleware/oidc-preflight-cors.js +267 -0
  355. package/dist/middleware/oidc-preflight-cors.js.map +1 -0
  356. package/dist/middleware/prompt-login-reset.d.ts +103 -0
  357. package/dist/middleware/prompt-login-reset.d.ts.map +1 -0
  358. package/dist/middleware/prompt-login-reset.js +204 -0
  359. package/dist/middleware/prompt-login-reset.js.map +1 -0
  360. package/dist/middleware/ready.d.ts +23 -0
  361. package/dist/middleware/ready.d.ts.map +1 -0
  362. package/dist/middleware/ready.js +60 -0
  363. package/dist/middleware/ready.js.map +1 -0
  364. package/dist/middleware/request-logger.d.ts +27 -0
  365. package/dist/middleware/request-logger.d.ts.map +1 -0
  366. package/dist/middleware/request-logger.js +46 -0
  367. package/dist/middleware/request-logger.js.map +1 -0
  368. package/dist/middleware/require-permission.d.ts +28 -0
  369. package/dist/middleware/require-permission.d.ts.map +1 -0
  370. package/dist/middleware/require-permission.js +63 -0
  371. package/dist/middleware/require-permission.js.map +1 -0
  372. package/dist/middleware/require-user-organization.d.ts +18 -0
  373. package/dist/middleware/require-user-organization.d.ts.map +1 -0
  374. package/dist/middleware/require-user-organization.js +53 -0
  375. package/dist/middleware/require-user-organization.js.map +1 -0
  376. package/dist/middleware/root-page.d.ts +62 -0
  377. package/dist/middleware/root-page.d.ts.map +1 -0
  378. package/dist/middleware/root-page.js +134 -0
  379. package/dist/middleware/root-page.js.map +1 -0
  380. package/dist/middleware/security-headers.d.ts +98 -0
  381. package/dist/middleware/security-headers.d.ts.map +1 -0
  382. package/dist/middleware/security-headers.js +159 -0
  383. package/dist/middleware/security-headers.js.map +1 -0
  384. package/dist/middleware/tenant-resolver.d.ts +37 -0
  385. package/dist/middleware/tenant-resolver.d.ts.map +1 -0
  386. package/dist/middleware/tenant-resolver.js +71 -0
  387. package/dist/middleware/tenant-resolver.js.map +1 -0
  388. package/dist/middleware/token-rate-limiter.d.ts +89 -0
  389. package/dist/middleware/token-rate-limiter.d.ts.map +1 -0
  390. package/dist/middleware/token-rate-limiter.js +189 -0
  391. package/dist/middleware/token-rate-limiter.js.map +1 -0
  392. package/dist/oidc/account-finder.d.ts +52 -0
  393. package/dist/oidc/account-finder.d.ts.map +1 -0
  394. package/dist/oidc/account-finder.js +134 -0
  395. package/dist/oidc/account-finder.js.map +1 -0
  396. package/dist/oidc/adapter-factory.d.ts +90 -0
  397. package/dist/oidc/adapter-factory.d.ts.map +1 -0
  398. package/dist/oidc/adapter-factory.js +165 -0
  399. package/dist/oidc/adapter-factory.js.map +1 -0
  400. package/dist/oidc/configuration.d.ts +155 -0
  401. package/dist/oidc/configuration.d.ts.map +1 -0
  402. package/dist/oidc/configuration.js +531 -0
  403. package/dist/oidc/configuration.js.map +1 -0
  404. package/dist/oidc/postgres-adapter.d.ts +159 -0
  405. package/dist/oidc/postgres-adapter.d.ts.map +1 -0
  406. package/dist/oidc/postgres-adapter.js +222 -0
  407. package/dist/oidc/postgres-adapter.js.map +1 -0
  408. package/dist/oidc/protocol-security-observer.d.ts +38 -0
  409. package/dist/oidc/protocol-security-observer.d.ts.map +1 -0
  410. package/dist/oidc/protocol-security-observer.js +93 -0
  411. package/dist/oidc/protocol-security-observer.js.map +1 -0
  412. package/dist/oidc/provider.d.ts +37 -0
  413. package/dist/oidc/provider.d.ts.map +1 -0
  414. package/dist/oidc/provider.js +71 -0
  415. package/dist/oidc/provider.js.map +1 -0
  416. package/dist/oidc/redis-adapter.d.ts +140 -0
  417. package/dist/oidc/redis-adapter.d.ts.map +1 -0
  418. package/dist/oidc/redis-adapter.js +344 -0
  419. package/dist/oidc/redis-adapter.js.map +1 -0
  420. package/dist/organizations/cache.d.ts +60 -0
  421. package/dist/organizations/cache.d.ts.map +1 -0
  422. package/dist/organizations/cache.js +157 -0
  423. package/dist/organizations/cache.js.map +1 -0
  424. package/dist/organizations/errors.d.ts +25 -0
  425. package/dist/organizations/errors.d.ts.map +1 -0
  426. package/dist/organizations/errors.js +31 -0
  427. package/dist/organizations/errors.js.map +1 -0
  428. package/dist/organizations/index.d.ts +15 -0
  429. package/dist/organizations/index.d.ts.map +1 -0
  430. package/dist/organizations/index.js +15 -0
  431. package/dist/organizations/index.js.map +1 -0
  432. package/dist/organizations/repository.d.ts +183 -0
  433. package/dist/organizations/repository.d.ts.map +1 -0
  434. package/dist/organizations/repository.js +354 -0
  435. package/dist/organizations/repository.js.map +1 -0
  436. package/dist/organizations/service.d.ts +168 -0
  437. package/dist/organizations/service.d.ts.map +1 -0
  438. package/dist/organizations/service.js +511 -0
  439. package/dist/organizations/service.js.map +1 -0
  440. package/dist/organizations/slugs.d.ts +57 -0
  441. package/dist/organizations/slugs.d.ts.map +1 -0
  442. package/dist/organizations/slugs.js +130 -0
  443. package/dist/organizations/slugs.js.map +1 -0
  444. package/dist/organizations/types.d.ts +146 -0
  445. package/dist/organizations/types.d.ts.map +1 -0
  446. package/dist/organizations/types.js +49 -0
  447. package/dist/organizations/types.js.map +1 -0
  448. package/dist/rbac/cache.d.ts +110 -0
  449. package/dist/rbac/cache.d.ts.map +1 -0
  450. package/dist/rbac/cache.js +271 -0
  451. package/dist/rbac/cache.js.map +1 -0
  452. package/dist/rbac/errors.d.ts +34 -0
  453. package/dist/rbac/errors.d.ts.map +1 -0
  454. package/dist/rbac/errors.js +43 -0
  455. package/dist/rbac/errors.js.map +1 -0
  456. package/dist/rbac/index.d.ts +17 -0
  457. package/dist/rbac/index.d.ts.map +1 -0
  458. package/dist/rbac/index.js +21 -0
  459. package/dist/rbac/index.js.map +1 -0
  460. package/dist/rbac/mapping-repository.d.ts +121 -0
  461. package/dist/rbac/mapping-repository.d.ts.map +1 -0
  462. package/dist/rbac/mapping-repository.js +224 -0
  463. package/dist/rbac/mapping-repository.js.map +1 -0
  464. package/dist/rbac/permission-repository.d.ts +100 -0
  465. package/dist/rbac/permission-repository.d.ts.map +1 -0
  466. package/dist/rbac/permission-repository.js +190 -0
  467. package/dist/rbac/permission-repository.js.map +1 -0
  468. package/dist/rbac/permission-service.d.ts +85 -0
  469. package/dist/rbac/permission-service.d.ts.map +1 -0
  470. package/dist/rbac/permission-service.js +179 -0
  471. package/dist/rbac/permission-service.js.map +1 -0
  472. package/dist/rbac/role-repository.d.ts +104 -0
  473. package/dist/rbac/role-repository.d.ts.map +1 -0
  474. package/dist/rbac/role-repository.js +202 -0
  475. package/dist/rbac/role-repository.js.map +1 -0
  476. package/dist/rbac/role-service.d.ts +111 -0
  477. package/dist/rbac/role-service.d.ts.map +1 -0
  478. package/dist/rbac/role-service.js +256 -0
  479. package/dist/rbac/role-service.js.map +1 -0
  480. package/dist/rbac/slugs.d.ts +116 -0
  481. package/dist/rbac/slugs.d.ts.map +1 -0
  482. package/dist/rbac/slugs.js +178 -0
  483. package/dist/rbac/slugs.js.map +1 -0
  484. package/dist/rbac/types.d.ts +187 -0
  485. package/dist/rbac/types.d.ts.map +1 -0
  486. package/dist/rbac/types.js +75 -0
  487. package/dist/rbac/types.js.map +1 -0
  488. package/dist/rbac/user-role-service.d.ts +101 -0
  489. package/dist/rbac/user-role-service.d.ts.map +1 -0
  490. package/dist/rbac/user-role-service.js +166 -0
  491. package/dist/rbac/user-role-service.js.map +1 -0
  492. package/dist/routes/applications.d.ts +40 -0
  493. package/dist/routes/applications.d.ts.map +1 -0
  494. package/dist/routes/applications.js +284 -0
  495. package/dist/routes/applications.js.map +1 -0
  496. package/dist/routes/audit.d.ts +31 -0
  497. package/dist/routes/audit.d.ts.map +1 -0
  498. package/dist/routes/audit.js +140 -0
  499. package/dist/routes/audit.js.map +1 -0
  500. package/dist/routes/branding.d.ts +17 -0
  501. package/dist/routes/branding.d.ts.map +1 -0
  502. package/dist/routes/branding.js +104 -0
  503. package/dist/routes/branding.js.map +1 -0
  504. package/dist/routes/bulk.d.ts +37 -0
  505. package/dist/routes/bulk.d.ts.map +1 -0
  506. package/dist/routes/bulk.js +94 -0
  507. package/dist/routes/bulk.js.map +1 -0
  508. package/dist/routes/clients.d.ts +44 -0
  509. package/dist/routes/clients.d.ts.map +1 -0
  510. package/dist/routes/clients.js +353 -0
  511. package/dist/routes/clients.js.map +1 -0
  512. package/dist/routes/config.d.ts +35 -0
  513. package/dist/routes/config.d.ts.map +1 -0
  514. package/dist/routes/config.js +115 -0
  515. package/dist/routes/config.js.map +1 -0
  516. package/dist/routes/custom-claims.d.ts +38 -0
  517. package/dist/routes/custom-claims.d.ts.map +1 -0
  518. package/dist/routes/custom-claims.js +208 -0
  519. package/dist/routes/custom-claims.js.map +1 -0
  520. package/dist/routes/exports.d.ts +21 -0
  521. package/dist/routes/exports.d.ts.map +1 -0
  522. package/dist/routes/exports.js +98 -0
  523. package/dist/routes/exports.js.map +1 -0
  524. package/dist/routes/imports.d.ts +18 -0
  525. package/dist/routes/imports.d.ts.map +1 -0
  526. package/dist/routes/imports.js +72 -0
  527. package/dist/routes/imports.js.map +1 -0
  528. package/dist/routes/interactions.d.ts +111 -0
  529. package/dist/routes/interactions.d.ts.map +1 -0
  530. package/dist/routes/interactions.js +1074 -0
  531. package/dist/routes/interactions.js.map +1 -0
  532. package/dist/routes/invitation.d.ts +31 -0
  533. package/dist/routes/invitation.d.ts.map +1 -0
  534. package/dist/routes/invitation.js +342 -0
  535. package/dist/routes/invitation.js.map +1 -0
  536. package/dist/routes/keys.d.ts +28 -0
  537. package/dist/routes/keys.d.ts.map +1 -0
  538. package/dist/routes/keys.js +91 -0
  539. package/dist/routes/keys.js.map +1 -0
  540. package/dist/routes/magic-link.d.ts +43 -0
  541. package/dist/routes/magic-link.d.ts.map +1 -0
  542. package/dist/routes/magic-link.js +264 -0
  543. package/dist/routes/magic-link.js.map +1 -0
  544. package/dist/routes/organizations.d.ts +38 -0
  545. package/dist/routes/organizations.d.ts.map +1 -0
  546. package/dist/routes/organizations.js +347 -0
  547. package/dist/routes/organizations.js.map +1 -0
  548. package/dist/routes/password-reset.d.ts +65 -0
  549. package/dist/routes/password-reset.d.ts.map +1 -0
  550. package/dist/routes/password-reset.js +493 -0
  551. package/dist/routes/password-reset.js.map +1 -0
  552. package/dist/routes/permissions.d.ts +33 -0
  553. package/dist/routes/permissions.d.ts.map +1 -0
  554. package/dist/routes/permissions.js +166 -0
  555. package/dist/routes/permissions.js.map +1 -0
  556. package/dist/routes/roles.d.ts +37 -0
  557. package/dist/routes/roles.d.ts.map +1 -0
  558. package/dist/routes/roles.js +222 -0
  559. package/dist/routes/roles.js.map +1 -0
  560. package/dist/routes/sessions.d.ts +37 -0
  561. package/dist/routes/sessions.d.ts.map +1 -0
  562. package/dist/routes/sessions.js +121 -0
  563. package/dist/routes/sessions.js.map +1 -0
  564. package/dist/routes/stats.d.ts +28 -0
  565. package/dist/routes/stats.d.ts.map +1 -0
  566. package/dist/routes/stats.js +65 -0
  567. package/dist/routes/stats.js.map +1 -0
  568. package/dist/routes/two-factor-admin.d.ts +54 -0
  569. package/dist/routes/two-factor-admin.d.ts.map +1 -0
  570. package/dist/routes/two-factor-admin.js +344 -0
  571. package/dist/routes/two-factor-admin.js.map +1 -0
  572. package/dist/routes/two-factor.d.ts +31 -0
  573. package/dist/routes/two-factor.d.ts.map +1 -0
  574. package/dist/routes/two-factor.js +595 -0
  575. package/dist/routes/two-factor.js.map +1 -0
  576. package/dist/routes/user-roles.d.ts +33 -0
  577. package/dist/routes/user-roles.d.ts.map +1 -0
  578. package/dist/routes/user-roles.js +129 -0
  579. package/dist/routes/user-roles.js.map +1 -0
  580. package/dist/routes/users.d.ts +61 -0
  581. package/dist/routes/users.d.ts.map +1 -0
  582. package/dist/routes/users.js +868 -0
  583. package/dist/routes/users.js.map +1 -0
  584. package/dist/security/decision-context.d.ts +52 -0
  585. package/dist/security/decision-context.d.ts.map +1 -0
  586. package/dist/security/decision-context.js +150 -0
  587. package/dist/security/decision-context.js.map +1 -0
  588. package/dist/security/decision-event.d.ts +128 -0
  589. package/dist/security/decision-event.d.ts.map +1 -0
  590. package/dist/security/decision-event.js +225 -0
  591. package/dist/security/decision-event.js.map +1 -0
  592. package/dist/security/transport-decision.d.ts +6 -0
  593. package/dist/security/transport-decision.d.ts.map +1 -0
  594. package/dist/security/transport-decision.js +37 -0
  595. package/dist/security/transport-decision.js.map +1 -0
  596. package/dist/server.d.ts +50 -0
  597. package/dist/server.d.ts.map +1 -0
  598. package/dist/server.js +491 -0
  599. package/dist/server.js.map +1 -0
  600. package/dist/two-factor/cache.d.ts +47 -0
  601. package/dist/two-factor/cache.d.ts.map +1 -0
  602. package/dist/two-factor/cache.js +122 -0
  603. package/dist/two-factor/cache.js.map +1 -0
  604. package/dist/two-factor/crypto.d.ts +41 -0
  605. package/dist/two-factor/crypto.d.ts.map +1 -0
  606. package/dist/two-factor/crypto.js +94 -0
  607. package/dist/two-factor/crypto.js.map +1 -0
  608. package/dist/two-factor/errors.d.ts +82 -0
  609. package/dist/two-factor/errors.d.ts.map +1 -0
  610. package/dist/two-factor/errors.js +112 -0
  611. package/dist/two-factor/errors.js.map +1 -0
  612. package/dist/two-factor/index.d.ts +18 -0
  613. package/dist/two-factor/index.d.ts.map +1 -0
  614. package/dist/two-factor/index.js +25 -0
  615. package/dist/two-factor/index.js.map +1 -0
  616. package/dist/two-factor/otp.d.ts +43 -0
  617. package/dist/two-factor/otp.d.ts.map +1 -0
  618. package/dist/two-factor/otp.js +57 -0
  619. package/dist/two-factor/otp.js.map +1 -0
  620. package/dist/two-factor/recovery.d.ts +45 -0
  621. package/dist/two-factor/recovery.d.ts.map +1 -0
  622. package/dist/two-factor/recovery.js +104 -0
  623. package/dist/two-factor/recovery.js.map +1 -0
  624. package/dist/two-factor/repository.d.ts +156 -0
  625. package/dist/two-factor/repository.d.ts.map +1 -0
  626. package/dist/two-factor/repository.js +251 -0
  627. package/dist/two-factor/repository.js.map +1 -0
  628. package/dist/two-factor/service.d.ts +232 -0
  629. package/dist/two-factor/service.d.ts.map +1 -0
  630. package/dist/two-factor/service.js +599 -0
  631. package/dist/two-factor/service.js.map +1 -0
  632. package/dist/two-factor/totp.d.ts +57 -0
  633. package/dist/two-factor/totp.d.ts.map +1 -0
  634. package/dist/two-factor/totp.js +96 -0
  635. package/dist/two-factor/totp.js.map +1 -0
  636. package/dist/two-factor/types.d.ts +152 -0
  637. package/dist/two-factor/types.d.ts.map +1 -0
  638. package/dist/two-factor/types.js +64 -0
  639. package/dist/two-factor/types.js.map +1 -0
  640. package/dist/users/cache.d.ts +49 -0
  641. package/dist/users/cache.d.ts.map +1 -0
  642. package/dist/users/cache.js +140 -0
  643. package/dist/users/cache.js.map +1 -0
  644. package/dist/users/claims.d.ts +67 -0
  645. package/dist/users/claims.d.ts.map +1 -0
  646. package/dist/users/claims.js +104 -0
  647. package/dist/users/claims.js.map +1 -0
  648. package/dist/users/errors.d.ts +25 -0
  649. package/dist/users/errors.d.ts.map +1 -0
  650. package/dist/users/errors.js +31 -0
  651. package/dist/users/errors.js.map +1 -0
  652. package/dist/users/gdpr.d.ts +110 -0
  653. package/dist/users/gdpr.d.ts.map +1 -0
  654. package/dist/users/gdpr.js +211 -0
  655. package/dist/users/gdpr.js.map +1 -0
  656. package/dist/users/index.d.ts +20 -0
  657. package/dist/users/index.d.ts.map +1 -0
  658. package/dist/users/index.js +19 -0
  659. package/dist/users/index.js.map +1 -0
  660. package/dist/users/password.d.ts +85 -0
  661. package/dist/users/password.d.ts.map +1 -0
  662. package/dist/users/password.js +138 -0
  663. package/dist/users/password.js.map +1 -0
  664. package/dist/users/repository.d.ts +263 -0
  665. package/dist/users/repository.d.ts.map +1 -0
  666. package/dist/users/repository.js +499 -0
  667. package/dist/users/repository.js.map +1 -0
  668. package/dist/users/service.d.ts +299 -0
  669. package/dist/users/service.d.ts.map +1 -0
  670. package/dist/users/service.js +698 -0
  671. package/dist/users/service.js.map +1 -0
  672. package/dist/users/types.d.ts +220 -0
  673. package/dist/users/types.d.ts.map +1 -0
  674. package/dist/users/types.js +77 -0
  675. package/dist/users/types.js.map +1 -0
  676. package/locales/default/en/common.json +10 -0
  677. package/locales/default/en/consent.json +13 -0
  678. package/locales/default/en/emails.json +17 -0
  679. package/locales/default/en/errors.json +21 -0
  680. package/locales/default/en/forgot-password.json +11 -0
  681. package/locales/default/en/invitation.json +18 -0
  682. package/locales/default/en/login.json +17 -0
  683. package/locales/default/en/logout.json +9 -0
  684. package/locales/default/en/magic-link.json +12 -0
  685. package/locales/default/en/reset-password.json +16 -0
  686. package/locales/default/en/two-factor.json +29 -0
  687. package/migrations/.gitkeep +0 -0
  688. package/migrations/001_extensions.sql +22 -0
  689. package/migrations/002_organizations.sql +43 -0
  690. package/migrations/003_applications.sql +50 -0
  691. package/migrations/004_clients.sql +74 -0
  692. package/migrations/005_users.sql +119 -0
  693. package/migrations/006_roles_permissions.sql +80 -0
  694. package/migrations/007_custom_claims.sql +55 -0
  695. package/migrations/008_config.sql +51 -0
  696. package/migrations/009_audit_log.sql +31 -0
  697. package/migrations/010_oidc_adapter.sql +34 -0
  698. package/migrations/011_seed.sql +53 -0
  699. package/migrations/012_two_factor.sql +88 -0
  700. package/migrations/013_client_secret_sha256.sql +22 -0
  701. package/migrations/014_login_methods.sql +34 -0
  702. package/migrations/015_signing_key_encryption.sql +20 -0
  703. package/migrations/016_failed_login_count.sql +27 -0
  704. package/migrations/017_audit_retention.sql +11 -0
  705. package/migrations/018_admin_api_enhancements.sql +78 -0
  706. package/migrations/019_invitation_details.sql +27 -0
  707. package/migrations/020_two_factor_admin_permission.sql +108 -0
  708. package/migrations/021_auth_recovery_jobs.sql +74 -0
  709. package/migrations/022_recovery_artifact_ownership.sql +25 -0
  710. package/migrations/023_magic_link_authority.sql +39 -0
  711. package/package.json +106 -0
  712. package/templates/default/emails/invitation.hbs +39 -0
  713. package/templates/default/emails/invitation.txt.hbs +18 -0
  714. package/templates/default/emails/magic-link.hbs +30 -0
  715. package/templates/default/emails/magic-link.txt.hbs +11 -0
  716. package/templates/default/emails/otp-code.hbs +31 -0
  717. package/templates/default/emails/otp-code.txt.hbs +15 -0
  718. package/templates/default/emails/password-changed.hbs +24 -0
  719. package/templates/default/emails/password-changed.txt.hbs +7 -0
  720. package/templates/default/emails/password-reset.hbs +30 -0
  721. package/templates/default/emails/password-reset.txt.hbs +11 -0
  722. package/templates/default/emails/welcome.hbs +25 -0
  723. package/templates/default/emails/welcome.txt.hbs +9 -0
  724. package/templates/default/layouts/main.hbs +49 -0
  725. package/templates/default/pages/accept-invite.hbs +25 -0
  726. package/templates/default/pages/consent.hbs +27 -0
  727. package/templates/default/pages/error.hbs +15 -0
  728. package/templates/default/pages/forgot-password.hbs +21 -0
  729. package/templates/default/pages/invite-expired.hbs +6 -0
  730. package/templates/default/pages/invite-success.hbs +9 -0
  731. package/templates/default/pages/login.hbs +108 -0
  732. package/templates/default/pages/logout-success.hbs +5 -0
  733. package/templates/default/pages/logout.hbs +24 -0
  734. package/templates/default/pages/magic-link-sent.hbs +10 -0
  735. package/templates/default/pages/magic-link-success.hbs +17 -0
  736. package/templates/default/pages/reset-password.hbs +20 -0
  737. package/templates/default/pages/reset-success.hbs +9 -0
  738. package/templates/default/pages/two-factor-setup.hbs +65 -0
  739. package/templates/default/pages/two-factor-verify.hbs +77 -0
  740. package/templates/default/partials/flash-messages.hbs +10 -0
  741. package/templates/default/partials/footer.hbs +4 -0
  742. package/templates/default/partials/header.hbs +8 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * PostgreSQL adapter for node-oidc-provider.
3
+ *
4
+ * Stores long-lived OIDC artifacts (AccessToken, RefreshToken, Grant, DeviceCode)
5
+ * in the oidc_payloads table. Uses parameterized queries to prevent SQL injection.
6
+ *
7
+ * Table schema (from migration 010_oidc_adapter.sql):
8
+ * id VARCHAR(255) NOT NULL — artifact ID
9
+ * type VARCHAR(50) NOT NULL — model name (e.g., 'AccessToken')
10
+ * payload JSONB NOT NULL — full OIDC artifact payload
11
+ * grant_id VARCHAR(255) — for grant-based revocation
12
+ * user_code VARCHAR(255) — for device flow lookups
13
+ * uid VARCHAR(255) — for session lookups
14
+ * expires_at TIMESTAMPTZ — when the artifact expires
15
+ * consumed_at TIMESTAMPTZ — when the artifact was consumed (e.g., auth code used)
16
+ * created_at TIMESTAMPTZ NOT NULL — row creation timestamp
17
+ * PRIMARY KEY (id, type)
18
+ */
19
+ /** OIDC adapter payload — the data node-oidc-provider stores and retrieves */
20
+ export interface AdapterPayload {
21
+ [key: string]: unknown;
22
+ accountId?: string;
23
+ clientId?: string;
24
+ grantId?: string;
25
+ iat?: number;
26
+ exp?: number;
27
+ uid?: string;
28
+ userCode?: string;
29
+ jti?: string;
30
+ kind?: string;
31
+ consumed?: number | boolean;
32
+ }
33
+ /**
34
+ * PostgreSQL adapter implementing the node-oidc-provider storage interface.
35
+ *
36
+ * Each instance is created per-model (e.g., new PostgresAdapter('AccessToken')).
37
+ * The model name is used as the `type` column to partition artifacts in the
38
+ * shared oidc_payloads table.
39
+ */
40
+ export declare class PostgresAdapter {
41
+ /** Model name — used as the `type` column value (e.g., 'AccessToken', 'RefreshToken') */
42
+ protected name: string;
43
+ constructor(name: string);
44
+ /**
45
+ * Create or update an OIDC artifact.
46
+ *
47
+ * Uses INSERT ... ON CONFLICT to handle both initial creation and updates.
48
+ * Extracts grant_id, user_code, uid from payload for indexed lookups.
49
+ * Calculates expires_at from the current time + expiresIn seconds.
50
+ *
51
+ * @param id - Artifact ID (e.g., token jti)
52
+ * @param payload - Full OIDC artifact payload
53
+ * @param expiresIn - TTL in seconds from now
54
+ */
55
+ upsert(id: string, payload: AdapterPayload, expiresIn: number): Promise<void>;
56
+ /**
57
+ * Find an artifact by its ID.
58
+ *
59
+ * Returns undefined if not found or if the artifact has expired.
60
+ * Merges consumed_at into the payload as `consumed` (epoch seconds)
61
+ * which is the format node-oidc-provider expects.
62
+ *
63
+ * @param id - Artifact ID to look up
64
+ * @returns The artifact payload, or undefined if not found/expired
65
+ */
66
+ find(id: string): Promise<AdapterPayload | undefined>;
67
+ /**
68
+ * Find an artifact by user code (device flow).
69
+ *
70
+ * Used for OAuth 2.0 Device Authorization Grant where the user
71
+ * enters a code on a separate device.
72
+ *
73
+ * @param userCode - The user-facing device code
74
+ * @returns The artifact payload, or undefined if not found/expired
75
+ */
76
+ findByUserCode(userCode: string): Promise<AdapterPayload | undefined>;
77
+ /**
78
+ * Find an artifact by UID (sessions).
79
+ *
80
+ * Used to look up sessions by their unique identifier when
81
+ * the session ID is not directly available.
82
+ *
83
+ * @param uid - The unique identifier
84
+ * @returns The artifact payload, or undefined if not found/expired
85
+ */
86
+ findByUid(uid: string): Promise<AdapterPayload | undefined>;
87
+ /**
88
+ * Mark an artifact as consumed.
89
+ *
90
+ * Sets consumed_at to the current time. Used primarily for authorization
91
+ * code replay detection — once a code is consumed, subsequent attempts
92
+ * to use it are rejected by the provider.
93
+ *
94
+ * @param id - Artifact ID to mark as consumed
95
+ */
96
+ consume(id: string): Promise<void>;
97
+ /**
98
+ * Delete an artifact by its ID.
99
+ *
100
+ * Permanently removes the artifact from the database.
101
+ *
102
+ * @param id - Artifact ID to delete
103
+ */
104
+ destroy(id: string): Promise<void>;
105
+ /**
106
+ * Revoke all artifacts associated with a grant.
107
+ *
108
+ * Deletes all rows matching the given grant_id for this model type.
109
+ * Used when a grant is revoked (e.g., user revokes consent) to clean up
110
+ * all associated tokens and artifacts.
111
+ *
112
+ * @param grantId - Grant ID whose artifacts should be deleted
113
+ */
114
+ revokeByGrantId(grantId: string): Promise<void>;
115
+ /**
116
+ * Merge consumed_at into the payload as `consumed` (epoch seconds).
117
+ *
118
+ * node-oidc-provider expects the `consumed` field to be an epoch timestamp
119
+ * (number of seconds since Unix epoch) in the payload. The database stores
120
+ * it as a separate TIMESTAMPTZ column which we convert here.
121
+ *
122
+ * @param row - Database row with payload and consumed_at
123
+ * @returns The payload with consumed field merged if applicable
124
+ */
125
+ protected withConsumed(row: {
126
+ payload: AdapterPayload;
127
+ consumed_at: Date | null;
128
+ }): AdapterPayload;
129
+ }
130
+ /**
131
+ * Delete all oidc_payloads records matching any of the given grant_ids.
132
+ *
133
+ * Used for cascade cleanup when a session is destroyed during explicit logout.
134
+ * Deletes across ALL types (AccessToken, RefreshToken, Grant, etc.) in a single
135
+ * query — the grant_id column links tokens back to their originating grant.
136
+ *
137
+ * This is the critical step that ensures "logout = total cleanup": when a user
138
+ * clicks "Sign Out", all grants and tokens issued during that session are removed
139
+ * from PostgreSQL so they can no longer be used.
140
+ *
141
+ * @param grantIds - Array of grant IDs whose artifacts should be deleted
142
+ */
143
+ export declare function revokeGrantsByIds(grantIds: string[]): Promise<void>;
144
+ /**
145
+ * Delete all expired oidc_payloads records (fire-and-forget).
146
+ *
147
+ * Called opportunistically on auth flow start to keep the oidc_payloads table
148
+ * clean without requiring a cron job or external scheduler. This pattern is
149
+ * proven from Porta v4 — self-regulating cleanup tied to actual usage.
150
+ *
151
+ * The function is intentionally fire-and-forget: it does NOT return a promise
152
+ * that callers should await. Errors are silently caught and logged — a failed
153
+ * cleanup is harmless (expired rows are already inert) and will be retried on
154
+ * the next auth flow start.
155
+ *
156
+ * Uses the expires_at index for efficient deletion.
157
+ */
158
+ export declare function purgeExpired(): void;
159
+ //# sourceMappingURL=postgres-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-adapter.d.ts","sourceRoot":"","sources":["../../src/oidc/postgres-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,yFAAyF;IACzF,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IAEvB,YAAY,IAAI,EAAE,MAAM,EAEvB;IAED;;;;;;;;;;OAUG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;IAED;;;;;;;;;OASG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAY1D;IAED;;;;;;;;OAQG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAY1E;IAED;;;;;;;;OAQG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAYhE;IAED;;;;;;;;OAQG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvC;IAED;;;;;;OAMG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvC;IAED;;;;;;;;OAQG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOpD;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE;QAC1B,OAAO,EAAE,cAAc,CAAC;QACxB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;KAC1B,GAAG,cAAc,CASjB;CACF;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAQnC"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * PostgreSQL adapter for node-oidc-provider.
3
+ *
4
+ * Stores long-lived OIDC artifacts (AccessToken, RefreshToken, Grant, DeviceCode)
5
+ * in the oidc_payloads table. Uses parameterized queries to prevent SQL injection.
6
+ *
7
+ * Table schema (from migration 010_oidc_adapter.sql):
8
+ * id VARCHAR(255) NOT NULL — artifact ID
9
+ * type VARCHAR(50) NOT NULL — model name (e.g., 'AccessToken')
10
+ * payload JSONB NOT NULL — full OIDC artifact payload
11
+ * grant_id VARCHAR(255) — for grant-based revocation
12
+ * user_code VARCHAR(255) — for device flow lookups
13
+ * uid VARCHAR(255) — for session lookups
14
+ * expires_at TIMESTAMPTZ — when the artifact expires
15
+ * consumed_at TIMESTAMPTZ — when the artifact was consumed (e.g., auth code used)
16
+ * created_at TIMESTAMPTZ NOT NULL — row creation timestamp
17
+ * PRIMARY KEY (id, type)
18
+ */
19
+ import { errors } from 'oidc-provider';
20
+ import { getPool } from '../lib/database.js';
21
+ import { logger } from '../lib/logger.js';
22
+ /**
23
+ * PostgreSQL adapter implementing the node-oidc-provider storage interface.
24
+ *
25
+ * Each instance is created per-model (e.g., new PostgresAdapter('AccessToken')).
26
+ * The model name is used as the `type` column to partition artifacts in the
27
+ * shared oidc_payloads table.
28
+ */
29
+ export class PostgresAdapter {
30
+ /** Model name — used as the `type` column value (e.g., 'AccessToken', 'RefreshToken') */
31
+ name;
32
+ constructor(name) {
33
+ this.name = name;
34
+ }
35
+ /**
36
+ * Create or update an OIDC artifact.
37
+ *
38
+ * Uses INSERT ... ON CONFLICT to handle both initial creation and updates.
39
+ * Extracts grant_id, user_code, uid from payload for indexed lookups.
40
+ * Calculates expires_at from the current time + expiresIn seconds.
41
+ *
42
+ * @param id - Artifact ID (e.g., token jti)
43
+ * @param payload - Full OIDC artifact payload
44
+ * @param expiresIn - TTL in seconds from now
45
+ */
46
+ async upsert(id, payload, expiresIn) {
47
+ const pool = getPool();
48
+ // Extract indexed fields from payload for efficient lookups.
49
+ // These are stored as separate columns in addition to the full JSONB payload.
50
+ const grantId = payload.grantId ?? null;
51
+ const userCode = payload.userCode ?? null;
52
+ const uid = payload.uid ?? null;
53
+ // Calculate absolute expiration time using PostgreSQL interval arithmetic
54
+ const expiresAt = expiresIn
55
+ ? new Date(Date.now() + expiresIn * 1000)
56
+ : null;
57
+ await pool.query(`INSERT INTO oidc_payloads (id, type, payload, grant_id, user_code, uid, expires_at)
58
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
59
+ ON CONFLICT (id, type)
60
+ DO UPDATE SET payload = $3, grant_id = $4, user_code = $5, uid = $6, expires_at = $7`, [id, this.name, JSON.stringify(payload), grantId, userCode, uid, expiresAt]);
61
+ }
62
+ /**
63
+ * Find an artifact by its ID.
64
+ *
65
+ * Returns undefined if not found or if the artifact has expired.
66
+ * Merges consumed_at into the payload as `consumed` (epoch seconds)
67
+ * which is the format node-oidc-provider expects.
68
+ *
69
+ * @param id - Artifact ID to look up
70
+ * @returns The artifact payload, or undefined if not found/expired
71
+ */
72
+ async find(id) {
73
+ const pool = getPool();
74
+ const result = await pool.query(`SELECT payload, consumed_at FROM oidc_payloads
75
+ WHERE id = $1 AND type = $2 AND (expires_at IS NULL OR expires_at > NOW())`, [id, this.name]);
76
+ if (result.rows.length === 0)
77
+ return undefined;
78
+ return this.withConsumed(result.rows[0]);
79
+ }
80
+ /**
81
+ * Find an artifact by user code (device flow).
82
+ *
83
+ * Used for OAuth 2.0 Device Authorization Grant where the user
84
+ * enters a code on a separate device.
85
+ *
86
+ * @param userCode - The user-facing device code
87
+ * @returns The artifact payload, or undefined if not found/expired
88
+ */
89
+ async findByUserCode(userCode) {
90
+ const pool = getPool();
91
+ const result = await pool.query(`SELECT payload, consumed_at FROM oidc_payloads
92
+ WHERE user_code = $1 AND type = $2 AND (expires_at IS NULL OR expires_at > NOW())`, [userCode, this.name]);
93
+ if (result.rows.length === 0)
94
+ return undefined;
95
+ return this.withConsumed(result.rows[0]);
96
+ }
97
+ /**
98
+ * Find an artifact by UID (sessions).
99
+ *
100
+ * Used to look up sessions by their unique identifier when
101
+ * the session ID is not directly available.
102
+ *
103
+ * @param uid - The unique identifier
104
+ * @returns The artifact payload, or undefined if not found/expired
105
+ */
106
+ async findByUid(uid) {
107
+ const pool = getPool();
108
+ const result = await pool.query(`SELECT payload, consumed_at FROM oidc_payloads
109
+ WHERE uid = $1 AND type = $2 AND (expires_at IS NULL OR expires_at > NOW())`, [uid, this.name]);
110
+ if (result.rows.length === 0)
111
+ return undefined;
112
+ return this.withConsumed(result.rows[0]);
113
+ }
114
+ /**
115
+ * Mark an artifact as consumed.
116
+ *
117
+ * Sets consumed_at to the current time. Used primarily for authorization
118
+ * code replay detection — once a code is consumed, subsequent attempts
119
+ * to use it are rejected by the provider.
120
+ *
121
+ * @param id - Artifact ID to mark as consumed
122
+ */
123
+ async consume(id) {
124
+ const pool = getPool();
125
+ const result = await pool.query(`UPDATE oidc_payloads SET consumed_at = NOW()
126
+ WHERE id = $1 AND type = $2 AND consumed_at IS NULL
127
+ AND (expires_at IS NULL OR expires_at > NOW())
128
+ RETURNING id`, [id, this.name]);
129
+ // The conditional write is the durable single-use decision. A preceding read cannot provide
130
+ // that guarantee because two requests may both observe the artifact before either consumes it.
131
+ if (result.rowCount !== 1)
132
+ throw new errors.InvalidGrant();
133
+ }
134
+ /**
135
+ * Delete an artifact by its ID.
136
+ *
137
+ * Permanently removes the artifact from the database.
138
+ *
139
+ * @param id - Artifact ID to delete
140
+ */
141
+ async destroy(id) {
142
+ const pool = getPool();
143
+ await pool.query(`DELETE FROM oidc_payloads WHERE id = $1 AND type = $2`, [id, this.name]);
144
+ }
145
+ /**
146
+ * Revoke all artifacts associated with a grant.
147
+ *
148
+ * Deletes all rows matching the given grant_id for this model type.
149
+ * Used when a grant is revoked (e.g., user revokes consent) to clean up
150
+ * all associated tokens and artifacts.
151
+ *
152
+ * @param grantId - Grant ID whose artifacts should be deleted
153
+ */
154
+ async revokeByGrantId(grantId) {
155
+ const pool = getPool();
156
+ await pool.query(`DELETE FROM oidc_payloads WHERE grant_id = $1 AND type = $2`, [grantId, this.name]);
157
+ }
158
+ /**
159
+ * Merge consumed_at into the payload as `consumed` (epoch seconds).
160
+ *
161
+ * node-oidc-provider expects the `consumed` field to be an epoch timestamp
162
+ * (number of seconds since Unix epoch) in the payload. The database stores
163
+ * it as a separate TIMESTAMPTZ column which we convert here.
164
+ *
165
+ * @param row - Database row with payload and consumed_at
166
+ * @returns The payload with consumed field merged if applicable
167
+ */
168
+ withConsumed(row) {
169
+ const payload = row.payload;
170
+ if (row.consumed_at) {
171
+ // Convert TIMESTAMPTZ to epoch seconds as expected by node-oidc-provider
172
+ payload.consumed = Math.floor(row.consumed_at.getTime() / 1000);
173
+ }
174
+ return payload;
175
+ }
176
+ }
177
+ // ---------------------------------------------------------------------------
178
+ // Standalone helpers for session lifecycle management
179
+ // ---------------------------------------------------------------------------
180
+ /**
181
+ * Delete all oidc_payloads records matching any of the given grant_ids.
182
+ *
183
+ * Used for cascade cleanup when a session is destroyed during explicit logout.
184
+ * Deletes across ALL types (AccessToken, RefreshToken, Grant, etc.) in a single
185
+ * query — the grant_id column links tokens back to their originating grant.
186
+ *
187
+ * This is the critical step that ensures "logout = total cleanup": when a user
188
+ * clicks "Sign Out", all grants and tokens issued during that session are removed
189
+ * from PostgreSQL so they can no longer be used.
190
+ *
191
+ * @param grantIds - Array of grant IDs whose artifacts should be deleted
192
+ */
193
+ export async function revokeGrantsByIds(grantIds) {
194
+ if (grantIds.length === 0)
195
+ return;
196
+ const pool = getPool();
197
+ await pool.query('DELETE FROM oidc_payloads WHERE grant_id = ANY($1)', [grantIds]);
198
+ }
199
+ /**
200
+ * Delete all expired oidc_payloads records (fire-and-forget).
201
+ *
202
+ * Called opportunistically on auth flow start to keep the oidc_payloads table
203
+ * clean without requiring a cron job or external scheduler. This pattern is
204
+ * proven from Porta v4 — self-regulating cleanup tied to actual usage.
205
+ *
206
+ * The function is intentionally fire-and-forget: it does NOT return a promise
207
+ * that callers should await. Errors are silently caught and logged — a failed
208
+ * cleanup is harmless (expired rows are already inert) and will be retried on
209
+ * the next auth flow start.
210
+ *
211
+ * Uses the expires_at index for efficient deletion.
212
+ */
213
+ export function purgeExpired() {
214
+ const pool = getPool();
215
+ pool
216
+ .query('DELETE FROM oidc_payloads WHERE expires_at IS NOT NULL AND expires_at < NOW()')
217
+ .catch((err) => {
218
+ // Fire-and-forget — log but don't interrupt the auth flow
219
+ logger.warn({ err }, 'Failed to purge expired oidc_payloads (will retry on next auth flow)');
220
+ });
221
+ }
222
+ //# sourceMappingURL=postgres-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-adapter.js","sourceRoot":"","sources":["../../src/oidc/postgres-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import type Provider from 'oidc-provider';
3
+ /** Stable categories for rejected requests at public OIDC protocol boundaries. */
4
+ export type ProtocolSecurityEventClass = 'authorization-rejected' | 'token-grant-rejected' | 'userinfo-rejected' | 'end-session-rejected' | 'introspection-rejected' | 'revocation-rejected' | 'client-tenant-binding-rejected' | 'interaction-context-rejected';
5
+ /** Minimal input accepted by the privacy-safe protocol rejection observer. */
6
+ export interface ProtocolSecurityRejectionInput {
7
+ /** Raw request shared by the outer Koa application and the OIDC provider. */
8
+ request: IncomingMessage;
9
+ /** Stable location-oriented rejection category. */
10
+ eventClass: ProtocolSecurityEventClass;
11
+ /** Public client identifier when the rejecting boundary has already parsed one. */
12
+ clientId?: string;
13
+ }
14
+ /**
15
+ * Associates a server-generated request identifier with the raw request object.
16
+ *
17
+ * A weak association lets the nested OIDC provider retrieve the identifier without copying
18
+ * request-controlled headers or retaining request state after Node releases the request.
19
+ */
20
+ export declare function registerProtocolRequestCorrelation(request: IncomingMessage, requestId: string): void;
21
+ /**
22
+ * Produces a stable one-way representation of a bounded public client identifier.
23
+ *
24
+ * The domain separator prevents the digest from being confused with hashes used for a different
25
+ * purpose. Missing or malformed identifiers remain `null`; the observer never invents an ID.
26
+ */
27
+ export declare function digestProtocolClientId(clientId: unknown): string | null;
28
+ /**
29
+ * Emits one bounded, privacy-safe security-rejection event per request and category.
30
+ *
31
+ * Observation is deliberately best-effort: missing correlation suppresses the event, and logging
32
+ * never performs I/O or changes the protocol response. Error objects, request parameters, and raw
33
+ * identifiers are intentionally outside this API.
34
+ */
35
+ export declare function observeProtocolSecurityRejection(input: ProtocolSecurityRejectionInput): void;
36
+ /** Registers the enabled provider rejection events covered by Porta's protocol assurance. */
37
+ export declare function registerProtocolSecurityObservers(provider: Provider): void;
38
+ //# sourceMappingURL=protocol-security-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-security-observer.d.ts","sourceRoot":"","sources":["../../src/oidc/protocol-security-observer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAU1C,kFAAkF;AAClF,MAAM,MAAM,0BAA0B,GAClC,wBAAwB,GACxB,sBAAsB,GACtB,mBAAmB,GACnB,sBAAsB,GACtB,wBAAwB,GACxB,qBAAqB,GACrB,gCAAgC,GAChC,8BAA8B,CAAC;AAEnC,8EAA8E;AAC9E,MAAM,WAAW,8BAA8B;IAC7C,6EAA6E;IAC7E,OAAO,EAAE,eAAe,CAAC;IACzB,mDAAmD;IACnD,UAAU,EAAE,0BAA0B,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,GAChB,IAAI,CAEN;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,8BAA8B,GAAG,IAAI,CAsB5F;AAqBD,6FAA6F;AAC7F,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAmB1E"}
@@ -0,0 +1,93 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { logger } from '../lib/logger.js';
3
+ const MAX_CLIENT_ID_LENGTH = 255;
4
+ const CLIENT_ID_DIGEST_DOMAIN = 'porta:oidc-client-id:v1\0';
5
+ const requestCorrelations = new WeakMap();
6
+ const observedClasses = new WeakMap();
7
+ /**
8
+ * Associates a server-generated request identifier with the raw request object.
9
+ *
10
+ * A weak association lets the nested OIDC provider retrieve the identifier without copying
11
+ * request-controlled headers or retaining request state after Node releases the request.
12
+ */
13
+ export function registerProtocolRequestCorrelation(request, requestId) {
14
+ requestCorrelations.set(request, requestId);
15
+ }
16
+ /**
17
+ * Produces a stable one-way representation of a bounded public client identifier.
18
+ *
19
+ * The domain separator prevents the digest from being confused with hashes used for a different
20
+ * purpose. Missing or malformed identifiers remain `null`; the observer never invents an ID.
21
+ */
22
+ export function digestProtocolClientId(clientId) {
23
+ if (typeof clientId !== 'string' ||
24
+ clientId.length === 0 ||
25
+ clientId.length > MAX_CLIENT_ID_LENGTH) {
26
+ return null;
27
+ }
28
+ return createHash('sha256').update(CLIENT_ID_DIGEST_DOMAIN).update(clientId).digest('hex');
29
+ }
30
+ /**
31
+ * Emits one bounded, privacy-safe security-rejection event per request and category.
32
+ *
33
+ * Observation is deliberately best-effort: missing correlation suppresses the event, and logging
34
+ * never performs I/O or changes the protocol response. Error objects, request parameters, and raw
35
+ * identifiers are intentionally outside this API.
36
+ */
37
+ export function observeProtocolSecurityRejection(input) {
38
+ const requestId = requestCorrelations.get(input.request);
39
+ if (requestId === undefined)
40
+ return;
41
+ const previous = observedClasses.get(input.request) ?? new Set();
42
+ if (previous.has(input.eventClass))
43
+ return;
44
+ previous.add(input.eventClass);
45
+ observedClasses.set(input.request, previous);
46
+ try {
47
+ logger.warn({
48
+ event: 'protocol-security-rejection',
49
+ 'synthetic-correlation-id': requestId,
50
+ 'event-class': input.eventClass,
51
+ 'public-client-id-digest': digestProtocolClientId(input.clientId),
52
+ }, 'protocol-security-rejection');
53
+ }
54
+ catch {
55
+ // Security observation must never change the protocol response or create a secondary failure.
56
+ }
57
+ }
58
+ function clientIdFromProviderContext(context) {
59
+ const resolvedClientId = context.oidc.client?.clientId;
60
+ if (typeof resolvedClientId === 'string')
61
+ return resolvedClientId;
62
+ const parameterClientId = context.oidc.params?.client_id;
63
+ return typeof parameterClientId === 'string' ? parameterClientId : undefined;
64
+ }
65
+ function observeProviderRejection(context, eventClass) {
66
+ observeProtocolSecurityRejection({
67
+ request: context.req,
68
+ eventClass,
69
+ clientId: clientIdFromProviderContext(context),
70
+ });
71
+ }
72
+ /** Registers the enabled provider rejection events covered by Porta's protocol assurance. */
73
+ export function registerProtocolSecurityObservers(provider) {
74
+ provider.on('authorization.error', (context) => {
75
+ observeProviderRejection(context, 'authorization-rejected');
76
+ });
77
+ provider.on('grant.error', (context) => {
78
+ observeProviderRejection(context, 'token-grant-rejected');
79
+ });
80
+ provider.on('userinfo.error', (context) => {
81
+ observeProviderRejection(context, 'userinfo-rejected');
82
+ });
83
+ provider.on('end_session.error', (context) => {
84
+ observeProviderRejection(context, 'end-session-rejected');
85
+ });
86
+ provider.on('introspection.error', (context) => {
87
+ observeProviderRejection(context, 'introspection-rejected');
88
+ });
89
+ provider.on('revocation.error', (context) => {
90
+ observeProviderRejection(context, 'revocation-rejected');
91
+ });
92
+ }
93
+ //# sourceMappingURL=protocol-security-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-security-observer.js","sourceRoot":"","sources":["../../src/oidc/protocol-security-observer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * OIDC provider factory.
3
+ *
4
+ * Creates and configures the node-oidc-provider instance with all
5
+ * configuration, adapters, keys, and account finder wired together.
6
+ * This is the main entry point for provider creation, called once at startup.
7
+ *
8
+ * The provider uses a base issuer URL and supports path-based
9
+ * multi-tenancy where each organization gets a unique issuer:
10
+ * {issuerBaseUrl}/{orgSlug}
11
+ */
12
+ import Provider from 'oidc-provider';
13
+ import type { OidcTtlConfig } from '../lib/system-config.js';
14
+ import type { JwkKeyPair } from '../lib/signing-keys.js';
15
+ /**
16
+ * Create and configure the node-oidc-provider instance.
17
+ *
18
+ * Wires together the adapter factory, signing keys, TTL config,
19
+ * account finder, CORS handler, and interaction URL builder into a
20
+ * single Provider instance ready to handle OIDC requests.
21
+ *
22
+ * Client lookup is handled by the adapter pattern: oidc-provider calls
23
+ * adapter.find('Client', id), which the adapter factory routes to
24
+ * findForOidc() in the clients service. This returns client metadata
25
+ * including SHA-256 hashed secrets for confidential clients.
26
+ *
27
+ * @param params.jwks - JWK key set loaded from the signing_keys table
28
+ * @param params.ttl - TTL configuration loaded from the system_config table
29
+ * @returns Configured Provider instance
30
+ */
31
+ export declare function createOidcProvider(params: {
32
+ jwks: {
33
+ keys: JwkKeyPair[];
34
+ };
35
+ ttl: OidcTtlConfig;
36
+ }): Promise<Provider>;
37
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/oidc/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOzD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC7B,GAAG,EAAE,aAAa,CAAC;CACpB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0CpB"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * OIDC provider factory.
3
+ *
4
+ * Creates and configures the node-oidc-provider instance with all
5
+ * configuration, adapters, keys, and account finder wired together.
6
+ * This is the main entry point for provider creation, called once at startup.
7
+ *
8
+ * The provider uses a base issuer URL and supports path-based
9
+ * multi-tenancy where each organization gets a unique issuer:
10
+ * {issuerBaseUrl}/{orgSlug}
11
+ */
12
+ import Provider from 'oidc-provider';
13
+ import { config } from '../config/index.js';
14
+ import { getRedis } from '../lib/redis.js';
15
+ import { logger } from '../lib/logger.js';
16
+ import { buildProviderConfiguration } from './configuration.js';
17
+ import { createAdapterFactory } from './adapter-factory.js';
18
+ import { findAccount } from './account-finder.js';
19
+ import { oidcCors } from '../middleware/oidc-cors.js';
20
+ import { registerProtocolSecurityObservers } from './protocol-security-observer.js';
21
+ /**
22
+ * Create and configure the node-oidc-provider instance.
23
+ *
24
+ * Wires together the adapter factory, signing keys, TTL config,
25
+ * account finder, CORS handler, and interaction URL builder into a
26
+ * single Provider instance ready to handle OIDC requests.
27
+ *
28
+ * Client lookup is handled by the adapter pattern: oidc-provider calls
29
+ * adapter.find('Client', id), which the adapter factory routes to
30
+ * findForOidc() in the clients service. This returns client metadata
31
+ * including SHA-256 hashed secrets for confidential clients.
32
+ *
33
+ * @param params.jwks - JWK key set loaded from the signing_keys table
34
+ * @param params.ttl - TTL configuration loaded from the system_config table
35
+ * @returns Configured Provider instance
36
+ */
37
+ export async function createOidcProvider(params) {
38
+ const { jwks, ttl } = params;
39
+ // Build the complete provider configuration from all dependencies
40
+ const configuration = buildProviderConfiguration({
41
+ ttl,
42
+ jwks,
43
+ cookieKeys: config.cookieKeys,
44
+ findAccount,
45
+ adapterFactory: createAdapterFactory(),
46
+ clientBasedCORS: oidcCors,
47
+ // Interaction URL builder.
48
+ // Also stores the auth-flow org ID in Redis so interaction handlers
49
+ // can recover the validated client tenant after the URL slug is stripped.
50
+ interactionUrl: (ctx, interaction) => {
51
+ const req = ctx.req ?? ctx.request?.req;
52
+ const org = req?._portaOrganization;
53
+ if (org?.id && interaction?.uid) {
54
+ getRedis()
55
+ .set(`interaction:org:${interaction.uid}`, org.id, 'EX', 3600)
56
+ .catch((err) => logger.warn({ err }, 'Failed to store interaction org'));
57
+ }
58
+ return `/interaction/${interaction.uid}`;
59
+ },
60
+ });
61
+ // Create provider with base issuer URL.
62
+ // The actual per-org issuer is resolved dynamically via URL rewriting
63
+ // in the Koa router (server.ts strips the /:orgSlug prefix).
64
+ const provider = new Provider(config.issuerBaseUrl, configuration);
65
+ registerProtocolSecurityObservers(provider);
66
+ // Enable proxy mode — required for path-based multi-tenancy so the
67
+ // provider trusts forwarded headers and handles URL rewriting correctly.
68
+ provider.proxy = true;
69
+ return provider;
70
+ }
71
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/oidc/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AAEpF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAGxC;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAE7B,kEAAkE;IAClE,MAAM,aAAa,GAAG,0BAA0B,CAAC;QAC/C,GAAG;QACH,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW;QACX,cAAc,EAAE,oBAAoB,EAAE;QACtC,eAAe,EAAE,QAAQ;QACzB,2BAA2B;QAC3B,oEAAoE;QACpE,0EAA0E;QAC1E,cAAc,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE;YAKnC,MAAM,GAAG,GACN,GAA8B,CAAC,GAAG,IAAK,GAA8B,CAAC,OAAO,EAAE,GAAG,CAAC;YACtF,MAAM,GAAG,GAAG,GAAG,EAAE,kBAAkB,CAAC;YACpC,IAAI,GAAG,EAAE,EAAE,IAAI,WAAW,EAAE,GAAG,EAAE,CAAC;gBAChC,QAAQ,EAAE;qBACP,GAAG,CAAC,mBAAmB,WAAW,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC;qBAC7D,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAC,CAAC;YACtF,CAAC;YACD,OAAO,gBAAgB,WAAW,CAAC,GAAG,EAAE,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;IAEH,wCAAwC;IACxC,sEAAsE;IACtE,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACnE,iCAAiC,CAAC,QAAQ,CAAC,CAAC;IAE5C,mEAAmE;IACnE,yEAAyE;IACzE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;IAEtB,OAAO,QAAQ,CAAC;AAClB,CAAC"}