@memberjunction/server 6.2.0-edge.3 → 6.2.0-edge.4
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/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +25 -0
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -0
- package/dist/agentSessions/BridgeHostInstance.js +30 -0
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -0
- package/dist/agentSessions/HostInstance.d.ts +75 -11
- package/dist/agentSessions/HostInstance.d.ts.map +1 -1
- package/dist/agentSessions/HostInstance.js +99 -28
- package/dist/agentSessions/HostInstance.js.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.js +7 -3
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +173 -25
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +452 -54
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +43 -2
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +99 -8
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
- package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
- package/dist/agentSessions/SessionRunIDVerifier.js +129 -0
- package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
- package/dist/agentSessions/index.d.ts +2 -0
- package/dist/agentSessions/index.d.ts.map +1 -1
- package/dist/agentSessions/index.js +10 -3
- package/dist/agentSessions/index.js.map +1 -1
- package/dist/auth/actionAuthorization.d.ts +40 -0
- package/dist/auth/actionAuthorization.d.ts.map +1 -0
- package/dist/auth/actionAuthorization.js +94 -0
- package/dist/auth/actionAuthorization.js.map +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +6 -3
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/newUsers.d.ts +10 -0
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +80 -11
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/config.d.ts +2378 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +123 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +8 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +14 -11
- package/dist/context.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +135 -0
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +706 -0
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +20 -4
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +39 -10
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +4 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -131
- package/dist/index.js.map +1 -1
- package/dist/isolatedProvider.d.ts +20 -0
- package/dist/isolatedProvider.d.ts.map +1 -0
- package/dist/isolatedProvider.js +22 -0
- package/dist/isolatedProvider.js.map +1 -0
- package/dist/realtimeProxy/RealtimeProxyServer.d.ts +44 -4
- package/dist/realtimeProxy/RealtimeProxyServer.d.ts.map +1 -1
- package/dist/realtimeProxy/RealtimeProxyServer.js +121 -16
- package/dist/realtimeProxy/RealtimeProxyServer.js.map +1 -1
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts +171 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts.map +1 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js +532 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts +148 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js +191 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts +66 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +138 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts +38 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +98 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts +61 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +149 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts +57 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js +69 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js.map +1 -0
- package/dist/realtimeSessions/index.d.ts +17 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -0
- package/dist/realtimeSessions/index.js +17 -0
- package/dist/realtimeSessions/index.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +86 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionAccess.js +90 -0
- package/dist/realtimeSessions/sessionAccess.js.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts +70 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.js +93 -0
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts +65 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js +71 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -0
- package/dist/realtimeSessions/verificationCore.d.ts +243 -0
- package/dist/realtimeSessions/verificationCore.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationCore.js +356 -0
- package/dist/realtimeSessions/verificationCore.js.map +1 -0
- package/dist/realtimeSessions/verificationPages.d.ts +66 -0
- package/dist/realtimeSessions/verificationPages.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPages.js +110 -0
- package/dist/realtimeSessions/verificationPages.js.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts +147 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.js +249 -0
- package/dist/realtimeSessions/verificationPolicy.js.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts +263 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.js +435 -0
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +20 -2
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +31 -2
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +31 -5
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +75 -14
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts +14 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +21 -5
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/CacheStatsResolver.d.ts +27 -0
- package/dist/resolvers/CacheStatsResolver.d.ts.map +1 -1
- package/dist/resolvers/CacheStatsResolver.js +113 -2
- package/dist/resolvers/CacheStatsResolver.js.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.d.ts +4 -2
- package/dist/resolvers/ClientToolRequestResolver.d.ts.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.js +28 -10
- package/dist/resolvers/ClientToolRequestResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +12 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +83 -2
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/HumanHandoffResolver.d.ts.map +1 -1
- package/dist/resolvers/HumanHandoffResolver.js +7 -1
- package/dist/resolvers/HumanHandoffResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +9 -4
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts +54 -2
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +155 -10
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +155 -25
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +394 -90
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts +61 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js +130 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts +85 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js +188 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js.map +1 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +5 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +10 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +68 -11
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +12 -11
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +6 -2
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +2 -0
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +23 -6
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/UserAvatarResolver.d.ts +16 -0
- package/dist/resolvers/UserAvatarResolver.d.ts.map +1 -0
- package/dist/resolvers/UserAvatarResolver.js +124 -0
- package/dist/resolvers/UserAvatarResolver.js.map +1 -0
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +2 -17
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/agentVisionConsentAudit.d.ts +37 -0
- package/dist/resolvers/agentVisionConsentAudit.d.ts.map +1 -0
- package/dist/resolvers/agentVisionConsentAudit.js +63 -0
- package/dist/resolvers/agentVisionConsentAudit.js.map +1 -0
- package/dist/resolvers/avatarInputValidation.d.ts +40 -0
- package/dist/resolvers/avatarInputValidation.d.ts.map +1 -0
- package/dist/resolvers/avatarInputValidation.js +97 -0
- package/dist/resolvers/avatarInputValidation.js.map +1 -0
- package/dist/resolvers/currentUserRoles.d.ts +29 -0
- package/dist/resolvers/currentUserRoles.d.ts.map +1 -1
- package/dist/resolvers/currentUserRoles.js +30 -0
- package/dist/resolvers/currentUserRoles.js.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.d.ts +6 -0
- package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.js +21 -0
- package/dist/resolvers/meetings/meetingMutations.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +4 -3
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +13 -7
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts +105 -0
- package/dist/sharedCache.d.ts.map +1 -0
- package/dist/sharedCache.js +276 -0
- package/dist/sharedCache.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +97 -95
- package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
- package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
- package/src/__tests__/BridgeHostInstance.test.ts +232 -0
- package/src/__tests__/ClientToolRequestResolver.test.ts +116 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +285 -0
- package/src/__tests__/HostInstance.test.ts +84 -0
- package/src/__tests__/HumanHandoffResolver.test.ts +17 -0
- package/src/__tests__/MeetingResolver.test.ts +75 -1
- package/src/__tests__/RealtimeBridgeResolver.test.ts +415 -6
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +383 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +682 -58
- package/src/__tests__/RealtimeProxyServer.test.ts +16 -1
- package/src/__tests__/RealtimeRelay.test.ts +876 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
- package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +6 -3
- package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +169 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +4 -4
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +166 -0
- package/src/__tests__/RunTemplateResolver.test.ts +132 -0
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +63 -0
- package/src/__tests__/SessionJanitor.test.ts +845 -18
- package/src/__tests__/SessionManager.test.ts +213 -17
- package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
- package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +50 -3
- package/src/__tests__/UserAvatarResolver.test.ts +255 -0
- package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
- package/src/__tests__/actionAuthorization.test.ts +130 -0
- package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
- package/src/__tests__/avatarInputValidation.test.ts +160 -0
- package/src/__tests__/isolatedProviderTransactions.test.ts +169 -0
- package/src/__tests__/magicLinkService.consume.test.ts +6 -0
- package/src/__tests__/magicLinkService.provisionLog.test.ts +5 -0
- package/src/__tests__/newUsers.template.test.ts +151 -0
- package/src/__tests__/newUsers.test.ts +74 -5
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +17 -2
- package/src/__tests__/realtimeSessions/RealtimeSessionEventService.test.ts +201 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +215 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationResolver.test.ts +102 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationService.test.ts +349 -0
- package/src/__tests__/realtimeSessions/RealtimeVerifyRouter.test.ts +131 -0
- package/src/__tests__/realtimeSessions/SlidingWindowRateLimiter.test.ts +56 -0
- package/src/__tests__/realtimeSessions/helpers.ts +4 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +129 -0
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +124 -0
- package/src/__tests__/realtimeSessions/verificationCore.test.ts +355 -0
- package/src/__tests__/realtimeSessions/verificationPages.test.ts +84 -0
- package/src/__tests__/realtimeSessions/verificationPolicy.test.ts +226 -0
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +633 -0
- package/src/__tests__/resolverBase.fls.test.ts +87 -4
- package/src/__tests__/serverExtensionReservedRoots.test.ts +2 -0
- package/src/__tests__/sharedCache.test.ts +310 -0
- package/src/__tests__/widgetGuestElevation.test.ts +44 -0
- package/src/agentSessions/BridgeHostInstance.ts +32 -0
- package/src/agentSessions/HostInstance.ts +124 -28
- package/src/agentSessions/ReturningVisitorRecap.ts +7 -3
- package/src/agentSessions/SessionJanitor.ts +543 -57
- package/src/agentSessions/SessionManager.ts +125 -25
- package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
- package/src/agentSessions/index.ts +10 -3
- package/src/auth/actionAuthorization.ts +116 -0
- package/src/auth/index.ts +3 -8
- package/src/auth/magicLink/MagicLinkService.ts +6 -3
- package/src/auth/newUsers.ts +99 -11
- package/src/config.ts +125 -0
- package/src/context.ts +15 -10
- package/src/generated/graphql-schemas/__mj.ts +496 -1
- package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
- package/src/generic/ResolverBase.ts +39 -9
- package/src/generic/RunViewResolver.ts +4 -0
- package/src/index.ts +132 -143
- package/src/isolatedProvider.ts +22 -0
- package/src/realtimeProxy/RealtimeProxyServer.ts +148 -16
- package/src/realtimeProxy/RealtimeRelayTunnel.ts +645 -0
- package/src/realtimeSessions/README.md +179 -0
- package/src/realtimeSessions/RealtimeSessionEventService.ts +274 -0
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +167 -0
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +108 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
- package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
- package/src/realtimeSessions/index.ts +16 -0
- package/src/realtimeSessions/sessionAccess.ts +141 -0
- package/src/realtimeSessions/sessionConfigStamps.ts +123 -0
- package/src/realtimeSessions/subscriptionAuthorization.ts +116 -0
- package/src/realtimeSessions/verificationCore.ts +502 -0
- package/src/realtimeSessions/verificationPages.ts +149 -0
- package/src/realtimeSessions/verificationPolicy.ts +321 -0
- package/src/realtimeSessions/verificationWorkflow.ts +702 -0
- package/src/realtimeWidget/widgetGuestElevation.ts +34 -2
- package/src/resolvers/ActionResolver.ts +84 -21
- package/src/resolvers/AdhocQueryResolver.ts +24 -6
- package/src/resolvers/CacheStatsResolver.ts +89 -2
- package/src/resolvers/ClientToolRequestResolver.ts +25 -7
- package/src/resolvers/FetchEntityVectorsResolver.ts +97 -2
- package/src/resolvers/HumanHandoffResolver.ts +8 -0
- package/src/resolvers/MCPResolver.ts +8 -5
- package/src/resolvers/RealtimeBridgeResolver.ts +163 -11
- package/src/resolvers/RealtimeClientSessionResolver.ts +501 -96
- package/src/resolvers/RealtimeSessionEventsResolver.ts +133 -0
- package/src/resolvers/RealtimeSessionVerificationResolver.ts +174 -0
- package/src/resolvers/RemoteBrowserActionResolver.ts +11 -1
- package/src/resolvers/RunAIAgentResolver.ts +78 -11
- package/src/resolvers/RunTemplateResolver.ts +13 -12
- package/src/resolvers/SyncDataResolver.ts +6 -2
- package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
- package/src/resolvers/UserAvatarResolver.ts +111 -0
- package/src/resolvers/UserResolver.ts +2 -16
- package/src/resolvers/agentVisionConsentAudit.ts +82 -0
- package/src/resolvers/avatarInputValidation.ts +123 -0
- package/src/resolvers/currentUserRoles.ts +32 -1
- package/src/resolvers/meetings/meetingMutations.ts +21 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +13 -7
- package/src/sharedCache.ts +302 -0
- package/src/types.ts +7 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pure builders for the two pieces of content identity verification puts in front of a
|
|
3
|
+
* person: the verification EMAIL and the self-contained HTML PAGES the verify link lands on. No DB, no
|
|
4
|
+
* network, no MJ runtime — deterministic strings in, strings out.
|
|
5
|
+
*
|
|
6
|
+
* ## What the pages never contain
|
|
7
|
+
*
|
|
8
|
+
* Nothing about the session: no agent name, no conversation, no email address, no name, no hint that a
|
|
9
|
+
* session with this id exists. The page for an unknown token, an expired token and a used token is the
|
|
10
|
+
* **same page**, so the link cannot be used to probe which sessions exist or what state they are in.
|
|
11
|
+
*
|
|
12
|
+
* ## Why GET does not redeem
|
|
13
|
+
*
|
|
14
|
+
* Mail security scanners, link previewers and browser prefetchers issue GET requests for every URL in a
|
|
15
|
+
* message. A GET that consumed the single-use token would let a scanner burn it before the human clicks
|
|
16
|
+
* — the person would then see "already used". So the link opens a page with one button ({@link
|
|
17
|
+
* BuildVerifyConfirmHtml}) and only the human's POST redeems. The magic-link redeem endpoint made the
|
|
18
|
+
* same choice for the same reason.
|
|
19
|
+
*
|
|
20
|
+
* @module @memberjunction/server/realtimeSessions
|
|
21
|
+
*/
|
|
22
|
+
/** Inputs to {@link BuildVerificationEmail}. */
|
|
23
|
+
export interface VerificationEmailInput {
|
|
24
|
+
/** The person's sanitised name. */
|
|
25
|
+
Name: string;
|
|
26
|
+
/** The typed code (fallback for opening the email on another device). */
|
|
27
|
+
Code: string;
|
|
28
|
+
/** The full link that opens the confirmation page. */
|
|
29
|
+
LinkUrl: string;
|
|
30
|
+
/** Minutes the link and code stay valid. */
|
|
31
|
+
TtlMinutes: number;
|
|
32
|
+
}
|
|
33
|
+
/** A ready-to-send email. */
|
|
34
|
+
export interface VerificationEmail {
|
|
35
|
+
Subject: string;
|
|
36
|
+
Text: string;
|
|
37
|
+
Html: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Builds the verification email.
|
|
41
|
+
*
|
|
42
|
+
* The subject never carries the name or the code (subjects surface on lock screens and in notification
|
|
43
|
+
* previews). The name is HTML-escaped in the HTML body and reduced to a single line in the text body.
|
|
44
|
+
*/
|
|
45
|
+
export declare function BuildVerificationEmail(input: VerificationEmailInput): VerificationEmail;
|
|
46
|
+
/**
|
|
47
|
+
* The page a verify link opens. Side-effect free: it renders a single confirmation button whose POST
|
|
48
|
+
* performs the redemption (see the module header for why GET must not).
|
|
49
|
+
*
|
|
50
|
+
* @param token - the raw token, embedded in a hidden form field (never in the POST URL)
|
|
51
|
+
* @param actionPath - the same-origin path the form POSTs to
|
|
52
|
+
*/
|
|
53
|
+
export declare function BuildVerifyConfirmHtml(token: string, actionPath: string): string;
|
|
54
|
+
/** The page shown after a successful redemption. Says nothing about the session. */
|
|
55
|
+
export declare function BuildVerifySuccessHtml(): string;
|
|
56
|
+
/**
|
|
57
|
+
* The page shown for EVERY failed redemption — unknown, malformed, expired, used, or voided token alike —
|
|
58
|
+
* so the response cannot be used to learn anything about a session.
|
|
59
|
+
*/
|
|
60
|
+
export declare function BuildVerifyFailureHtml(): string;
|
|
61
|
+
/**
|
|
62
|
+
* The page shown when the server hit a fault while recording a verification (the link was valid but
|
|
63
|
+
* nothing was saved, so trying the link again is correct). Only a holder of a valid token can reach it.
|
|
64
|
+
*/
|
|
65
|
+
export declare function BuildVerifyErrorHtml(): string;
|
|
66
|
+
//# sourceMappingURL=verificationPages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificationPages.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/verificationPages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,gDAAgD;AAChD,MAAM,WAAW,sBAAsB;IACnC,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,6BAA6B;AAC7B,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAmBvF;AA8BD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAUhF;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pure builders for the two pieces of content identity verification puts in front of a
|
|
3
|
+
* person: the verification EMAIL and the self-contained HTML PAGES the verify link lands on. No DB, no
|
|
4
|
+
* network, no MJ runtime — deterministic strings in, strings out.
|
|
5
|
+
*
|
|
6
|
+
* ## What the pages never contain
|
|
7
|
+
*
|
|
8
|
+
* Nothing about the session: no agent name, no conversation, no email address, no name, no hint that a
|
|
9
|
+
* session with this id exists. The page for an unknown token, an expired token and a used token is the
|
|
10
|
+
* **same page**, so the link cannot be used to probe which sessions exist or what state they are in.
|
|
11
|
+
*
|
|
12
|
+
* ## Why GET does not redeem
|
|
13
|
+
*
|
|
14
|
+
* Mail security scanners, link previewers and browser prefetchers issue GET requests for every URL in a
|
|
15
|
+
* message. A GET that consumed the single-use token would let a scanner burn it before the human clicks
|
|
16
|
+
* — the person would then see "already used". So the link opens a page with one button ({@link
|
|
17
|
+
* BuildVerifyConfirmHtml}) and only the human's POST redeems. The magic-link redeem endpoint made the
|
|
18
|
+
* same choice for the same reason.
|
|
19
|
+
*
|
|
20
|
+
* @module @memberjunction/server/realtimeSessions
|
|
21
|
+
*/
|
|
22
|
+
import { EscapeHtml } from '../auth/magicLink/redeemLanding.js';
|
|
23
|
+
/**
|
|
24
|
+
* Builds the verification email.
|
|
25
|
+
*
|
|
26
|
+
* The subject never carries the name or the code (subjects surface on lock screens and in notification
|
|
27
|
+
* previews). The name is HTML-escaped in the HTML body and reduced to a single line in the text body.
|
|
28
|
+
*/
|
|
29
|
+
export function BuildVerificationEmail(input) {
|
|
30
|
+
const name = input.Name.replace(/\s+/g, ' ').trim();
|
|
31
|
+
const greeting = name ? `Hi ${name},` : 'Hi,';
|
|
32
|
+
const ttl = `${input.TtlMinutes} minute${input.TtlMinutes === 1 ? '' : 's'}`;
|
|
33
|
+
const text = `${greeting}\n\n` +
|
|
34
|
+
`Confirm your email address to continue your conversation. Open this link:\n\n${input.LinkUrl}\n\n` +
|
|
35
|
+
`Or, if you opened this email on a different device, type this code into your conversation:\n\n${input.Code}\n\n` +
|
|
36
|
+
`The link and the code work once and expire in ${ttl}.\n\n` +
|
|
37
|
+
`If you did not ask for this, you can ignore this email — nothing happens unless the link is opened or the code is entered.`;
|
|
38
|
+
const html = `<p>${EscapeHtml(greeting)}</p>` +
|
|
39
|
+
`<p>Confirm your email address to continue your conversation.</p>` +
|
|
40
|
+
`<p><a href="${EscapeHtml(input.LinkUrl)}">Confirm my email address</a></p>` +
|
|
41
|
+
`<p>Or, if you opened this email on a different device, type this code into your conversation:</p>` +
|
|
42
|
+
`<p style="font-size:1.5em;letter-spacing:.15em"><strong>${EscapeHtml(input.Code)}</strong></p>` +
|
|
43
|
+
`<p>The link and the code work once and expire in ${EscapeHtml(ttl)}.</p>` +
|
|
44
|
+
`<p>If you did not ask for this, you can ignore this email — nothing happens unless the link is opened or the code is entered.</p>`;
|
|
45
|
+
return { Subject: 'Confirm your email address', Text: text, Html: html };
|
|
46
|
+
}
|
|
47
|
+
/** Shared document shell for the verify pages. Hardcoded colours are intentional: standalone server-rendered HTML, not Angular CSS. */
|
|
48
|
+
function page(title, bodyInner) {
|
|
49
|
+
return `<!doctype html>
|
|
50
|
+
<html lang="en">
|
|
51
|
+
<head>
|
|
52
|
+
<meta charset="utf-8">
|
|
53
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
54
|
+
<meta name="robots" content="noindex, nofollow">
|
|
55
|
+
<meta name="referrer" content="no-referrer">
|
|
56
|
+
<title>${EscapeHtml(title)}</title>
|
|
57
|
+
<style>
|
|
58
|
+
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background:#f5f5f5; margin:0; display:flex; min-height:100vh; align-items:center; justify-content:center; }
|
|
59
|
+
.card { background:#fff; padding:2.5rem; border-radius:12px; box-shadow:0 1px 4px rgba(0,0,0,.12); max-width:24rem; text-align:center; margin:1rem; }
|
|
60
|
+
h1 { font-size:1.25rem; margin:0 0 .5rem; color:#1f2937; }
|
|
61
|
+
p { color:#4b5563; margin:0 0 1.5rem; font-size:.95rem; }
|
|
62
|
+
p:last-child { margin-bottom:0; }
|
|
63
|
+
button { background:#264FAF; color:#fff; border:0; border-radius:8px; padding:.75rem 1.5rem; font-size:1rem; cursor:pointer; width:100%; }
|
|
64
|
+
button:hover { background:#1e3f8c; }
|
|
65
|
+
</style>
|
|
66
|
+
</head>
|
|
67
|
+
<body>
|
|
68
|
+
<div class="card">
|
|
69
|
+
${bodyInner}
|
|
70
|
+
</div>
|
|
71
|
+
</body>
|
|
72
|
+
</html>`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The page a verify link opens. Side-effect free: it renders a single confirmation button whose POST
|
|
76
|
+
* performs the redemption (see the module header for why GET must not).
|
|
77
|
+
*
|
|
78
|
+
* @param token - the raw token, embedded in a hidden form field (never in the POST URL)
|
|
79
|
+
* @param actionPath - the same-origin path the form POSTs to
|
|
80
|
+
*/
|
|
81
|
+
export function BuildVerifyConfirmHtml(token, actionPath) {
|
|
82
|
+
return page('Confirm your email', ` <h1>Confirm your email address</h1>
|
|
83
|
+
<p>Press the button to confirm. Then return to your conversation.</p>
|
|
84
|
+
<form method="POST" action="${EscapeHtml(actionPath)}">
|
|
85
|
+
<input type="hidden" name="token" value="${EscapeHtml(token)}">
|
|
86
|
+
<button type="submit">Confirm my email address</button>
|
|
87
|
+
</form>`);
|
|
88
|
+
}
|
|
89
|
+
/** The page shown after a successful redemption. Says nothing about the session. */
|
|
90
|
+
export function BuildVerifySuccessHtml() {
|
|
91
|
+
return page("You're verified", ` <h1>You're verified</h1>
|
|
92
|
+
<p>Return to your conversation — it will carry on from where you left off. You can close this tab.</p>`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The page shown for EVERY failed redemption — unknown, malformed, expired, used, or voided token alike —
|
|
96
|
+
* so the response cannot be used to learn anything about a session.
|
|
97
|
+
*/
|
|
98
|
+
export function BuildVerifyFailureHtml() {
|
|
99
|
+
return page('Link not valid', ` <h1>This link is no longer valid</h1>
|
|
100
|
+
<p>It may have expired or already been used. Return to your conversation to request a new one.</p>`);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The page shown when the server hit a fault while recording a verification (the link was valid but
|
|
104
|
+
* nothing was saved, so trying the link again is correct). Only a holder of a valid token can reach it.
|
|
105
|
+
*/
|
|
106
|
+
export function BuildVerifyErrorHtml() {
|
|
107
|
+
return page('Something went wrong', ` <h1>We could not complete this just now</h1>
|
|
108
|
+
<p>Please open the link from your email again in a moment.</p>`);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=verificationPages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificationPages.js","sourceRoot":"","sources":["../../src/realtimeSessions/verificationPages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAqBhE;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA6B;IAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,UAAU,UAAU,KAAK,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAC7E,MAAM,IAAI,GACN,GAAG,QAAQ,MAAM;QACjB,gFAAgF,KAAK,CAAC,OAAO,MAAM;QACnG,iGAAiG,KAAK,CAAC,IAAI,MAAM;QACjH,iDAAiD,GAAG,OAAO;QAC3D,4HAA4H,CAAC;IACjI,MAAM,IAAI,GACN,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM;QAChC,kEAAkE;QAClE,eAAe,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,oCAAoC;QAC5E,mGAAmG;QACnG,2DAA2D,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe;QAChG,oDAAoD,UAAU,CAAC,GAAG,CAAC,OAAO;QAC1E,mIAAmI,CAAC;IACxI,OAAO,EAAE,OAAO,EAAE,4BAA4B,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7E,CAAC;AAED,uIAAuI;AACvI,SAAS,IAAI,CAAC,KAAa,EAAE,SAAiB;IAC1C,OAAO;;;;;;;SAOF,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;EAaxB,SAAS;;;QAGH,CAAC;AACT,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa,EAAE,UAAkB;IACpE,OAAO,IAAI,CACP,oBAAoB,EACpB;;kCAE0B,UAAU,CAAC,UAAU,CAAC;iDACP,UAAU,CAAC,KAAK,CAAC;;YAEtD,CACP,CAAC;AACN,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,sBAAsB;IAClC,OAAO,IAAI,CACP,iBAAiB,EACjB;2GACmG,CACtG,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IAClC,OAAO,IAAI,CACP,gBAAgB,EAChB;uGAC+F,CAClG,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAChC,OAAO,IAAI,CACP,sBAAsB,EACtB;mEAC2D,CAC9D,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The policy a realtime session's identity verification is held to — pure, no I/O.
|
|
3
|
+
*
|
|
4
|
+
* Policy arrives in layers and the most specific layer wins:
|
|
5
|
+
*
|
|
6
|
+
* 1. built-in defaults (this file)
|
|
7
|
+
* 2. server config — `realtime.identityVerification` in `mj.config.cjs`
|
|
8
|
+
* 3. the config cascade — `channels.config.IdentityVerification` (+ `session.unverifiedMaxSeconds` /
|
|
9
|
+
* `session.verifiedMaxSeconds`) resolved for this session at mint, **snapshotted onto the session**
|
|
10
|
+
*
|
|
11
|
+
* Layer 3 is stored server-side on the session at mint and never read from the client: a request to
|
|
12
|
+
* verify carries only `{ agentSessionId, name, email }`, so a caller cannot choose the rules it is
|
|
13
|
+
* judged by.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/server/realtimeSessions
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Consumer ("free mail") email domains, matched exactly or as a parent of the address's domain.
|
|
19
|
+
*
|
|
20
|
+
* **Curated, not exhaustive**, and deliberately about *consumer mailbox providers*, not about
|
|
21
|
+
* disposable/throwaway domains (a different, much larger, constantly-moving list). A deployment can
|
|
22
|
+
* replace it entirely through `consumerDomains`. Lower-case, no leading `@`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_CONSUMER_EMAIL_DOMAINS: readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* The knobs of identity verification, in the shape an administrator authors them (JSON in the config
|
|
27
|
+
* cascade or `mj.config.cjs`). Every field is optional; absent means "inherit the next layer".
|
|
28
|
+
*
|
|
29
|
+
* Members are camelCase on purpose: they ARE the JSON config keys (`mj.config.cjs`,
|
|
30
|
+
* `channels.config.IdentityVerification`, and the snapshot stored on the session). Renaming one would
|
|
31
|
+
* rename a configuration key that deployments and stored sessions already use.
|
|
32
|
+
*/
|
|
33
|
+
export interface IdentityVerificationPolicy {
|
|
34
|
+
/** Refuse consumer mailbox domains (see {@link DEFAULT_CONSUMER_EMAIL_DOMAINS}). Default `false`. */
|
|
35
|
+
requireBusinessDomain?: boolean;
|
|
36
|
+
/** Domains refused outright (matched exactly or as a parent domain), whatever else is allowed. */
|
|
37
|
+
blockedDomains?: string[];
|
|
38
|
+
/** REPLACES the built-in consumer-domain list when set (and non-empty). */
|
|
39
|
+
consumerDomains?: string[];
|
|
40
|
+
/** Minutes an emailed link/code stays redeemable. Default 30, clamped to 1–1440. */
|
|
41
|
+
linkTtlMinutes?: number;
|
|
42
|
+
/** Most verification emails one session may trigger. Default 3, clamped to 1–20. */
|
|
43
|
+
maxSendsPerSession?: number;
|
|
44
|
+
/** Most wrong code entries before the pending verification is voided. Default 5, clamped to 1–10. */
|
|
45
|
+
maxCodeAttempts?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Session duration cap while UNVERIFIED, in seconds. Stamped at mint as the session's absolute
|
|
48
|
+
* deadline. Absent ⇒ no cap from this layer.
|
|
49
|
+
*/
|
|
50
|
+
unverifiedMaxSeconds?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Session duration cap once VERIFIED, in seconds (measured from the session's start). On
|
|
53
|
+
* verification the deadline is moved out to this — never pulled in. Absent ⇒ verification does not
|
|
54
|
+
* change the deadline.
|
|
55
|
+
*/
|
|
56
|
+
verifiedMaxSeconds?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A policy with every knob resolved. camelCase for the same reason as {@link IdentityVerificationPolicy}:
|
|
60
|
+
* it is that shape with its defaults applied.
|
|
61
|
+
*/
|
|
62
|
+
export interface ResolvedIdentityVerificationPolicy {
|
|
63
|
+
requireBusinessDomain: boolean;
|
|
64
|
+
blockedDomains: string[];
|
|
65
|
+
consumerDomains: string[];
|
|
66
|
+
linkTtlMinutes: number;
|
|
67
|
+
maxSendsPerSession: number;
|
|
68
|
+
maxCodeAttempts: number;
|
|
69
|
+
unverifiedMaxSeconds: number | undefined;
|
|
70
|
+
verifiedMaxSeconds: number | undefined;
|
|
71
|
+
}
|
|
72
|
+
/** Built-in numeric defaults. */
|
|
73
|
+
export declare const DEFAULT_LINK_TTL_MINUTES = 30;
|
|
74
|
+
export declare const DEFAULT_MAX_SENDS_PER_SESSION = 3;
|
|
75
|
+
export declare const DEFAULT_MAX_CODE_ATTEMPTS = 5;
|
|
76
|
+
/**
|
|
77
|
+
* Reads ONE policy layer from untrusted JSON (a cascade section, a stored snapshot, a config file).
|
|
78
|
+
* Every field is type-checked; anything that is not the right type is ignored rather than coerced.
|
|
79
|
+
*
|
|
80
|
+
* @param raw - the layer, as parsed JSON of unknown shape
|
|
81
|
+
*/
|
|
82
|
+
export declare function ReadIdentityVerificationPolicyLayer(raw: unknown): IdentityVerificationPolicy;
|
|
83
|
+
/**
|
|
84
|
+
* Extracts the session-scoped policy layer from a RESOLVED realtime configuration (the object the
|
|
85
|
+
* config cascade produced at mint).
|
|
86
|
+
*
|
|
87
|
+
* Reads, defensively and without depending on the cascade's TypeScript types (so this keeps working as
|
|
88
|
+
* the cascade gains fields):
|
|
89
|
+
*
|
|
90
|
+
* - `channels.config.IdentityVerification` — the verification channel's own knobs
|
|
91
|
+
* - `session.unverifiedMaxSeconds` / `session.verifiedMaxSeconds` — the duration caps
|
|
92
|
+
*
|
|
93
|
+
* Duration caps in the channel's own config are honoured too; the `session` section wins when both
|
|
94
|
+
* are present, because it is the dedicated, documented home for them.
|
|
95
|
+
*
|
|
96
|
+
* @param realtimeConfig - the effective `realtime` section (`EffectiveConfig.realtime`), or anything
|
|
97
|
+
* @returns the layer; `{}` when the cascade carries nothing relevant
|
|
98
|
+
*/
|
|
99
|
+
export declare function ExtractIdentityVerificationPolicyFromRealtimeConfig(realtimeConfig: unknown): IdentityVerificationPolicy;
|
|
100
|
+
/**
|
|
101
|
+
* Merges policy layers (later layers win per knob) into a fully-resolved policy, applying defaults
|
|
102
|
+
* and clamping every numeric knob into a safe range. An empty `consumerDomains` in a layer is treated
|
|
103
|
+
* as absent (it would silently turn `requireBusinessDomain` into a no-op).
|
|
104
|
+
*
|
|
105
|
+
* @param layers - lowest-precedence first; `undefined` entries are skipped
|
|
106
|
+
*/
|
|
107
|
+
export declare function ResolveIdentityVerificationPolicy(layers: ReadonlyArray<IdentityVerificationPolicy | undefined>): ResolvedIdentityVerificationPolicy;
|
|
108
|
+
/** Outcome of {@link ParseEmailAddress}. */
|
|
109
|
+
export type ParsedEmail = {
|
|
110
|
+
Ok: true;
|
|
111
|
+
Email: string;
|
|
112
|
+
Domain: string;
|
|
113
|
+
} | {
|
|
114
|
+
Ok: false;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Normalises and validates an email address (trim + lower-case). Deliberately conservative: it rejects
|
|
118
|
+
* anything with whitespace, control characters, quotes, angle brackets or a display-name form, because
|
|
119
|
+
* the address is about to be placed in a message header and a link context.
|
|
120
|
+
*
|
|
121
|
+
* @param raw - what the person typed
|
|
122
|
+
*/
|
|
123
|
+
export declare function ParseEmailAddress(raw: string): ParsedEmail;
|
|
124
|
+
/** Outcome of {@link EvaluateEmailDomainPolicy}. */
|
|
125
|
+
export type EmailPolicyDecision = {
|
|
126
|
+
Allowed: true;
|
|
127
|
+
} | {
|
|
128
|
+
Allowed: false;
|
|
129
|
+
Reason: 'domain_blocked' | 'consumer_domain';
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Applies the domain rules of a policy to an address's domain: `blockedDomains` first (always wins),
|
|
133
|
+
* then — when `requireBusinessDomain` — the consumer-domain list.
|
|
134
|
+
*
|
|
135
|
+
* @param domain - lower-case domain of the (already parsed) address
|
|
136
|
+
*/
|
|
137
|
+
export declare function EvaluateEmailDomainPolicy(domain: string, policy: ResolvedIdentityVerificationPolicy): EmailPolicyDecision;
|
|
138
|
+
/**
|
|
139
|
+
* Tightens a session deadline: returns the earlier of the existing deadline (ISO) and `candidateMs`,
|
|
140
|
+
* as an ISO string. Used at mint so a configured unverified cap never LOOSENS a deadline another rule
|
|
141
|
+
* (the widget voice cap) already set.
|
|
142
|
+
*
|
|
143
|
+
* @param existingIso - the deadline already stamped, if any
|
|
144
|
+
* @param candidateMs - the candidate deadline, epoch ms
|
|
145
|
+
*/
|
|
146
|
+
export declare function TightenSessionDeadline(existingIso: string | undefined, candidateMs: number): string;
|
|
147
|
+
//# sourceMappingURL=verificationPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificationPolicy.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/verificationPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,MAAM,EAqB3D,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACvC,qGAAqG;IACrG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,oFAAoF;IACpF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qGAAqG;IACrG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IAC/C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,iCAAiC;AACjC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAsC3C;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,OAAO,GAAG,0BAA0B,CAqC5F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mDAAmD,CAAC,cAAc,EAAE,OAAO,GAAG,0BAA0B,CAmBvH;AAOD;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC7C,MAAM,EAAE,aAAa,CAAC,0BAA0B,GAAG,SAAS,CAAC,GAC9D,kCAAkC,CA2BpC;AAOD,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAOtF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAM1D;AAED,oDAAoD;AACpD,MAAM,MAAM,mBAAmB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEvH;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kCAAkC,GAAG,mBAAmB,CAQzH;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAGnG"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The policy a realtime session's identity verification is held to — pure, no I/O.
|
|
3
|
+
*
|
|
4
|
+
* Policy arrives in layers and the most specific layer wins:
|
|
5
|
+
*
|
|
6
|
+
* 1. built-in defaults (this file)
|
|
7
|
+
* 2. server config — `realtime.identityVerification` in `mj.config.cjs`
|
|
8
|
+
* 3. the config cascade — `channels.config.IdentityVerification` (+ `session.unverifiedMaxSeconds` /
|
|
9
|
+
* `session.verifiedMaxSeconds`) resolved for this session at mint, **snapshotted onto the session**
|
|
10
|
+
*
|
|
11
|
+
* Layer 3 is stored server-side on the session at mint and never read from the client: a request to
|
|
12
|
+
* verify carries only `{ agentSessionId, name, email }`, so a caller cannot choose the rules it is
|
|
13
|
+
* judged by.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/server/realtimeSessions
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Consumer ("free mail") email domains, matched exactly or as a parent of the address's domain.
|
|
19
|
+
*
|
|
20
|
+
* **Curated, not exhaustive**, and deliberately about *consumer mailbox providers*, not about
|
|
21
|
+
* disposable/throwaway domains (a different, much larger, constantly-moving list). A deployment can
|
|
22
|
+
* replace it entirely through `consumerDomains`. Lower-case, no leading `@`.
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_CONSUMER_EMAIL_DOMAINS = [
|
|
25
|
+
// Google
|
|
26
|
+
'gmail.com', 'googlemail.com',
|
|
27
|
+
// Yahoo / AOL (Verizon Media lineage)
|
|
28
|
+
'yahoo.com', 'yahoo.co.uk', 'yahoo.co.in', 'yahoo.co.jp', 'yahoo.ca', 'yahoo.com.au', 'yahoo.com.br',
|
|
29
|
+
'yahoo.fr', 'yahoo.de', 'yahoo.es', 'yahoo.it', 'ymail.com', 'rocketmail.com', 'aol.com', 'aim.com',
|
|
30
|
+
// Microsoft consumer
|
|
31
|
+
'outlook.com', 'outlook.fr', 'outlook.de', 'hotmail.com', 'hotmail.co.uk', 'hotmail.fr', 'hotmail.de',
|
|
32
|
+
'hotmail.it', 'hotmail.es', 'live.com', 'live.co.uk', 'live.fr', 'msn.com',
|
|
33
|
+
// Apple
|
|
34
|
+
'icloud.com', 'me.com', 'mac.com',
|
|
35
|
+
// Privacy-focused
|
|
36
|
+
'proton.me', 'protonmail.com', 'pm.me', 'tutanota.com', 'tuta.io', 'hey.com', 'fastmail.com', 'fastmail.fm',
|
|
37
|
+
// Portal / regional
|
|
38
|
+
'gmx.com', 'gmx.net', 'gmx.de', 'gmx.us', 'web.de', 'mail.com', 'zoho.com', 'zohomail.com',
|
|
39
|
+
'yandex.com', 'yandex.ru', 'mail.ru', 'qq.com', '163.com', '126.com', 'sina.com', 'naver.com',
|
|
40
|
+
'daum.net', 'hanmail.net', 'rediffmail.com', 'orange.fr', 'free.fr', 'laposte.net', 'libero.it', 't-online.de',
|
|
41
|
+
// ISP mailboxes
|
|
42
|
+
'comcast.net', 'verizon.net', 'att.net', 'sbcglobal.net', 'bellsouth.net', 'cox.net', 'charter.net',
|
|
43
|
+
'earthlink.net', 'juno.com', 'optonline.net', 'btinternet.com', 'sky.com', 'virginmedia.com',
|
|
44
|
+
'shaw.ca', 'rogers.com', 'bell.net',
|
|
45
|
+
];
|
|
46
|
+
/** Built-in numeric defaults. */
|
|
47
|
+
export const DEFAULT_LINK_TTL_MINUTES = 30;
|
|
48
|
+
export const DEFAULT_MAX_SENDS_PER_SESSION = 3;
|
|
49
|
+
export const DEFAULT_MAX_CODE_ATTEMPTS = 5;
|
|
50
|
+
const MIN_LINK_TTL_MINUTES = 1;
|
|
51
|
+
const MAX_LINK_TTL_MINUTES = 24 * 60;
|
|
52
|
+
const MIN_MAX_SENDS = 1;
|
|
53
|
+
const MAX_MAX_SENDS = 20;
|
|
54
|
+
const MIN_MAX_ATTEMPTS = 1;
|
|
55
|
+
const MAX_MAX_ATTEMPTS = 10;
|
|
56
|
+
/** Sanity ceiling for a session-duration knob: 24 h. A larger value is a config mistake, not a policy. */
|
|
57
|
+
const MAX_SESSION_SECONDS = 24 * 60 * 60;
|
|
58
|
+
/** True for a plain object. */
|
|
59
|
+
function isRecord(value) {
|
|
60
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
61
|
+
}
|
|
62
|
+
/** A finite number, or undefined. */
|
|
63
|
+
function readNumber(value) {
|
|
64
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
65
|
+
}
|
|
66
|
+
/** A positive finite number within the session-duration ceiling, or undefined. */
|
|
67
|
+
function readSessionSeconds(value) {
|
|
68
|
+
const n = readNumber(value);
|
|
69
|
+
return n !== undefined && n > 0 ? Math.min(Math.floor(n), MAX_SESSION_SECONDS) : undefined;
|
|
70
|
+
}
|
|
71
|
+
/** A list of non-empty strings, normalised to lower-case domains without a leading `@`; undefined when not a list. */
|
|
72
|
+
function readDomainList(value) {
|
|
73
|
+
if (!Array.isArray(value)) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
return value
|
|
77
|
+
.filter((entry) => typeof entry === 'string')
|
|
78
|
+
.map((entry) => entry.trim().toLowerCase().replace(/^@/, ''))
|
|
79
|
+
.filter((entry) => entry.length > 0);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reads ONE policy layer from untrusted JSON (a cascade section, a stored snapshot, a config file).
|
|
83
|
+
* Every field is type-checked; anything that is not the right type is ignored rather than coerced.
|
|
84
|
+
*
|
|
85
|
+
* @param raw - the layer, as parsed JSON of unknown shape
|
|
86
|
+
*/
|
|
87
|
+
export function ReadIdentityVerificationPolicyLayer(raw) {
|
|
88
|
+
if (!isRecord(raw)) {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
const layer = {};
|
|
92
|
+
if (typeof raw['requireBusinessDomain'] === 'boolean') {
|
|
93
|
+
layer.requireBusinessDomain = raw['requireBusinessDomain'];
|
|
94
|
+
}
|
|
95
|
+
const blocked = readDomainList(raw['blockedDomains']);
|
|
96
|
+
if (blocked) {
|
|
97
|
+
layer.blockedDomains = blocked;
|
|
98
|
+
}
|
|
99
|
+
const consumer = readDomainList(raw['consumerDomains']);
|
|
100
|
+
if (consumer) {
|
|
101
|
+
layer.consumerDomains = consumer;
|
|
102
|
+
}
|
|
103
|
+
const ttl = readNumber(raw['linkTtlMinutes']);
|
|
104
|
+
if (ttl !== undefined) {
|
|
105
|
+
layer.linkTtlMinutes = ttl;
|
|
106
|
+
}
|
|
107
|
+
const sends = readNumber(raw['maxSendsPerSession']);
|
|
108
|
+
if (sends !== undefined) {
|
|
109
|
+
layer.maxSendsPerSession = sends;
|
|
110
|
+
}
|
|
111
|
+
const attempts = readNumber(raw['maxCodeAttempts']);
|
|
112
|
+
if (attempts !== undefined) {
|
|
113
|
+
layer.maxCodeAttempts = attempts;
|
|
114
|
+
}
|
|
115
|
+
const unverified = readSessionSeconds(raw['unverifiedMaxSeconds']);
|
|
116
|
+
if (unverified !== undefined) {
|
|
117
|
+
layer.unverifiedMaxSeconds = unverified;
|
|
118
|
+
}
|
|
119
|
+
const verified = readSessionSeconds(raw['verifiedMaxSeconds']);
|
|
120
|
+
if (verified !== undefined) {
|
|
121
|
+
layer.verifiedMaxSeconds = verified;
|
|
122
|
+
}
|
|
123
|
+
return layer;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extracts the session-scoped policy layer from a RESOLVED realtime configuration (the object the
|
|
127
|
+
* config cascade produced at mint).
|
|
128
|
+
*
|
|
129
|
+
* Reads, defensively and without depending on the cascade's TypeScript types (so this keeps working as
|
|
130
|
+
* the cascade gains fields):
|
|
131
|
+
*
|
|
132
|
+
* - `channels.config.IdentityVerification` — the verification channel's own knobs
|
|
133
|
+
* - `session.unverifiedMaxSeconds` / `session.verifiedMaxSeconds` — the duration caps
|
|
134
|
+
*
|
|
135
|
+
* Duration caps in the channel's own config are honoured too; the `session` section wins when both
|
|
136
|
+
* are present, because it is the dedicated, documented home for them.
|
|
137
|
+
*
|
|
138
|
+
* @param realtimeConfig - the effective `realtime` section (`EffectiveConfig.realtime`), or anything
|
|
139
|
+
* @returns the layer; `{}` when the cascade carries nothing relevant
|
|
140
|
+
*/
|
|
141
|
+
export function ExtractIdentityVerificationPolicyFromRealtimeConfig(realtimeConfig) {
|
|
142
|
+
if (!isRecord(realtimeConfig)) {
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
145
|
+
const channels = realtimeConfig['channels'];
|
|
146
|
+
const channelConfig = isRecord(channels) && isRecord(channels['config']) ? channels['config']['IdentityVerification'] : undefined;
|
|
147
|
+
const layer = ReadIdentityVerificationPolicyLayer(channelConfig);
|
|
148
|
+
const session = realtimeConfig['session'];
|
|
149
|
+
if (isRecord(session)) {
|
|
150
|
+
const unverified = readSessionSeconds(session['unverifiedMaxSeconds']);
|
|
151
|
+
if (unverified !== undefined) {
|
|
152
|
+
layer.unverifiedMaxSeconds = unverified;
|
|
153
|
+
}
|
|
154
|
+
const verified = readSessionSeconds(session['verifiedMaxSeconds']);
|
|
155
|
+
if (verified !== undefined) {
|
|
156
|
+
layer.verifiedMaxSeconds = verified;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return layer;
|
|
160
|
+
}
|
|
161
|
+
/** Clamps `value` into `[min, max]`, falling back to `fallback` when it is not a finite number. */
|
|
162
|
+
function clamp(value, min, max, fallback) {
|
|
163
|
+
return value === undefined ? fallback : Math.min(max, Math.max(min, Math.floor(value)));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Merges policy layers (later layers win per knob) into a fully-resolved policy, applying defaults
|
|
167
|
+
* and clamping every numeric knob into a safe range. An empty `consumerDomains` in a layer is treated
|
|
168
|
+
* as absent (it would silently turn `requireBusinessDomain` into a no-op).
|
|
169
|
+
*
|
|
170
|
+
* @param layers - lowest-precedence first; `undefined` entries are skipped
|
|
171
|
+
*/
|
|
172
|
+
export function ResolveIdentityVerificationPolicy(layers) {
|
|
173
|
+
const merged = {};
|
|
174
|
+
for (const layer of layers) {
|
|
175
|
+
if (!layer) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
for (const key of Object.keys(layer)) {
|
|
179
|
+
const value = layer[key];
|
|
180
|
+
if (value === undefined) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (key === 'consumerDomains' && Array.isArray(value) && value.length === 0) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
merged[key] = value;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
requireBusinessDomain: merged.requireBusinessDomain ?? false,
|
|
191
|
+
blockedDomains: merged.blockedDomains ?? [],
|
|
192
|
+
consumerDomains: merged.consumerDomains ?? [...DEFAULT_CONSUMER_EMAIL_DOMAINS],
|
|
193
|
+
linkTtlMinutes: clamp(merged.linkTtlMinutes, MIN_LINK_TTL_MINUTES, MAX_LINK_TTL_MINUTES, DEFAULT_LINK_TTL_MINUTES),
|
|
194
|
+
maxSendsPerSession: clamp(merged.maxSendsPerSession, MIN_MAX_SENDS, MAX_MAX_SENDS, DEFAULT_MAX_SENDS_PER_SESSION),
|
|
195
|
+
maxCodeAttempts: clamp(merged.maxCodeAttempts, MIN_MAX_ATTEMPTS, MAX_MAX_ATTEMPTS, DEFAULT_MAX_CODE_ATTEMPTS),
|
|
196
|
+
unverifiedMaxSeconds: merged.unverifiedMaxSeconds,
|
|
197
|
+
verifiedMaxSeconds: merged.verifiedMaxSeconds,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** True when `domain` equals `entry` or is a subdomain of it. */
|
|
201
|
+
function domainMatches(domain, entry) {
|
|
202
|
+
return domain === entry || domain.endsWith(`.${entry}`);
|
|
203
|
+
}
|
|
204
|
+
/** RFC-5321 maximum length of a forward-path. */
|
|
205
|
+
const MAX_EMAIL_LENGTH = 254;
|
|
206
|
+
/** A pragmatic address check: one `@`, a dotted domain of safe labels, no whitespace/control/angle characters. */
|
|
207
|
+
const EMAIL_PATTERN = /^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]{1,64}@(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$/;
|
|
208
|
+
/**
|
|
209
|
+
* Normalises and validates an email address (trim + lower-case). Deliberately conservative: it rejects
|
|
210
|
+
* anything with whitespace, control characters, quotes, angle brackets or a display-name form, because
|
|
211
|
+
* the address is about to be placed in a message header and a link context.
|
|
212
|
+
*
|
|
213
|
+
* @param raw - what the person typed
|
|
214
|
+
*/
|
|
215
|
+
export function ParseEmailAddress(raw) {
|
|
216
|
+
const email = (raw ?? '').trim().toLowerCase();
|
|
217
|
+
if (email.length === 0 || email.length > MAX_EMAIL_LENGTH || !EMAIL_PATTERN.test(email)) {
|
|
218
|
+
return { Ok: false };
|
|
219
|
+
}
|
|
220
|
+
return { Ok: true, Email: email, Domain: email.slice(email.lastIndexOf('@') + 1) };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Applies the domain rules of a policy to an address's domain: `blockedDomains` first (always wins),
|
|
224
|
+
* then — when `requireBusinessDomain` — the consumer-domain list.
|
|
225
|
+
*
|
|
226
|
+
* @param domain - lower-case domain of the (already parsed) address
|
|
227
|
+
*/
|
|
228
|
+
export function EvaluateEmailDomainPolicy(domain, policy) {
|
|
229
|
+
if (policy.blockedDomains.some((entry) => domainMatches(domain, entry))) {
|
|
230
|
+
return { Allowed: false, Reason: 'domain_blocked' };
|
|
231
|
+
}
|
|
232
|
+
if (policy.requireBusinessDomain && policy.consumerDomains.some((entry) => domainMatches(domain, entry))) {
|
|
233
|
+
return { Allowed: false, Reason: 'consumer_domain' };
|
|
234
|
+
}
|
|
235
|
+
return { Allowed: true };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Tightens a session deadline: returns the earlier of the existing deadline (ISO) and `candidateMs`,
|
|
239
|
+
* as an ISO string. Used at mint so a configured unverified cap never LOOSENS a deadline another rule
|
|
240
|
+
* (the widget voice cap) already set.
|
|
241
|
+
*
|
|
242
|
+
* @param existingIso - the deadline already stamped, if any
|
|
243
|
+
* @param candidateMs - the candidate deadline, epoch ms
|
|
244
|
+
*/
|
|
245
|
+
export function TightenSessionDeadline(existingIso, candidateMs) {
|
|
246
|
+
const existingMs = existingIso ? Date.parse(existingIso) : Number.NaN;
|
|
247
|
+
return new Date(Number.isNaN(existingMs) ? candidateMs : Math.min(existingMs, candidateMs)).toISOString();
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=verificationPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificationPolicy.js","sourceRoot":"","sources":["../../src/realtimeSessions/verificationPolicy.ts"],"names":[],"mappings":"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"}
|