@payez/next-mvp 3.0.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 (654) hide show
  1. package/README.md +782 -0
  2. package/dist/api/auth-handler.d.ts +67 -0
  3. package/dist/api/auth-handler.js +397 -0
  4. package/dist/api/index.d.ts +10 -0
  5. package/dist/api/index.js +19 -0
  6. package/dist/api-handlers/account/change-password.d.ts +9 -0
  7. package/dist/api-handlers/account/change-password.js +112 -0
  8. package/dist/api-handlers/account/masked-info.d.ts +2 -0
  9. package/dist/api-handlers/account/masked-info.js +41 -0
  10. package/dist/api-handlers/account/profile.d.ts +3 -0
  11. package/dist/api-handlers/account/profile.js +63 -0
  12. package/dist/api-handlers/account/recovery/initiate.d.ts +2 -0
  13. package/dist/api-handlers/account/recovery/initiate.js +26 -0
  14. package/dist/api-handlers/account/recovery/send-code.d.ts +2 -0
  15. package/dist/api-handlers/account/recovery/send-code.js +28 -0
  16. package/dist/api-handlers/account/recovery/verify-code.d.ts +2 -0
  17. package/dist/api-handlers/account/recovery/verify-code.js +28 -0
  18. package/dist/api-handlers/account/reset-password.d.ts +2 -0
  19. package/dist/api-handlers/account/reset-password.js +26 -0
  20. package/dist/api-handlers/account/send-code.d.ts +24 -0
  21. package/dist/api-handlers/account/send-code.js +60 -0
  22. package/dist/api-handlers/account/update-phone.d.ts +27 -0
  23. package/dist/api-handlers/account/update-phone.js +64 -0
  24. package/dist/api-handlers/account/validate-password.d.ts +17 -0
  25. package/dist/api-handlers/account/validate-password.js +81 -0
  26. package/dist/api-handlers/account/verify-email.d.ts +26 -0
  27. package/dist/api-handlers/account/verify-email.js +106 -0
  28. package/dist/api-handlers/account/verify-sms.d.ts +26 -0
  29. package/dist/api-handlers/account/verify-sms.js +106 -0
  30. package/dist/api-handlers/admin/analytics.d.ts +20 -0
  31. package/dist/api-handlers/admin/analytics.js +379 -0
  32. package/dist/api-handlers/admin/audit.d.ts +20 -0
  33. package/dist/api-handlers/admin/audit.js +214 -0
  34. package/dist/api-handlers/admin/index.d.ts +21 -0
  35. package/dist/api-handlers/admin/index.js +41 -0
  36. package/dist/api-handlers/admin/redis-sessions.d.ts +36 -0
  37. package/dist/api-handlers/admin/redis-sessions.js +204 -0
  38. package/dist/api-handlers/admin/sessions.d.ts +21 -0
  39. package/dist/api-handlers/admin/sessions.js +284 -0
  40. package/dist/api-handlers/admin/site-logs.d.ts +46 -0
  41. package/dist/api-handlers/admin/site-logs.js +318 -0
  42. package/dist/api-handlers/admin/users.d.ts +20 -0
  43. package/dist/api-handlers/admin/users.js +222 -0
  44. package/dist/api-handlers/admin/vibe-data.d.ts +80 -0
  45. package/dist/api-handlers/admin/vibe-data.js +268 -0
  46. package/dist/api-handlers/anon/preferences.d.ts +37 -0
  47. package/dist/api-handlers/anon/preferences.js +96 -0
  48. package/dist/api-handlers/auth/jwks.d.ts +2 -0
  49. package/dist/api-handlers/auth/jwks.js +24 -0
  50. package/dist/api-handlers/auth/login.d.ts +42 -0
  51. package/dist/api-handlers/auth/login.js +178 -0
  52. package/dist/api-handlers/auth/refresh.d.ts +74 -0
  53. package/dist/api-handlers/auth/refresh.js +635 -0
  54. package/dist/api-handlers/auth/signout.d.ts +37 -0
  55. package/dist/api-handlers/auth/signout.js +187 -0
  56. package/dist/api-handlers/auth/status.d.ts +8 -0
  57. package/dist/api-handlers/auth/status.js +26 -0
  58. package/dist/api-handlers/auth/update-session.d.ts +37 -0
  59. package/dist/api-handlers/auth/update-session.js +95 -0
  60. package/dist/api-handlers/auth/validate.d.ts +6 -0
  61. package/dist/api-handlers/auth/validate.js +43 -0
  62. package/dist/api-handlers/auth/verify-code.d.ts +43 -0
  63. package/dist/api-handlers/auth/verify-code.js +94 -0
  64. package/dist/api-handlers/session/refresh-viability.d.ts +14 -0
  65. package/dist/api-handlers/session/refresh-viability.js +39 -0
  66. package/dist/api-handlers/session/viability.d.ts +13 -0
  67. package/dist/api-handlers/session/viability.js +146 -0
  68. package/dist/api-handlers/test/force-expire.d.ts +23 -0
  69. package/dist/api-handlers/test/force-expire.js +65 -0
  70. package/dist/auth/auth-decision.d.ts +39 -0
  71. package/dist/auth/auth-decision.js +182 -0
  72. package/dist/auth/auth-options.d.ts +57 -0
  73. package/dist/auth/auth-options.js +213 -0
  74. package/dist/auth/callbacks/index.d.ts +6 -0
  75. package/dist/auth/callbacks/index.js +12 -0
  76. package/dist/auth/callbacks/jwt.d.ts +45 -0
  77. package/dist/auth/callbacks/jwt.js +305 -0
  78. package/dist/auth/callbacks/session.d.ts +60 -0
  79. package/dist/auth/callbacks/session.js +170 -0
  80. package/dist/auth/callbacks/signin.d.ts +23 -0
  81. package/dist/auth/callbacks/signin.js +44 -0
  82. package/dist/auth/events/index.d.ts +4 -0
  83. package/dist/auth/events/index.js +8 -0
  84. package/dist/auth/events/signout.d.ts +17 -0
  85. package/dist/auth/events/signout.js +32 -0
  86. package/dist/auth/providers/credentials.d.ts +32 -0
  87. package/dist/auth/providers/credentials.js +223 -0
  88. package/dist/auth/providers/index.d.ts +5 -0
  89. package/dist/auth/providers/index.js +21 -0
  90. package/dist/auth/providers/oauth.d.ts +26 -0
  91. package/dist/auth/providers/oauth.js +105 -0
  92. package/dist/auth/route-config.d.ts +66 -0
  93. package/dist/auth/route-config.js +190 -0
  94. package/dist/auth/types/auth-types.d.ts +417 -0
  95. package/dist/auth/types/auth-types.js +53 -0
  96. package/dist/auth/types/index.d.ts +6 -0
  97. package/dist/auth/types/index.js +22 -0
  98. package/dist/auth/unauthenticated-routes.d.ts +1 -0
  99. package/dist/auth/unauthenticated-routes.js +19 -0
  100. package/dist/auth/utils/idp-client.d.ts +94 -0
  101. package/dist/auth/utils/idp-client.js +383 -0
  102. package/dist/auth/utils/index.d.ts +5 -0
  103. package/dist/auth/utils/index.js +21 -0
  104. package/dist/auth/utils/token-utils.d.ts +84 -0
  105. package/dist/auth/utils/token-utils.js +219 -0
  106. package/dist/client/AuthContext.d.ts +19 -0
  107. package/dist/client/AuthContext.js +112 -0
  108. package/dist/client/fetch-with-auth.d.ts +11 -0
  109. package/dist/client/fetch-with-auth.js +44 -0
  110. package/dist/client/fetchWithSession.d.ts +3 -0
  111. package/dist/client/fetchWithSession.js +24 -0
  112. package/dist/client/index.d.ts +9 -0
  113. package/dist/client/index.js +20 -0
  114. package/dist/client/useAnonSession.d.ts +36 -0
  115. package/dist/client/useAnonSession.js +99 -0
  116. package/dist/components/SessionSync.d.ts +13 -0
  117. package/dist/components/SessionSync.js +119 -0
  118. package/dist/components/SignalRHealthCheck.d.ts +10 -0
  119. package/dist/components/SignalRHealthCheck.js +97 -0
  120. package/dist/components/account/UserAvatarMenu.d.ts +20 -0
  121. package/dist/components/account/UserAvatarMenu.js +80 -0
  122. package/dist/components/account/index.d.ts +7 -0
  123. package/dist/components/account/index.js +10 -0
  124. package/dist/components/admin/AlertSettingsTab.d.ts +48 -0
  125. package/dist/components/admin/AlertSettingsTab.js +351 -0
  126. package/dist/components/admin/AnalyticsTab.d.ts +22 -0
  127. package/dist/components/admin/AnalyticsTab.js +167 -0
  128. package/dist/components/admin/DataBrowserTab.d.ts +19 -0
  129. package/dist/components/admin/DataBrowserTab.js +252 -0
  130. package/dist/components/admin/LoggingSettingsTab.d.ts +73 -0
  131. package/dist/components/admin/LoggingSettingsTab.js +339 -0
  132. package/dist/components/admin/SessionsTab.d.ts +37 -0
  133. package/dist/components/admin/SessionsTab.js +165 -0
  134. package/dist/components/admin/StatsTab.d.ts +53 -0
  135. package/dist/components/admin/StatsTab.js +161 -0
  136. package/dist/components/admin/VibeAdminContext.d.ts +32 -0
  137. package/dist/components/admin/VibeAdminContext.js +38 -0
  138. package/dist/components/admin/VibeAdminLayout.d.ts +11 -0
  139. package/dist/components/admin/VibeAdminLayout.js +69 -0
  140. package/dist/components/admin/index.d.ts +29 -0
  141. package/dist/components/admin/index.js +44 -0
  142. package/dist/components/auth/FederatedAuthSection.d.ts +8 -0
  143. package/dist/components/auth/FederatedAuthSection.js +45 -0
  144. package/dist/components/auth/ModeAwareLoginPage.d.ts +10 -0
  145. package/dist/components/auth/ModeAwareLoginPage.js +42 -0
  146. package/dist/components/auth/ModeAwareSignupPage.d.ts +9 -0
  147. package/dist/components/auth/ModeAwareSignupPage.js +78 -0
  148. package/dist/components/auth/TraditionalAuthSection.d.ts +14 -0
  149. package/dist/components/auth/TraditionalAuthSection.js +20 -0
  150. package/dist/components/recovery/CompleteStep.d.ts +5 -0
  151. package/dist/components/recovery/CompleteStep.js +8 -0
  152. package/dist/components/recovery/InitiateRecoveryStep.d.ts +8 -0
  153. package/dist/components/recovery/InitiateRecoveryStep.js +20 -0
  154. package/dist/components/recovery/SelectMethodStep.d.ts +8 -0
  155. package/dist/components/recovery/SelectMethodStep.js +8 -0
  156. package/dist/components/recovery/SetPasswordStep.d.ts +6 -0
  157. package/dist/components/recovery/SetPasswordStep.js +20 -0
  158. package/dist/components/recovery/VerifyCodeStep.d.ts +10 -0
  159. package/dist/components/recovery/VerifyCodeStep.js +24 -0
  160. package/dist/components/reserved/ReservedRecoveryWarning.d.ts +38 -0
  161. package/dist/components/reserved/ReservedRecoveryWarning.js +92 -0
  162. package/dist/components/reserved/ReservedStatusBox.d.ts +30 -0
  163. package/dist/components/reserved/ReservedStatusBox.js +71 -0
  164. package/dist/components/ui/BetaBadge.d.ts +29 -0
  165. package/dist/components/ui/BetaBadge.js +38 -0
  166. package/dist/components/ui/Footer.d.ts +37 -0
  167. package/dist/components/ui/Footer.js +41 -0
  168. package/dist/config/env.d.ts +66 -0
  169. package/dist/config/env.js +57 -0
  170. package/dist/config/logger.d.ts +57 -0
  171. package/dist/config/logger.js +73 -0
  172. package/dist/config/logging-config.d.ts +30 -0
  173. package/dist/config/logging-config.js +122 -0
  174. package/dist/config/unauthenticated-routes.d.ts +17 -0
  175. package/dist/config/unauthenticated-routes.js +24 -0
  176. package/dist/config/vibe-log-transport.d.ts +79 -0
  177. package/dist/config/vibe-log-transport.js +203 -0
  178. package/dist/edge/internal-api-url.d.ts +53 -0
  179. package/dist/edge/internal-api-url.js +63 -0
  180. package/dist/edge/middleware.d.ts +14 -0
  181. package/dist/edge/middleware.js +32 -0
  182. package/dist/hooks/useAuth.d.ts +23 -0
  183. package/dist/hooks/useAuth.js +81 -0
  184. package/dist/hooks/useAuthSettings.d.ts +59 -0
  185. package/dist/hooks/useAuthSettings.js +93 -0
  186. package/dist/hooks/useAvailableProviders.d.ts +45 -0
  187. package/dist/hooks/useAvailableProviders.js +108 -0
  188. package/dist/hooks/usePasswordValidation.d.ts +27 -0
  189. package/dist/hooks/usePasswordValidation.js +102 -0
  190. package/dist/hooks/useProfile.d.ts +15 -0
  191. package/dist/hooks/useProfile.js +59 -0
  192. package/dist/hooks/usePublicAuthSettings.d.ts +56 -0
  193. package/dist/hooks/usePublicAuthSettings.js +131 -0
  194. package/dist/hooks/useSessionExpiration.d.ts +57 -0
  195. package/dist/hooks/useSessionExpiration.js +72 -0
  196. package/dist/hooks/useViabilitySession.d.ts +75 -0
  197. package/dist/hooks/useViabilitySession.js +268 -0
  198. package/dist/index.d.ts +12 -0
  199. package/dist/index.js +54 -0
  200. package/dist/lib/anon-session.d.ts +74 -0
  201. package/dist/lib/anon-session.js +169 -0
  202. package/dist/lib/api-handler.d.ts +123 -0
  203. package/dist/lib/api-handler.js +478 -0
  204. package/dist/lib/app-slug.d.ts +95 -0
  205. package/dist/lib/app-slug.js +172 -0
  206. package/dist/lib/demo-mode.d.ts +6 -0
  207. package/dist/lib/demo-mode.js +16 -0
  208. package/dist/lib/geolocation.d.ts +64 -0
  209. package/dist/lib/geolocation.js +235 -0
  210. package/dist/lib/idp-client-config.d.ts +75 -0
  211. package/dist/lib/idp-client-config.js +351 -0
  212. package/dist/lib/idp-fetch.d.ts +14 -0
  213. package/dist/lib/idp-fetch.js +91 -0
  214. package/dist/lib/internal-api.d.ts +87 -0
  215. package/dist/lib/internal-api.js +122 -0
  216. package/dist/lib/jwt-decode-client.d.ts +10 -0
  217. package/dist/lib/jwt-decode-client.js +46 -0
  218. package/dist/lib/jwt-decode.d.ts +48 -0
  219. package/dist/lib/jwt-decode.js +57 -0
  220. package/dist/lib/nextauth-secret.d.ts +10 -0
  221. package/dist/lib/nextauth-secret.js +104 -0
  222. package/dist/lib/rate-limit-service.d.ts +23 -0
  223. package/dist/lib/rate-limit-service.js +6 -0
  224. package/dist/lib/redis.d.ts +5 -0
  225. package/dist/lib/redis.js +28 -0
  226. package/dist/lib/refresh-token-validator.d.ts +13 -0
  227. package/dist/lib/refresh-token-validator.js +117 -0
  228. package/dist/lib/roles.d.ts +145 -0
  229. package/dist/lib/roles.js +168 -0
  230. package/dist/lib/secret-validation.d.ts +4 -0
  231. package/dist/lib/secret-validation.js +14 -0
  232. package/dist/lib/session-store.d.ts +166 -0
  233. package/dist/lib/session-store.js +537 -0
  234. package/dist/lib/session.d.ts +21 -0
  235. package/dist/lib/session.js +26 -0
  236. package/dist/lib/site-logger.d.ts +214 -0
  237. package/dist/lib/site-logger.js +210 -0
  238. package/dist/lib/standardized-client-api.d.ts +161 -0
  239. package/dist/lib/standardized-client-api.js +786 -0
  240. package/dist/lib/startup-init.d.ts +40 -0
  241. package/dist/lib/startup-init.js +261 -0
  242. package/dist/lib/test-aware-get-token.d.ts +2 -0
  243. package/dist/lib/test-aware-get-token.js +81 -0
  244. package/dist/lib/token-expiry.d.ts +14 -0
  245. package/dist/lib/token-expiry.js +39 -0
  246. package/dist/lib/token-lifecycle.d.ts +52 -0
  247. package/dist/lib/token-lifecycle.js +398 -0
  248. package/dist/lib/types/api-responses.d.ts +128 -0
  249. package/dist/lib/types/api-responses.js +171 -0
  250. package/dist/lib/user-agent-parser.d.ts +50 -0
  251. package/dist/lib/user-agent-parser.js +220 -0
  252. package/dist/logging/api/admin-analytics.d.ts +3 -0
  253. package/dist/logging/api/admin-analytics.js +45 -0
  254. package/dist/logging/api/audit-log.d.ts +3 -0
  255. package/dist/logging/api/audit-log.js +52 -0
  256. package/dist/logging/components/AdminAnalyticsLayout.d.ts +10 -0
  257. package/dist/logging/components/AdminAnalyticsLayout.js +11 -0
  258. package/dist/logging/components/AuditLogViewer.d.ts +7 -0
  259. package/dist/logging/components/AuditLogViewer.js +51 -0
  260. package/dist/logging/components/ErrorMetricsCard.d.ts +7 -0
  261. package/dist/logging/components/ErrorMetricsCard.js +16 -0
  262. package/dist/logging/components/HealthMetricsCard.d.ts +7 -0
  263. package/dist/logging/components/HealthMetricsCard.js +19 -0
  264. package/dist/logging/hooks/useAdminAnalytics.d.ts +24 -0
  265. package/dist/logging/hooks/useAdminAnalytics.js +22 -0
  266. package/dist/logging/hooks/useAuditLog.d.ts +6 -0
  267. package/dist/logging/hooks/useAuditLog.js +25 -0
  268. package/dist/logging/hooks/useErrorMetrics.d.ts +6 -0
  269. package/dist/logging/hooks/useErrorMetrics.js +38 -0
  270. package/dist/logging/hooks/useHealthMetrics.d.ts +6 -0
  271. package/dist/logging/hooks/useHealthMetrics.js +41 -0
  272. package/dist/logging/index.d.ts +11 -0
  273. package/dist/logging/index.js +40 -0
  274. package/dist/logging/types/analytics.d.ts +68 -0
  275. package/dist/logging/types/analytics.js +3 -0
  276. package/dist/logging/types/audit.d.ts +29 -0
  277. package/dist/logging/types/audit.js +2 -0
  278. package/dist/logging/types/index.d.ts +2 -0
  279. package/dist/logging/types/index.js +19 -0
  280. package/dist/middleware/auth-decision.d.ts +33 -0
  281. package/dist/middleware/auth-decision.js +65 -0
  282. package/dist/middleware/create-middleware.d.ts +100 -0
  283. package/dist/middleware/create-middleware.js +445 -0
  284. package/dist/middleware/rbac-check.d.ts +44 -0
  285. package/dist/middleware/rbac-check.js +191 -0
  286. package/dist/middleware/twofa-presets.d.ts +134 -0
  287. package/dist/middleware/twofa-presets.js +175 -0
  288. package/dist/models/DecodedAccessToken.d.ts +17 -0
  289. package/dist/models/DecodedAccessToken.js +2 -0
  290. package/dist/models/SessionModel.d.ts +122 -0
  291. package/dist/models/SessionModel.js +136 -0
  292. package/dist/pages/admin-login/page.d.ts +31 -0
  293. package/dist/pages/admin-login/page.js +83 -0
  294. package/dist/pages/admin-roles/RolesAdminPage.d.ts +15 -0
  295. package/dist/pages/admin-roles/RolesAdminPage.js +78 -0
  296. package/dist/pages/admin-roles/index.d.ts +8 -0
  297. package/dist/pages/admin-roles/index.js +15 -0
  298. package/dist/pages/admin-roles/modals.d.ts +72 -0
  299. package/dist/pages/admin-roles/modals.js +154 -0
  300. package/dist/pages/client-admin/ClientSiteAdminPage.d.ts +79 -0
  301. package/dist/pages/client-admin/ClientSiteAdminPage.js +177 -0
  302. package/dist/pages/client-admin/index.d.ts +32 -0
  303. package/dist/pages/client-admin/index.js +37 -0
  304. package/dist/pages/login/page.d.ts +22 -0
  305. package/dist/pages/login/page.js +239 -0
  306. package/dist/pages/profile/EnhancedProfilePage.d.ts +13 -0
  307. package/dist/pages/profile/EnhancedProfilePage.js +150 -0
  308. package/dist/pages/profile/index.d.ts +8 -0
  309. package/dist/pages/profile/index.js +16 -0
  310. package/dist/pages/profile/page.d.ts +19 -0
  311. package/dist/pages/profile/page.js +47 -0
  312. package/dist/pages/profile/profile-patch.d.ts +1 -0
  313. package/dist/pages/profile/profile-patch.js +281 -0
  314. package/dist/pages/recovery/page.d.ts +1 -0
  315. package/dist/pages/recovery/page.js +142 -0
  316. package/dist/pages/roles/MyRolesPage.d.ts +24 -0
  317. package/dist/pages/roles/MyRolesPage.js +71 -0
  318. package/dist/pages/roles/components.d.ts +63 -0
  319. package/dist/pages/roles/components.js +108 -0
  320. package/dist/pages/roles/index.d.ts +8 -0
  321. package/dist/pages/roles/index.js +19 -0
  322. package/dist/pages/security/EnhancedSecurityPage.d.ts +14 -0
  323. package/dist/pages/security/EnhancedSecurityPage.js +248 -0
  324. package/dist/pages/security/index.d.ts +8 -0
  325. package/dist/pages/security/index.js +16 -0
  326. package/dist/pages/security/page.d.ts +21 -0
  327. package/dist/pages/security/page.js +212 -0
  328. package/dist/pages/security/security-patch.d.ts +1 -0
  329. package/dist/pages/security/security-patch.js +302 -0
  330. package/dist/pages/settings/EnhancedSettingsPage.d.ts +46 -0
  331. package/dist/pages/settings/EnhancedSettingsPage.js +231 -0
  332. package/dist/pages/settings/index.d.ts +8 -0
  333. package/dist/pages/settings/index.js +16 -0
  334. package/dist/pages/settings/page.d.ts +7 -0
  335. package/dist/pages/settings/page.js +26 -0
  336. package/dist/pages/showcase/ShowcasePage.d.ts +13 -0
  337. package/dist/pages/showcase/ShowcasePage.js +140 -0
  338. package/dist/pages/showcase/index.d.ts +12 -0
  339. package/dist/pages/showcase/index.js +17 -0
  340. package/dist/pages/test-env/EmergencyLogoutPage.d.ts +14 -0
  341. package/dist/pages/test-env/EmergencyLogoutPage.js +98 -0
  342. package/dist/pages/test-env/JwtInspectPage.d.ts +14 -0
  343. package/dist/pages/test-env/JwtInspectPage.js +114 -0
  344. package/dist/pages/test-env/RefreshTokenPage.d.ts +15 -0
  345. package/dist/pages/test-env/RefreshTokenPage.js +91 -0
  346. package/dist/pages/test-env/TestEnvPage.d.ts +13 -0
  347. package/dist/pages/test-env/TestEnvPage.js +49 -0
  348. package/dist/pages/test-env/index.d.ts +24 -0
  349. package/dist/pages/test-env/index.js +32 -0
  350. package/dist/pages/verify-code/page.d.ts +30 -0
  351. package/dist/pages/verify-code/page.js +408 -0
  352. package/dist/routes/account/index.d.ts +28 -0
  353. package/dist/routes/account/index.js +71 -0
  354. package/dist/routes/account/masked-info.d.ts +33 -0
  355. package/dist/routes/account/masked-info.js +39 -0
  356. package/dist/routes/account/send-code.d.ts +37 -0
  357. package/dist/routes/account/send-code.js +42 -0
  358. package/dist/routes/account/update-phone.d.ts +13 -0
  359. package/dist/routes/account/update-phone.js +17 -0
  360. package/dist/routes/account/verify-email.d.ts +38 -0
  361. package/dist/routes/account/verify-email.js +43 -0
  362. package/dist/routes/account/verify-sms.d.ts +38 -0
  363. package/dist/routes/account/verify-sms.js +43 -0
  364. package/dist/routes/auth/index.d.ts +19 -0
  365. package/dist/routes/auth/index.js +64 -0
  366. package/dist/routes/auth/logout.d.ts +31 -0
  367. package/dist/routes/auth/logout.js +113 -0
  368. package/dist/routes/auth/nextauth.d.ts +19 -0
  369. package/dist/routes/auth/nextauth.js +72 -0
  370. package/dist/routes/auth/refresh.d.ts +30 -0
  371. package/dist/routes/auth/refresh.js +51 -0
  372. package/dist/routes/auth/session.d.ts +72 -0
  373. package/dist/routes/auth/session.js +180 -0
  374. package/dist/routes/auth/settings.d.ts +25 -0
  375. package/dist/routes/auth/settings.js +55 -0
  376. package/dist/routes/auth/viability.d.ts +52 -0
  377. package/dist/routes/auth/viability.js +201 -0
  378. package/dist/routes/index.d.ts +12 -0
  379. package/dist/routes/index.js +54 -0
  380. package/dist/routes/session/index.d.ts +6 -0
  381. package/dist/routes/session/index.js +10 -0
  382. package/dist/routes/session/refresh-viability.d.ts +16 -0
  383. package/dist/routes/session/refresh-viability.js +20 -0
  384. package/dist/services/signalrActivityService.d.ts +44 -0
  385. package/dist/services/signalrActivityService.js +257 -0
  386. package/dist/stores/authStore.d.ts +154 -0
  387. package/dist/stores/authStore.js +1531 -0
  388. package/dist/theme/ThemeProvider.d.ts +14 -0
  389. package/dist/theme/ThemeProvider.js +28 -0
  390. package/dist/theme/default.d.ts +8 -0
  391. package/dist/theme/default.js +33 -0
  392. package/dist/theme/index.d.ts +15 -0
  393. package/dist/theme/index.js +25 -0
  394. package/dist/theme/types.d.ts +56 -0
  395. package/dist/theme/types.js +8 -0
  396. package/dist/theme/useTheme.d.ts +60 -0
  397. package/dist/theme/useTheme.js +63 -0
  398. package/dist/theme/utils.d.ts +13 -0
  399. package/dist/theme/utils.js +39 -0
  400. package/dist/types/api.d.ts +134 -0
  401. package/dist/types/api.js +44 -0
  402. package/dist/types/auth.d.ts +19 -0
  403. package/dist/types/auth.js +2 -0
  404. package/dist/types/logging.d.ts +42 -0
  405. package/dist/types/logging.js +2 -0
  406. package/dist/types/recovery.d.ts +48 -0
  407. package/dist/types/recovery.js +2 -0
  408. package/dist/types/security.d.ts +1 -0
  409. package/dist/types/security.js +2 -0
  410. package/dist/utils/api.d.ts +85 -0
  411. package/dist/utils/api.js +287 -0
  412. package/dist/utils/circuitBreaker.d.ts +43 -0
  413. package/dist/utils/circuitBreaker.js +91 -0
  414. package/dist/utils/error-message.d.ts +1 -0
  415. package/dist/utils/error-message.js +103 -0
  416. package/dist/utils/layout/reservedSpace.d.ts +59 -0
  417. package/dist/utils/layout/reservedSpace.js +102 -0
  418. package/dist/utils/logout.d.ts +14 -0
  419. package/dist/utils/logout.js +32 -0
  420. package/dist/vibe/client.d.ts +261 -0
  421. package/dist/vibe/client.js +445 -0
  422. package/dist/vibe/errors.d.ts +83 -0
  423. package/dist/vibe/errors.js +146 -0
  424. package/dist/vibe/generic.d.ts +234 -0
  425. package/dist/vibe/generic.js +369 -0
  426. package/dist/vibe/hooks/index.d.ts +169 -0
  427. package/dist/vibe/hooks/index.js +252 -0
  428. package/dist/vibe/index.d.ts +23 -0
  429. package/dist/vibe/index.js +67 -0
  430. package/dist/vibe/sessions.d.ts +161 -0
  431. package/dist/vibe/sessions.js +391 -0
  432. package/dist/vibe/types.d.ts +353 -0
  433. package/dist/vibe/types.js +315 -0
  434. package/package.json +855 -0
  435. package/scripts/check-internal-url-usage.sh +73 -0
  436. package/scripts/dev-broker.ps1 +35 -0
  437. package/scripts/dev-local.ps1 +45 -0
  438. package/src/api/auth-handler.ts +550 -0
  439. package/src/api/index.ts +18 -0
  440. package/src/api-handlers/account/change-password.ts +145 -0
  441. package/src/api-handlers/account/masked-info.ts +45 -0
  442. package/src/api-handlers/account/profile.ts +80 -0
  443. package/src/api-handlers/account/recovery/initiate.ts +23 -0
  444. package/src/api-handlers/account/recovery/send-code.ts +25 -0
  445. package/src/api-handlers/account/recovery/verify-code.ts +25 -0
  446. package/src/api-handlers/account/reset-password.ts +23 -0
  447. package/src/api-handlers/account/send-code.ts +76 -0
  448. package/src/api-handlers/account/update-phone.ts +79 -0
  449. package/src/api-handlers/account/validate-password.ts +118 -0
  450. package/src/api-handlers/account/verify-email.ts +125 -0
  451. package/src/api-handlers/account/verify-sms.ts +125 -0
  452. package/src/api-handlers/admin/analytics.ts +445 -0
  453. package/src/api-handlers/admin/audit.ts +225 -0
  454. package/src/api-handlers/admin/index.ts +59 -0
  455. package/src/api-handlers/admin/redis-sessions.ts +253 -0
  456. package/src/api-handlers/admin/sessions.ts +320 -0
  457. package/src/api-handlers/admin/site-logs.ts +367 -0
  458. package/src/api-handlers/admin/users.ts +244 -0
  459. package/src/api-handlers/admin/vibe-data.ts +326 -0
  460. package/src/api-handlers/anon/preferences.ts +123 -0
  461. package/src/api-handlers/auth/jwks.ts +20 -0
  462. package/src/api-handlers/auth/login.ts +240 -0
  463. package/src/api-handlers/auth/refresh.ts +687 -0
  464. package/src/api-handlers/auth/signout.ts +212 -0
  465. package/src/api-handlers/auth/status.ts +23 -0
  466. package/src/api-handlers/auth/update-session.ts +125 -0
  467. package/src/api-handlers/auth/validate.ts +44 -0
  468. package/src/api-handlers/auth/verify-code.ts +129 -0
  469. package/src/api-handlers/session/refresh-viability.ts +36 -0
  470. package/src/api-handlers/session/viability.ts +166 -0
  471. package/src/api-handlers/test/force-expire.ts +67 -0
  472. package/src/auth/auth-decision.ts +230 -0
  473. package/src/auth/auth-options.ts +237 -0
  474. package/src/auth/callbacks/index.ts +7 -0
  475. package/src/auth/callbacks/jwt.ts +382 -0
  476. package/src/auth/callbacks/session.ts +243 -0
  477. package/src/auth/callbacks/signin.ts +56 -0
  478. package/src/auth/events/index.ts +5 -0
  479. package/src/auth/events/signout.ts +33 -0
  480. package/src/auth/providers/credentials.ts +256 -0
  481. package/src/auth/providers/index.ts +6 -0
  482. package/src/auth/providers/oauth.ts +114 -0
  483. package/src/auth/route-config.ts +220 -0
  484. package/src/auth/types/auth-types.ts +555 -0
  485. package/src/auth/types/index.ts +7 -0
  486. package/src/auth/unauthenticated-routes.ts +3 -0
  487. package/src/auth/utils/idp-client.ts +444 -0
  488. package/src/auth/utils/index.ts +6 -0
  489. package/src/auth/utils/token-utils.ts +244 -0
  490. package/src/client/AuthContext.tsx +140 -0
  491. package/src/client/fetch-with-auth.ts +48 -0
  492. package/src/client/fetchWithSession.ts +21 -0
  493. package/src/client/index.ts +13 -0
  494. package/src/client/useAnonSession.ts +131 -0
  495. package/src/components/SessionSync.tsx +137 -0
  496. package/src/components/SignalRHealthCheck.tsx +131 -0
  497. package/src/components/account/UserAvatarMenu.tsx +217 -0
  498. package/src/components/account/index.ts +8 -0
  499. package/src/components/admin/AlertSettingsTab.tsx +728 -0
  500. package/src/components/admin/AnalyticsTab.tsx +703 -0
  501. package/src/components/admin/DataBrowserTab.tsx +505 -0
  502. package/src/components/admin/LoggingSettingsTab.tsx +665 -0
  503. package/src/components/admin/SessionsTab.tsx +414 -0
  504. package/src/components/admin/StatsTab.tsx +379 -0
  505. package/src/components/admin/VibeAdminContext.tsx +87 -0
  506. package/src/components/admin/VibeAdminLayout.tsx +185 -0
  507. package/src/components/admin/index.ts +59 -0
  508. package/src/components/auth/FederatedAuthSection.tsx +95 -0
  509. package/src/components/auth/ModeAwareLoginPage.tsx +135 -0
  510. package/src/components/auth/ModeAwareSignupPage.tsx +267 -0
  511. package/src/components/auth/TraditionalAuthSection.tsx +99 -0
  512. package/src/components/recovery/CompleteStep.tsx +36 -0
  513. package/src/components/recovery/InitiateRecoveryStep.tsx +68 -0
  514. package/src/components/recovery/SelectMethodStep.tsx +73 -0
  515. package/src/components/recovery/SetPasswordStep.tsx +97 -0
  516. package/src/components/recovery/VerifyCodeStep.tsx +90 -0
  517. package/src/components/reserved/ReservedRecoveryWarning.tsx +160 -0
  518. package/src/components/reserved/ReservedStatusBox.tsx +118 -0
  519. package/src/components/ui/BetaBadge.tsx +58 -0
  520. package/src/components/ui/Footer.tsx +93 -0
  521. package/src/config/env.ts +57 -0
  522. package/src/config/logger.ts +62 -0
  523. package/src/config/logging-config.ts +82 -0
  524. package/src/config/unauthenticated-routes.ts +19 -0
  525. package/src/config/vibe-log-transport.ts +250 -0
  526. package/src/edge/internal-api-url.ts +65 -0
  527. package/src/edge/middleware.ts +42 -0
  528. package/src/hooks/useAuth.ts +115 -0
  529. package/src/hooks/useAuthSettings.ts +97 -0
  530. package/src/hooks/useAvailableProviders.ts +118 -0
  531. package/src/hooks/usePasswordValidation.ts +127 -0
  532. package/src/hooks/useProfile.ts +75 -0
  533. package/src/hooks/usePublicAuthSettings.ts +149 -0
  534. package/src/hooks/useSessionExpiration.ts +102 -0
  535. package/src/hooks/useViabilitySession.ts +335 -0
  536. package/src/index.ts +63 -0
  537. package/src/lib/anon-session.ts +213 -0
  538. package/src/lib/api-handler.ts +625 -0
  539. package/src/lib/app-slug.ts +178 -0
  540. package/src/lib/demo-mode.ts +13 -0
  541. package/src/lib/geolocation.ts +265 -0
  542. package/src/lib/idp-client-config.ts +442 -0
  543. package/src/lib/idp-fetch.ts +101 -0
  544. package/src/lib/internal-api.ts +171 -0
  545. package/src/lib/jwt-decode-client.ts +45 -0
  546. package/src/lib/jwt-decode.ts +83 -0
  547. package/src/lib/nextauth-secret.ts +126 -0
  548. package/src/lib/rate-limit-service.ts +9 -0
  549. package/src/lib/redis.ts +27 -0
  550. package/src/lib/refresh-token-validator.ts +64 -0
  551. package/src/lib/roles.ts +177 -0
  552. package/src/lib/secret-validation.ts +8 -0
  553. package/src/lib/session-store.ts +637 -0
  554. package/src/lib/session.ts +34 -0
  555. package/src/lib/site-logger.ts +245 -0
  556. package/src/lib/standardized-client-api.ts +896 -0
  557. package/src/lib/startup-init.ts +247 -0
  558. package/src/lib/test-aware-get-token.ts +30 -0
  559. package/src/lib/token-expiry.ts +40 -0
  560. package/src/lib/token-lifecycle.ts +477 -0
  561. package/src/lib/types/api-responses.ts +336 -0
  562. package/src/lib/user-agent-parser.ts +252 -0
  563. package/src/logging/api/admin-analytics.ts +51 -0
  564. package/src/logging/api/audit-log.ts +53 -0
  565. package/src/logging/components/AdminAnalyticsLayout.tsx +49 -0
  566. package/src/logging/components/AuditLogViewer.tsx +125 -0
  567. package/src/logging/components/ErrorMetricsCard.tsx +98 -0
  568. package/src/logging/components/HealthMetricsCard.tsx +70 -0
  569. package/src/logging/hooks/useAdminAnalytics.ts +22 -0
  570. package/src/logging/hooks/useAuditLog.ts +24 -0
  571. package/src/logging/hooks/useErrorMetrics.ts +40 -0
  572. package/src/logging/hooks/useHealthMetrics.ts +44 -0
  573. package/src/logging/index.ts +18 -0
  574. package/src/logging/types/analytics.ts +81 -0
  575. package/src/logging/types/audit.ts +31 -0
  576. package/src/logging/types/index.ts +3 -0
  577. package/src/middleware/auth-decision.ts +43 -0
  578. package/src/middleware/create-middleware.ts +626 -0
  579. package/src/middleware/rbac-check.ts +244 -0
  580. package/src/middleware/twofa-presets.ts +224 -0
  581. package/src/models/DecodedAccessToken.ts +17 -0
  582. package/src/models/SessionModel.ts +258 -0
  583. package/src/pages/admin-login/page.tsx +229 -0
  584. package/src/pages/admin-roles/RolesAdminPage.tsx +357 -0
  585. package/src/pages/admin-roles/index.ts +9 -0
  586. package/src/pages/admin-roles/modals.tsx +469 -0
  587. package/src/pages/client-admin/ClientSiteAdminPage.tsx +380 -0
  588. package/src/pages/client-admin/index.ts +33 -0
  589. package/src/pages/login/page.tsx +463 -0
  590. package/src/pages/profile/EnhancedProfilePage.tsx +479 -0
  591. package/src/pages/profile/index.ts +9 -0
  592. package/src/pages/profile/page.tsx +166 -0
  593. package/src/pages/recovery/page.tsx +234 -0
  594. package/src/pages/roles/MyRolesPage.tsx +211 -0
  595. package/src/pages/roles/components.tsx +294 -0
  596. package/src/pages/roles/index.ts +17 -0
  597. package/src/pages/security/EnhancedSecurityPage.tsx +574 -0
  598. package/src/pages/security/index.ts +9 -0
  599. package/src/pages/security/page.tsx +507 -0
  600. package/src/pages/settings/EnhancedSettingsPage.tsx +642 -0
  601. package/src/pages/settings/index.ts +9 -0
  602. package/src/pages/settings/page.tsx +47 -0
  603. package/src/pages/showcase/ShowcasePage.tsx +530 -0
  604. package/src/pages/showcase/index.ts +13 -0
  605. package/src/pages/test-env/EmergencyLogoutPage.tsx +179 -0
  606. package/src/pages/test-env/JwtInspectPage.tsx +418 -0
  607. package/src/pages/test-env/RefreshTokenPage.tsx +155 -0
  608. package/src/pages/test-env/TestEnvPage.tsx +116 -0
  609. package/src/pages/test-env/index.ts +25 -0
  610. package/src/pages/verify-code/page.tsx +648 -0
  611. package/src/routes/account/index.ts +32 -0
  612. package/src/routes/account/masked-info.ts +37 -0
  613. package/src/routes/account/send-code.ts +40 -0
  614. package/src/routes/account/update-phone.ts +13 -0
  615. package/src/routes/account/verify-email.ts +41 -0
  616. package/src/routes/account/verify-sms.ts +41 -0
  617. package/src/routes/auth/index.ts +23 -0
  618. package/src/routes/auth/logout.ts +127 -0
  619. package/src/routes/auth/nextauth.ts +71 -0
  620. package/src/routes/auth/refresh.ts +54 -0
  621. package/src/routes/auth/session.ts +193 -0
  622. package/src/routes/auth/settings.ts +75 -0
  623. package/src/routes/auth/viability.ts +220 -0
  624. package/src/routes/index.ts +18 -0
  625. package/src/routes/session/index.ts +7 -0
  626. package/src/routes/session/refresh-viability.ts +17 -0
  627. package/src/services/signalrActivityService.ts +258 -0
  628. package/src/stores/authStore.ts +1904 -0
  629. package/src/templates/instrumentation.ts +41 -0
  630. package/src/theme/ThemeProvider.tsx +39 -0
  631. package/src/theme/default.ts +33 -0
  632. package/src/theme/index.ts +31 -0
  633. package/src/theme/types.ts +69 -0
  634. package/src/theme/useTheme.ts +57 -0
  635. package/src/theme/utils.ts +40 -0
  636. package/src/types/api.ts +13 -0
  637. package/src/types/auth.d.ts +15 -0
  638. package/src/types/auth.ts +22 -0
  639. package/src/types/logging.ts +11 -0
  640. package/src/types/next-auth.d.ts +15 -0
  641. package/src/types/recovery.ts +54 -0
  642. package/src/types/security.ts +1 -0
  643. package/src/utils/api.ts +353 -0
  644. package/src/utils/circuitBreaker.ts +40 -0
  645. package/src/utils/error-message.ts +108 -0
  646. package/src/utils/layout/reservedSpace.ts +124 -0
  647. package/src/utils/logout.ts +30 -0
  648. package/src/vibe/client.ts +590 -0
  649. package/src/vibe/errors.ts +185 -0
  650. package/src/vibe/generic.ts +429 -0
  651. package/src/vibe/hooks/index.ts +367 -0
  652. package/src/vibe/index.ts +121 -0
  653. package/src/vibe/sessions.ts +551 -0
  654. package/src/vibe/types.ts +577 -0
