@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,786 @@
1
+ "use strict";
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.standardizedApi = exports.ApiNetworkError = exports.ApiValidationError = exports.ApiBusinessLogicError = exports.ApiResponseFormatError = void 0;
38
+ exports.isApiSuccess = isApiSuccess;
39
+ exports.isApiPagedSuccess = isApiPagedSuccess;
40
+ exports.isApiError = isApiError;
41
+ exports.extractApiData = extractApiData;
42
+ exports.extractApiItems = extractApiItems;
43
+ // ========================================================================================
44
+ // BULLETPROOF STANDARDIZED CLIENT API - ZERO TOLERANCE FOR BAD RESPONSES
45
+ // ========================================================================================
46
+ // This client API ENFORCES the standardized response format
47
+ // It will BREAK if APIs don't return the expected structure
48
+ // NO MORE GUESSING data.data.data.data - EVER AGAIN!
49
+ // ========================================================================================
50
+ const react_1 = require("next-auth/react");
51
+ const api_responses_1 = require("./types/api-responses");
52
+ // ========================================================================================
53
+ // CLIENT API ERROR TYPES
54
+ // ========================================================================================
55
+ /**
56
+ * ERROR THROWN WHEN API RESPONSE FORMAT IS INVALID
57
+ * This means the API is NOT following our standardized format
58
+ */
59
+ class ApiResponseFormatError extends Error {
60
+ endpoint;
61
+ rawResponse;
62
+ constructor(message, endpoint, rawResponse) {
63
+ super(`API_FORMAT_ERROR: ${message}`);
64
+ this.endpoint = endpoint;
65
+ this.rawResponse = rawResponse;
66
+ this.name = 'ApiResponseFormatError';
67
+ }
68
+ }
69
+ exports.ApiResponseFormatError = ApiResponseFormatError;
70
+ /**
71
+ * ERROR THROWN WHEN API RETURNS A STANDARDIZED ERROR RESPONSE
72
+ * This is a properly formatted error from the API
73
+ */
74
+ class ApiBusinessLogicError extends Error {
75
+ errorCode;
76
+ operation;
77
+ details;
78
+ constructor(errorCode, message, operation, details) {
79
+ super(message);
80
+ this.errorCode = errorCode;
81
+ this.operation = operation;
82
+ this.details = details;
83
+ this.name = 'ApiBusinessLogicError';
84
+ }
85
+ }
86
+ exports.ApiBusinessLogicError = ApiBusinessLogicError;
87
+ /**
88
+ * ERROR THROWN WHEN VALIDATION FAILS
89
+ * This is a properly formatted validation error from the API
90
+ */
91
+ class ApiValidationError extends Error {
92
+ operation;
93
+ validationErrors;
94
+ invalidValue;
95
+ primaryField;
96
+ constructor(message, operation, validationErrors, invalidValue, primaryField) {
97
+ super(message);
98
+ this.operation = operation;
99
+ this.validationErrors = validationErrors;
100
+ this.invalidValue = invalidValue;
101
+ this.primaryField = primaryField;
102
+ this.name = 'ApiValidationError';
103
+ }
104
+ }
105
+ exports.ApiValidationError = ApiValidationError;
106
+ /**
107
+ * ERROR THROWN WHEN NETWORK/HTTP ISSUES OCCUR
108
+ */
109
+ class ApiNetworkError extends Error {
110
+ status;
111
+ endpoint;
112
+ constructor(message, status, endpoint) {
113
+ super(`NETWORK_ERROR: ${message}`);
114
+ this.status = status;
115
+ this.endpoint = endpoint;
116
+ this.name = 'ApiNetworkError';
117
+ }
118
+ }
119
+ exports.ApiNetworkError = ApiNetworkError;
120
+ // ========================================================================================
121
+ // AUTHENTICATION STATE MANAGEMENT
122
+ // ========================================================================================
123
+ // Coordinate client-side refresh to avoid duplicate refresh calls racing with
124
+ // server-side middleware or other tabs. Only one refresh runs at a time.
125
+ let refreshInFlight = null;
126
+ // Enhanced redirect logic with grace period and retry attempts
127
+ let authRedirectScheduled = false;
128
+ let lastAuthFailureTime = 0;
129
+ let consecutiveAuthFailures = 0;
130
+ const AUTH_FAILURE_GRACE_PERIOD = 2000; // 2 seconds grace period
131
+ const MAX_AUTH_FAILURES_BEFORE_REDIRECT = 2; // Allow 2 failures before redirect
132
+ const AUTH_FAILURE_RESET_WINDOW = 30000; // Reset failure count after 30 seconds
133
+ // Helper: detect pre-2FA session (session exists, requires 2FA and not completed)
134
+ function isPreTwoFactorSession(session) {
135
+ return !!(session?.user?.requiresTwoFactor && !session?.user?.twoFactorSessionVerified);
136
+ }
137
+ // Reset auth failure state on successful requests
138
+ function resetAuthFailureState() {
139
+ if (consecutiveAuthFailures > 0) {
140
+ console.log(`✅ Resetting auth failure state (was ${consecutiveAuthFailures} failures)`);
141
+ consecutiveAuthFailures = 0;
142
+ lastAuthFailureTime = 0;
143
+ authRedirectScheduled = false;
144
+ }
145
+ }
146
+ function scheduleLoginRedirect(isImmediate = false) {
147
+ if (authRedirectScheduled)
148
+ return;
149
+ const now = Date.now();
150
+ // Reset consecutive failures if enough time has passed
151
+ if (now - lastAuthFailureTime > AUTH_FAILURE_RESET_WINDOW) {
152
+ consecutiveAuthFailures = 0;
153
+ }
154
+ consecutiveAuthFailures++;
155
+ lastAuthFailureTime = now;
156
+ console.warn(`🔴 Auth failure #${consecutiveAuthFailures}, immediate: ${isImmediate}`);
157
+ // Only redirect if we've had multiple failures or if explicitly requested
158
+ if (!isImmediate && consecutiveAuthFailures < MAX_AUTH_FAILURES_BEFORE_REDIRECT) {
159
+ console.log(`⏳ Delaying redirect - only ${consecutiveAuthFailures} failures so far`);
160
+ return;
161
+ }
162
+ authRedirectScheduled = true;
163
+ const redirectFunction = () => {
164
+ try {
165
+ const returnUrl = encodeURIComponent(`${window.location.pathname}${window.location.search}`);
166
+ console.warn(`🔄 Redirecting to login with return URL: ${returnUrl}`);
167
+ window.location.href = `/account-auth/login?returnUrl=${returnUrl}`;
168
+ }
169
+ catch (error) {
170
+ console.error('❌ Error during login redirect:', error);
171
+ // Final fallback
172
+ try {
173
+ window.location.href = '/account-auth/login';
174
+ }
175
+ catch {
176
+ // no-op if window is not available
177
+ }
178
+ }
179
+ };
180
+ if (isImmediate) {
181
+ // Immediate redirect for critical auth failures
182
+ redirectFunction();
183
+ }
184
+ else {
185
+ // Small delay to allow any pending requests to complete
186
+ console.log(`⏳ Scheduling redirect with ${AUTH_FAILURE_GRACE_PERIOD}ms grace period`);
187
+ setTimeout(redirectFunction, AUTH_FAILURE_GRACE_PERIOD);
188
+ }
189
+ }
190
+ // ========================================================================================
191
+ // BULLETPROOF CLIENT API SERVICE
192
+ // ========================================================================================
193
+ class StandardizedClientApiService {
194
+ baseUrl;
195
+ constructor() {
196
+ this.baseUrl = '';
197
+ }
198
+ /**
199
+ * MAKES HTTP REQUEST AND VALIDATES RESPONSE FORMAT
200
+ * This method ENFORCES standardized response format compliance
201
+ * Will throw ApiResponseFormatError if format is invalid
202
+ */
203
+ async makeRequest(endpoint, options = {}, sessionToken) {
204
+ const fullEndpoint = `${this.baseUrl}${endpoint}`;
205
+ try {
206
+ // Use provided token or get from NextAuth session
207
+ const currentSession = await (0, react_1.getSession)();
208
+ let token = sessionToken || currentSession?.accessToken;
209
+ // Preflight freshness check: if token is near expiry, coordinate refresh BEFORE making request
210
+ const pre2FA = isPreTwoFactorSession(currentSession);
211
+ const hasRefresh = !!currentSession?.refreshToken;
212
+ if (!pre2FA && hasRefresh) {
213
+ try {
214
+ let timeLeft = null;
215
+ if (currentSession?.accessTokenExpires) {
216
+ timeLeft = currentSession.accessTokenExpires - Date.now();
217
+ }
218
+ else if (token) {
219
+ // Fallback decode only if session did not include expiry
220
+ const { jwtDecode } = await Promise.resolve().then(() => __importStar(require('./jwt-decode-client')));
221
+ const decoded = jwtDecode(token);
222
+ const expMs = decoded?.exp ? decoded.exp * 1000 : 0;
223
+ timeLeft = expMs - Date.now();
224
+ }
225
+ // Refresh if <= 60s remaining (or already expired)
226
+ if (timeLeft !== null && !Number.isNaN(timeLeft) && timeLeft <= 60000) {
227
+ console.log(`⏳ Access token expiring soon (${Math.floor(timeLeft / 1000)}s). Coordinating refresh before request...`);
228
+ if (!refreshInFlight) {
229
+ refreshInFlight = (async () => {
230
+ const reqId = crypto.randomUUID();
231
+ const rr = await fetch('/api/auth/refresh', {
232
+ method: 'POST',
233
+ credentials: 'include',
234
+ headers: { 'X-Request-ID': reqId },
235
+ });
236
+ if (rr.ok || rr.status === 409) {
237
+ // ok or in-progress; give it a beat in case of 409
238
+ if (rr.status === 409)
239
+ await new Promise(r => setTimeout(r, 1200));
240
+ return true;
241
+ }
242
+ if (rr.status === 401 || rr.status === 403) {
243
+ scheduleLoginRedirect();
244
+ throw new ApiNetworkError('Authentication failed - unable to refresh session', rr.status, endpoint);
245
+ }
246
+ const et = await rr.text();
247
+ throw new ApiNetworkError(et || 'Token refresh failed', rr.status, endpoint);
248
+ })().finally(() => { refreshInFlight = null; });
249
+ }
250
+ await refreshInFlight;
251
+ const newSessionAfter = await (0, react_1.getSession)();
252
+ token = newSessionAfter?.accessToken || token;
253
+ }
254
+ }
255
+ catch (preErr) {
256
+ console.warn('Preflight token freshness check failed (continuing to attempt request):', preErr);
257
+ }
258
+ }
259
+ else {
260
+ // Elegantly skip preflight refresh in pre-2FA window or when no refresh token exists
261
+ if (pre2FA) {
262
+ console.log('⏭️ Skipping preflight refresh: 2FA not complete (no refresh allowed yet)');
263
+ }
264
+ else if (!hasRefresh) {
265
+ console.log('⏭️ Skipping preflight refresh: no refresh token present');
266
+ }
267
+ }
268
+ const config = {
269
+ ...options,
270
+ headers: {
271
+ 'Content-Type': 'application/json',
272
+ ...(token && { 'Authorization': `Bearer ${token}` }),
273
+ ...options.headers,
274
+ },
275
+ };
276
+ console.log(`🔄 API Request: ${options.method || 'GET'} ${fullEndpoint}`);
277
+ const response = await fetch(fullEndpoint, config);
278
+ if (!response.ok) {
279
+ // Handle coordination blocking (503) with auto-retry
280
+ if (response.status === 503) {
281
+ console.log('🔄 Got 503 Service Unavailable, attempting auto-retry for coordination...');
282
+ // Parse Retry-After header (in seconds)
283
+ const retryAfterHeader = response.headers.get('Retry-After');
284
+ let retryAfterSeconds = 1; // Default to 1 second
285
+ if (retryAfterHeader && /^\d+$/.test(retryAfterHeader)) {
286
+ retryAfterSeconds = parseInt(retryAfterHeader, 10);
287
+ }
288
+ const baseDelayMs = retryAfterSeconds * 1000;
289
+ const maxRetries = 3;
290
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
291
+ // Add jitter to prevent thundering herd
292
+ const jitterMs = Math.floor(Math.random() * 300) - 150; // ±150ms jitter
293
+ const exponentialBackoff = Math.pow(1.5, attempt - 1); // Mild exponential backoff
294
+ const delayMs = Math.max(100, baseDelayMs * exponentialBackoff + jitterMs);
295
+ console.log(`🔄 503 retry attempt ${attempt}/${maxRetries}, waiting ${delayMs}ms...`);
296
+ await new Promise(resolve => setTimeout(resolve, delayMs));
297
+ try {
298
+ const retryResponse = await fetch(fullEndpoint, config);
299
+ if (retryResponse.ok) {
300
+ console.log(`✅ 503 retry attempt ${attempt} succeeded`);
301
+ const rawData = await retryResponse.json();
302
+ resetAuthFailureState();
303
+ // COMPATIBILITY MODE: Handle both formats
304
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
305
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
306
+ return this.convertToApiResult(validatedResponse);
307
+ }
308
+ else {
309
+ // New format - raw data
310
+ const wrappedResponse = {
311
+ success: true,
312
+ data: rawData,
313
+ message: 'Success',
314
+ operation_code: 'RAW_RESPONSE',
315
+ timestamp: new Date().toISOString()
316
+ };
317
+ return wrappedResponse;
318
+ }
319
+ }
320
+ // If we get another 503, continue retrying
321
+ if (retryResponse.status === 503) {
322
+ console.log(`🔄 503 retry attempt ${attempt} got another 503, will retry...`);
323
+ continue;
324
+ }
325
+ // If we get a different error, break and handle it normally
326
+ console.log(`❌ 503 retry attempt ${attempt} got ${retryResponse.status}, stopping retries`);
327
+ // Fall through to handle the retry response error
328
+ const errorText = await retryResponse.text();
329
+ let errorData;
330
+ try {
331
+ errorData = JSON.parse(errorText);
332
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
333
+ // Detect PayEz canonical error envelope and map accordingly
334
+ if (errorData.error && typeof errorData.error === 'object') {
335
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
336
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
337
+ const errorResult = {
338
+ success: false,
339
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
340
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${retryResponse.status}`,
341
+ operation: endpoint,
342
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
343
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
344
+ };
345
+ return errorResult;
346
+ }
347
+ // Otherwise attempt to validate as our standardized error shape
348
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
349
+ return this.convertToApiResult(validatedError);
350
+ }
351
+ else {
352
+ // New/unknown error format - best-effort mapping
353
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
354
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
355
+ const errorResult = {
356
+ success: false,
357
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
358
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${retryResponse.status}`,
359
+ operation: endpoint,
360
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
361
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
362
+ };
363
+ return errorResult;
364
+ }
365
+ }
366
+ catch {
367
+ const reqIdHeader2 = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
368
+ const errorResult = {
369
+ success: false,
370
+ error_code: `HTTP_${retryResponse.status}`,
371
+ message: errorText || `Request failed with status ${retryResponse.status}`,
372
+ operation: endpoint,
373
+ ...(reqIdHeader2 ? { request_id: reqIdHeader2 } : {})
374
+ };
375
+ return errorResult;
376
+ }
377
+ }
378
+ catch (retryError) {
379
+ console.log(`❌ 503 retry attempt ${attempt} failed with network error:`, retryError);
380
+ if (attempt === maxRetries) {
381
+ // If all retries failed with network errors, throw the original error
382
+ throw new ApiNetworkError('Service temporarily unavailable after retries', 503, endpoint);
383
+ }
384
+ continue;
385
+ }
386
+ }
387
+ // If we got here, all retries failed - fall through to normal error handling
388
+ console.log('❌ All 503 retry attempts exhausted, treating as error');
389
+ }
390
+ // Handle authentication errors with a single refresh+retry
391
+ if (response.status === 401) {
392
+ console.log('🔑 Got 401, checking if we have a session to refresh...');
393
+ // CRITICAL FIX: Check if we actually have a session before attempting refresh
394
+ const currentSession = await (0, react_1.getSession)();
395
+ if (!currentSession || !currentSession.accessToken) {
396
+ console.log('🚫 No valid session found, redirecting to login instead of refresh');
397
+ scheduleLoginRedirect(true); // Immediate redirect
398
+ throw new ApiNetworkError('Authentication required - no valid session', 401, endpoint);
399
+ }
400
+ // Elegantly gate refresh during pre-2FA or when no refresh token exists
401
+ const pre2FA_now = isPreTwoFactorSession(currentSession);
402
+ const hasRefresh_now = !!currentSession?.refreshToken;
403
+ if (pre2FA_now || !hasRefresh_now) {
404
+ console.log('⏭️ Skipping 401-driven refresh:', {
405
+ reason: pre2FA_now ? 'pre-2FA session' : 'no refresh token',
406
+ requiresTwoFactor: currentSession?.user?.requiresTwoFactor,
407
+ twoFactorVerified: currentSession?.user?.twoFactorSessionVerified,
408
+ hasRefreshToken: hasRefresh_now
409
+ });
410
+ // CRITICAL: Redirect to login immediately if refresh is impossible
411
+ console.log('🚫 Cannot refresh session, redirecting to login');
412
+ scheduleLoginRedirect(true); // Immediate redirect
413
+ throw new ApiNetworkError(pre2FA_now
414
+ ? 'Two-factor authentication required'
415
+ : 'Session expired - refresh token unavailable', 401, endpoint);
416
+ }
417
+ console.log('🔑 Valid session found, attempting token refresh...');
418
+ // Try to refresh the token, but coordinate to avoid double refresh
419
+ if (!refreshInFlight) {
420
+ refreshInFlight = (async () => {
421
+ const reqId = crypto.randomUUID();
422
+ const refreshResponse = await fetch('/api/auth/refresh', {
423
+ method: 'POST',
424
+ credentials: 'include',
425
+ headers: { 'X-Request-ID': reqId },
426
+ });
427
+ if (refreshResponse.ok) {
428
+ console.log('✅ Token refreshed successfully (client-side coordinator)');
429
+ return true;
430
+ }
431
+ // If refresh is already in progress server-side, wait briefly and allow retry
432
+ if (refreshResponse.status === 409) {
433
+ console.log('↪️ Refresh in progress server-side (409). Waiting for completion...');
434
+ await new Promise(r => setTimeout(r, 1500));
435
+ return true;
436
+ }
437
+ // For auth failures, schedule redirect; for others, throw
438
+ if (refreshResponse.status === 401 || refreshResponse.status === 403) {
439
+ scheduleLoginRedirect();
440
+ throw new ApiNetworkError('Authentication failed - unable to refresh session', refreshResponse.status, endpoint);
441
+ }
442
+ const errorText = await refreshResponse.text();
443
+ throw new ApiNetworkError(errorText || 'Token refresh failed', refreshResponse.status, endpoint);
444
+ })().finally(() => { refreshInFlight = null; });
445
+ }
446
+ try {
447
+ await refreshInFlight;
448
+ }
449
+ catch (e) {
450
+ throw e; // bubble up to caller handling
451
+ }
452
+ console.log('🔁 Retrying original request after coordinated refresh...');
453
+ // Get the new session and retry the original request
454
+ const newSession = await (0, react_1.getSession)();
455
+ const newToken = newSession?.accessToken;
456
+ const retryConfig = {
457
+ ...options,
458
+ headers: {
459
+ 'Content-Type': 'application/json',
460
+ ...(newToken && { 'Authorization': `Bearer ${newToken}` }),
461
+ ...options.headers,
462
+ },
463
+ };
464
+ const retryResponse = await fetch(fullEndpoint, retryConfig);
465
+ if (retryResponse.ok) {
466
+ const rawData = await retryResponse.json();
467
+ // Reset auth failure state on successful retry
468
+ resetAuthFailureState();
469
+ // COMPATIBILITY MODE: Handle both formats in retry as well
470
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
471
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
472
+ return this.convertToApiResult(validatedResponse);
473
+ }
474
+ else {
475
+ // New format - raw data
476
+ console.log(`🔄 Converting raw retry response to standardized format for ${endpoint}`);
477
+ const wrappedResponse = {
478
+ success: true,
479
+ data: rawData,
480
+ message: 'Success',
481
+ operation_code: 'RAW_RESPONSE',
482
+ timestamp: new Date().toISOString()
483
+ };
484
+ return wrappedResponse;
485
+ }
486
+ }
487
+ else {
488
+ // If retry still 401, schedule redirect
489
+ if (retryResponse.status === 401) {
490
+ scheduleLoginRedirect();
491
+ }
492
+ const errorText = await retryResponse.text();
493
+ let errorData;
494
+ try {
495
+ errorData = JSON.parse(errorText);
496
+ // Check if it has the success field (old format)
497
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
498
+ // Detect PayEz canonical error envelope and map accordingly
499
+ if (errorData.error && typeof errorData.error === 'object') {
500
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
501
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
502
+ const errorResult = {
503
+ success: false,
504
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
505
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${retryResponse.status}`,
506
+ operation: endpoint,
507
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
508
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
509
+ };
510
+ return errorResult;
511
+ }
512
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
513
+ return this.convertToApiResult(validatedError);
514
+ }
515
+ else {
516
+ // New format - convert raw error to standardized format
517
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
518
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
519
+ const errorResult = {
520
+ success: false,
521
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
522
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${retryResponse.status}`,
523
+ operation: endpoint,
524
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
525
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
526
+ };
527
+ return errorResult;
528
+ }
529
+ }
530
+ catch {
531
+ // If we can't parse the error, create a generic error response
532
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
533
+ const errorResult = {
534
+ success: false,
535
+ error_code: `HTTP_${retryResponse.status}`,
536
+ message: errorText || `Request failed with status ${retryResponse.status}`,
537
+ operation: endpoint,
538
+ ...(reqIdHeader ? { request_id: reqIdHeader } : {})
539
+ };
540
+ return errorResult;
541
+ }
542
+ }
543
+ }
544
+ // Non-401 error: try to parse as standardized error response
545
+ const errorText = await response.text();
546
+ let errorData;
547
+ try {
548
+ errorData = JSON.parse(errorText);
549
+ // Check if it has the success field (old format)
550
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
551
+ // Detect PayEz canonical error envelope and map accordingly
552
+ if (errorData.error && typeof errorData.error === 'object') {
553
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
554
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
555
+ const errorResult = {
556
+ success: false,
557
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${response.status}`,
558
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${response.status}`,
559
+ operation: endpoint,
560
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
561
+ validation_errors: errorData?.validation_errors || undefined,
562
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
563
+ };
564
+ return errorResult;
565
+ }
566
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
567
+ return this.convertToApiResult(validatedError);
568
+ }
569
+ else {
570
+ // New format - convert raw error to standardized format
571
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
572
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
573
+ const errorResult = {
574
+ success: false,
575
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${response.status}`,
576
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${response.status}`,
577
+ operation: endpoint,
578
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
579
+ validation_errors: errorData?.validation_errors || undefined,
580
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
581
+ };
582
+ return errorResult;
583
+ }
584
+ }
585
+ catch (parseError) {
586
+ // If we can't parse the error, create a generic error response
587
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
588
+ const errorResult = {
589
+ success: false,
590
+ error_code: `HTTP_${response.status}`,
591
+ message: errorText || `Request failed with status ${response.status}`,
592
+ operation: endpoint,
593
+ details: undefined,
594
+ ...(reqIdHeader ? { request_id: reqIdHeader } : {})
595
+ };
596
+ return errorResult;
597
+ }
598
+ }
599
+ // SUCCESS PATH: Parse and validate response
600
+ const rawData = await response.json();
601
+ // Reset auth failure state on successful request
602
+ resetAuthFailureState();
603
+ // COMPATIBILITY MODE: Handle both old envelope format and new raw format
604
+ try {
605
+ // First check if it's the old standardized format with success field
606
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
607
+ // Old format - validate as standardized response
608
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
609
+ return this.convertToApiResult(validatedResponse);
610
+ }
611
+ else {
612
+ // New format - raw data, wrap it in success envelope for compatibility
613
+ console.log(`🔄 Converting raw response to standardized format for ${endpoint}`);
614
+ const wrappedResponse = {
615
+ success: true,
616
+ data: rawData,
617
+ message: 'Success',
618
+ operation_code: 'RAW_RESPONSE',
619
+ timestamp: new Date().toISOString()
620
+ };
621
+ return wrappedResponse;
622
+ }
623
+ }
624
+ catch (validationError) {
625
+ // If response format is invalid, this is a CRITICAL error
626
+ throw new ApiResponseFormatError(validationError instanceof Error ? validationError.message : 'Response format validation failed', endpoint, rawData);
627
+ }
628
+ }
629
+ catch (error) {
630
+ // Re-throw our custom errors as-is
631
+ if (error instanceof ApiResponseFormatError ||
632
+ error instanceof ApiBusinessLogicError ||
633
+ error instanceof ApiValidationError ||
634
+ error instanceof ApiNetworkError) {
635
+ throw error;
636
+ }
637
+ // Wrap unknown errors as network errors
638
+ console.error('❌ API request failed:', error);
639
+ throw new ApiNetworkError(error instanceof Error ? error.message : 'Network error', 0, endpoint);
640
+ }
641
+ }
642
+ /**
643
+ * CONVERTS VALIDATED STANDARDIZED RESPONSE TO CLIENT RESULT
644
+ * This normalizes the response for client consumption
645
+ */
646
+ convertToApiResult(validatedResponse) {
647
+ if ((0, api_responses_1.isSuccessResponse)(validatedResponse)) {
648
+ return {
649
+ success: true,
650
+ data: validatedResponse.data,
651
+ message: validatedResponse.message,
652
+ operation_code: validatedResponse.operation_code,
653
+ timestamp: validatedResponse.timestamp
654
+ };
655
+ }
656
+ if ((0, api_responses_1.isPagedResponse)(validatedResponse)) {
657
+ return {
658
+ success: true,
659
+ items: validatedResponse.data,
660
+ message: validatedResponse.message,
661
+ operation_code: validatedResponse.operation_code,
662
+ pagination: validatedResponse.pagination,
663
+ timestamp: validatedResponse.timestamp
664
+ };
665
+ }
666
+ if ((0, api_responses_1.isErrorResponse)(validatedResponse)) {
667
+ const reqId = validatedResponse?.request_id || validatedResponse?.requestId;
668
+ if (validatedResponse.error_code === 'VALIDATION_ERROR') {
669
+ // Handle validation error
670
+ const valError = validatedResponse;
671
+ return {
672
+ success: false,
673
+ error_code: validatedResponse.error_code,
674
+ message: validatedResponse.message,
675
+ operation: validatedResponse.operation,
676
+ details: validatedResponse.details,
677
+ validation_errors: valError.payload?.validation_errors,
678
+ ...(reqId ? { request_id: reqId } : {})
679
+ };
680
+ }
681
+ else {
682
+ // Handle regular error
683
+ return {
684
+ success: false,
685
+ error_code: validatedResponse.error_code,
686
+ message: validatedResponse.message,
687
+ operation: validatedResponse.operation,
688
+ details: validatedResponse.details,
689
+ ...(reqId ? { request_id: reqId } : {})
690
+ };
691
+ }
692
+ }
693
+ // This should never happen due to validation, but TypeScript requires it
694
+ throw new ApiResponseFormatError('Unknown response type after validation', 'unknown', validatedResponse);
695
+ }
696
+ // ========================================================================================
697
+ // HTTP METHOD WRAPPERS - PUBLIC API
698
+ // ========================================================================================
699
+ /**
700
+ * GET REQUEST - Returns typed result with direct data access
701
+ */
702
+ async get(endpoint, sessionToken) {
703
+ return this.makeRequest(endpoint, { method: 'GET' }, sessionToken);
704
+ }
705
+ /**
706
+ * POST REQUEST - Returns typed result with direct data access
707
+ */
708
+ async post(endpoint, data, sessionToken) {
709
+ return this.makeRequest(endpoint, {
710
+ method: 'POST',
711
+ body: data ? JSON.stringify(data) : undefined,
712
+ }, sessionToken);
713
+ }
714
+ /**
715
+ * PUT REQUEST - Returns typed result with direct data access
716
+ */
717
+ async put(endpoint, data, sessionToken) {
718
+ return this.makeRequest(endpoint, {
719
+ method: 'PUT',
720
+ body: data ? JSON.stringify(data) : undefined,
721
+ }, sessionToken);
722
+ }
723
+ /**
724
+ * DELETE REQUEST - Returns typed result with direct data access
725
+ */
726
+ async delete(endpoint) {
727
+ return this.makeRequest(endpoint, { method: 'DELETE' });
728
+ }
729
+ }
730
+ // ========================================================================================
731
+ // SINGLETON INSTANCE - READY TO USE
732
+ // ========================================================================================
733
+ exports.standardizedApi = new StandardizedClientApiService();
734
+ // ========================================================================================
735
+ // CONVENIENCE HELPER FUNCTIONS
736
+ // ========================================================================================
737
+ /**
738
+ * TYPE-SAFE SUCCESS CHECK
739
+ * Use this to check if API call was successful with proper type narrowing
740
+ */
741
+ function isApiSuccess(result) {
742
+ return result.success === true && 'data' in result;
743
+ }
744
+ /**
745
+ * TYPE-SAFE PAGED SUCCESS CHECK
746
+ * Use this to check if API call was successful paged response with proper type narrowing
747
+ */
748
+ function isApiPagedSuccess(result) {
749
+ return result.success === true && 'items' in result;
750
+ }
751
+ /**
752
+ * TYPE-SAFE ERROR CHECK
753
+ * Use this to check if API call failed with proper type narrowing
754
+ */
755
+ function isApiError(result) {
756
+ return result.success === false;
757
+ }
758
+ /**
759
+ * EXTRACT DATA FROM SUCCESS RESULT
760
+ * Use this to get the data from a successful API call
761
+ * Will throw if result is not successful
762
+ */
763
+ function extractApiData(result) {
764
+ if (isApiSuccess(result)) {
765
+ return result.data;
766
+ }
767
+ if (isApiPagedSuccess(result)) {
768
+ return result.items;
769
+ }
770
+ throw new ApiBusinessLogicError(result.error_code, result.message, result.operation, result.details);
771
+ }
772
+ /**
773
+ * EXTRACT ITEMS FROM PAGED SUCCESS RESULT
774
+ * Use this to get the items array from a successful paged API call
775
+ * Will throw if result is not successful paged response
776
+ */
777
+ function extractApiItems(result) {
778
+ if (isApiPagedSuccess(result)) {
779
+ return result.items;
780
+ }
781
+ if (isApiSuccess(result)) {
782
+ // If it's a regular success but expected paged, data should be array
783
+ return result.data;
784
+ }
785
+ throw new ApiBusinessLogicError(result.error_code, result.message, result.operation, result.details);
786
+ }