@microsoft/agents-hosting 0.1.49
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 +57 -0
- package/dist/src/activityHandler.d.ts +108 -0
- package/dist/src/activityHandler.js +395 -0
- package/dist/src/activityHandler.js.map +1 -0
- package/dist/src/agent-client/agentClient.d.ts +13 -0
- package/dist/src/agent-client/agentClient.js +75 -0
- package/dist/src/agent-client/agentClient.js.map +1 -0
- package/dist/src/agent-client/expressApi.d.ts +4 -0
- package/dist/src/agent-client/expressApi.js +50 -0
- package/dist/src/agent-client/expressApi.js.map +1 -0
- package/dist/src/agent-client/index.d.ts +2 -0
- package/dist/src/agent-client/index.js +19 -0
- package/dist/src/agent-client/index.js.map +1 -0
- package/dist/src/app/agentApplication.d.ts +47 -0
- package/dist/src/app/agentApplication.js +317 -0
- package/dist/src/app/agentApplication.js.map +1 -0
- package/dist/src/app/appRoute.d.ts +11 -0
- package/dist/src/app/appRoute.js +7 -0
- package/dist/src/app/appRoute.js.map +1 -0
- package/dist/src/app/applicationBuilder.d.ts +18 -0
- package/dist/src/app/applicationBuilder.js +37 -0
- package/dist/src/app/applicationBuilder.js.map +1 -0
- package/dist/src/app/applicationOptions.d.ts +19 -0
- package/dist/src/app/applicationOptions.js +7 -0
- package/dist/src/app/applicationOptions.js.map +1 -0
- package/dist/src/app/attachmentDownloader.d.ts +13 -0
- package/dist/src/app/attachmentDownloader.js +72 -0
- package/dist/src/app/attachmentDownloader.js.map +1 -0
- package/dist/src/app/conversationUpdateEvents.d.ts +5 -0
- package/dist/src/app/conversationUpdateEvents.js +7 -0
- package/dist/src/app/conversationUpdateEvents.js.map +1 -0
- package/dist/src/app/index.d.ts +10 -0
- package/dist/src/app/index.js +27 -0
- package/dist/src/app/index.js.map +1 -0
- package/dist/src/app/inputFileDownloader.d.ts +14 -0
- package/dist/src/app/inputFileDownloader.js +7 -0
- package/dist/src/app/inputFileDownloader.js.map +1 -0
- package/dist/src/app/memory.d.ts +10 -0
- package/dist/src/app/memory.js +7 -0
- package/dist/src/app/memory.js.map +1 -0
- package/dist/src/app/oauth/authenticationOptions.d.ts +7 -0
- package/dist/src/app/oauth/authenticationOptions.js +7 -0
- package/dist/src/app/oauth/authenticationOptions.js.map +1 -0
- package/dist/src/app/oauth/webChatOAuthFlowAppStyle.d.ts +11 -0
- package/dist/src/app/oauth/webChatOAuthFlowAppStyle.js +85 -0
- package/dist/src/app/oauth/webChatOAuthFlowAppStyle.js.map +1 -0
- package/dist/src/app/routeHandler.d.ts +7 -0
- package/dist/src/app/routeHandler.js +7 -0
- package/dist/src/app/routeHandler.js.map +1 -0
- package/dist/src/app/routeSelector.d.ts +7 -0
- package/dist/src/app/routeSelector.js +7 -0
- package/dist/src/app/routeSelector.js.map +1 -0
- package/dist/src/app/turnEvents.d.ts +5 -0
- package/dist/src/app/turnEvents.js +7 -0
- package/dist/src/app/turnEvents.js.map +1 -0
- package/dist/src/app/turnState.d.ts +85 -0
- package/dist/src/app/turnState.js +274 -0
- package/dist/src/app/turnState.js.map +1 -0
- package/dist/src/app/turnStateEntry.d.ts +17 -0
- package/dist/src/app/turnStateEntry.js +39 -0
- package/dist/src/app/turnStateEntry.js.map +1 -0
- package/dist/src/auth/authConfiguration.d.ts +29 -0
- package/dist/src/auth/authConfiguration.js +58 -0
- package/dist/src/auth/authConfiguration.js.map +1 -0
- package/dist/src/auth/authProvider.d.ts +17 -0
- package/dist/src/auth/authProvider.js +7 -0
- package/dist/src/auth/authProvider.js.map +1 -0
- package/dist/src/auth/index.d.ts +4 -0
- package/dist/src/auth/index.js +21 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/jwt-middleware.d.ts +13 -0
- package/dist/src/auth/jwt-middleware.js +97 -0
- package/dist/src/auth/jwt-middleware.js.map +1 -0
- package/dist/src/auth/msalTokenProvider.d.ts +53 -0
- package/dist/src/auth/msalTokenProvider.js +198 -0
- package/dist/src/auth/msalTokenProvider.js.map +1 -0
- package/dist/src/auth/request.d.ts +15 -0
- package/dist/src/auth/request.js +7 -0
- package/dist/src/auth/request.js.map +1 -0
- package/dist/src/baseAdapter.d.ts +88 -0
- package/dist/src/baseAdapter.js +94 -0
- package/dist/src/baseAdapter.js.map +1 -0
- package/dist/src/cards/animationCard.d.ts +36 -0
- package/dist/src/cards/animationCard.js +7 -0
- package/dist/src/cards/animationCard.js.map +1 -0
- package/dist/src/cards/audioCard.d.ts +36 -0
- package/dist/src/cards/audioCard.js +7 -0
- package/dist/src/cards/audioCard.js.map +1 -0
- package/dist/src/cards/cardFactory.d.ts +123 -0
- package/dist/src/cards/cardFactory.js +225 -0
- package/dist/src/cards/cardFactory.js.map +1 -0
- package/dist/src/cards/cardImage.d.ts +16 -0
- package/dist/src/cards/cardImage.js +7 -0
- package/dist/src/cards/cardImage.js.map +1 -0
- package/dist/src/cards/fact.d.ts +13 -0
- package/dist/src/cards/fact.js +7 -0
- package/dist/src/cards/fact.js.map +1 -0
- package/dist/src/cards/heroCard.d.ts +23 -0
- package/dist/src/cards/heroCard.js +7 -0
- package/dist/src/cards/heroCard.js.map +1 -0
- package/dist/src/cards/index.d.ts +17 -0
- package/dist/src/cards/index.js +34 -0
- package/dist/src/cards/index.js.map +1 -0
- package/dist/src/cards/mediaUrl.d.ts +17 -0
- package/dist/src/cards/mediaUrl.js +7 -0
- package/dist/src/cards/mediaUrl.js.map +1 -0
- package/dist/src/cards/o365ConnectorCard.d.ts +35 -0
- package/dist/src/cards/o365ConnectorCard.js +7 -0
- package/dist/src/cards/o365ConnectorCard.js.map +1 -0
- package/dist/src/cards/o365ConnectorCardActionBase.d.ts +22 -0
- package/dist/src/cards/o365ConnectorCardActionBase.js +7 -0
- package/dist/src/cards/o365ConnectorCardActionBase.js.map +1 -0
- package/dist/src/cards/o365ConnectorCardFact.d.ts +17 -0
- package/dist/src/cards/o365ConnectorCardFact.js +7 -0
- package/dist/src/cards/o365ConnectorCardFact.js.map +1 -0
- package/dist/src/cards/o365ConnectorCardImage.d.ts +17 -0
- package/dist/src/cards/o365ConnectorCardImage.js +7 -0
- package/dist/src/cards/o365ConnectorCardImage.js.map +1 -0
- package/dist/src/cards/o365ConnectorCardSection.d.ts +57 -0
- package/dist/src/cards/o365ConnectorCardSection.js +7 -0
- package/dist/src/cards/o365ConnectorCardSection.js.map +1 -0
- package/dist/src/cards/receiptCard.d.ts +44 -0
- package/dist/src/cards/receiptCard.js +7 -0
- package/dist/src/cards/receiptCard.js.map +1 -0
- package/dist/src/cards/receiptItem.d.ts +39 -0
- package/dist/src/cards/receiptItem.js +7 -0
- package/dist/src/cards/receiptItem.js.map +1 -0
- package/dist/src/cards/signinCard.d.ts +14 -0
- package/dist/src/cards/signinCard.js +5 -0
- package/dist/src/cards/signinCard.js.map +1 -0
- package/dist/src/cards/taskModuleAction.d.ts +43 -0
- package/dist/src/cards/taskModuleAction.js +30 -0
- package/dist/src/cards/taskModuleAction.js.map +1 -0
- package/dist/src/cards/thumbnailCard.d.ts +35 -0
- package/dist/src/cards/thumbnailCard.js +7 -0
- package/dist/src/cards/thumbnailCard.js.map +1 -0
- package/dist/src/cards/thumbnailUrl.d.ts +17 -0
- package/dist/src/cards/thumbnailUrl.js +7 -0
- package/dist/src/cards/thumbnailUrl.js.map +1 -0
- package/dist/src/cards/videoCard.d.ts +60 -0
- package/dist/src/cards/videoCard.js +7 -0
- package/dist/src/cards/videoCard.js.map +1 -0
- package/dist/src/claimsIdentity.d.ts +35 -0
- package/dist/src/claimsIdentity.js +43 -0
- package/dist/src/claimsIdentity.js.map +1 -0
- package/dist/src/cloudAdapter.d.ts +128 -0
- package/dist/src/cloudAdapter.js +376 -0
- package/dist/src/cloudAdapter.js.map +1 -0
- package/dist/src/connector-client/attachmentData.d.ts +25 -0
- package/dist/src/connector-client/attachmentData.js +7 -0
- package/dist/src/connector-client/attachmentData.js.map +1 -0
- package/dist/src/connector-client/attachmentInfo.d.ts +22 -0
- package/dist/src/connector-client/attachmentInfo.js +7 -0
- package/dist/src/connector-client/attachmentInfo.js.map +1 -0
- package/dist/src/connector-client/attachmentView.d.ts +17 -0
- package/dist/src/connector-client/attachmentView.js +7 -0
- package/dist/src/connector-client/attachmentView.js.map +1 -0
- package/dist/src/connector-client/connectorClient.d.ts +93 -0
- package/dist/src/connector-client/connectorClient.js +249 -0
- package/dist/src/connector-client/connectorClient.js.map +1 -0
- package/dist/src/connector-client/conversationMembers.d.ts +18 -0
- package/dist/src/connector-client/conversationMembers.js +7 -0
- package/dist/src/connector-client/conversationMembers.js.map +1 -0
- package/dist/src/connector-client/conversationParameters.d.ts +38 -0
- package/dist/src/connector-client/conversationParameters.js +7 -0
- package/dist/src/connector-client/conversationParameters.js.map +1 -0
- package/dist/src/connector-client/conversationResourceResponse.d.ts +21 -0
- package/dist/src/connector-client/conversationResourceResponse.js +7 -0
- package/dist/src/connector-client/conversationResourceResponse.js.map +1 -0
- package/dist/src/connector-client/conversationsResult.d.ts +18 -0
- package/dist/src/connector-client/conversationsResult.js +7 -0
- package/dist/src/connector-client/conversationsResult.js.map +1 -0
- package/dist/src/connector-client/index.d.ts +9 -0
- package/dist/src/connector-client/index.js +26 -0
- package/dist/src/connector-client/index.js.map +1 -0
- package/dist/src/connector-client/resourceResponse.d.ts +13 -0
- package/dist/src/connector-client/resourceResponse.js +7 -0
- package/dist/src/connector-client/resourceResponse.js.map +1 -0
- package/dist/src/index.d.ts +26 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/invoke/adaptiveCardAuthentication.d.ts +10 -0
- package/dist/src/invoke/adaptiveCardAuthentication.js +7 -0
- package/dist/src/invoke/adaptiveCardAuthentication.js.map +1 -0
- package/dist/src/invoke/adaptiveCardInvokeResponse.d.ts +21 -0
- package/dist/src/invoke/adaptiveCardInvokeResponse.js +7 -0
- package/dist/src/invoke/adaptiveCardInvokeResponse.js.map +1 -0
- package/dist/src/invoke/adaptiveCardInvokeValue.d.ts +23 -0
- package/dist/src/invoke/adaptiveCardInvokeValue.js +7 -0
- package/dist/src/invoke/adaptiveCardInvokeValue.js.map +1 -0
- package/dist/src/invoke/index.d.ts +9 -0
- package/dist/src/invoke/index.js +26 -0
- package/dist/src/invoke/index.js.map +1 -0
- package/dist/src/invoke/invokeException.d.ts +24 -0
- package/dist/src/invoke/invokeException.js +35 -0
- package/dist/src/invoke/invokeException.js.map +1 -0
- package/dist/src/invoke/invokeResponse.d.ts +17 -0
- package/dist/src/invoke/invokeResponse.js +7 -0
- package/dist/src/invoke/invokeResponse.js.map +1 -0
- package/dist/src/invoke/searchInvokeOptions.d.ts +17 -0
- package/dist/src/invoke/searchInvokeOptions.js +7 -0
- package/dist/src/invoke/searchInvokeOptions.js.map +1 -0
- package/dist/src/invoke/searchInvokeResponse.d.ts +10 -0
- package/dist/src/invoke/searchInvokeResponse.js +7 -0
- package/dist/src/invoke/searchInvokeResponse.js.map +1 -0
- package/dist/src/invoke/searchInvokeValue.d.ts +26 -0
- package/dist/src/invoke/searchInvokeValue.js +7 -0
- package/dist/src/invoke/searchInvokeValue.js.map +1 -0
- package/dist/src/invoke/tokenExchangeInvokeRequest.d.ts +21 -0
- package/dist/src/invoke/tokenExchangeInvokeRequest.js +7 -0
- package/dist/src/invoke/tokenExchangeInvokeRequest.js.map +1 -0
- package/dist/src/logger.d.ts +12 -0
- package/dist/src/logger.js +42 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/messageFactory.d.ts +62 -0
- package/dist/src/messageFactory.js +143 -0
- package/dist/src/messageFactory.js.map +1 -0
- package/dist/src/middlewareSet.d.ts +43 -0
- package/dist/src/middlewareSet.js +57 -0
- package/dist/src/middlewareSet.js.map +1 -0
- package/dist/src/oauth/index.d.ts +7 -0
- package/dist/src/oauth/index.js +24 -0
- package/dist/src/oauth/index.js.map +1 -0
- package/dist/src/oauth/oauthCard.d.ts +28 -0
- package/dist/src/oauth/oauthCard.js +5 -0
- package/dist/src/oauth/oauthCard.js.map +1 -0
- package/dist/src/oauth/signingResource.d.ts +19 -0
- package/dist/src/oauth/signingResource.js +5 -0
- package/dist/src/oauth/signingResource.js.map +1 -0
- package/dist/src/oauth/tokenExchangeRequest.d.ts +17 -0
- package/dist/src/oauth/tokenExchangeRequest.js +5 -0
- package/dist/src/oauth/tokenExchangeRequest.js.map +1 -0
- package/dist/src/oauth/tokenExchangeResource.d.ts +17 -0
- package/dist/src/oauth/tokenExchangeResource.js +5 -0
- package/dist/src/oauth/tokenExchangeResource.js.map +1 -0
- package/dist/src/oauth/tokenPostResource.d.ts +9 -0
- package/dist/src/oauth/tokenPostResource.js +5 -0
- package/dist/src/oauth/tokenPostResource.js.map +1 -0
- package/dist/src/oauth/userTokenClient.d.ts +49 -0
- package/dist/src/oauth/userTokenClient.js +117 -0
- package/dist/src/oauth/userTokenClient.js.map +1 -0
- package/dist/src/oauth/webChatOAuthFlow.d.ts +41 -0
- package/dist/src/oauth/webChatOAuthFlow.js +117 -0
- package/dist/src/oauth/webChatOAuthFlow.js.map +1 -0
- package/dist/src/state/agentState.d.ts +71 -0
- package/dist/src/state/agentState.js +122 -0
- package/dist/src/state/agentState.js.map +1 -0
- package/dist/src/state/agentStatePropertyAccesor.d.ts +39 -0
- package/dist/src/state/agentStatePropertyAccesor.js +60 -0
- package/dist/src/state/agentStatePropertyAccesor.js.map +1 -0
- package/dist/src/state/conversationState.d.ts +18 -0
- package/dist/src/state/conversationState.js +38 -0
- package/dist/src/state/conversationState.js.map +1 -0
- package/dist/src/state/index.d.ts +4 -0
- package/dist/src/state/index.js +21 -0
- package/dist/src/state/index.js.map +1 -0
- package/dist/src/state/userState.d.ts +18 -0
- package/dist/src/state/userState.js +38 -0
- package/dist/src/state/userState.js.map +1 -0
- package/dist/src/statusCodes.d.ts +19 -0
- package/dist/src/statusCodes.js +24 -0
- package/dist/src/statusCodes.js.map +1 -0
- package/dist/src/storage/index.d.ts +2 -0
- package/dist/src/storage/index.js +19 -0
- package/dist/src/storage/index.js.map +1 -0
- package/dist/src/storage/memoryStorage.d.ts +50 -0
- package/dist/src/storage/memoryStorage.js +100 -0
- package/dist/src/storage/memoryStorage.js.map +1 -0
- package/dist/src/storage/storage.d.ts +47 -0
- package/dist/src/storage/storage.js +7 -0
- package/dist/src/storage/storage.js.map +1 -0
- package/dist/src/tokenResponseEventName.d.ts +5 -0
- package/dist/src/tokenResponseEventName.js +9 -0
- package/dist/src/tokenResponseEventName.js.map +1 -0
- package/dist/src/transcript/consoleTranscriptLogger.d.ts +13 -0
- package/dist/src/transcript/consoleTranscriptLogger.js +21 -0
- package/dist/src/transcript/consoleTranscriptLogger.js.map +1 -0
- package/dist/src/transcript/index.d.ts +4 -0
- package/dist/src/transcript/index.js +21 -0
- package/dist/src/transcript/index.js.map +1 -0
- package/dist/src/transcript/transcriptLogger.d.ts +42 -0
- package/dist/src/transcript/transcriptLogger.js +3 -0
- package/dist/src/transcript/transcriptLogger.js.map +1 -0
- package/dist/src/transcript/transcriptLoggerMiddleware.d.ts +38 -0
- package/dist/src/transcript/transcriptLoggerMiddleware.js +126 -0
- package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -0
- package/dist/src/transcript/transcriptStore.d.ts +30 -0
- package/dist/src/transcript/transcriptStore.js +3 -0
- package/dist/src/transcript/transcriptStore.js.map +1 -0
- package/dist/src/turnContext.d.ts +160 -0
- package/dist/src/turnContext.js +286 -0
- package/dist/src/turnContext.js.map +1 -0
- package/dist/src/turnContextStateCollection.d.ts +29 -0
- package/dist/src/turnContextStateCollection.js +56 -0
- package/dist/src/turnContextStateCollection.js.map +1 -0
- package/package.json +48 -0
- package/src/activityHandler.ts +461 -0
- package/src/agent-client/agentClient.ts +84 -0
- package/src/agent-client/expressApi.ts +59 -0
- package/src/agent-client/index.ts +2 -0
- package/src/app/agentApplication.ts +401 -0
- package/src/app/appRoute.ts +13 -0
- package/src/app/applicationBuilder.ts +42 -0
- package/src/app/applicationOptions.ts +21 -0
- package/src/app/attachmentDownloader.ts +83 -0
- package/src/app/conversationUpdateEvents.ts +8 -0
- package/src/app/index.ts +10 -0
- package/src/app/inputFileDownloader.ts +17 -0
- package/src/app/memory.ts +14 -0
- package/src/app/oauth/authenticationOptions.ts +8 -0
- package/src/app/oauth/webChatOAuthFlowAppStyle.ts +90 -0
- package/src/app/routeHandler.ts +9 -0
- package/src/app/routeSelector.ts +10 -0
- package/src/app/turnEvents.ts +6 -0
- package/src/app/turnState.ts +338 -0
- package/src/app/turnStateEntry.ts +46 -0
- package/src/auth/authConfiguration.ts +68 -0
- package/src/auth/authProvider.ts +19 -0
- package/src/auth/index.ts +4 -0
- package/src/auth/jwt-middleware.ts +99 -0
- package/src/auth/msalTokenProvider.ts +202 -0
- package/src/auth/request.ts +20 -0
- package/src/baseAdapter.ts +174 -0
- package/src/cards/animationCard.ts +38 -0
- package/src/cards/audioCard.ts +38 -0
- package/src/cards/cardFactory.ts +276 -0
- package/src/cards/cardImage.ts +18 -0
- package/src/cards/fact.ts +14 -0
- package/src/cards/heroCard.ts +25 -0
- package/src/cards/index.ts +17 -0
- package/src/cards/mediaUrl.ts +18 -0
- package/src/cards/o365ConnectorCard.ts +37 -0
- package/src/cards/o365ConnectorCardActionBase.ts +24 -0
- package/src/cards/o365ConnectorCardFact.ts +18 -0
- package/src/cards/o365ConnectorCardImage.ts +18 -0
- package/src/cards/o365ConnectorCardSection.ts +60 -0
- package/src/cards/receiptCard.ts +46 -0
- package/src/cards/receiptItem.ts +41 -0
- package/src/cards/signinCard.ts +18 -0
- package/src/cards/taskModuleAction.ts +61 -0
- package/src/cards/thumbnailCard.ts +37 -0
- package/src/cards/thumbnailUrl.ts +18 -0
- package/src/cards/videoCard.ts +62 -0
- package/src/claimsIdentity.ts +47 -0
- package/src/cloudAdapter.ts +431 -0
- package/src/connector-client/attachmentData.ts +26 -0
- package/src/connector-client/attachmentInfo.ts +24 -0
- package/src/connector-client/attachmentView.ts +18 -0
- package/src/connector-client/connectorClient.ts +295 -0
- package/src/connector-client/conversationMembers.ts +20 -0
- package/src/connector-client/conversationParameters.ts +40 -0
- package/src/connector-client/conversationResourceResponse.ts +22 -0
- package/src/connector-client/conversationsResult.ts +20 -0
- package/src/connector-client/index.ts +9 -0
- package/src/connector-client/resourceResponse.ts +14 -0
- package/src/index.ts +31 -0
- package/src/invoke/adaptiveCardAuthentication.ts +13 -0
- package/src/invoke/adaptiveCardInvokeResponse.ts +22 -0
- package/src/invoke/adaptiveCardInvokeValue.ts +25 -0
- package/src/invoke/index.ts +9 -0
- package/src/invoke/invokeException.ts +33 -0
- package/src/invoke/invokeResponse.ts +18 -0
- package/src/invoke/searchInvokeOptions.ts +18 -0
- package/src/invoke/searchInvokeResponse.ts +11 -0
- package/src/invoke/searchInvokeValue.ts +28 -0
- package/src/invoke/tokenExchangeInvokeRequest.ts +22 -0
- package/src/logger.ts +43 -0
- package/src/messageFactory.ts +177 -0
- package/src/middlewareSet.ts +76 -0
- package/src/oauth/index.ts +7 -0
- package/src/oauth/oauthCard.ts +32 -0
- package/src/oauth/signingResource.ts +23 -0
- package/src/oauth/tokenExchangeRequest.ts +20 -0
- package/src/oauth/tokenExchangeResource.ts +20 -0
- package/src/oauth/tokenPostResource.ts +12 -0
- package/src/oauth/userTokenClient.ts +116 -0
- package/src/oauth/webChatOAuthFlow.ts +123 -0
- package/src/state/agentState.ts +142 -0
- package/src/state/agentStatePropertyAccesor.ts +61 -0
- package/src/state/conversationState.ts +42 -0
- package/src/state/index.ts +4 -0
- package/src/state/userState.ts +43 -0
- package/src/statusCodes.ts +20 -0
- package/src/storage/index.ts +2 -0
- package/src/storage/memoryStorage.ts +105 -0
- package/src/storage/storage.ts +52 -0
- package/src/tokenResponseEventName.ts +6 -0
- package/src/transcript/consoleTranscriptLogger.ts +20 -0
- package/src/transcript/index.ts +4 -0
- package/src/transcript/transcriptLogger.ts +45 -0
- package/src/transcript/transcriptLoggerMiddleware.ts +151 -0
- package/src/transcript/transcriptStore.ts +38 -0
- package/src/turnContext.ts +335 -0
- package/src/turnContextStateCollection.ts +69 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import { Attachment } from '@microsoft/agents-activity'
|
|
5
|
+
import { UserTokenClient } from '../../oauth/userTokenClient'
|
|
6
|
+
import { CloudAdapter } from '../../cloudAdapter'
|
|
7
|
+
import { CardFactory } from '../../cards/cardFactory'
|
|
8
|
+
import { TurnContext } from '../../turnContext'
|
|
9
|
+
import { MessageFactory } from '../../messageFactory'
|
|
10
|
+
import { debug } from '../../logger'
|
|
11
|
+
import { TurnState } from '../turnState'
|
|
12
|
+
import { Storage } from '../../storage'
|
|
13
|
+
|
|
14
|
+
const logger = debug('agents:web-chat-oauth-flow')
|
|
15
|
+
|
|
16
|
+
export class WebChatOAuthFlowAppStyle {
|
|
17
|
+
userTokenClient?: UserTokenClient
|
|
18
|
+
storage: Storage
|
|
19
|
+
|
|
20
|
+
constructor (storage: Storage) {
|
|
21
|
+
this.storage = storage
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async getOAuthToken (context: TurnContext, state: TurnState) : Promise<string> {
|
|
25
|
+
if (Object.keys(state.sso).length === 0) {
|
|
26
|
+
state.sso.flowStarted = false
|
|
27
|
+
state.sso.userToken = ''
|
|
28
|
+
state.sso.flowExpires = 0
|
|
29
|
+
await state.save(context)
|
|
30
|
+
}
|
|
31
|
+
if (state.sso!.userToken !== '') {
|
|
32
|
+
return state.sso.userToken
|
|
33
|
+
}
|
|
34
|
+
if (state.sso?.flowExpires !== 0 && Date.now() > state.sso.flowExpires) {
|
|
35
|
+
logger.warn('Sign-in flow expired')
|
|
36
|
+
state.sso.flowStarted = false
|
|
37
|
+
state.sso.userToken = ''
|
|
38
|
+
await context.sendActivity(MessageFactory.text('Sign-in session expired. Please try again.'))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let retVal: string = ''
|
|
42
|
+
const authConfig = context.adapter.authConfig
|
|
43
|
+
if (authConfig.connectionName === undefined) {
|
|
44
|
+
throw new Error('connectionName is not set in the auth config, review your environment variables')
|
|
45
|
+
}
|
|
46
|
+
const adapter = context.adapter as CloudAdapter
|
|
47
|
+
const scope = 'https://api.botframework.com'
|
|
48
|
+
const accessToken = await adapter.authProvider.getAccessToken(authConfig, scope)
|
|
49
|
+
this.userTokenClient = new UserTokenClient(accessToken)
|
|
50
|
+
|
|
51
|
+
if (state.sso!.flowStarted === true) {
|
|
52
|
+
const userToken = await this.userTokenClient.getUserToken(authConfig.connectionName!, context.activity.channelId!, context.activity.from?.id!)
|
|
53
|
+
if (userToken !== null) {
|
|
54
|
+
logger.info('Token obtained')
|
|
55
|
+
state.sso.userToken = userToken.token
|
|
56
|
+
state.sso.flowStarted = false
|
|
57
|
+
} else {
|
|
58
|
+
const code = context.activity.text as string
|
|
59
|
+
const userToken = await this.userTokenClient!.getUserToken(authConfig.connectionName!, context.activity.channelId!, context.activity.from?.id!, code)
|
|
60
|
+
if (userToken !== null) {
|
|
61
|
+
logger.info('Token obtained with code')
|
|
62
|
+
state.sso.userToken = userToken.token
|
|
63
|
+
state.sso.flowStarted = false
|
|
64
|
+
} else {
|
|
65
|
+
logger.error('Sign in failed')
|
|
66
|
+
await context.sendActivity(MessageFactory.text('Sign in failed'))
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
retVal = state.sso.userToken
|
|
70
|
+
} else if (state.sso!.flowStarted === false) {
|
|
71
|
+
const signingResource = await this.userTokenClient.getSignInResource(authConfig.clientId!, authConfig.connectionName!, context.activity)
|
|
72
|
+
const oCard: Attachment = CardFactory.oauthCard(authConfig.connectionName!, 'Sign in', '', signingResource)
|
|
73
|
+
await context.sendActivity(MessageFactory.attachment(oCard))
|
|
74
|
+
state.sso!.flowStarted = true
|
|
75
|
+
state.sso.flowExpires = Date.now() + 30000
|
|
76
|
+
logger.info('OAuth flow started')
|
|
77
|
+
}
|
|
78
|
+
state.save(context)
|
|
79
|
+
return retVal
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async signOut (context: TurnContext, state: TurnState) {
|
|
83
|
+
await this.userTokenClient!.signOut(context.activity.from?.id!, context.adapter.authConfig.connectionName!, context.activity.channelId!)
|
|
84
|
+
state.sso!.flowStarted = false
|
|
85
|
+
state.sso!.userToken = ''
|
|
86
|
+
state.sso!.flowExpires = 0
|
|
87
|
+
state.save(context)
|
|
88
|
+
logger.info('User signed out successfully')
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TurnContext } from '../turnContext'
|
|
7
|
+
import { TurnState } from './turnState'
|
|
8
|
+
|
|
9
|
+
export type RouteHandler<TState extends TurnState> = (context: TurnContext, state: TState) => Promise<void>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TurnContext } from '../turnContext'
|
|
7
|
+
|
|
8
|
+
export type Selector = (context: TurnContext) => Promise<boolean>
|
|
9
|
+
|
|
10
|
+
export type RouteSelector = Selector
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Storage, StoreItems } from '../storage'
|
|
7
|
+
import { Memory } from './memory'
|
|
8
|
+
import { InputFile } from './inputFileDownloader'
|
|
9
|
+
import { TurnStateEntry } from './turnStateEntry'
|
|
10
|
+
import { TurnContext } from '../turnContext'
|
|
11
|
+
import { debug } from '../logger'
|
|
12
|
+
|
|
13
|
+
const logger = debug('agents:turnState')
|
|
14
|
+
|
|
15
|
+
const CONVERSATION_SCOPE = 'conversation'
|
|
16
|
+
|
|
17
|
+
const USER_SCOPE = 'user'
|
|
18
|
+
|
|
19
|
+
const TEMP_SCOPE = 'temp'
|
|
20
|
+
|
|
21
|
+
const SSO_SCOPE = 'sso'
|
|
22
|
+
|
|
23
|
+
export interface DefaultConversationState {}
|
|
24
|
+
|
|
25
|
+
export interface DefaultUserState {}
|
|
26
|
+
export interface DefaultTempState {
|
|
27
|
+
input: string;
|
|
28
|
+
inputFiles: InputFile[];
|
|
29
|
+
lastOutput: string;
|
|
30
|
+
actionOutputs: Record<string, string>;
|
|
31
|
+
authTokens: { [key: string]: string };
|
|
32
|
+
duplicateTokenExchange?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface DefaultSSOState {
|
|
36
|
+
flowStarted: boolean;
|
|
37
|
+
userToken: string;
|
|
38
|
+
flowExpires: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Base class defining a collection of turn state scopes.
|
|
43
|
+
* @remarks
|
|
44
|
+
* Developers can create a derived class that extends `TurnState` to add additional state scopes.
|
|
45
|
+
* ```JavaScript
|
|
46
|
+
* class MyTurnState extends TurnState {
|
|
47
|
+
* protected async onComputeStorageKeys(context) {
|
|
48
|
+
* const keys = await super.onComputeStorageKeys(context);
|
|
49
|
+
* keys['myScope'] = `myScopeKey`;
|
|
50
|
+
* return keys;
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* public get myScope() {
|
|
54
|
+
* const scope = this.getScope('myScope');
|
|
55
|
+
* if (!scope) {
|
|
56
|
+
* throw new Error(`MyTurnState hasn't been loaded. Call load() first.`);
|
|
57
|
+
* }
|
|
58
|
+
* return scope.value;
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* public set myScope(value) {
|
|
62
|
+
* const scope = this.getScope('myScope');
|
|
63
|
+
* if (!scope) {
|
|
64
|
+
* throw new Error(`MyTurnState hasn't been loaded. Call load() first.`);
|
|
65
|
+
* }
|
|
66
|
+
* scope.replace(value);
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
export class TurnState<
|
|
73
|
+
TConversationState = DefaultConversationState,
|
|
74
|
+
TUserState = DefaultUserState,
|
|
75
|
+
TTempState = DefaultTempState,
|
|
76
|
+
TSSOState = DefaultSSOState
|
|
77
|
+
> implements Memory {
|
|
78
|
+
private _scopes: Record<string, TurnStateEntry> = {}
|
|
79
|
+
private _isLoaded = false
|
|
80
|
+
private _loadingPromise?: Promise<boolean>
|
|
81
|
+
private _stateNotLoadedString = 'TurnState hasn\'t been loaded. Call load() first.'
|
|
82
|
+
|
|
83
|
+
public get conversation (): TConversationState {
|
|
84
|
+
const scope = this.getScope(CONVERSATION_SCOPE)
|
|
85
|
+
if (!scope) {
|
|
86
|
+
throw new Error(this._stateNotLoadedString)
|
|
87
|
+
}
|
|
88
|
+
return scope.value as TConversationState
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public set conversation (value: TConversationState) {
|
|
92
|
+
const scope = this.getScope(CONVERSATION_SCOPE)
|
|
93
|
+
if (!scope) {
|
|
94
|
+
throw new Error(this._stateNotLoadedString)
|
|
95
|
+
}
|
|
96
|
+
scope.replace(value as Record<string, unknown>)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public get isLoaded (): boolean {
|
|
100
|
+
return this._isLoaded
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public get temp (): TTempState {
|
|
104
|
+
const scope = this.getScope(TEMP_SCOPE)
|
|
105
|
+
if (!scope) {
|
|
106
|
+
throw new Error(this._stateNotLoadedString)
|
|
107
|
+
}
|
|
108
|
+
return scope.value as TTempState
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public set temp (value: TTempState) {
|
|
112
|
+
const scope = this.getScope(TEMP_SCOPE)
|
|
113
|
+
if (!scope) {
|
|
114
|
+
throw new Error(this._stateNotLoadedString)
|
|
115
|
+
}
|
|
116
|
+
scope.replace(value as Record<string, unknown>)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public get user (): TUserState {
|
|
120
|
+
const scope = this.getScope(USER_SCOPE)
|
|
121
|
+
if (!scope) {
|
|
122
|
+
throw new Error(this._stateNotLoadedString)
|
|
123
|
+
}
|
|
124
|
+
return scope.value as TUserState
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public set user (value: TUserState) {
|
|
128
|
+
const scope = this.getScope(USER_SCOPE)
|
|
129
|
+
if (!scope) {
|
|
130
|
+
throw new Error(this._stateNotLoadedString)
|
|
131
|
+
}
|
|
132
|
+
scope.replace(value as Record<string, unknown>)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public get sso (): TSSOState {
|
|
136
|
+
const scope = this.getScope(SSO_SCOPE)
|
|
137
|
+
if (!scope) {
|
|
138
|
+
throw new Error(this._stateNotLoadedString)
|
|
139
|
+
}
|
|
140
|
+
return scope.value as TSSOState
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public set sso (value: TSSOState) {
|
|
144
|
+
const scope = this.getScope(SSO_SCOPE)
|
|
145
|
+
if (!scope) {
|
|
146
|
+
throw new Error(this._stateNotLoadedString)
|
|
147
|
+
}
|
|
148
|
+
scope.replace(value as Record<string, unknown>)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public deleteConversationState (): void {
|
|
152
|
+
const scope = this.getScope(CONVERSATION_SCOPE)
|
|
153
|
+
if (!scope) {
|
|
154
|
+
throw new Error(this._stateNotLoadedString)
|
|
155
|
+
}
|
|
156
|
+
scope.delete()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public deleteTempState (): void {
|
|
160
|
+
const scope = this.getScope(TEMP_SCOPE)
|
|
161
|
+
if (!scope) {
|
|
162
|
+
throw new Error(this._stateNotLoadedString)
|
|
163
|
+
}
|
|
164
|
+
scope.delete()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public deleteUserState (): void {
|
|
168
|
+
const scope = this.getScope(USER_SCOPE)
|
|
169
|
+
if (!scope) {
|
|
170
|
+
throw new Error(this._stateNotLoadedString)
|
|
171
|
+
}
|
|
172
|
+
scope.delete()
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public getScope (scope: string): TurnStateEntry | undefined {
|
|
176
|
+
return this._scopes[scope]
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public deleteValue (path: string): void {
|
|
180
|
+
const { scope, name } = this.getScopeAndName(path)
|
|
181
|
+
if (Object.prototype.hasOwnProperty.call(scope.value, name)) {
|
|
182
|
+
delete scope.value[name]
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public hasValue (path: string): boolean {
|
|
187
|
+
const { scope, name } = this.getScopeAndName(path)
|
|
188
|
+
return Object.prototype.hasOwnProperty.call(scope.value, name)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public getValue<TValue = unknown>(path: string): TValue {
|
|
192
|
+
const { scope, name } = this.getScopeAndName(path)
|
|
193
|
+
return scope.value[name] as TValue
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public setValue (path: string, value: unknown): void {
|
|
197
|
+
const { scope, name } = this.getScopeAndName(path)
|
|
198
|
+
scope.value[name] = value
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public load (context: TurnContext, storage?: Storage): Promise<boolean> {
|
|
202
|
+
if (this._isLoaded) {
|
|
203
|
+
return Promise.resolve(false)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!this._loadingPromise) {
|
|
207
|
+
this._loadingPromise = new Promise<boolean>((resolve, reject) => {
|
|
208
|
+
this._isLoaded = true
|
|
209
|
+
|
|
210
|
+
const keys: string[] = []
|
|
211
|
+
this.onComputeStorageKeys(context)
|
|
212
|
+
.then(async (scopes) => {
|
|
213
|
+
for (const key in scopes) {
|
|
214
|
+
if (Object.prototype.hasOwnProperty.call(scopes, key)) {
|
|
215
|
+
keys.push(scopes[key])
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const items = storage ? await storage.read(keys) : {}
|
|
220
|
+
|
|
221
|
+
for (const key in scopes) {
|
|
222
|
+
if (Object.prototype.hasOwnProperty.call(scopes, key)) {
|
|
223
|
+
const storageKey = scopes[key]
|
|
224
|
+
const value = items[storageKey]
|
|
225
|
+
this._scopes[key] = new TurnStateEntry(value, storageKey)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
this._scopes[TEMP_SCOPE] = new TurnStateEntry({})
|
|
230
|
+
this._isLoaded = true
|
|
231
|
+
this._loadingPromise = undefined
|
|
232
|
+
resolve(true)
|
|
233
|
+
})
|
|
234
|
+
.catch((err) => {
|
|
235
|
+
logger.error(err)
|
|
236
|
+
this._loadingPromise = undefined
|
|
237
|
+
reject(err)
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return this._loadingPromise
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public async save (context: TurnContext, storage?: Storage): Promise<void> {
|
|
246
|
+
if (!this._isLoaded && this._loadingPromise) {
|
|
247
|
+
await this._loadingPromise
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!this._isLoaded) {
|
|
251
|
+
throw new Error(this._stateNotLoadedString)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let changes: StoreItems | undefined
|
|
255
|
+
let deletions: string[] | undefined
|
|
256
|
+
for (const key in this._scopes) {
|
|
257
|
+
if (!Object.prototype.hasOwnProperty.call(this._scopes, key)) {
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
260
|
+
const entry = this._scopes[key]
|
|
261
|
+
if (entry.storageKey) {
|
|
262
|
+
if (entry.isDeleted) {
|
|
263
|
+
if (deletions) {
|
|
264
|
+
deletions.push(entry.storageKey)
|
|
265
|
+
} else {
|
|
266
|
+
deletions = [entry.storageKey]
|
|
267
|
+
}
|
|
268
|
+
} else if (entry.hasChanged) {
|
|
269
|
+
if (!changes) {
|
|
270
|
+
changes = {}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
changes[entry.storageKey] = entry.value
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (storage) {
|
|
279
|
+
const promises: Promise<void>[] = []
|
|
280
|
+
if (changes) {
|
|
281
|
+
promises.push(storage.write(changes))
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (deletions) {
|
|
285
|
+
promises.push(storage.delete(deletions))
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (promises.length > 0) {
|
|
289
|
+
await Promise.all(promises)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
protected onComputeStorageKeys (context: TurnContext): Promise<Record<string, string>> {
|
|
295
|
+
const activity = context.activity
|
|
296
|
+
const channelId = activity?.channelId
|
|
297
|
+
const agentId = activity?.recipient?.id
|
|
298
|
+
const conversationId = activity?.conversation?.id
|
|
299
|
+
const userId = activity?.from?.id
|
|
300
|
+
|
|
301
|
+
if (!channelId) {
|
|
302
|
+
throw new Error('missing context.activity.channelId')
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (!agentId) {
|
|
306
|
+
throw new Error('missing context.activity.recipient.id')
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (!conversationId) {
|
|
310
|
+
throw new Error('missing context.activity.conversation.id')
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!userId) {
|
|
314
|
+
throw new Error('missing context.activity.from.id')
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const keys: Record<string, string> = {}
|
|
318
|
+
keys[CONVERSATION_SCOPE] = `${channelId}/${agentId}/conversations/${conversationId}`
|
|
319
|
+
keys[USER_SCOPE] = `${channelId}/${agentId}/users/${userId}`
|
|
320
|
+
keys[SSO_SCOPE] = `${channelId}/${agentId}/sso`
|
|
321
|
+
return Promise.resolve(keys)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private getScopeAndName (path: string): { scope: TurnStateEntry; name: string } {
|
|
325
|
+
const parts = path.split('.')
|
|
326
|
+
if (parts.length > 2) {
|
|
327
|
+
throw new Error(`Invalid state path: ${path}`)
|
|
328
|
+
} else if (parts.length === 1) {
|
|
329
|
+
parts.unshift(TEMP_SCOPE)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const scope = this.getScope(parts[0])
|
|
333
|
+
if (scope === undefined) {
|
|
334
|
+
throw new Error(`Invalid state scope: ${parts[0]}`)
|
|
335
|
+
}
|
|
336
|
+
return { scope, name: parts[1] }
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class TurnStateEntry {
|
|
7
|
+
private _value: Record<string, unknown>
|
|
8
|
+
private _storageKey?: string
|
|
9
|
+
private _deleted = false
|
|
10
|
+
private _hash: string
|
|
11
|
+
|
|
12
|
+
public constructor (value?: Record<string, unknown>, storageKey?: string) {
|
|
13
|
+
this._value = value || {}
|
|
14
|
+
this._storageKey = storageKey
|
|
15
|
+
this._hash = JSON.stringify(this._value)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public get hasChanged (): boolean {
|
|
19
|
+
return JSON.stringify(this._value) !== this._hash
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public get isDeleted (): boolean {
|
|
23
|
+
return this._deleted
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public get value (): Record<string, unknown> {
|
|
27
|
+
if (this.isDeleted) {
|
|
28
|
+
this._value = {}
|
|
29
|
+
this._deleted = false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return this._value
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public get storageKey (): string | undefined {
|
|
36
|
+
return this._storageKey
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public delete (): void {
|
|
40
|
+
this._deleted = true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public replace (value?: Record<string, unknown>): void {
|
|
44
|
+
this._value = value || {}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents the authentication configuration.
|
|
8
|
+
*/
|
|
9
|
+
export interface AuthConfiguration {
|
|
10
|
+
tenantId?: string
|
|
11
|
+
clientId?: string
|
|
12
|
+
clientSecret?: string
|
|
13
|
+
certPemFile?: string
|
|
14
|
+
certKeyFile?: string
|
|
15
|
+
issuers: string[]
|
|
16
|
+
connectionName?: string,
|
|
17
|
+
FICClientId?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Loads the authentication configuration from environment variables.
|
|
22
|
+
* @returns The authentication configuration.
|
|
23
|
+
* @throws Will throw an error if clientId is not provided in production.
|
|
24
|
+
*/
|
|
25
|
+
export const loadAuthConfigFromEnv: () => AuthConfiguration = () => {
|
|
26
|
+
if (process.env.clientId === undefined && process.env.NODE_ENV === 'production') {
|
|
27
|
+
throw new Error('ClientId required in production')
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
tenantId: process.env.tenantId,
|
|
31
|
+
clientId: process.env.clientId,
|
|
32
|
+
clientSecret: process.env.clientSecret,
|
|
33
|
+
certPemFile: process.env.certPemFile,
|
|
34
|
+
certKeyFile: process.env.certKeyFile,
|
|
35
|
+
connectionName: process.env.connectionName,
|
|
36
|
+
FICClientId: process.env.FICClientId,
|
|
37
|
+
issuers: [
|
|
38
|
+
'https://api.botframework.com',
|
|
39
|
+
`https://sts.windows.net/${process.env.tenantId}/`,
|
|
40
|
+
`https://login.microsoftonline.com/${process.env.tenantId}/v2.0`
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Loads the agent authentication configuration from environment variables.
|
|
47
|
+
* @returns The agent authentication configuration.
|
|
48
|
+
* @throws Will throw an error if MicrosoftAppId is not provided in production.
|
|
49
|
+
*/
|
|
50
|
+
export const loadBotAuthConfigFromEnv: () => AuthConfiguration = () => {
|
|
51
|
+
if (process.env.MicrosoftAppId === undefined && process.env.NODE_ENV === 'production') {
|
|
52
|
+
throw new Error('ClientId required in production')
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
tenantId: process.env.MicrosoftAppTenantId,
|
|
56
|
+
clientId: process.env.MicrosoftAppId,
|
|
57
|
+
clientSecret: process.env.MicrosoftAppPassword,
|
|
58
|
+
certPemFile: process.env.certPemFile,
|
|
59
|
+
certKeyFile: process.env.certKeyFile,
|
|
60
|
+
connectionName: process.env.connectionName,
|
|
61
|
+
FICClientId: process.env.MicrosoftAppClientId,
|
|
62
|
+
issuers: [
|
|
63
|
+
'https://api.botframework.com',
|
|
64
|
+
`https://sts.windows.net/${process.env.MicrosoftAppTenantId}/`,
|
|
65
|
+
`https://login.microsoftonline.com/${process.env.MicrosoftAppTenantId}/v2.0`
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AuthConfiguration } from './authConfiguration'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Interface representing an authentication provider.
|
|
10
|
+
*/
|
|
11
|
+
export interface AuthProvider {
|
|
12
|
+
/**
|
|
13
|
+
* Gets an access token for the specified authentication configuration and scope.
|
|
14
|
+
* @param authConfig - The authentication configuration.
|
|
15
|
+
* @param scope - The scope for which the access token is requested.
|
|
16
|
+
* @returns A promise that resolves to the access token.
|
|
17
|
+
*/
|
|
18
|
+
getAccessToken: (authConfig: AuthConfiguration, scope: string) => Promise<string>
|
|
19
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AuthConfiguration } from './authConfiguration'
|
|
7
|
+
import { Response, NextFunction } from 'express'
|
|
8
|
+
import { Request } from './request'
|
|
9
|
+
import jwksRsa, { JwksClient, SigningKey } from 'jwks-rsa'
|
|
10
|
+
import jwt, { JwtHeader, JwtPayload, SignCallback, GetPublicKeyOrSecret } from 'jsonwebtoken'
|
|
11
|
+
import { debug } from '../logger'
|
|
12
|
+
|
|
13
|
+
const logger = debug('agents:jwt-middleware')
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Verifies the JWT token.
|
|
17
|
+
* @param raw The raw JWT token.
|
|
18
|
+
* @param config The authentication configuration.
|
|
19
|
+
* @returns A promise that resolves to the JWT payload.
|
|
20
|
+
*/
|
|
21
|
+
const verifyToken = async (raw: string, config: AuthConfiguration): Promise<JwtPayload> => {
|
|
22
|
+
const getKey: GetPublicKeyOrSecret = (header: JwtHeader, callback: SignCallback) => {
|
|
23
|
+
const payload = jwt.decode(raw) as JwtPayload
|
|
24
|
+
|
|
25
|
+
const jwksUri: string = payload.iss === 'https://api.botframework.com'
|
|
26
|
+
? 'https://login.botframework.com/v1/.well-known/keys'
|
|
27
|
+
: `https://login.microsoftonline.com/${config.tenantId}/discovery/v2.0/keys`
|
|
28
|
+
|
|
29
|
+
logger.info(`fetching keys from ${jwksUri}`)
|
|
30
|
+
const jwksClient: JwksClient = jwksRsa({ jwksUri })
|
|
31
|
+
|
|
32
|
+
jwksClient.getSigningKey(header.kid, (err: Error | null, key: SigningKey | undefined): void => {
|
|
33
|
+
if (err != null) {
|
|
34
|
+
logger.error('jwksClient.getSigningKey ', JSON.stringify(err))
|
|
35
|
+
logger.error(JSON.stringify(err))
|
|
36
|
+
callback(err, undefined)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
const signingKey = key?.getPublicKey()
|
|
40
|
+
callback(null, signingKey)
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return await new Promise((resolve, reject) => {
|
|
45
|
+
const verifyOptions: jwt.VerifyOptions = {
|
|
46
|
+
issuer: config.issuers,
|
|
47
|
+
audience: [config.clientId!, 'https://api.botframework.com'],
|
|
48
|
+
ignoreExpiration: false,
|
|
49
|
+
algorithms: ['RS256']
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
jwt.verify(raw, getKey, verifyOptions, (err, user) => {
|
|
53
|
+
if (err != null) {
|
|
54
|
+
logger.error('jwt.verify ', JSON.stringify(err))
|
|
55
|
+
reject(err)
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
const tokenClaims = user as JwtPayload
|
|
59
|
+
|
|
60
|
+
resolve(tokenClaims)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Middleware to authorize JWT tokens.
|
|
67
|
+
* @param authConfig The authentication configuration.
|
|
68
|
+
* @returns An Express middleware function.
|
|
69
|
+
*/
|
|
70
|
+
export const authorizeJWT = (authConfig: AuthConfiguration) => {
|
|
71
|
+
return async function (req: Request, res: Response, next: NextFunction) {
|
|
72
|
+
let failed = false
|
|
73
|
+
logger.info('authorizing jwt')
|
|
74
|
+
const authHeader = req.headers.authorization as string
|
|
75
|
+
if (authHeader) {
|
|
76
|
+
const token: string = authHeader.split(' ')[1] // Extract the token from the Bearer string
|
|
77
|
+
try {
|
|
78
|
+
const user = await verifyToken(token, authConfig)
|
|
79
|
+
logger.debug('token verified for ', user)
|
|
80
|
+
req.user = user
|
|
81
|
+
} catch (err: Error | any) {
|
|
82
|
+
failed = true
|
|
83
|
+
logger.error(err)
|
|
84
|
+
res.status(401).send({ 'jwt-auth-error': err.message })
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (!authConfig.clientId && process.env.NODE_ENV !== 'production') {
|
|
88
|
+
logger.info('using anonymous auth')
|
|
89
|
+
req.user = { name: 'anonymous' }
|
|
90
|
+
} else {
|
|
91
|
+
logger.error('authorization header not found')
|
|
92
|
+
res.status(401).send({ 'jwt-auth-error': 'authorization header not found' })
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!failed) {
|
|
96
|
+
next()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|