@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,551 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* =============================================================================
|
|
3
|
+
* VIBE LOGIN SESSIONS
|
|
4
|
+
* =============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Server-side utilities for managing login sessions in Vibe.
|
|
7
|
+
* Tracks user logins with location, device info, and allows session control.
|
|
8
|
+
*
|
|
9
|
+
* This module uses the MVP's vibe client with proper auth token handling
|
|
10
|
+
* for member-to-vibe calls.
|
|
11
|
+
*
|
|
12
|
+
* USAGE:
|
|
13
|
+
* ------
|
|
14
|
+
* import { createLoginSession, getUserSessions, revokeSession } from '@payez/next-mvp/vibe/sessions';
|
|
15
|
+
*
|
|
16
|
+
* // On login (requires user's access token):
|
|
17
|
+
* await createLoginSession({
|
|
18
|
+
* idpUserId: 22,
|
|
19
|
+
* email: 'user@example.com',
|
|
20
|
+
* ipAddress: '1.2.3.4',
|
|
21
|
+
* userAgent: '...',
|
|
22
|
+
* location: { city: 'NYC', ... },
|
|
23
|
+
* accessToken: userAccessToken, // Required for member-to-vibe
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Admin: revoke a session
|
|
27
|
+
* await revokeSession(sessionId, 'admin@example.com', accessToken, 'Suspicious activity');
|
|
28
|
+
*
|
|
29
|
+
* =============================================================================
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import crypto from 'crypto';
|
|
33
|
+
import type { IVibeLoginSession, SessionStatus } from './types';
|
|
34
|
+
import type { LocationInfo } from '../lib/geolocation';
|
|
35
|
+
import type { DeviceInfo } from '../lib/user-agent-parser';
|
|
36
|
+
|
|
37
|
+
// -----------------------------------------------------------------------------
|
|
38
|
+
// CONFIGURATION
|
|
39
|
+
// -----------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
// Sessions expire after 30 days
|
|
42
|
+
const SESSION_EXPIRY_DAYS = 30;
|
|
43
|
+
|
|
44
|
+
// Table name in vibe_app collection
|
|
45
|
+
const TABLE = 'login_sessions';
|
|
46
|
+
const COLLECTION = 'vibe_app';
|
|
47
|
+
|
|
48
|
+
// Environment variables
|
|
49
|
+
const getEnv = (key: string): string => {
|
|
50
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
51
|
+
return process.env[key] || '';
|
|
52
|
+
}
|
|
53
|
+
return '';
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generate HMAC-SHA256 signature for proxy authentication
|
|
58
|
+
*/
|
|
59
|
+
function generateHmacSignature(
|
|
60
|
+
signingKey: string,
|
|
61
|
+
timestamp: number,
|
|
62
|
+
method: string,
|
|
63
|
+
endpoint: string
|
|
64
|
+
): string {
|
|
65
|
+
const stringToSign = `${timestamp}|${method}|${endpoint}`;
|
|
66
|
+
return crypto
|
|
67
|
+
.createHmac('sha256', Buffer.from(signingKey, 'base64'))
|
|
68
|
+
.update(stringToSign)
|
|
69
|
+
.digest('base64');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Make a request through the IDP Vibe proxy
|
|
74
|
+
*/
|
|
75
|
+
async function vibeProxyRequest<T>(
|
|
76
|
+
endpoint: string,
|
|
77
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
|
78
|
+
accessToken: string,
|
|
79
|
+
body?: unknown
|
|
80
|
+
): Promise<T | null> {
|
|
81
|
+
const idpUrl = getEnv('IDP_URL');
|
|
82
|
+
const clientId = getEnv('VIBE_CLIENT_ID');
|
|
83
|
+
const signingKey = getEnv('VIBE_HMAC_KEY');
|
|
84
|
+
|
|
85
|
+
if (!idpUrl || !clientId || !signingKey) {
|
|
86
|
+
console.error('[vibe-sessions] Missing env vars: IDP_URL, VIBE_CLIENT_ID, or VIBE_HMAC_KEY');
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const proxyUrl = `${idpUrl}/api/vibe/proxy`;
|
|
91
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
92
|
+
const signature = generateHmacSignature(signingKey, timestamp, method, endpoint);
|
|
93
|
+
|
|
94
|
+
const headers: Record<string, string> = {
|
|
95
|
+
'Content-Type': 'application/json',
|
|
96
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
97
|
+
'X-Vibe-Client-Id': clientId,
|
|
98
|
+
'X-Vibe-Timestamp': String(timestamp),
|
|
99
|
+
'X-Vibe-Signature': signature,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const response = await fetch(proxyUrl, {
|
|
104
|
+
method: 'POST',
|
|
105
|
+
headers,
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
endpoint,
|
|
108
|
+
method,
|
|
109
|
+
data: body ?? null,
|
|
110
|
+
}),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (response.status === 204) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
const errorText = await response.text();
|
|
119
|
+
console.error(`[vibe-sessions] Proxy error ${response.status}:`, errorText);
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const data = await response.json();
|
|
124
|
+
// Unwrap IDP envelope if present
|
|
125
|
+
return (data?.data ?? data) as T;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error('[vibe-sessions] Proxy request failed:', error);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// -----------------------------------------------------------------------------
|
|
133
|
+
// TYPES
|
|
134
|
+
// -----------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
export interface CreateSessionInput {
|
|
137
|
+
/** IDP user ID */
|
|
138
|
+
idpUserId: number;
|
|
139
|
+
/** User email */
|
|
140
|
+
email: string;
|
|
141
|
+
/** User's display name */
|
|
142
|
+
name?: string;
|
|
143
|
+
/** Client IP address */
|
|
144
|
+
ipAddress: string;
|
|
145
|
+
/** User agent string */
|
|
146
|
+
userAgent: string;
|
|
147
|
+
/** Location info from geolocation lookup */
|
|
148
|
+
location?: LocationInfo | null;
|
|
149
|
+
/** Parsed device info */
|
|
150
|
+
device?: DeviceInfo;
|
|
151
|
+
/** OAuth provider used for login */
|
|
152
|
+
oauthProvider?: string;
|
|
153
|
+
/** Hashed session token for lookup */
|
|
154
|
+
sessionTokenHash?: string;
|
|
155
|
+
/**
|
|
156
|
+
* User's access token - REQUIRED for member-to-vibe calls.
|
|
157
|
+
* Without this, the request will fail with 401.
|
|
158
|
+
*/
|
|
159
|
+
accessToken: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface SessionQueryOptions {
|
|
163
|
+
status?: SessionStatus;
|
|
164
|
+
page?: number;
|
|
165
|
+
pageSize?: number;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// -----------------------------------------------------------------------------
|
|
169
|
+
// CREATE SESSION
|
|
170
|
+
// -----------------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Create a new login session record.
|
|
174
|
+
* Called when a user successfully logs in.
|
|
175
|
+
*
|
|
176
|
+
* @param input - Session creation parameters including accessToken
|
|
177
|
+
* @returns The created session, or null on failure
|
|
178
|
+
*/
|
|
179
|
+
export async function createLoginSession(
|
|
180
|
+
input: CreateSessionInput
|
|
181
|
+
): Promise<IVibeLoginSession | null> {
|
|
182
|
+
if (!input.accessToken) {
|
|
183
|
+
console.error('[vibe-sessions] accessToken is required for createLoginSession');
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const now = new Date();
|
|
188
|
+
const expiresAt = new Date(now.getTime() + SESSION_EXPIRY_DAYS * 24 * 60 * 60 * 1000);
|
|
189
|
+
|
|
190
|
+
const sessionData = {
|
|
191
|
+
idp_user_id: input.idpUserId,
|
|
192
|
+
email: input.email,
|
|
193
|
+
name: input.name || null,
|
|
194
|
+
|
|
195
|
+
// Location
|
|
196
|
+
ip_address: input.ipAddress,
|
|
197
|
+
city: input.location?.city || null,
|
|
198
|
+
region: input.location?.region || null,
|
|
199
|
+
country: input.location?.country || null,
|
|
200
|
+
country_code: input.location?.countryCode || null,
|
|
201
|
+
latitude: input.location?.latitude || null,
|
|
202
|
+
longitude: input.location?.longitude || null,
|
|
203
|
+
timezone: input.location?.timezone || null,
|
|
204
|
+
|
|
205
|
+
// Device
|
|
206
|
+
user_agent: input.userAgent,
|
|
207
|
+
device_type: input.device?.deviceType || 'unknown',
|
|
208
|
+
browser: input.device?.browser || 'Unknown',
|
|
209
|
+
browser_version: input.device?.browserVersion || null,
|
|
210
|
+
os: input.device?.os || 'Unknown',
|
|
211
|
+
os_version: input.device?.osVersion || null,
|
|
212
|
+
|
|
213
|
+
// Auth
|
|
214
|
+
oauth_provider: input.oauthProvider || null,
|
|
215
|
+
session_token_hash: input.sessionTokenHash || null,
|
|
216
|
+
|
|
217
|
+
// Status
|
|
218
|
+
status: 'active' as SessionStatus,
|
|
219
|
+
revoked_by: null,
|
|
220
|
+
revoked_at: null,
|
|
221
|
+
revoke_reason: null,
|
|
222
|
+
|
|
223
|
+
// Timestamps
|
|
224
|
+
last_activity: now.toISOString(),
|
|
225
|
+
expires_at: expiresAt.toISOString(),
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}`;
|
|
229
|
+
const session = await vibeProxyRequest<IVibeLoginSession>(
|
|
230
|
+
endpoint,
|
|
231
|
+
'POST',
|
|
232
|
+
input.accessToken,
|
|
233
|
+
sessionData
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
if (session) {
|
|
237
|
+
console.log(`[vibe-sessions] Created session for ${input.email} from ${input.ipAddress}`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return session;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// -----------------------------------------------------------------------------
|
|
244
|
+
// GET SESSIONS
|
|
245
|
+
// -----------------------------------------------------------------------------
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Get all sessions for a specific user.
|
|
249
|
+
*
|
|
250
|
+
* @param idpUserId - The user's IDP ID
|
|
251
|
+
* @param accessToken - User's access token for auth
|
|
252
|
+
* @returns Array of sessions
|
|
253
|
+
*/
|
|
254
|
+
export async function getUserSessions(
|
|
255
|
+
idpUserId: number,
|
|
256
|
+
accessToken: string
|
|
257
|
+
): Promise<IVibeLoginSession[]> {
|
|
258
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}/query`;
|
|
259
|
+
const result = await vibeProxyRequest<{ data?: IVibeLoginSession[]; items?: IVibeLoginSession[] }>(
|
|
260
|
+
endpoint,
|
|
261
|
+
'POST',
|
|
262
|
+
accessToken,
|
|
263
|
+
{
|
|
264
|
+
filter: [{ field: 'idp_user_id', operator: 'eq', value: idpUserId }],
|
|
265
|
+
pageSize: 100,
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
return result?.data || result?.items || [];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Get all sessions (admin only).
|
|
274
|
+
* Returns sessions from all users, sorted by most recent first.
|
|
275
|
+
*
|
|
276
|
+
* @param options - Query options
|
|
277
|
+
* @param accessToken - Admin's access token
|
|
278
|
+
* @returns Array of sessions with total count
|
|
279
|
+
*/
|
|
280
|
+
export async function getAllSessions(
|
|
281
|
+
options: SessionQueryOptions = {},
|
|
282
|
+
accessToken: string
|
|
283
|
+
): Promise<{ sessions: IVibeLoginSession[]; total: number }> {
|
|
284
|
+
const page = options.page || 1;
|
|
285
|
+
const pageSize = options.pageSize || 50;
|
|
286
|
+
|
|
287
|
+
const query: Record<string, unknown> = {
|
|
288
|
+
page,
|
|
289
|
+
pageSize,
|
|
290
|
+
orderBy: 'created_at',
|
|
291
|
+
orderDir: 'desc',
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
if (options.status) {
|
|
295
|
+
query.filter = [{ field: 'status', operator: 'eq', value: options.status }];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}/query`;
|
|
299
|
+
const result = await vibeProxyRequest<{
|
|
300
|
+
data?: IVibeLoginSession[];
|
|
301
|
+
items?: IVibeLoginSession[];
|
|
302
|
+
meta?: { total?: number; totalCount?: number };
|
|
303
|
+
totalCount?: number;
|
|
304
|
+
}>(endpoint, 'POST', accessToken, query);
|
|
305
|
+
|
|
306
|
+
const sessions = result?.data || result?.items || [];
|
|
307
|
+
const total = result?.meta?.total ?? result?.meta?.totalCount ?? result?.totalCount ?? sessions.length;
|
|
308
|
+
|
|
309
|
+
return { sessions, total };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get a single session by ID.
|
|
314
|
+
*
|
|
315
|
+
* @param sessionId - The session document ID
|
|
316
|
+
* @param accessToken - Access token for auth
|
|
317
|
+
*/
|
|
318
|
+
export async function getSessionById(
|
|
319
|
+
sessionId: number,
|
|
320
|
+
accessToken: string
|
|
321
|
+
): Promise<IVibeLoginSession | null> {
|
|
322
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}/${sessionId}`;
|
|
323
|
+
return vibeProxyRequest<IVibeLoginSession>(endpoint, 'GET', accessToken);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// -----------------------------------------------------------------------------
|
|
327
|
+
// REVOKE SESSION
|
|
328
|
+
// -----------------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Revoke a specific session.
|
|
332
|
+
* The user will be logged out on their next request.
|
|
333
|
+
*
|
|
334
|
+
* @param sessionId - The session document ID
|
|
335
|
+
* @param adminEmail - Email of the admin performing the revocation
|
|
336
|
+
* @param accessToken - Admin's access token
|
|
337
|
+
* @param reason - Optional reason for revocation
|
|
338
|
+
* @returns The updated session, or null on failure
|
|
339
|
+
*/
|
|
340
|
+
export async function revokeSession(
|
|
341
|
+
sessionId: number,
|
|
342
|
+
adminEmail: string,
|
|
343
|
+
accessToken: string,
|
|
344
|
+
reason?: string
|
|
345
|
+
): Promise<IVibeLoginSession | null> {
|
|
346
|
+
const now = new Date().toISOString();
|
|
347
|
+
|
|
348
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}/${sessionId}`;
|
|
349
|
+
const session = await vibeProxyRequest<IVibeLoginSession>(
|
|
350
|
+
endpoint,
|
|
351
|
+
'PUT',
|
|
352
|
+
accessToken,
|
|
353
|
+
{
|
|
354
|
+
status: 'revoked',
|
|
355
|
+
revoked_by: adminEmail,
|
|
356
|
+
revoked_at: now,
|
|
357
|
+
revoke_reason: reason || 'Revoked by administrator',
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
if (session) {
|
|
362
|
+
console.log(`[vibe-sessions] Session ${sessionId} revoked by ${adminEmail}`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return session;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Revoke all sessions for a specific user.
|
|
370
|
+
* Useful when an account is compromised.
|
|
371
|
+
*
|
|
372
|
+
* @param idpUserId - The user's IDP ID
|
|
373
|
+
* @param adminEmail - Email of the admin performing the revocation
|
|
374
|
+
* @param accessToken - Admin's access token
|
|
375
|
+
* @param reason - Optional reason for revocation
|
|
376
|
+
* @returns Number of sessions revoked
|
|
377
|
+
*/
|
|
378
|
+
export async function revokeAllUserSessions(
|
|
379
|
+
idpUserId: number,
|
|
380
|
+
adminEmail: string,
|
|
381
|
+
accessToken: string,
|
|
382
|
+
reason?: string
|
|
383
|
+
): Promise<number> {
|
|
384
|
+
const sessions = await getUserSessions(idpUserId, accessToken);
|
|
385
|
+
const activeSessions = sessions.filter(s => s.status === 'active');
|
|
386
|
+
|
|
387
|
+
let revokedCount = 0;
|
|
388
|
+
for (const session of activeSessions) {
|
|
389
|
+
const result = await revokeSession(session.id, adminEmail, accessToken, reason);
|
|
390
|
+
if (result) revokedCount++;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
console.log(`[vibe-sessions] Revoked ${revokedCount} sessions for user ${idpUserId}`);
|
|
394
|
+
return revokedCount;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// -----------------------------------------------------------------------------
|
|
398
|
+
// UPDATE ACTIVITY
|
|
399
|
+
// -----------------------------------------------------------------------------
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Update the last_activity timestamp for a session.
|
|
403
|
+
* Call this periodically during user activity.
|
|
404
|
+
*
|
|
405
|
+
* @param sessionId - The session document ID
|
|
406
|
+
* @param accessToken - Access token for auth
|
|
407
|
+
* @returns true if updated successfully
|
|
408
|
+
*/
|
|
409
|
+
export async function updateSessionActivity(
|
|
410
|
+
sessionId: number,
|
|
411
|
+
accessToken: string
|
|
412
|
+
): Promise<boolean> {
|
|
413
|
+
const endpoint = `/v1/collections/${COLLECTION}/tables/${TABLE}/${sessionId}`;
|
|
414
|
+
const result = await vibeProxyRequest<IVibeLoginSession>(
|
|
415
|
+
endpoint,
|
|
416
|
+
'PUT',
|
|
417
|
+
accessToken,
|
|
418
|
+
{ last_activity: new Date().toISOString() }
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
return result !== null;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// -----------------------------------------------------------------------------
|
|
425
|
+
// CHECK SESSION STATUS
|
|
426
|
+
// -----------------------------------------------------------------------------
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Check if a session is still valid (not revoked/expired).
|
|
430
|
+
* Use this in middleware to enforce session revocation.
|
|
431
|
+
*
|
|
432
|
+
* @param sessionId - The session document ID
|
|
433
|
+
* @param accessToken - Access token for auth
|
|
434
|
+
* @returns true if session is active and not expired
|
|
435
|
+
*/
|
|
436
|
+
export async function isSessionValid(
|
|
437
|
+
sessionId: number,
|
|
438
|
+
accessToken: string
|
|
439
|
+
): Promise<boolean> {
|
|
440
|
+
const session = await getSessionById(sessionId, accessToken);
|
|
441
|
+
|
|
442
|
+
if (!session) return false;
|
|
443
|
+
if (session.status !== 'active') return false;
|
|
444
|
+
|
|
445
|
+
// Check expiry
|
|
446
|
+
const expiresAt = new Date(session.expires_at);
|
|
447
|
+
if (expiresAt < new Date()) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Check if a user has any revoked sessions that need enforcement.
|
|
456
|
+
* Returns the most recently revoked session if found.
|
|
457
|
+
*
|
|
458
|
+
* @param idpUserId - The user's IDP ID
|
|
459
|
+
* @param accessToken - Access token for auth
|
|
460
|
+
* @param sessionTokenHash - Optional token hash to check specific session
|
|
461
|
+
* @returns Revoked session info if enforcement needed, null otherwise
|
|
462
|
+
*/
|
|
463
|
+
export async function checkSessionRevocation(
|
|
464
|
+
idpUserId: number,
|
|
465
|
+
accessToken: string,
|
|
466
|
+
sessionTokenHash?: string
|
|
467
|
+
): Promise<IVibeLoginSession | null> {
|
|
468
|
+
const sessions = await getUserSessions(idpUserId, accessToken);
|
|
469
|
+
|
|
470
|
+
// If we have a specific token hash, check that session
|
|
471
|
+
if (sessionTokenHash) {
|
|
472
|
+
const matchingSession = sessions.find(s => s.session_token_hash === sessionTokenHash);
|
|
473
|
+
if (matchingSession && matchingSession.status === 'revoked') {
|
|
474
|
+
return matchingSession;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Otherwise, check if there are any recently revoked sessions
|
|
479
|
+
// (revoked within the last hour - gives time for enforcement)
|
|
480
|
+
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
|
481
|
+
const recentlyRevoked = sessions.find(
|
|
482
|
+
s =>
|
|
483
|
+
s.status === 'revoked' &&
|
|
484
|
+
s.revoked_at &&
|
|
485
|
+
new Date(s.revoked_at) > oneHourAgo
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
return recentlyRevoked || null;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// -----------------------------------------------------------------------------
|
|
492
|
+
// STATISTICS
|
|
493
|
+
// -----------------------------------------------------------------------------
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Get session statistics for admin dashboard.
|
|
497
|
+
*
|
|
498
|
+
* @param accessToken - Admin's access token
|
|
499
|
+
*/
|
|
500
|
+
export async function getSessionStats(accessToken: string): Promise<{
|
|
501
|
+
totalActive: number;
|
|
502
|
+
totalRevoked: number;
|
|
503
|
+
uniqueUsers: number;
|
|
504
|
+
byCountry: Record<string, number>;
|
|
505
|
+
byDevice: Record<string, number>;
|
|
506
|
+
recentLogins: number; // Last 24 hours
|
|
507
|
+
}> {
|
|
508
|
+
const { sessions } = await getAllSessions({ pageSize: 1000 }, accessToken);
|
|
509
|
+
|
|
510
|
+
const stats = {
|
|
511
|
+
totalActive: 0,
|
|
512
|
+
totalRevoked: 0,
|
|
513
|
+
uniqueUsers: new Set<number>(),
|
|
514
|
+
byCountry: {} as Record<string, number>,
|
|
515
|
+
byDevice: {} as Record<string, number>,
|
|
516
|
+
recentLogins: 0,
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
520
|
+
|
|
521
|
+
for (const session of sessions) {
|
|
522
|
+
// Status counts
|
|
523
|
+
if (session.status === 'active') stats.totalActive++;
|
|
524
|
+
if (session.status === 'revoked') stats.totalRevoked++;
|
|
525
|
+
|
|
526
|
+
// Unique users
|
|
527
|
+
stats.uniqueUsers.add(session.idp_user_id);
|
|
528
|
+
|
|
529
|
+
// By country
|
|
530
|
+
const country = session.country_code || 'Unknown';
|
|
531
|
+
stats.byCountry[country] = (stats.byCountry[country] || 0) + 1;
|
|
532
|
+
|
|
533
|
+
// By device type
|
|
534
|
+
const device = session.device_type || 'unknown';
|
|
535
|
+
stats.byDevice[device] = (stats.byDevice[device] || 0) + 1;
|
|
536
|
+
|
|
537
|
+
// Recent logins
|
|
538
|
+
if (new Date(session.created_at) > oneDayAgo) {
|
|
539
|
+
stats.recentLogins++;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return {
|
|
544
|
+
totalActive: stats.totalActive,
|
|
545
|
+
totalRevoked: stats.totalRevoked,
|
|
546
|
+
uniqueUsers: stats.uniqueUsers.size,
|
|
547
|
+
byCountry: stats.byCountry,
|
|
548
|
+
byDevice: stats.byDevice,
|
|
549
|
+
recentLogins: stats.recentLogins,
|
|
550
|
+
};
|
|
551
|
+
}
|