@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.
- package/README.md +782 -0
- package/dist/api/auth-handler.d.ts +67 -0
- package/dist/api/auth-handler.js +397 -0
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.js +19 -0
- package/dist/api-handlers/account/change-password.d.ts +9 -0
- package/dist/api-handlers/account/change-password.js +112 -0
- package/dist/api-handlers/account/masked-info.d.ts +2 -0
- package/dist/api-handlers/account/masked-info.js +41 -0
- package/dist/api-handlers/account/profile.d.ts +3 -0
- package/dist/api-handlers/account/profile.js +63 -0
- package/dist/api-handlers/account/recovery/initiate.d.ts +2 -0
- package/dist/api-handlers/account/recovery/initiate.js +26 -0
- package/dist/api-handlers/account/recovery/send-code.d.ts +2 -0
- package/dist/api-handlers/account/recovery/send-code.js +28 -0
- package/dist/api-handlers/account/recovery/verify-code.d.ts +2 -0
- package/dist/api-handlers/account/recovery/verify-code.js +28 -0
- package/dist/api-handlers/account/reset-password.d.ts +2 -0
- package/dist/api-handlers/account/reset-password.js +26 -0
- package/dist/api-handlers/account/send-code.d.ts +24 -0
- package/dist/api-handlers/account/send-code.js +60 -0
- package/dist/api-handlers/account/update-phone.d.ts +27 -0
- package/dist/api-handlers/account/update-phone.js +64 -0
- package/dist/api-handlers/account/validate-password.d.ts +17 -0
- package/dist/api-handlers/account/validate-password.js +81 -0
- package/dist/api-handlers/account/verify-email.d.ts +26 -0
- package/dist/api-handlers/account/verify-email.js +106 -0
- package/dist/api-handlers/account/verify-sms.d.ts +26 -0
- package/dist/api-handlers/account/verify-sms.js +106 -0
- package/dist/api-handlers/admin/analytics.d.ts +20 -0
- package/dist/api-handlers/admin/analytics.js +379 -0
- package/dist/api-handlers/admin/audit.d.ts +20 -0
- package/dist/api-handlers/admin/audit.js +214 -0
- package/dist/api-handlers/admin/index.d.ts +21 -0
- package/dist/api-handlers/admin/index.js +41 -0
- package/dist/api-handlers/admin/redis-sessions.d.ts +36 -0
- package/dist/api-handlers/admin/redis-sessions.js +204 -0
- package/dist/api-handlers/admin/sessions.d.ts +21 -0
- package/dist/api-handlers/admin/sessions.js +284 -0
- package/dist/api-handlers/admin/site-logs.d.ts +46 -0
- package/dist/api-handlers/admin/site-logs.js +318 -0
- package/dist/api-handlers/admin/users.d.ts +20 -0
- package/dist/api-handlers/admin/users.js +222 -0
- package/dist/api-handlers/admin/vibe-data.d.ts +80 -0
- package/dist/api-handlers/admin/vibe-data.js +268 -0
- package/dist/api-handlers/anon/preferences.d.ts +37 -0
- package/dist/api-handlers/anon/preferences.js +96 -0
- package/dist/api-handlers/auth/jwks.d.ts +2 -0
- package/dist/api-handlers/auth/jwks.js +24 -0
- package/dist/api-handlers/auth/login.d.ts +42 -0
- package/dist/api-handlers/auth/login.js +178 -0
- package/dist/api-handlers/auth/refresh.d.ts +74 -0
- package/dist/api-handlers/auth/refresh.js +635 -0
- package/dist/api-handlers/auth/signout.d.ts +37 -0
- package/dist/api-handlers/auth/signout.js +187 -0
- package/dist/api-handlers/auth/status.d.ts +8 -0
- package/dist/api-handlers/auth/status.js +26 -0
- package/dist/api-handlers/auth/update-session.d.ts +37 -0
- package/dist/api-handlers/auth/update-session.js +95 -0
- package/dist/api-handlers/auth/validate.d.ts +6 -0
- package/dist/api-handlers/auth/validate.js +43 -0
- package/dist/api-handlers/auth/verify-code.d.ts +43 -0
- package/dist/api-handlers/auth/verify-code.js +94 -0
- package/dist/api-handlers/session/refresh-viability.d.ts +14 -0
- package/dist/api-handlers/session/refresh-viability.js +39 -0
- package/dist/api-handlers/session/viability.d.ts +13 -0
- package/dist/api-handlers/session/viability.js +146 -0
- package/dist/api-handlers/test/force-expire.d.ts +23 -0
- package/dist/api-handlers/test/force-expire.js +65 -0
- package/dist/auth/auth-decision.d.ts +39 -0
- package/dist/auth/auth-decision.js +182 -0
- package/dist/auth/auth-options.d.ts +57 -0
- package/dist/auth/auth-options.js +213 -0
- package/dist/auth/callbacks/index.d.ts +6 -0
- package/dist/auth/callbacks/index.js +12 -0
- package/dist/auth/callbacks/jwt.d.ts +45 -0
- package/dist/auth/callbacks/jwt.js +305 -0
- package/dist/auth/callbacks/session.d.ts +60 -0
- package/dist/auth/callbacks/session.js +170 -0
- package/dist/auth/callbacks/signin.d.ts +23 -0
- package/dist/auth/callbacks/signin.js +44 -0
- package/dist/auth/events/index.d.ts +4 -0
- package/dist/auth/events/index.js +8 -0
- package/dist/auth/events/signout.d.ts +17 -0
- package/dist/auth/events/signout.js +32 -0
- package/dist/auth/providers/credentials.d.ts +32 -0
- package/dist/auth/providers/credentials.js +223 -0
- package/dist/auth/providers/index.d.ts +5 -0
- package/dist/auth/providers/index.js +21 -0
- package/dist/auth/providers/oauth.d.ts +26 -0
- package/dist/auth/providers/oauth.js +105 -0
- package/dist/auth/route-config.d.ts +66 -0
- package/dist/auth/route-config.js +190 -0
- package/dist/auth/types/auth-types.d.ts +417 -0
- package/dist/auth/types/auth-types.js +53 -0
- package/dist/auth/types/index.d.ts +6 -0
- package/dist/auth/types/index.js +22 -0
- package/dist/auth/unauthenticated-routes.d.ts +1 -0
- package/dist/auth/unauthenticated-routes.js +19 -0
- package/dist/auth/utils/idp-client.d.ts +94 -0
- package/dist/auth/utils/idp-client.js +383 -0
- package/dist/auth/utils/index.d.ts +5 -0
- package/dist/auth/utils/index.js +21 -0
- package/dist/auth/utils/token-utils.d.ts +84 -0
- package/dist/auth/utils/token-utils.js +219 -0
- package/dist/client/AuthContext.d.ts +19 -0
- package/dist/client/AuthContext.js +112 -0
- package/dist/client/fetch-with-auth.d.ts +11 -0
- package/dist/client/fetch-with-auth.js +44 -0
- package/dist/client/fetchWithSession.d.ts +3 -0
- package/dist/client/fetchWithSession.js +24 -0
- package/dist/client/index.d.ts +9 -0
- package/dist/client/index.js +20 -0
- package/dist/client/useAnonSession.d.ts +36 -0
- package/dist/client/useAnonSession.js +99 -0
- package/dist/components/SessionSync.d.ts +13 -0
- package/dist/components/SessionSync.js +119 -0
- package/dist/components/SignalRHealthCheck.d.ts +10 -0
- package/dist/components/SignalRHealthCheck.js +97 -0
- package/dist/components/account/UserAvatarMenu.d.ts +20 -0
- package/dist/components/account/UserAvatarMenu.js +80 -0
- package/dist/components/account/index.d.ts +7 -0
- package/dist/components/account/index.js +10 -0
- package/dist/components/admin/AlertSettingsTab.d.ts +48 -0
- package/dist/components/admin/AlertSettingsTab.js +351 -0
- package/dist/components/admin/AnalyticsTab.d.ts +22 -0
- package/dist/components/admin/AnalyticsTab.js +167 -0
- package/dist/components/admin/DataBrowserTab.d.ts +19 -0
- package/dist/components/admin/DataBrowserTab.js +252 -0
- package/dist/components/admin/LoggingSettingsTab.d.ts +73 -0
- package/dist/components/admin/LoggingSettingsTab.js +339 -0
- package/dist/components/admin/SessionsTab.d.ts +37 -0
- package/dist/components/admin/SessionsTab.js +165 -0
- package/dist/components/admin/StatsTab.d.ts +53 -0
- package/dist/components/admin/StatsTab.js +161 -0
- package/dist/components/admin/VibeAdminContext.d.ts +32 -0
- package/dist/components/admin/VibeAdminContext.js +38 -0
- package/dist/components/admin/VibeAdminLayout.d.ts +11 -0
- package/dist/components/admin/VibeAdminLayout.js +69 -0
- package/dist/components/admin/index.d.ts +29 -0
- package/dist/components/admin/index.js +44 -0
- package/dist/components/auth/FederatedAuthSection.d.ts +8 -0
- package/dist/components/auth/FederatedAuthSection.js +45 -0
- package/dist/components/auth/ModeAwareLoginPage.d.ts +10 -0
- package/dist/components/auth/ModeAwareLoginPage.js +42 -0
- package/dist/components/auth/ModeAwareSignupPage.d.ts +9 -0
- package/dist/components/auth/ModeAwareSignupPage.js +78 -0
- package/dist/components/auth/TraditionalAuthSection.d.ts +14 -0
- package/dist/components/auth/TraditionalAuthSection.js +20 -0
- package/dist/components/recovery/CompleteStep.d.ts +5 -0
- package/dist/components/recovery/CompleteStep.js +8 -0
- package/dist/components/recovery/InitiateRecoveryStep.d.ts +8 -0
- package/dist/components/recovery/InitiateRecoveryStep.js +20 -0
- package/dist/components/recovery/SelectMethodStep.d.ts +8 -0
- package/dist/components/recovery/SelectMethodStep.js +8 -0
- package/dist/components/recovery/SetPasswordStep.d.ts +6 -0
- package/dist/components/recovery/SetPasswordStep.js +20 -0
- package/dist/components/recovery/VerifyCodeStep.d.ts +10 -0
- package/dist/components/recovery/VerifyCodeStep.js +24 -0
- package/dist/components/reserved/ReservedRecoveryWarning.d.ts +38 -0
- package/dist/components/reserved/ReservedRecoveryWarning.js +92 -0
- package/dist/components/reserved/ReservedStatusBox.d.ts +30 -0
- package/dist/components/reserved/ReservedStatusBox.js +71 -0
- package/dist/components/ui/BetaBadge.d.ts +29 -0
- package/dist/components/ui/BetaBadge.js +38 -0
- package/dist/components/ui/Footer.d.ts +37 -0
- package/dist/components/ui/Footer.js +41 -0
- package/dist/config/env.d.ts +66 -0
- package/dist/config/env.js +57 -0
- package/dist/config/logger.d.ts +57 -0
- package/dist/config/logger.js +73 -0
- package/dist/config/logging-config.d.ts +30 -0
- package/dist/config/logging-config.js +122 -0
- package/dist/config/unauthenticated-routes.d.ts +17 -0
- package/dist/config/unauthenticated-routes.js +24 -0
- package/dist/config/vibe-log-transport.d.ts +79 -0
- package/dist/config/vibe-log-transport.js +203 -0
- package/dist/edge/internal-api-url.d.ts +53 -0
- package/dist/edge/internal-api-url.js +63 -0
- package/dist/edge/middleware.d.ts +14 -0
- package/dist/edge/middleware.js +32 -0
- package/dist/hooks/useAuth.d.ts +23 -0
- package/dist/hooks/useAuth.js +81 -0
- package/dist/hooks/useAuthSettings.d.ts +59 -0
- package/dist/hooks/useAuthSettings.js +93 -0
- package/dist/hooks/useAvailableProviders.d.ts +45 -0
- package/dist/hooks/useAvailableProviders.js +108 -0
- package/dist/hooks/usePasswordValidation.d.ts +27 -0
- package/dist/hooks/usePasswordValidation.js +102 -0
- package/dist/hooks/useProfile.d.ts +15 -0
- package/dist/hooks/useProfile.js +59 -0
- package/dist/hooks/usePublicAuthSettings.d.ts +56 -0
- package/dist/hooks/usePublicAuthSettings.js +131 -0
- package/dist/hooks/useSessionExpiration.d.ts +57 -0
- package/dist/hooks/useSessionExpiration.js +72 -0
- package/dist/hooks/useViabilitySession.d.ts +75 -0
- package/dist/hooks/useViabilitySession.js +268 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +54 -0
- package/dist/lib/anon-session.d.ts +74 -0
- package/dist/lib/anon-session.js +169 -0
- package/dist/lib/api-handler.d.ts +123 -0
- package/dist/lib/api-handler.js +478 -0
- package/dist/lib/app-slug.d.ts +95 -0
- package/dist/lib/app-slug.js +172 -0
- package/dist/lib/demo-mode.d.ts +6 -0
- package/dist/lib/demo-mode.js +16 -0
- package/dist/lib/geolocation.d.ts +64 -0
- package/dist/lib/geolocation.js +235 -0
- package/dist/lib/idp-client-config.d.ts +75 -0
- package/dist/lib/idp-client-config.js +351 -0
- package/dist/lib/idp-fetch.d.ts +14 -0
- package/dist/lib/idp-fetch.js +91 -0
- package/dist/lib/internal-api.d.ts +87 -0
- package/dist/lib/internal-api.js +122 -0
- package/dist/lib/jwt-decode-client.d.ts +10 -0
- package/dist/lib/jwt-decode-client.js +46 -0
- package/dist/lib/jwt-decode.d.ts +48 -0
- package/dist/lib/jwt-decode.js +57 -0
- package/dist/lib/nextauth-secret.d.ts +10 -0
- package/dist/lib/nextauth-secret.js +104 -0
- package/dist/lib/rate-limit-service.d.ts +23 -0
- package/dist/lib/rate-limit-service.js +6 -0
- package/dist/lib/redis.d.ts +5 -0
- package/dist/lib/redis.js +28 -0
- package/dist/lib/refresh-token-validator.d.ts +13 -0
- package/dist/lib/refresh-token-validator.js +117 -0
- package/dist/lib/roles.d.ts +145 -0
- package/dist/lib/roles.js +168 -0
- package/dist/lib/secret-validation.d.ts +4 -0
- package/dist/lib/secret-validation.js +14 -0
- package/dist/lib/session-store.d.ts +166 -0
- package/dist/lib/session-store.js +537 -0
- package/dist/lib/session.d.ts +21 -0
- package/dist/lib/session.js +26 -0
- package/dist/lib/site-logger.d.ts +214 -0
- package/dist/lib/site-logger.js +210 -0
- package/dist/lib/standardized-client-api.d.ts +161 -0
- package/dist/lib/standardized-client-api.js +786 -0
- package/dist/lib/startup-init.d.ts +40 -0
- package/dist/lib/startup-init.js +261 -0
- package/dist/lib/test-aware-get-token.d.ts +2 -0
- package/dist/lib/test-aware-get-token.js +81 -0
- package/dist/lib/token-expiry.d.ts +14 -0
- package/dist/lib/token-expiry.js +39 -0
- package/dist/lib/token-lifecycle.d.ts +52 -0
- package/dist/lib/token-lifecycle.js +398 -0
- package/dist/lib/types/api-responses.d.ts +128 -0
- package/dist/lib/types/api-responses.js +171 -0
- package/dist/lib/user-agent-parser.d.ts +50 -0
- package/dist/lib/user-agent-parser.js +220 -0
- package/dist/logging/api/admin-analytics.d.ts +3 -0
- package/dist/logging/api/admin-analytics.js +45 -0
- package/dist/logging/api/audit-log.d.ts +3 -0
- package/dist/logging/api/audit-log.js +52 -0
- package/dist/logging/components/AdminAnalyticsLayout.d.ts +10 -0
- package/dist/logging/components/AdminAnalyticsLayout.js +11 -0
- package/dist/logging/components/AuditLogViewer.d.ts +7 -0
- package/dist/logging/components/AuditLogViewer.js +51 -0
- package/dist/logging/components/ErrorMetricsCard.d.ts +7 -0
- package/dist/logging/components/ErrorMetricsCard.js +16 -0
- package/dist/logging/components/HealthMetricsCard.d.ts +7 -0
- package/dist/logging/components/HealthMetricsCard.js +19 -0
- package/dist/logging/hooks/useAdminAnalytics.d.ts +24 -0
- package/dist/logging/hooks/useAdminAnalytics.js +22 -0
- package/dist/logging/hooks/useAuditLog.d.ts +6 -0
- package/dist/logging/hooks/useAuditLog.js +25 -0
- package/dist/logging/hooks/useErrorMetrics.d.ts +6 -0
- package/dist/logging/hooks/useErrorMetrics.js +38 -0
- package/dist/logging/hooks/useHealthMetrics.d.ts +6 -0
- package/dist/logging/hooks/useHealthMetrics.js +41 -0
- package/dist/logging/index.d.ts +11 -0
- package/dist/logging/index.js +40 -0
- package/dist/logging/types/analytics.d.ts +68 -0
- package/dist/logging/types/analytics.js +3 -0
- package/dist/logging/types/audit.d.ts +29 -0
- package/dist/logging/types/audit.js +2 -0
- package/dist/logging/types/index.d.ts +2 -0
- package/dist/logging/types/index.js +19 -0
- package/dist/middleware/auth-decision.d.ts +33 -0
- package/dist/middleware/auth-decision.js +65 -0
- package/dist/middleware/create-middleware.d.ts +100 -0
- package/dist/middleware/create-middleware.js +445 -0
- package/dist/middleware/rbac-check.d.ts +44 -0
- package/dist/middleware/rbac-check.js +191 -0
- package/dist/middleware/twofa-presets.d.ts +134 -0
- package/dist/middleware/twofa-presets.js +175 -0
- package/dist/models/DecodedAccessToken.d.ts +17 -0
- package/dist/models/DecodedAccessToken.js +2 -0
- package/dist/models/SessionModel.d.ts +122 -0
- package/dist/models/SessionModel.js +136 -0
- package/dist/pages/admin-login/page.d.ts +31 -0
- package/dist/pages/admin-login/page.js +83 -0
- package/dist/pages/admin-roles/RolesAdminPage.d.ts +15 -0
- package/dist/pages/admin-roles/RolesAdminPage.js +78 -0
- package/dist/pages/admin-roles/index.d.ts +8 -0
- package/dist/pages/admin-roles/index.js +15 -0
- package/dist/pages/admin-roles/modals.d.ts +72 -0
- package/dist/pages/admin-roles/modals.js +154 -0
- package/dist/pages/client-admin/ClientSiteAdminPage.d.ts +79 -0
- package/dist/pages/client-admin/ClientSiteAdminPage.js +177 -0
- package/dist/pages/client-admin/index.d.ts +32 -0
- package/dist/pages/client-admin/index.js +37 -0
- package/dist/pages/login/page.d.ts +22 -0
- package/dist/pages/login/page.js +239 -0
- package/dist/pages/profile/EnhancedProfilePage.d.ts +13 -0
- package/dist/pages/profile/EnhancedProfilePage.js +150 -0
- package/dist/pages/profile/index.d.ts +8 -0
- package/dist/pages/profile/index.js +16 -0
- package/dist/pages/profile/page.d.ts +19 -0
- package/dist/pages/profile/page.js +47 -0
- package/dist/pages/profile/profile-patch.d.ts +1 -0
- package/dist/pages/profile/profile-patch.js +281 -0
- package/dist/pages/recovery/page.d.ts +1 -0
- package/dist/pages/recovery/page.js +142 -0
- package/dist/pages/roles/MyRolesPage.d.ts +24 -0
- package/dist/pages/roles/MyRolesPage.js +71 -0
- package/dist/pages/roles/components.d.ts +63 -0
- package/dist/pages/roles/components.js +108 -0
- package/dist/pages/roles/index.d.ts +8 -0
- package/dist/pages/roles/index.js +19 -0
- package/dist/pages/security/EnhancedSecurityPage.d.ts +14 -0
- package/dist/pages/security/EnhancedSecurityPage.js +248 -0
- package/dist/pages/security/index.d.ts +8 -0
- package/dist/pages/security/index.js +16 -0
- package/dist/pages/security/page.d.ts +21 -0
- package/dist/pages/security/page.js +212 -0
- package/dist/pages/security/security-patch.d.ts +1 -0
- package/dist/pages/security/security-patch.js +302 -0
- package/dist/pages/settings/EnhancedSettingsPage.d.ts +46 -0
- package/dist/pages/settings/EnhancedSettingsPage.js +231 -0
- package/dist/pages/settings/index.d.ts +8 -0
- package/dist/pages/settings/index.js +16 -0
- package/dist/pages/settings/page.d.ts +7 -0
- package/dist/pages/settings/page.js +26 -0
- package/dist/pages/showcase/ShowcasePage.d.ts +13 -0
- package/dist/pages/showcase/ShowcasePage.js +140 -0
- package/dist/pages/showcase/index.d.ts +12 -0
- package/dist/pages/showcase/index.js +17 -0
- package/dist/pages/test-env/EmergencyLogoutPage.d.ts +14 -0
- package/dist/pages/test-env/EmergencyLogoutPage.js +98 -0
- package/dist/pages/test-env/JwtInspectPage.d.ts +14 -0
- package/dist/pages/test-env/JwtInspectPage.js +114 -0
- package/dist/pages/test-env/RefreshTokenPage.d.ts +15 -0
- package/dist/pages/test-env/RefreshTokenPage.js +91 -0
- package/dist/pages/test-env/TestEnvPage.d.ts +13 -0
- package/dist/pages/test-env/TestEnvPage.js +49 -0
- package/dist/pages/test-env/index.d.ts +24 -0
- package/dist/pages/test-env/index.js +32 -0
- package/dist/pages/verify-code/page.d.ts +30 -0
- package/dist/pages/verify-code/page.js +408 -0
- package/dist/routes/account/index.d.ts +28 -0
- package/dist/routes/account/index.js +71 -0
- package/dist/routes/account/masked-info.d.ts +33 -0
- package/dist/routes/account/masked-info.js +39 -0
- package/dist/routes/account/send-code.d.ts +37 -0
- package/dist/routes/account/send-code.js +42 -0
- package/dist/routes/account/update-phone.d.ts +13 -0
- package/dist/routes/account/update-phone.js +17 -0
- package/dist/routes/account/verify-email.d.ts +38 -0
- package/dist/routes/account/verify-email.js +43 -0
- package/dist/routes/account/verify-sms.d.ts +38 -0
- package/dist/routes/account/verify-sms.js +43 -0
- package/dist/routes/auth/index.d.ts +19 -0
- package/dist/routes/auth/index.js +64 -0
- package/dist/routes/auth/logout.d.ts +31 -0
- package/dist/routes/auth/logout.js +113 -0
- package/dist/routes/auth/nextauth.d.ts +19 -0
- package/dist/routes/auth/nextauth.js +72 -0
- package/dist/routes/auth/refresh.d.ts +30 -0
- package/dist/routes/auth/refresh.js +51 -0
- package/dist/routes/auth/session.d.ts +72 -0
- package/dist/routes/auth/session.js +180 -0
- package/dist/routes/auth/settings.d.ts +25 -0
- package/dist/routes/auth/settings.js +55 -0
- package/dist/routes/auth/viability.d.ts +52 -0
- package/dist/routes/auth/viability.js +201 -0
- package/dist/routes/index.d.ts +12 -0
- package/dist/routes/index.js +54 -0
- package/dist/routes/session/index.d.ts +6 -0
- package/dist/routes/session/index.js +10 -0
- package/dist/routes/session/refresh-viability.d.ts +16 -0
- package/dist/routes/session/refresh-viability.js +20 -0
- package/dist/services/signalrActivityService.d.ts +44 -0
- package/dist/services/signalrActivityService.js +257 -0
- package/dist/stores/authStore.d.ts +154 -0
- package/dist/stores/authStore.js +1531 -0
- package/dist/theme/ThemeProvider.d.ts +14 -0
- package/dist/theme/ThemeProvider.js +28 -0
- package/dist/theme/default.d.ts +8 -0
- package/dist/theme/default.js +33 -0
- package/dist/theme/index.d.ts +15 -0
- package/dist/theme/index.js +25 -0
- package/dist/theme/types.d.ts +56 -0
- package/dist/theme/types.js +8 -0
- package/dist/theme/useTheme.d.ts +60 -0
- package/dist/theme/useTheme.js +63 -0
- package/dist/theme/utils.d.ts +13 -0
- package/dist/theme/utils.js +39 -0
- package/dist/types/api.d.ts +134 -0
- package/dist/types/api.js +44 -0
- package/dist/types/auth.d.ts +19 -0
- package/dist/types/auth.js +2 -0
- package/dist/types/logging.d.ts +42 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/recovery.d.ts +48 -0
- package/dist/types/recovery.js +2 -0
- package/dist/types/security.d.ts +1 -0
- package/dist/types/security.js +2 -0
- package/dist/utils/api.d.ts +85 -0
- package/dist/utils/api.js +287 -0
- package/dist/utils/circuitBreaker.d.ts +43 -0
- package/dist/utils/circuitBreaker.js +91 -0
- package/dist/utils/error-message.d.ts +1 -0
- package/dist/utils/error-message.js +103 -0
- package/dist/utils/layout/reservedSpace.d.ts +59 -0
- package/dist/utils/layout/reservedSpace.js +102 -0
- package/dist/utils/logout.d.ts +14 -0
- package/dist/utils/logout.js +32 -0
- package/dist/vibe/client.d.ts +261 -0
- package/dist/vibe/client.js +445 -0
- package/dist/vibe/errors.d.ts +83 -0
- package/dist/vibe/errors.js +146 -0
- package/dist/vibe/generic.d.ts +234 -0
- package/dist/vibe/generic.js +369 -0
- package/dist/vibe/hooks/index.d.ts +169 -0
- package/dist/vibe/hooks/index.js +252 -0
- package/dist/vibe/index.d.ts +23 -0
- package/dist/vibe/index.js +67 -0
- package/dist/vibe/sessions.d.ts +161 -0
- package/dist/vibe/sessions.js +391 -0
- package/dist/vibe/types.d.ts +353 -0
- package/dist/vibe/types.js +315 -0
- package/package.json +855 -0
- package/scripts/check-internal-url-usage.sh +73 -0
- package/scripts/dev-broker.ps1 +35 -0
- package/scripts/dev-local.ps1 +45 -0
- package/src/api/auth-handler.ts +550 -0
- package/src/api/index.ts +18 -0
- package/src/api-handlers/account/change-password.ts +145 -0
- package/src/api-handlers/account/masked-info.ts +45 -0
- package/src/api-handlers/account/profile.ts +80 -0
- package/src/api-handlers/account/recovery/initiate.ts +23 -0
- package/src/api-handlers/account/recovery/send-code.ts +25 -0
- package/src/api-handlers/account/recovery/verify-code.ts +25 -0
- package/src/api-handlers/account/reset-password.ts +23 -0
- package/src/api-handlers/account/send-code.ts +76 -0
- package/src/api-handlers/account/update-phone.ts +79 -0
- package/src/api-handlers/account/validate-password.ts +118 -0
- package/src/api-handlers/account/verify-email.ts +125 -0
- package/src/api-handlers/account/verify-sms.ts +125 -0
- package/src/api-handlers/admin/analytics.ts +445 -0
- package/src/api-handlers/admin/audit.ts +225 -0
- package/src/api-handlers/admin/index.ts +59 -0
- package/src/api-handlers/admin/redis-sessions.ts +253 -0
- package/src/api-handlers/admin/sessions.ts +320 -0
- package/src/api-handlers/admin/site-logs.ts +367 -0
- package/src/api-handlers/admin/users.ts +244 -0
- package/src/api-handlers/admin/vibe-data.ts +326 -0
- package/src/api-handlers/anon/preferences.ts +123 -0
- package/src/api-handlers/auth/jwks.ts +20 -0
- package/src/api-handlers/auth/login.ts +240 -0
- package/src/api-handlers/auth/refresh.ts +687 -0
- package/src/api-handlers/auth/signout.ts +212 -0
- package/src/api-handlers/auth/status.ts +23 -0
- package/src/api-handlers/auth/update-session.ts +125 -0
- package/src/api-handlers/auth/validate.ts +44 -0
- package/src/api-handlers/auth/verify-code.ts +129 -0
- package/src/api-handlers/session/refresh-viability.ts +36 -0
- package/src/api-handlers/session/viability.ts +166 -0
- package/src/api-handlers/test/force-expire.ts +67 -0
- package/src/auth/auth-decision.ts +230 -0
- package/src/auth/auth-options.ts +237 -0
- package/src/auth/callbacks/index.ts +7 -0
- package/src/auth/callbacks/jwt.ts +382 -0
- package/src/auth/callbacks/session.ts +243 -0
- package/src/auth/callbacks/signin.ts +56 -0
- package/src/auth/events/index.ts +5 -0
- package/src/auth/events/signout.ts +33 -0
- package/src/auth/providers/credentials.ts +256 -0
- package/src/auth/providers/index.ts +6 -0
- package/src/auth/providers/oauth.ts +114 -0
- package/src/auth/route-config.ts +220 -0
- package/src/auth/types/auth-types.ts +555 -0
- package/src/auth/types/index.ts +7 -0
- package/src/auth/unauthenticated-routes.ts +3 -0
- package/src/auth/utils/idp-client.ts +444 -0
- package/src/auth/utils/index.ts +6 -0
- package/src/auth/utils/token-utils.ts +244 -0
- package/src/client/AuthContext.tsx +140 -0
- package/src/client/fetch-with-auth.ts +48 -0
- package/src/client/fetchWithSession.ts +21 -0
- package/src/client/index.ts +13 -0
- package/src/client/useAnonSession.ts +131 -0
- package/src/components/SessionSync.tsx +137 -0
- package/src/components/SignalRHealthCheck.tsx +131 -0
- package/src/components/account/UserAvatarMenu.tsx +217 -0
- package/src/components/account/index.ts +8 -0
- package/src/components/admin/AlertSettingsTab.tsx +728 -0
- package/src/components/admin/AnalyticsTab.tsx +703 -0
- package/src/components/admin/DataBrowserTab.tsx +505 -0
- package/src/components/admin/LoggingSettingsTab.tsx +665 -0
- package/src/components/admin/SessionsTab.tsx +414 -0
- package/src/components/admin/StatsTab.tsx +379 -0
- package/src/components/admin/VibeAdminContext.tsx +87 -0
- package/src/components/admin/VibeAdminLayout.tsx +185 -0
- package/src/components/admin/index.ts +59 -0
- package/src/components/auth/FederatedAuthSection.tsx +95 -0
- package/src/components/auth/ModeAwareLoginPage.tsx +135 -0
- package/src/components/auth/ModeAwareSignupPage.tsx +267 -0
- package/src/components/auth/TraditionalAuthSection.tsx +99 -0
- package/src/components/recovery/CompleteStep.tsx +36 -0
- package/src/components/recovery/InitiateRecoveryStep.tsx +68 -0
- package/src/components/recovery/SelectMethodStep.tsx +73 -0
- package/src/components/recovery/SetPasswordStep.tsx +97 -0
- package/src/components/recovery/VerifyCodeStep.tsx +90 -0
- package/src/components/reserved/ReservedRecoveryWarning.tsx +160 -0
- package/src/components/reserved/ReservedStatusBox.tsx +118 -0
- package/src/components/ui/BetaBadge.tsx +58 -0
- package/src/components/ui/Footer.tsx +93 -0
- package/src/config/env.ts +57 -0
- package/src/config/logger.ts +62 -0
- package/src/config/logging-config.ts +82 -0
- package/src/config/unauthenticated-routes.ts +19 -0
- package/src/config/vibe-log-transport.ts +250 -0
- package/src/edge/internal-api-url.ts +65 -0
- package/src/edge/middleware.ts +42 -0
- package/src/hooks/useAuth.ts +115 -0
- package/src/hooks/useAuthSettings.ts +97 -0
- package/src/hooks/useAvailableProviders.ts +118 -0
- package/src/hooks/usePasswordValidation.ts +127 -0
- package/src/hooks/useProfile.ts +75 -0
- package/src/hooks/usePublicAuthSettings.ts +149 -0
- package/src/hooks/useSessionExpiration.ts +102 -0
- package/src/hooks/useViabilitySession.ts +335 -0
- package/src/index.ts +63 -0
- package/src/lib/anon-session.ts +213 -0
- package/src/lib/api-handler.ts +625 -0
- package/src/lib/app-slug.ts +178 -0
- package/src/lib/demo-mode.ts +13 -0
- package/src/lib/geolocation.ts +265 -0
- package/src/lib/idp-client-config.ts +442 -0
- package/src/lib/idp-fetch.ts +101 -0
- package/src/lib/internal-api.ts +171 -0
- package/src/lib/jwt-decode-client.ts +45 -0
- package/src/lib/jwt-decode.ts +83 -0
- package/src/lib/nextauth-secret.ts +126 -0
- package/src/lib/rate-limit-service.ts +9 -0
- package/src/lib/redis.ts +27 -0
- package/src/lib/refresh-token-validator.ts +64 -0
- package/src/lib/roles.ts +177 -0
- package/src/lib/secret-validation.ts +8 -0
- package/src/lib/session-store.ts +637 -0
- package/src/lib/session.ts +34 -0
- package/src/lib/site-logger.ts +245 -0
- package/src/lib/standardized-client-api.ts +896 -0
- package/src/lib/startup-init.ts +247 -0
- package/src/lib/test-aware-get-token.ts +30 -0
- package/src/lib/token-expiry.ts +40 -0
- package/src/lib/token-lifecycle.ts +477 -0
- package/src/lib/types/api-responses.ts +336 -0
- package/src/lib/user-agent-parser.ts +252 -0
- package/src/logging/api/admin-analytics.ts +51 -0
- package/src/logging/api/audit-log.ts +53 -0
- package/src/logging/components/AdminAnalyticsLayout.tsx +49 -0
- package/src/logging/components/AuditLogViewer.tsx +125 -0
- package/src/logging/components/ErrorMetricsCard.tsx +98 -0
- package/src/logging/components/HealthMetricsCard.tsx +70 -0
- package/src/logging/hooks/useAdminAnalytics.ts +22 -0
- package/src/logging/hooks/useAuditLog.ts +24 -0
- package/src/logging/hooks/useErrorMetrics.ts +40 -0
- package/src/logging/hooks/useHealthMetrics.ts +44 -0
- package/src/logging/index.ts +18 -0
- package/src/logging/types/analytics.ts +81 -0
- package/src/logging/types/audit.ts +31 -0
- package/src/logging/types/index.ts +3 -0
- package/src/middleware/auth-decision.ts +43 -0
- package/src/middleware/create-middleware.ts +626 -0
- package/src/middleware/rbac-check.ts +244 -0
- package/src/middleware/twofa-presets.ts +224 -0
- package/src/models/DecodedAccessToken.ts +17 -0
- package/src/models/SessionModel.ts +258 -0
- package/src/pages/admin-login/page.tsx +229 -0
- package/src/pages/admin-roles/RolesAdminPage.tsx +357 -0
- package/src/pages/admin-roles/index.ts +9 -0
- package/src/pages/admin-roles/modals.tsx +469 -0
- package/src/pages/client-admin/ClientSiteAdminPage.tsx +380 -0
- package/src/pages/client-admin/index.ts +33 -0
- package/src/pages/login/page.tsx +463 -0
- package/src/pages/profile/EnhancedProfilePage.tsx +479 -0
- package/src/pages/profile/index.ts +9 -0
- package/src/pages/profile/page.tsx +166 -0
- package/src/pages/recovery/page.tsx +234 -0
- package/src/pages/roles/MyRolesPage.tsx +211 -0
- package/src/pages/roles/components.tsx +294 -0
- package/src/pages/roles/index.ts +17 -0
- package/src/pages/security/EnhancedSecurityPage.tsx +574 -0
- package/src/pages/security/index.ts +9 -0
- package/src/pages/security/page.tsx +507 -0
- package/src/pages/settings/EnhancedSettingsPage.tsx +642 -0
- package/src/pages/settings/index.ts +9 -0
- package/src/pages/settings/page.tsx +47 -0
- package/src/pages/showcase/ShowcasePage.tsx +530 -0
- package/src/pages/showcase/index.ts +13 -0
- package/src/pages/test-env/EmergencyLogoutPage.tsx +179 -0
- package/src/pages/test-env/JwtInspectPage.tsx +418 -0
- package/src/pages/test-env/RefreshTokenPage.tsx +155 -0
- package/src/pages/test-env/TestEnvPage.tsx +116 -0
- package/src/pages/test-env/index.ts +25 -0
- package/src/pages/verify-code/page.tsx +648 -0
- package/src/routes/account/index.ts +32 -0
- package/src/routes/account/masked-info.ts +37 -0
- package/src/routes/account/send-code.ts +40 -0
- package/src/routes/account/update-phone.ts +13 -0
- package/src/routes/account/verify-email.ts +41 -0
- package/src/routes/account/verify-sms.ts +41 -0
- package/src/routes/auth/index.ts +23 -0
- package/src/routes/auth/logout.ts +127 -0
- package/src/routes/auth/nextauth.ts +71 -0
- package/src/routes/auth/refresh.ts +54 -0
- package/src/routes/auth/session.ts +193 -0
- package/src/routes/auth/settings.ts +75 -0
- package/src/routes/auth/viability.ts +220 -0
- package/src/routes/index.ts +18 -0
- package/src/routes/session/index.ts +7 -0
- package/src/routes/session/refresh-viability.ts +17 -0
- package/src/services/signalrActivityService.ts +258 -0
- package/src/stores/authStore.ts +1904 -0
- package/src/templates/instrumentation.ts +41 -0
- package/src/theme/ThemeProvider.tsx +39 -0
- package/src/theme/default.ts +33 -0
- package/src/theme/index.ts +31 -0
- package/src/theme/types.ts +69 -0
- package/src/theme/useTheme.ts +57 -0
- package/src/theme/utils.ts +40 -0
- package/src/types/api.ts +13 -0
- package/src/types/auth.d.ts +15 -0
- package/src/types/auth.ts +22 -0
- package/src/types/logging.ts +11 -0
- package/src/types/next-auth.d.ts +15 -0
- package/src/types/recovery.ts +54 -0
- package/src/types/security.ts +1 -0
- package/src/utils/api.ts +353 -0
- package/src/utils/circuitBreaker.ts +40 -0
- package/src/utils/error-message.ts +108 -0
- package/src/utils/layout/reservedSpace.ts +124 -0
- package/src/utils/logout.ts +30 -0
- package/src/vibe/client.ts +590 -0
- package/src/vibe/errors.ts +185 -0
- package/src/vibe/generic.ts +429 -0
- package/src/vibe/hooks/index.ts +367 -0
- package/src/vibe/index.ts +121 -0
- package/src/vibe/sessions.ts +551 -0
- package/src/vibe/types.ts +577 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ready-to-Use Session Viability Route
|
|
4
|
+
*
|
|
5
|
+
* Checks if the current session is viable (valid and not expired).
|
|
6
|
+
* Used by client-side code to determine if a refresh is needed.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // app/api/session/viability/route.ts
|
|
11
|
+
* export { GET } from '@payez/next-mvp/routes/auth/viability';
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @version 2.0.0
|
|
15
|
+
* @since auth-ready-v2
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.GET = GET;
|
|
19
|
+
const server_1 = require("next/server");
|
|
20
|
+
const jwt_1 = require("next-auth/jwt");
|
|
21
|
+
const session_store_1 = require("../../lib/session-store");
|
|
22
|
+
const app_slug_1 = require("../../lib/app-slug");
|
|
23
|
+
const idp_client_config_1 = require("../../lib/idp-client-config");
|
|
24
|
+
/**
|
|
25
|
+
* Get NextAuth secret from IDP config (cached).
|
|
26
|
+
* NEVER use process.env.NEXTAUTH_SECRET at module level - it may not be set yet.
|
|
27
|
+
*/
|
|
28
|
+
async function getNextAuthSecret() {
|
|
29
|
+
const config = await (0, idp_client_config_1.getIDPClientConfig)();
|
|
30
|
+
return config.nextAuthSecret || '';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get tenant-wide 2FA requirement from cached client config (from broker handshake)
|
|
34
|
+
*/
|
|
35
|
+
async function getTenantRequiresTwoFactor() {
|
|
36
|
+
try {
|
|
37
|
+
const config = await (0, idp_client_config_1.getIDPClientConfig)();
|
|
38
|
+
return config.authSettings?.require2FA ?? true; // Default to true for security
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
console.warn('[VIABILITY] Could not get client config, defaulting tenantRequiresTwoFactor to true');
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* GET /api/session/viability - Check if session is viable
|
|
47
|
+
*
|
|
48
|
+
* Returns:
|
|
49
|
+
* - viable: boolean - Whether the session can be used
|
|
50
|
+
* - needsRefresh: boolean - Whether a refresh is recommended
|
|
51
|
+
* - expiresIn: number - Seconds until token expires
|
|
52
|
+
*/
|
|
53
|
+
async function GET(req) {
|
|
54
|
+
try {
|
|
55
|
+
const cookieName = (0, app_slug_1.getJwtCookieName)();
|
|
56
|
+
const secret = await getNextAuthSecret();
|
|
57
|
+
const token = await (0, jwt_1.getToken)({ req, secret, cookieName });
|
|
58
|
+
if (!token) {
|
|
59
|
+
return server_1.NextResponse.json({
|
|
60
|
+
viable: false,
|
|
61
|
+
needsRefresh: false,
|
|
62
|
+
authenticated: false,
|
|
63
|
+
reason: 'No session found'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Support both field names: sessionToken (auth.ts JWT) and redisSessionId (legacy)
|
|
67
|
+
const sessionToken = token.sessionToken || token.redisSessionId;
|
|
68
|
+
const session = sessionToken ? await (0, session_store_1.getSession)(sessionToken) : null;
|
|
69
|
+
// CRITICAL: Detect stale cookie state (JWT exists but Redis session missing)
|
|
70
|
+
if (sessionToken && !session) {
|
|
71
|
+
console.warn('[VIABILITY] Stale cookie detected - session not in Redis');
|
|
72
|
+
return server_1.NextResponse.json({
|
|
73
|
+
viable: false,
|
|
74
|
+
needsRefresh: false,
|
|
75
|
+
authenticated: false,
|
|
76
|
+
sessionToken, // Return sessionToken so middleware can detect and clear stale cookie
|
|
77
|
+
reason: 'Stale session - cookie exists but session not found in Redis'
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Check access token expiry
|
|
81
|
+
const now = Math.floor(Date.now() / 1000);
|
|
82
|
+
const accessTokenExpires = token.accessTokenExpires || token.exp;
|
|
83
|
+
if (!accessTokenExpires) {
|
|
84
|
+
// No expiry info, assume viable but recommend refresh
|
|
85
|
+
const tenantRequiresTwoFactor = await getTenantRequiresTwoFactor();
|
|
86
|
+
// CRITICAL: Check if MFA has expired (2FA TTL enforcement)
|
|
87
|
+
const mfaExpiresAt = session?.mfaExpiresAt || 0;
|
|
88
|
+
const mfaExpired = mfaExpiresAt > 0 && mfaExpiresAt < Date.now();
|
|
89
|
+
// Check mfaVerified (normalized name) with fallback to twoFactorComplete for compatibility
|
|
90
|
+
const mfaVerifiedInSession = session?.mfaVerified ?? session?.twoFactorComplete ?? false;
|
|
91
|
+
// User has completed 2FA requirements if: they verified AND it hasn't expired
|
|
92
|
+
const userHasCompletedTenantTwoFactorRequirements = mfaVerifiedInSession && !mfaExpired;
|
|
93
|
+
// userStillNeedsTwoFactor = inverse of completed (matches session callback logic)
|
|
94
|
+
const userStillNeedsTwoFactor = !userHasCompletedTenantTwoFactorRequirements;
|
|
95
|
+
return server_1.NextResponse.json({
|
|
96
|
+
viable: true,
|
|
97
|
+
needsRefresh: true,
|
|
98
|
+
authenticated: true,
|
|
99
|
+
sessionToken,
|
|
100
|
+
// Clear names for middleware decision-making
|
|
101
|
+
tenantRequiresTwoFactor,
|
|
102
|
+
userHasCompletedTenantTwoFactorRequirements,
|
|
103
|
+
userStillNeedsTwoFactor,
|
|
104
|
+
// Legacy field names for backwards compatibility
|
|
105
|
+
requires2FA: tenantRequiresTwoFactor,
|
|
106
|
+
twoFactorComplete: userHasCompletedTenantTwoFactorRequirements,
|
|
107
|
+
accessTokenExpired: false,
|
|
108
|
+
reason: 'No expiry information'
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Convert to seconds if needed
|
|
112
|
+
const expiryTime = accessTokenExpires > 1000000000000
|
|
113
|
+
? Math.floor(accessTokenExpires / 1000)
|
|
114
|
+
: accessTokenExpires;
|
|
115
|
+
const expiresIn = expiryTime - now;
|
|
116
|
+
const isExpired = expiresIn <= 0;
|
|
117
|
+
const needsRefresh = expiresIn <= 300; // 5 minutes buffer
|
|
118
|
+
// Check if we have refresh capability (check normalized field name first)
|
|
119
|
+
const hasRefreshToken = !!(session?.idpRefreshToken || session?.refreshToken || token.refreshToken);
|
|
120
|
+
// CLEAR NAMING: Tenant-wide 2FA requirement from client config
|
|
121
|
+
const tenantRequiresTwoFactor = await getTenantRequiresTwoFactor();
|
|
122
|
+
// CRITICAL: Check if MFA has expired (2FA TTL enforcement)
|
|
123
|
+
// The session may have mfaVerified=true from days ago, but if mfaExpiresAt
|
|
124
|
+
// has passed, we must treat 2FA as incomplete to force re-verification.
|
|
125
|
+
const mfaExpiresAt = session?.mfaExpiresAt || 0;
|
|
126
|
+
const mfaExpired = mfaExpiresAt > 0 && mfaExpiresAt < Date.now();
|
|
127
|
+
// Check mfaVerified (normalized name) with fallback to twoFactorComplete for compatibility
|
|
128
|
+
const mfaVerifiedInSession = session?.mfaVerified ?? session?.twoFactorComplete ?? false;
|
|
129
|
+
// DEBUG: Log what we're reading from the session
|
|
130
|
+
console.log('[VIABILITY] Session 2FA state:', {
|
|
131
|
+
sessionToken: sessionToken?.substring(0, 8) + '...',
|
|
132
|
+
'session.mfaVerified': session?.mfaVerified,
|
|
133
|
+
'session.twoFactorComplete': session?.twoFactorComplete,
|
|
134
|
+
mfaVerifiedInSession,
|
|
135
|
+
mfaExpiresAt,
|
|
136
|
+
mfaExpired,
|
|
137
|
+
hasRefreshToken,
|
|
138
|
+
'session.idpRefreshToken': !!session?.idpRefreshToken,
|
|
139
|
+
'session.refreshToken': !!session?.refreshToken,
|
|
140
|
+
});
|
|
141
|
+
// CLEAR NAMING: User has completed 2FA requirements if: they verified AND it hasn't expired
|
|
142
|
+
const userHasCompletedTenantTwoFactorRequirements = mfaVerifiedInSession && !mfaExpired;
|
|
143
|
+
// userStillNeedsTwoFactor = inverse of completed (matches session callback logic)
|
|
144
|
+
const userStillNeedsTwoFactor = !userHasCompletedTenantTwoFactorRequirements;
|
|
145
|
+
if (mfaExpired && mfaVerifiedInSession) {
|
|
146
|
+
console.warn('[VIABILITY] MFA expired - forcing 2FA re-verification');
|
|
147
|
+
}
|
|
148
|
+
if (isExpired) {
|
|
149
|
+
return server_1.NextResponse.json({
|
|
150
|
+
viable: false,
|
|
151
|
+
needsRefresh: hasRefreshToken,
|
|
152
|
+
expiresIn: 0,
|
|
153
|
+
hasRefreshToken,
|
|
154
|
+
authenticated: true,
|
|
155
|
+
sessionToken,
|
|
156
|
+
// Clear names
|
|
157
|
+
tenantRequiresTwoFactor,
|
|
158
|
+
userHasCompletedTenantTwoFactorRequirements,
|
|
159
|
+
userStillNeedsTwoFactor,
|
|
160
|
+
// Legacy names for backwards compatibility
|
|
161
|
+
requires2FA: tenantRequiresTwoFactor,
|
|
162
|
+
twoFactorComplete: userHasCompletedTenantTwoFactorRequirements,
|
|
163
|
+
accessTokenExpired: true,
|
|
164
|
+
reason: 'Token expired',
|
|
165
|
+
// RBAC fields
|
|
166
|
+
roles: session?.roles || [],
|
|
167
|
+
clientId: session?.idpClientId || process.env.IDP_CLIENT_ID || '',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return server_1.NextResponse.json({
|
|
171
|
+
viable: true,
|
|
172
|
+
needsRefresh,
|
|
173
|
+
expiresIn,
|
|
174
|
+
hasRefreshToken,
|
|
175
|
+
authenticated: true,
|
|
176
|
+
sessionToken,
|
|
177
|
+
// Clear names
|
|
178
|
+
tenantRequiresTwoFactor,
|
|
179
|
+
userHasCompletedTenantTwoFactorRequirements,
|
|
180
|
+
userStillNeedsTwoFactor,
|
|
181
|
+
// Legacy names for backwards compatibility
|
|
182
|
+
requires2FA: tenantRequiresTwoFactor,
|
|
183
|
+
twoFactorComplete: userHasCompletedTenantTwoFactorRequirements,
|
|
184
|
+
accessTokenExpired: false,
|
|
185
|
+
expiresAt: new Date(expiryTime * 1000).toISOString(),
|
|
186
|
+
// RBAC fields
|
|
187
|
+
roles: session?.roles || [],
|
|
188
|
+
clientId: session?.idpClientId || process.env.IDP_CLIENT_ID || '',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.error('[VIABILITY_ROUTE] Error checking session viability:', error);
|
|
193
|
+
return server_1.NextResponse.json({
|
|
194
|
+
viable: false,
|
|
195
|
+
needsRefresh: false,
|
|
196
|
+
authenticated: false,
|
|
197
|
+
error: 'Failed to check session',
|
|
198
|
+
details: error instanceof Error ? error.message : 'Unknown error'
|
|
199
|
+
}, { status: 500 });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @payez/next-mvp Route Module Exports
|
|
3
|
+
*
|
|
4
|
+
* Ready-to-use route handlers for quick integration
|
|
5
|
+
*
|
|
6
|
+
* @version 2.3.0
|
|
7
|
+
* @since auth-ready-v2
|
|
8
|
+
*/
|
|
9
|
+
export * from './auth';
|
|
10
|
+
export * from './account';
|
|
11
|
+
export * as auth from './auth';
|
|
12
|
+
export * as account from './account';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @payez/next-mvp Route Module Exports
|
|
4
|
+
*
|
|
5
|
+
* Ready-to-use route handlers for quick integration
|
|
6
|
+
*
|
|
7
|
+
* @version 2.3.0
|
|
8
|
+
* @since auth-ready-v2
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
27
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
28
|
+
};
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.account = exports.auth = void 0;
|
|
48
|
+
// Export auth routes
|
|
49
|
+
__exportStar(require("./auth"), exports);
|
|
50
|
+
// Export account/2FA routes
|
|
51
|
+
__exportStar(require("./account"), exports);
|
|
52
|
+
// Namespace exports for cleaner imports
|
|
53
|
+
exports.auth = __importStar(require("./auth"));
|
|
54
|
+
exports.account = __importStar(require("./account"));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Session Routes Index
|
|
4
|
+
*
|
|
5
|
+
* Re-exports all session-related route handlers for easy importing.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.refreshViabilityGET = void 0;
|
|
9
|
+
var refresh_viability_1 = require("./refresh-viability");
|
|
10
|
+
Object.defineProperty(exports, "refreshViabilityGET", { enumerable: true, get: function () { return refresh_viability_1.GET; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ready-to-Use Refresh Viability Route
|
|
3
|
+
*
|
|
4
|
+
* Checks if a session has a valid refresh token for automatic refresh.
|
|
5
|
+
* Used by middleware to decide whether to attempt refresh or redirect to login.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // app/api/session/refresh-viability/route.ts
|
|
10
|
+
* export { GET } from '@payez/next-mvp/routes/session/refresh-viability';
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @version 2.0.0
|
|
14
|
+
* @since auth-ready-v2
|
|
15
|
+
*/
|
|
16
|
+
export { GET } from '../../api-handlers/session/refresh-viability';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ready-to-Use Refresh Viability Route
|
|
4
|
+
*
|
|
5
|
+
* Checks if a session has a valid refresh token for automatic refresh.
|
|
6
|
+
* Used by middleware to decide whether to attempt refresh or redirect to login.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // app/api/session/refresh-viability/route.ts
|
|
11
|
+
* export { GET } from '@payez/next-mvp/routes/session/refresh-viability';
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @version 2.0.0
|
|
15
|
+
* @since auth-ready-v2
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.GET = void 0;
|
|
19
|
+
var refresh_viability_1 = require("../../api-handlers/session/refresh-viability");
|
|
20
|
+
Object.defineProperty(exports, "GET", { enumerable: true, get: function () { return refresh_viability_1.GET; } });
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface HealthStatus {
|
|
2
|
+
isHealthy: boolean;
|
|
3
|
+
message: string;
|
|
4
|
+
lastHeartbeat: Date | null;
|
|
5
|
+
connectionId: string | null | undefined;
|
|
6
|
+
responseTime?: string;
|
|
7
|
+
}
|
|
8
|
+
export type HealthStatusCallback = (status: HealthStatus) => void;
|
|
9
|
+
/**
|
|
10
|
+
* SignalR-based health service following Occam's Razor principle:
|
|
11
|
+
* - If SignalR connection is alive = Service is working
|
|
12
|
+
* - If SignalR connection is dead = Service is not working
|
|
13
|
+
* - No complex orchestration, just connection state monitoring
|
|
14
|
+
*/
|
|
15
|
+
declare class SignalRActivityService {
|
|
16
|
+
private connection;
|
|
17
|
+
private subscribers;
|
|
18
|
+
private currentStatus;
|
|
19
|
+
private heartbeatTimeout;
|
|
20
|
+
private readonly heartbeatTimeoutMs;
|
|
21
|
+
/**
|
|
22
|
+
* Start the health monitoring connection
|
|
23
|
+
* @param idpBaseUrl - The base URL of the IDP server (e.g., 'http://localhost:32785')
|
|
24
|
+
*/
|
|
25
|
+
start(idpBaseUrl: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Stop the health monitoring connection
|
|
28
|
+
*/
|
|
29
|
+
stop(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Subscribe to health status changes
|
|
32
|
+
*/
|
|
33
|
+
subscribe(callback: HealthStatusCallback): () => void;
|
|
34
|
+
/**
|
|
35
|
+
* Get current health status
|
|
36
|
+
*/
|
|
37
|
+
getCurrentStatus(): HealthStatus;
|
|
38
|
+
private updateStatus;
|
|
39
|
+
private notifySubscribers;
|
|
40
|
+
private resetHeartbeatTimeout;
|
|
41
|
+
private clearHeartbeatTimeout;
|
|
42
|
+
}
|
|
43
|
+
export declare const signalRActivityService: SignalRActivityService;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.signalRActivityService = void 0;
|
|
37
|
+
const signalR = __importStar(require("@microsoft/signalr"));
|
|
38
|
+
/**
|
|
39
|
+
* SignalR-based health service following Occam's Razor principle:
|
|
40
|
+
* - If SignalR connection is alive = Service is working
|
|
41
|
+
* - If SignalR connection is dead = Service is not working
|
|
42
|
+
* - No complex orchestration, just connection state monitoring
|
|
43
|
+
*/
|
|
44
|
+
class SignalRActivityService {
|
|
45
|
+
connection = null;
|
|
46
|
+
subscribers = new Set();
|
|
47
|
+
currentStatus = {
|
|
48
|
+
isHealthy: false,
|
|
49
|
+
message: 'Disconnected',
|
|
50
|
+
lastHeartbeat: null,
|
|
51
|
+
connectionId: null
|
|
52
|
+
};
|
|
53
|
+
heartbeatTimeout = null;
|
|
54
|
+
heartbeatTimeoutMs = 45000; // 45 seconds (server sends every 30s)
|
|
55
|
+
/**
|
|
56
|
+
* Start the health monitoring connection
|
|
57
|
+
* @param idpBaseUrl - The base URL of the IDP server (e.g., 'http://localhost:32785')
|
|
58
|
+
*/
|
|
59
|
+
async start(idpBaseUrl) {
|
|
60
|
+
// If we already have a connected or connecting connection, don't start again
|
|
61
|
+
if (this.connection &&
|
|
62
|
+
(this.connection.state === signalR.HubConnectionState.Connected ||
|
|
63
|
+
this.connection.state === signalR.HubConnectionState.Connecting)) {
|
|
64
|
+
console.info('[SignalRHealth] Connection already active, skipping start');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Stop existing connection if it exists
|
|
68
|
+
if (this.connection) {
|
|
69
|
+
await this.stop();
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
if (!idpBaseUrl) {
|
|
73
|
+
throw new Error('IDP base URL is required for health monitoring');
|
|
74
|
+
}
|
|
75
|
+
// Construct absolute hub URL safely
|
|
76
|
+
const activityHubUrl = new URL('/healthHub', idpBaseUrl).toString();
|
|
77
|
+
console.info('[SignalRHealth] Using hub URL:', activityHubUrl);
|
|
78
|
+
this.connection = new signalR.HubConnectionBuilder()
|
|
79
|
+
.withUrl(activityHubUrl, {
|
|
80
|
+
withCredentials: false,
|
|
81
|
+
transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.ServerSentEvents | signalR.HttpTransportType.LongPolling,
|
|
82
|
+
})
|
|
83
|
+
.withAutomaticReconnect({
|
|
84
|
+
nextRetryDelayInMilliseconds: (retryContext) => {
|
|
85
|
+
// More conservative backoff: 5s, 15s, 45s, then stop trying
|
|
86
|
+
const delays = [5000, 15000, 45000];
|
|
87
|
+
if (retryContext.previousRetryCount >= delays.length) {
|
|
88
|
+
return null; // Stop automatic reconnection
|
|
89
|
+
}
|
|
90
|
+
return delays[retryContext.previousRetryCount];
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
.configureLogging(signalR.LogLevel.Critical) // Only critical errors, hide connection noise
|
|
94
|
+
.build();
|
|
95
|
+
// Handle connection events
|
|
96
|
+
this.connection.onclose(() => {
|
|
97
|
+
this.updateStatus({
|
|
98
|
+
isHealthy: false,
|
|
99
|
+
message: 'Service unavailable',
|
|
100
|
+
lastHeartbeat: null,
|
|
101
|
+
connectionId: null
|
|
102
|
+
});
|
|
103
|
+
this.clearHeartbeatTimeout();
|
|
104
|
+
});
|
|
105
|
+
this.connection.onreconnecting(() => {
|
|
106
|
+
this.updateStatus({
|
|
107
|
+
isHealthy: false,
|
|
108
|
+
message: 'Service unavailable',
|
|
109
|
+
lastHeartbeat: this.currentStatus.lastHeartbeat,
|
|
110
|
+
connectionId: null
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
this.connection.onreconnected((connectionId) => {
|
|
114
|
+
this.updateStatus({
|
|
115
|
+
isHealthy: true,
|
|
116
|
+
message: 'Service operational',
|
|
117
|
+
lastHeartbeat: new Date(),
|
|
118
|
+
connectionId
|
|
119
|
+
});
|
|
120
|
+
this.resetHeartbeatTimeout();
|
|
121
|
+
});
|
|
122
|
+
// Handle heartbeat messages - this is the core health indicator
|
|
123
|
+
this.connection.on('Heartbeat', (data) => {
|
|
124
|
+
this.updateStatus({
|
|
125
|
+
isHealthy: true,
|
|
126
|
+
message: 'Service operational',
|
|
127
|
+
lastHeartbeat: new Date(),
|
|
128
|
+
connectionId: this.connection?.connectionId || null
|
|
129
|
+
});
|
|
130
|
+
this.resetHeartbeatTimeout();
|
|
131
|
+
});
|
|
132
|
+
// Handle initial health status
|
|
133
|
+
this.connection.on('HealthStatus', (data) => {
|
|
134
|
+
this.updateStatus({
|
|
135
|
+
isHealthy: data.status === 'healthy',
|
|
136
|
+
message: data.message || 'Service connected',
|
|
137
|
+
lastHeartbeat: new Date(),
|
|
138
|
+
connectionId: this.connection?.connectionId || null
|
|
139
|
+
});
|
|
140
|
+
this.resetHeartbeatTimeout();
|
|
141
|
+
});
|
|
142
|
+
// Start the connection
|
|
143
|
+
await this.connection.start();
|
|
144
|
+
console.info('[SignalRHealth] Connection started, connectionId:', this.connection.connectionId);
|
|
145
|
+
this.updateStatus({
|
|
146
|
+
isHealthy: true,
|
|
147
|
+
message: 'Service connected',
|
|
148
|
+
lastHeartbeat: new Date(),
|
|
149
|
+
connectionId: this.connection.connectionId
|
|
150
|
+
});
|
|
151
|
+
this.resetHeartbeatTimeout();
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// Reduce console noise for expected connection failures
|
|
155
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
156
|
+
console.warn('[SignalRHealth] Connection start failed:', errorMessage);
|
|
157
|
+
const isConnectionRefused = errorMessage.includes('ERR_CONNECTION_REFUSED') ||
|
|
158
|
+
errorMessage.includes('Failed to fetch') ||
|
|
159
|
+
errorMessage.includes('Failed to complete negotiation');
|
|
160
|
+
if (isConnectionRefused) {
|
|
161
|
+
// Service is down - this is expected, log at info level
|
|
162
|
+
console.info('SignalR Health Service: Backend service unavailable');
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Unexpected error - log as error
|
|
166
|
+
console.error('SignalR Health Service failed to start:', error);
|
|
167
|
+
}
|
|
168
|
+
this.updateStatus({
|
|
169
|
+
isHealthy: false,
|
|
170
|
+
message: 'Service unavailable',
|
|
171
|
+
lastHeartbeat: null,
|
|
172
|
+
connectionId: null
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Stop the health monitoring connection
|
|
178
|
+
*/
|
|
179
|
+
async stop() {
|
|
180
|
+
this.clearHeartbeatTimeout();
|
|
181
|
+
if (this.connection) {
|
|
182
|
+
try {
|
|
183
|
+
// Check if connection is in a state that can be stopped
|
|
184
|
+
if (this.connection.state !== signalR.HubConnectionState.Disconnected) {
|
|
185
|
+
await this.connection.stop();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
// Ignore "connection was stopped before the hub handshake could complete" errors
|
|
190
|
+
// as these are expected during rapid start/stop cycles
|
|
191
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
192
|
+
if (!errorMessage.includes('stopped before the hub handshake could complete')) {
|
|
193
|
+
console.error('Error stopping SignalR health connection:', error);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
this.connection = null;
|
|
197
|
+
}
|
|
198
|
+
this.updateStatus({
|
|
199
|
+
isHealthy: false,
|
|
200
|
+
message: 'Disconnected',
|
|
201
|
+
lastHeartbeat: null,
|
|
202
|
+
connectionId: null
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Subscribe to health status changes
|
|
207
|
+
*/
|
|
208
|
+
subscribe(callback) {
|
|
209
|
+
this.subscribers.add(callback);
|
|
210
|
+
// Immediately notify with current status
|
|
211
|
+
callback(this.currentStatus);
|
|
212
|
+
// Return unsubscribe function
|
|
213
|
+
return () => {
|
|
214
|
+
this.subscribers.delete(callback);
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get current health status
|
|
219
|
+
*/
|
|
220
|
+
getCurrentStatus() {
|
|
221
|
+
return { ...this.currentStatus };
|
|
222
|
+
}
|
|
223
|
+
updateStatus(newStatus) {
|
|
224
|
+
this.currentStatus = newStatus;
|
|
225
|
+
this.notifySubscribers();
|
|
226
|
+
}
|
|
227
|
+
notifySubscribers() {
|
|
228
|
+
this.subscribers.forEach(callback => {
|
|
229
|
+
try {
|
|
230
|
+
callback(this.currentStatus);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error('Error in health status subscriber:', error);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
resetHeartbeatTimeout() {
|
|
238
|
+
this.clearHeartbeatTimeout();
|
|
239
|
+
// If we don't receive a heartbeat within the timeout period, consider service unhealthy
|
|
240
|
+
this.heartbeatTimeout = setTimeout(() => {
|
|
241
|
+
this.updateStatus({
|
|
242
|
+
isHealthy: false,
|
|
243
|
+
message: 'Service unavailable',
|
|
244
|
+
lastHeartbeat: this.currentStatus.lastHeartbeat,
|
|
245
|
+
connectionId: this.currentStatus.connectionId
|
|
246
|
+
});
|
|
247
|
+
}, this.heartbeatTimeoutMs);
|
|
248
|
+
}
|
|
249
|
+
clearHeartbeatTimeout() {
|
|
250
|
+
if (this.heartbeatTimeout) {
|
|
251
|
+
clearTimeout(this.heartbeatTimeout);
|
|
252
|
+
this.heartbeatTimeout = null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Export singleton instance
|
|
257
|
+
exports.signalRActivityService = new SignalRActivityService();
|