@@ -0,0 +1,537 @@
1
+ "use strict";
2
+ /**
3
+ * Session Store for `@payez/next-mvp` using ioredis
4
+ *
5
+ * This module provides a Redis-backed session store that is compatible with the
6
+ * `ioredis` client. It handles the creation, retrieval, and deletion of
7
+ * session data, which is the single source of truth for authentication.
8
+ *
9
+ * Includes advanced distributed refresh coordination with version control.
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.generateSessionToken = generateSessionToken;
16
+ exports.createSession = createSession;
17
+ exports.getSession = getSession;
18
+ exports.getSessionWithVersion = getSessionWithVersion;
19
+ exports.isAccessTokenFresh = isAccessTokenFresh;
20
+ exports.deleteSession = deleteSession;
21
+ exports.setSession = setSession;
22
+ exports.updateSession = updateSession;
23
+ exports.transitionTo2FASession = transitionTo2FASession;
24
+ exports.updateTokens = updateTokens;
25
+ exports.mark2FAComplete = mark2FAComplete;
26
+ exports.is2FAComplete = is2FAComplete;
27
+ exports.getTokens = getTokens;
28
+ exports.refreshJWTSession = refreshJWTSession;
29
+ exports.clearAllSessions = clearAllSessions;
30
+ exports.listAllSessions = listAllSessions;
31
+ exports.acquireRefreshLock = acquireRefreshLock;
32
+ exports.releaseRefreshLock = releaseRefreshLock;
33
+ exports.checkRefreshLock = checkRefreshLock;
34
+ exports.isRefreshInProgress = isRefreshInProgress;
35
+ exports.cleanupRefreshLocks = cleanupRefreshLocks;
36
+ const redis_1 = __importDefault(require("./redis"));
37
+ const crypto_1 = require("crypto");
38
+ const app_slug_1 = require("./app-slug");
39
+ const token_utils_1 = require("../auth/utils/token-utils");
40
+ // Use app-slug prefixes for multi-app isolation
41
+ const getSessionKey = (token) => `${(0, app_slug_1.getSessionPrefix)()}${token}`;
42
+ const getRefreshLockKey = (token) => `${(0, app_slug_1.getRefreshLockPrefix)()}${token}`;
43
+ const getSessionVersionKey = (token) => `${(0, app_slug_1.getSessionPrefix)()}ver:${token}`;
44
+ const REFRESH_LOCK_TTL = 60; // 60 seconds
45
+ const SESSION_TTL = 3 * 24 * 60 * 60; // 3 days in seconds (matches refresh token lifetime)
46
+ /**
47
+ * Generates a new session token.
48
+ * @returns A new session token string.
49
+ */
50
+ function generateSessionToken() {
51
+ return (0, crypto_1.randomBytes)(32).toString('hex');
52
+ }
53
+ /**
54
+ * Creates a new session in Redis.
55
+ *
56
+ * @param data The session data to store.
57
+ * @returns The generated session token (redisSessionId).
58
+ */
59
+ async function createSession(data) {
60
+ const sessionToken = (0, crypto_1.randomBytes)(32).toString('hex');
61
+ const key = getSessionKey(sessionToken);
62
+ const versionKey = getSessionVersionKey(sessionToken);
63
+ try {
64
+ await redis_1.default.multi()
65
+ .setex(key, SESSION_TTL, JSON.stringify(data))
66
+ .setex(versionKey, SESSION_TTL, '1')
67
+ .exec();
68
+ }
69
+ catch (error) {
70
+ console.error('[SESSION-STORE] Failed to create session:', error);
71
+ throw error;
72
+ }
73
+ return sessionToken;
74
+ }
75
+ /**
76
+ * Retrieves a session from Redis.
77
+ *
78
+ * @param sessionToken The session token (redisSessionId) to look up.
79
+ * @returns The session data, or null if not found.
80
+ */
81
+ async function getSession(sessionToken) {
82
+ if (!sessionToken) {
83
+ return null;
84
+ }
85
+ const key = getSessionKey(sessionToken);
86
+ const json = await redis_1.default.get(key);
87
+ if (!json) {
88
+ return null;
89
+ }
90
+ try {
91
+ return JSON.parse(json);
92
+ }
93
+ catch {
94
+ console.error('[SESSION-STORE] Failed to parse session data');
95
+ return null;
96
+ }
97
+ }
98
+ /**
99
+ * Retrieves a session along with a version identifier for optimistic locking.
100
+ * @param sessionToken The session token to look up.
101
+ * @returns An object with session and version, or null if not found.
102
+ */
103
+ async function getSessionWithVersion(sessionToken) {
104
+ const session = await getSession(sessionToken);
105
+ if (!session) {
106
+ return null;
107
+ }
108
+ const versionKey = getSessionVersionKey(sessionToken);
109
+ const version = await redis_1.default.get(versionKey);
110
+ if (!version) {
111
+ // Session exists but version key missing - use idpAccessTokenExpires as fallback
112
+ const fallbackVersion = String(session.idpAccessTokenExpires || Date.now());
113
+ return { session, version: fallbackVersion };
114
+ }
115
+ return { session, version };
116
+ }
117
+ /**
118
+ * Checks if the access token in a session is still fresh (not expired).
119
+ * @param sessionToken The session token to check.
120
+ * @param currentAccessToken The current access token to compare.
121
+ * @param currentVersion Optional version to check for changes.
122
+ * @returns Object with freshness status and latest token info.
123
+ */
124
+ async function isAccessTokenFresh(sessionToken, currentAccessToken, currentVersion) {
125
+ const sessionWithVersion = await getSessionWithVersion(sessionToken);
126
+ if (!sessionWithVersion) {
127
+ return { isFresh: false, versionChanged: true };
128
+ }
129
+ const { session, version } = sessionWithVersion;
130
+ const versionChanged = currentVersion ? version !== currentVersion : false;
131
+ // If version changed, the token might be stale
132
+ // Use normalized field name (idpAccessToken)
133
+ const isFresh = !versionChanged && session.idpAccessToken === currentAccessToken;
134
+ return {
135
+ isFresh,
136
+ latestAccessToken: session.idpAccessToken || undefined,
137
+ latestVersion: version,
138
+ versionChanged
139
+ };
140
+ }
141
+ /**
142
+ * Deletes a session from Redis.
143
+ * @param sessionToken The session token to delete.
144
+ */
145
+ async function deleteSession(sessionToken) {
146
+ if (!sessionToken) {
147
+ return;
148
+ }
149
+ const key = getSessionKey(sessionToken);
150
+ const versionKey = getSessionVersionKey(sessionToken);
151
+ await redis_1.default.del(key, versionKey);
152
+ }
153
+ /**
154
+ * Sets a session directly (for testing or migrations).
155
+ * @param sessionToken The session token.
156
+ * @param data The session data.
157
+ */
158
+ async function setSession(sessionToken, data) {
159
+ const key = getSessionKey(sessionToken);
160
+ const versionKey = getSessionVersionKey(sessionToken);
161
+ await redis_1.default.multi()
162
+ .setex(key, SESSION_TTL, JSON.stringify(data))
163
+ .incr(versionKey)
164
+ .expire(versionKey, SESSION_TTL)
165
+ .exec();
166
+ }
167
+ /**
168
+ * Updates tokens within an existing session.
169
+ * @param sessionToken The session token to update.
170
+ * @param updates Partial session data to update.
171
+ * @returns The updated session data, or null if the session was not found.
172
+ */
173
+ async function updateSession(sessionToken, updates) {
174
+ const key = getSessionKey(sessionToken);
175
+ const versionKey = getSessionVersionKey(sessionToken);
176
+ // Get current session to merge with updates
177
+ const currentSession = await getSession(sessionToken);
178
+ if (!currentSession) {
179
+ return null;
180
+ }
181
+ // CRITICAL: Track any refresh token changes (check both old and new field names)
182
+ const hadRefreshToken = !!(currentSession.idpRefreshToken || currentSession.refreshToken);
183
+ const willHaveRefreshToken = updates.idpRefreshToken !== undefined
184
+ ? !!updates.idpRefreshToken
185
+ : updates.refreshToken !== undefined
186
+ ? !!updates.refreshToken
187
+ : hadRefreshToken;
188
+ if (hadRefreshToken && !willHaveRefreshToken) {
189
+ console.error('[SESSION-STORE] ⚠️ REFRESH_TOKEN_BEING_CLEARED', {
190
+ sessionToken: sessionToken.substring(0, 8) + '...',
191
+ userId: currentSession.userId,
192
+ updateKeys: Object.keys(updates),
193
+ refreshTokenInUpdate: updates.idpRefreshToken || updates.refreshToken,
194
+ refreshTokenClearedReason: updates.refreshTokenClearedReason || 'UNKNOWN',
195
+ stack: new Error().stack
196
+ });
197
+ }
198
+ // Merge current session with updates
199
+ const updatedSession = { ...currentSession, ...updates };
200
+ // Write the entire updated session back to Redis with version increment
201
+ await redis_1.default.multi()
202
+ .setex(key, SESSION_TTL, JSON.stringify(updatedSession))
203
+ .incr(versionKey)
204
+ .expire(versionKey, SESSION_TTL)
205
+ .exec();
206
+ return updatedSession;
207
+ }
208
+ /**
209
+ * Transitions a session to a MFA-completed state.
210
+ * @param sessionToken The session token to update.
211
+ * @param tokens The new tokens received after MFA completion.
212
+ * @param mfaMethod The MFA method used (email, sms, totp) - required for token refresh.
213
+ * @returns The updated session data.
214
+ */
215
+ async function transitionTo2FASession(sessionToken, tokens, mfaMethod) {
216
+ const newAccessToken = tokens.idpAccessToken || tokens.accessToken;
217
+ console.log('[transitionTo2FASession] Called with:', {
218
+ sessionToken: sessionToken?.substring(0, 8) + '...',
219
+ mfaMethod,
220
+ hasAccessToken: !!newAccessToken,
221
+ hasRefreshToken: !!(tokens.idpRefreshToken || tokens.refreshToken),
222
+ });
223
+ // Extract bearerKeyId from the new access token (IDP may use different key after 2FA)
224
+ let bearerKeyId;
225
+ if (newAccessToken) {
226
+ bearerKeyId = (0, token_utils_1.extractKidFromToken)(newAccessToken);
227
+ if (bearerKeyId) {
228
+ console.log('[transitionTo2FASession] Extracted bearerKeyId (kid) from new JWT header:', bearerKeyId);
229
+ }
230
+ }
231
+ // Support both old and new field names in input
232
+ // CRITICAL: Set BOTH mfaVerified (new) AND twoFactorComplete (legacy) for compatibility
233
+ // auth.ts session callback reads twoFactorComplete, so we must set it here
234
+ const updates = {
235
+ idpAccessToken: newAccessToken,
236
+ idpRefreshToken: tokens.idpRefreshToken || tokens.refreshToken,
237
+ idpAccessTokenExpires: tokens.idpAccessTokenExpires || tokens.accessTokenExpires,
238
+ mfaVerified: true,
239
+ twoFactorComplete: true, // Legacy field - required by auth.ts session callback
240
+ mfaMethod: mfaMethod,
241
+ // Update bearerKeyId if extracted from new token
242
+ ...(bearerKeyId && { bearerKeyId }),
243
+ };
244
+ const refreshExpires = tokens.idpRefreshTokenExpires || tokens.refreshTokenExpires;
245
+ if (refreshExpires !== undefined) {
246
+ updates.idpRefreshTokenExpires = refreshExpires;
247
+ }
248
+ console.log('[transitionTo2FASession] Updates to apply:', {
249
+ mfaVerified: updates.mfaVerified,
250
+ twoFactorComplete: updates.twoFactorComplete,
251
+ mfaMethod: updates.mfaMethod,
252
+ hasIdpAccessToken: !!updates.idpAccessToken,
253
+ });
254
+ const result = await updateSession(sessionToken, updates);
255
+ console.log('[transitionTo2FASession] Result:', {
256
+ success: !!result,
257
+ resultMfaVerified: result?.mfaVerified,
258
+ });
259
+ return result;
260
+ }
261
+ /**
262
+ * Updates IDP tokens and their expiries in an existing session.
263
+ * @param sessionToken The session token to update.
264
+ * @param idpAccessToken The new IDP access token.
265
+ * @param idpRefreshToken The new IDP refresh token.
266
+ * @param idpAccessTokenExpires The access token expiry timestamp.
267
+ * @param idpRefreshTokenExpires The refresh token expiry timestamp (optional).
268
+ * @returns The updated session data.
269
+ */
270
+ async function updateTokens(sessionToken, idpAccessToken, idpRefreshToken, idpAccessTokenExpires, idpRefreshTokenExpires) {
271
+ return updateSession(sessionToken, {
272
+ idpAccessToken,
273
+ idpRefreshToken,
274
+ idpAccessTokenExpires,
275
+ idpRefreshTokenExpires,
276
+ });
277
+ }
278
+ /**
279
+ * Marks a session as having completed MFA.
280
+ * @param sessionToken The session token to update.
281
+ * @returns The updated session data.
282
+ */
283
+ async function mark2FAComplete(sessionToken) {
284
+ return updateSession(sessionToken, {
285
+ mfaVerified: true,
286
+ });
287
+ }
288
+ /**
289
+ * Checks if MFA is complete for a session.
290
+ * @param sessionToken The session token.
291
+ * @returns True if MFA is complete.
292
+ */
293
+ async function is2FAComplete(sessionToken) {
294
+ const session = await getSession(sessionToken);
295
+ return session?.mfaVerified === true;
296
+ }
297
+ /**
298
+ * Gets IDP tokens from a session.
299
+ * @param sessionToken The session token.
300
+ * @returns The tokens or null if session not found.
301
+ */
302
+ async function getTokens(sessionToken) {
303
+ const session = await getSession(sessionToken);
304
+ if (!session || !session.idpAccessToken || !session.idpRefreshToken) {
305
+ return null;
306
+ }
307
+ return {
308
+ // Legacy names for backward compatibility
309
+ accessToken: session.idpAccessToken,
310
+ refreshToken: session.idpRefreshToken,
311
+ // New normalized names
312
+ idpAccessToken: session.idpAccessToken,
313
+ idpRefreshToken: session.idpRefreshToken,
314
+ };
315
+ }
316
+ /**
317
+ * Refreshes a JWT session (placeholder for compatibility).
318
+ * @param sessionToken The session token.
319
+ * @returns The session data or null.
320
+ */
321
+ async function refreshJWTSession(sessionToken) {
322
+ return getSession(sessionToken);
323
+ }
324
+ /**
325
+ * Clears all sessions (for testing only).
326
+ */
327
+ async function clearAllSessions() {
328
+ console.warn('[SESSION-STORE] clearAllSessions called - this should only be used in testing');
329
+ }
330
+ /**
331
+ * Lists all sessions (for testing/debugging only).
332
+ * @returns An empty array (placeholder).
333
+ */
334
+ async function listAllSessions() {
335
+ console.warn('[SESSION-STORE] listAllSessions called - this should only be used in testing');
336
+ return [];
337
+ }
338
+ // ===============================
339
+ // DISTRIBUTED REFRESH COORDINATION
340
+ // ===============================
341
+ /**
342
+ * Attempt to acquire a refresh lock for a session
343
+ * Uses Redis SET with NX (Not eXists) for atomic lock acquisition
344
+ */
345
+ async function acquireRefreshLock(sessionToken, requestId, maxWaitMs = 5000) {
346
+ const lockKey = getRefreshLockKey(sessionToken);
347
+ const acquiredAt = Date.now();
348
+ const lockVersion = Math.floor(Math.random() * 1000000);
349
+ const lockInfo = {
350
+ sessionToken,
351
+ acquiredAt,
352
+ acquiredBy: requestId,
353
+ lockVersion
354
+ };
355
+ try {
356
+ // Try to acquire the lock atomically
357
+ const result = await redis_1.default.set(lockKey, JSON.stringify(lockInfo), 'PX', REFRESH_LOCK_TTL * 1000, 'NX');
358
+ if (result === 'OK') {
359
+ console.log('[SESSION-STORE] Refresh lock acquired', {
360
+ sessionToken: sessionToken.substring(0, 8) + '...',
361
+ requestId,
362
+ lockVersion
363
+ });
364
+ return { acquired: true, lockInfo };
365
+ }
366
+ else {
367
+ // Lock already exists, check if we should wait
368
+ if (maxWaitMs > 0) {
369
+ console.log('[SESSION-STORE] Refresh lock already exists, waiting for release', {
370
+ sessionToken: sessionToken.substring(0, 8) + '...',
371
+ requestId,
372
+ maxWaitMs
373
+ });
374
+ return await waitForRefreshLockRelease(sessionToken, requestId, maxWaitMs);
375
+ }
376
+ console.warn('[SESSION-STORE] Refresh lock already exists, not waiting', {
377
+ sessionToken: sessionToken.substring(0, 8) + '...',
378
+ requestId
379
+ });
380
+ return { acquired: false };
381
+ }
382
+ }
383
+ catch (error) {
384
+ console.error('[SESSION-STORE] Failed to acquire refresh lock', {
385
+ sessionToken: sessionToken.substring(0, 8) + '...',
386
+ requestId,
387
+ error: error instanceof Error ? error.message : String(error)
388
+ });
389
+ return { acquired: false };
390
+ }
391
+ }
392
+ /**
393
+ * Wait for a refresh lock to be released
394
+ */
395
+ async function waitForRefreshLockRelease(sessionToken, requestId, maxWaitMs) {
396
+ const lockKey = getRefreshLockKey(sessionToken);
397
+ const startTime = Date.now();
398
+ const pollInterval = 100;
399
+ while (Date.now() - startTime < maxWaitMs) {
400
+ try {
401
+ const lockExists = await redis_1.default.exists(lockKey);
402
+ if (!lockExists) {
403
+ // Lock released - do not reacquire here to avoid double refresh
404
+ return { acquired: false };
405
+ }
406
+ // Wait before next check
407
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
408
+ }
409
+ catch (error) {
410
+ console.error('[SESSION-STORE] Error while waiting for refresh lock release', {
411
+ sessionToken: sessionToken.substring(0, 8) + '...',
412
+ requestId,
413
+ error: error instanceof Error ? error.message : String(error)
414
+ });
415
+ break;
416
+ }
417
+ }
418
+ console.warn('[SESSION-STORE] Timeout waiting for refresh lock release', {
419
+ sessionToken: sessionToken.substring(0, 8) + '...',
420
+ requestId,
421
+ waitedMs: Date.now() - startTime
422
+ });
423
+ return { acquired: false };
424
+ }
425
+ /**
426
+ * Release a refresh lock
427
+ * Uses Lua script to ensure atomic validation and release
428
+ */
429
+ async function releaseRefreshLock(sessionToken, requestId, lockVersion) {
430
+ const lockKey = getRefreshLockKey(sessionToken);
431
+ try {
432
+ // Lua script for atomic lock validation and release
433
+ const luaScript = `
434
+ local lockKey = KEYS[1]
435
+ local expectedRequestId = ARGV[1]
436
+ local expectedVersion = ARGV[2]
437
+
438
+ local lockData = redis.call('GET', lockKey)
439
+ if not lockData then
440
+ return 0 -- Lock doesn't exist
441
+ end
442
+
443
+ local lockInfo = cjson.decode(lockData)
444
+ if lockInfo.acquiredBy == expectedRequestId then
445
+ if not expectedVersion or expectedVersion == '' or tostring(lockInfo.lockVersion) == expectedVersion then
446
+ redis.call('DEL', lockKey)
447
+ return 1 -- Successfully released
448
+ else
449
+ return -2 -- Version mismatch
450
+ end
451
+ else
452
+ return -1 -- Wrong owner
453
+ end
454
+ `;
455
+ const result = await redis_1.default.eval(luaScript, 1, lockKey, requestId, lockVersion ? lockVersion.toString() : '');
456
+ if (result === 1) {
457
+ console.log('[SESSION-STORE] Refresh lock released successfully', {
458
+ sessionToken: sessionToken.substring(0, 8) + '...',
459
+ requestId,
460
+ lockVersion
461
+ });
462
+ return true;
463
+ }
464
+ else if (result === 0) {
465
+ console.warn('[SESSION-STORE] Attempted to release non-existent refresh lock', {
466
+ sessionToken: sessionToken.substring(0, 8) + '...',
467
+ requestId
468
+ });
469
+ return false;
470
+ }
471
+ else if (result === -1) {
472
+ console.error('[SESSION-STORE] Attempted to release refresh lock owned by another request', {
473
+ sessionToken: sessionToken.substring(0, 8) + '...',
474
+ requestId
475
+ });
476
+ return false;
477
+ }
478
+ else if (result === -2) {
479
+ console.error('[SESSION-STORE] Lock version mismatch during release', {
480
+ sessionToken: sessionToken.substring(0, 8) + '...',
481
+ requestId,
482
+ lockVersion
483
+ });
484
+ return false;
485
+ }
486
+ else {
487
+ console.error('[SESSION-STORE] Unexpected result from lock release script', {
488
+ sessionToken: sessionToken.substring(0, 8) + '...',
489
+ requestId,
490
+ result
491
+ });
492
+ return false;
493
+ }
494
+ }
495
+ catch (error) {
496
+ console.error('[SESSION-STORE] Failed to release refresh lock', {
497
+ sessionToken: sessionToken.substring(0, 8) + '...',
498
+ requestId,
499
+ error: error instanceof Error ? error.message : String(error)
500
+ });
501
+ return false;
502
+ }
503
+ }
504
+ /**
505
+ * Check if a refresh lock exists for a session
506
+ */
507
+ async function checkRefreshLock(sessionToken) {
508
+ const lockKey = getRefreshLockKey(sessionToken);
509
+ try {
510
+ const lockData = await redis_1.default.get(lockKey);
511
+ if (!lockData) {
512
+ return null;
513
+ }
514
+ return JSON.parse(lockData);
515
+ }
516
+ catch (error) {
517
+ console.error('[SESSION-STORE] Failed to check refresh lock', {
518
+ sessionToken: sessionToken.substring(0, 8) + '...',
519
+ error: error instanceof Error ? error.message : String(error)
520
+ });
521
+ return null;
522
+ }
523
+ }
524
+ /**
525
+ * Simple check if a refresh is currently in progress for a session
526
+ */
527
+ async function isRefreshInProgress(sessionToken) {
528
+ const lock = await checkRefreshLock(sessionToken);
529
+ return lock !== null;
530
+ }
531
+ /**
532
+ * Force cleanup of expired or orphaned refresh locks
533
+ */
534
+ async function cleanupRefreshLocks() {
535
+ console.warn('[SESSION-STORE] cleanupRefreshLocks called - scanning for expired locks');
536
+ return 0;
537
+ }
@@ -0,0 +1,21 @@
1
+ export type MinimalSession = {
2
+ user?: {
3
+ id?: string | null;
4
+ email?: string | null;
5
+ } | null;
6
+ accessToken?: string | null;
7
+ expires?: string;
8
+ [k: string]: any;
9
+ };
10
+ export type AppSession = MinimalSession;
11
+ /**
12
+ * Strict session validation for client-side guards.
13
+ * A session is considered valid when:
14
+ * - a user object exists with non-empty id and email
15
+ * - an accessToken string exists
16
+ */
17
+ export declare function isValidSession(session: MinimalSession | null | undefined): boolean;
18
+ /**
19
+ * Sanitize session data - returns null if session is invalid
20
+ */
21
+ export declare function sanitizeSession(session: MinimalSession | null | undefined): MinimalSession | null;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidSession = isValidSession;
4
+ exports.sanitizeSession = sanitizeSession;
5
+ /**
6
+ * Strict session validation for client-side guards.
7
+ * A session is considered valid when:
8
+ * - a user object exists with non-empty id and email
9
+ * - an accessToken string exists
10
+ */
11
+ function isValidSession(session) {
12
+ if (!session)
13
+ return false;
14
+ const u = session.user;
15
+ const hasUser = !!u && typeof u.id === 'string' && u.id.length > 0 && typeof u.email === 'string' && u.email.length > 0;
16
+ const hasAccessToken = typeof session.accessToken === 'string' && session.accessToken.length > 0;
17
+ return hasUser && hasAccessToken;
18
+ }
19
+ /**
20
+ * Sanitize session data - returns null if session is invalid
21
+ */
22
+ function sanitizeSession(session) {
23
+ if (!isValidSession(session))
24
+ return null;
25
+ return session;
26
+ }