@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.
Files changed (394) hide show
  1. package/README.md +57 -0
  2. package/dist/src/activityHandler.d.ts +108 -0
  3. package/dist/src/activityHandler.js +395 -0
  4. package/dist/src/activityHandler.js.map +1 -0
  5. package/dist/src/agent-client/agentClient.d.ts +13 -0
  6. package/dist/src/agent-client/agentClient.js +75 -0
  7. package/dist/src/agent-client/agentClient.js.map +1 -0
  8. package/dist/src/agent-client/expressApi.d.ts +4 -0
  9. package/dist/src/agent-client/expressApi.js +50 -0
  10. package/dist/src/agent-client/expressApi.js.map +1 -0
  11. package/dist/src/agent-client/index.d.ts +2 -0
  12. package/dist/src/agent-client/index.js +19 -0
  13. package/dist/src/agent-client/index.js.map +1 -0
  14. package/dist/src/app/agentApplication.d.ts +47 -0
  15. package/dist/src/app/agentApplication.js +317 -0
  16. package/dist/src/app/agentApplication.js.map +1 -0
  17. package/dist/src/app/appRoute.d.ts +11 -0
  18. package/dist/src/app/appRoute.js +7 -0
  19. package/dist/src/app/appRoute.js.map +1 -0
  20. package/dist/src/app/applicationBuilder.d.ts +18 -0
  21. package/dist/src/app/applicationBuilder.js +37 -0
  22. package/dist/src/app/applicationBuilder.js.map +1 -0
  23. package/dist/src/app/applicationOptions.d.ts +19 -0
  24. package/dist/src/app/applicationOptions.js +7 -0
  25. package/dist/src/app/applicationOptions.js.map +1 -0
  26. package/dist/src/app/attachmentDownloader.d.ts +13 -0
  27. package/dist/src/app/attachmentDownloader.js +72 -0
  28. package/dist/src/app/attachmentDownloader.js.map +1 -0
  29. package/dist/src/app/conversationUpdateEvents.d.ts +5 -0
  30. package/dist/src/app/conversationUpdateEvents.js +7 -0
  31. package/dist/src/app/conversationUpdateEvents.js.map +1 -0
  32. package/dist/src/app/index.d.ts +10 -0
  33. package/dist/src/app/index.js +27 -0
  34. package/dist/src/app/index.js.map +1 -0
  35. package/dist/src/app/inputFileDownloader.d.ts +14 -0
  36. package/dist/src/app/inputFileDownloader.js +7 -0
  37. package/dist/src/app/inputFileDownloader.js.map +1 -0
  38. package/dist/src/app/memory.d.ts +10 -0
  39. package/dist/src/app/memory.js +7 -0
  40. package/dist/src/app/memory.js.map +1 -0
  41. package/dist/src/app/oauth/authenticationOptions.d.ts +7 -0
  42. package/dist/src/app/oauth/authenticationOptions.js +7 -0
  43. package/dist/src/app/oauth/authenticationOptions.js.map +1 -0
  44. package/dist/src/app/oauth/webChatOAuthFlowAppStyle.d.ts +11 -0
  45. package/dist/src/app/oauth/webChatOAuthFlowAppStyle.js +85 -0
  46. package/dist/src/app/oauth/webChatOAuthFlowAppStyle.js.map +1 -0
  47. package/dist/src/app/routeHandler.d.ts +7 -0
  48. package/dist/src/app/routeHandler.js +7 -0
  49. package/dist/src/app/routeHandler.js.map +1 -0
  50. package/dist/src/app/routeSelector.d.ts +7 -0
  51. package/dist/src/app/routeSelector.js +7 -0
  52. package/dist/src/app/routeSelector.js.map +1 -0
  53. package/dist/src/app/turnEvents.d.ts +5 -0
  54. package/dist/src/app/turnEvents.js +7 -0
  55. package/dist/src/app/turnEvents.js.map +1 -0
  56. package/dist/src/app/turnState.d.ts +85 -0
  57. package/dist/src/app/turnState.js +274 -0
  58. package/dist/src/app/turnState.js.map +1 -0
  59. package/dist/src/app/turnStateEntry.d.ts +17 -0
  60. package/dist/src/app/turnStateEntry.js +39 -0
  61. package/dist/src/app/turnStateEntry.js.map +1 -0
  62. package/dist/src/auth/authConfiguration.d.ts +29 -0
  63. package/dist/src/auth/authConfiguration.js +58 -0
  64. package/dist/src/auth/authConfiguration.js.map +1 -0
  65. package/dist/src/auth/authProvider.d.ts +17 -0
  66. package/dist/src/auth/authProvider.js +7 -0
  67. package/dist/src/auth/authProvider.js.map +1 -0
  68. package/dist/src/auth/index.d.ts +4 -0
  69. package/dist/src/auth/index.js +21 -0
  70. package/dist/src/auth/index.js.map +1 -0
  71. package/dist/src/auth/jwt-middleware.d.ts +13 -0
  72. package/dist/src/auth/jwt-middleware.js +97 -0
  73. package/dist/src/auth/jwt-middleware.js.map +1 -0
  74. package/dist/src/auth/msalTokenProvider.d.ts +53 -0
  75. package/dist/src/auth/msalTokenProvider.js +198 -0
  76. package/dist/src/auth/msalTokenProvider.js.map +1 -0
  77. package/dist/src/auth/request.d.ts +15 -0
  78. package/dist/src/auth/request.js +7 -0
  79. package/dist/src/auth/request.js.map +1 -0
  80. package/dist/src/baseAdapter.d.ts +88 -0
  81. package/dist/src/baseAdapter.js +94 -0
  82. package/dist/src/baseAdapter.js.map +1 -0
  83. package/dist/src/cards/animationCard.d.ts +36 -0
  84. package/dist/src/cards/animationCard.js +7 -0
  85. package/dist/src/cards/animationCard.js.map +1 -0
  86. package/dist/src/cards/audioCard.d.ts +36 -0
  87. package/dist/src/cards/audioCard.js +7 -0
  88. package/dist/src/cards/audioCard.js.map +1 -0
  89. package/dist/src/cards/cardFactory.d.ts +123 -0
  90. package/dist/src/cards/cardFactory.js +225 -0
  91. package/dist/src/cards/cardFactory.js.map +1 -0
  92. package/dist/src/cards/cardImage.d.ts +16 -0
  93. package/dist/src/cards/cardImage.js +7 -0
  94. package/dist/src/cards/cardImage.js.map +1 -0
  95. package/dist/src/cards/fact.d.ts +13 -0
  96. package/dist/src/cards/fact.js +7 -0
  97. package/dist/src/cards/fact.js.map +1 -0
  98. package/dist/src/cards/heroCard.d.ts +23 -0
  99. package/dist/src/cards/heroCard.js +7 -0
  100. package/dist/src/cards/heroCard.js.map +1 -0
  101. package/dist/src/cards/index.d.ts +17 -0
  102. package/dist/src/cards/index.js +34 -0
  103. package/dist/src/cards/index.js.map +1 -0
  104. package/dist/src/cards/mediaUrl.d.ts +17 -0
  105. package/dist/src/cards/mediaUrl.js +7 -0
  106. package/dist/src/cards/mediaUrl.js.map +1 -0
  107. package/dist/src/cards/o365ConnectorCard.d.ts +35 -0
  108. package/dist/src/cards/o365ConnectorCard.js +7 -0
  109. package/dist/src/cards/o365ConnectorCard.js.map +1 -0
  110. package/dist/src/cards/o365ConnectorCardActionBase.d.ts +22 -0
  111. package/dist/src/cards/o365ConnectorCardActionBase.js +7 -0
  112. package/dist/src/cards/o365ConnectorCardActionBase.js.map +1 -0
  113. package/dist/src/cards/o365ConnectorCardFact.d.ts +17 -0
  114. package/dist/src/cards/o365ConnectorCardFact.js +7 -0
  115. package/dist/src/cards/o365ConnectorCardFact.js.map +1 -0
  116. package/dist/src/cards/o365ConnectorCardImage.d.ts +17 -0
  117. package/dist/src/cards/o365ConnectorCardImage.js +7 -0
  118. package/dist/src/cards/o365ConnectorCardImage.js.map +1 -0
  119. package/dist/src/cards/o365ConnectorCardSection.d.ts +57 -0
  120. package/dist/src/cards/o365ConnectorCardSection.js +7 -0
  121. package/dist/src/cards/o365ConnectorCardSection.js.map +1 -0
  122. package/dist/src/cards/receiptCard.d.ts +44 -0
  123. package/dist/src/cards/receiptCard.js +7 -0
  124. package/dist/src/cards/receiptCard.js.map +1 -0
  125. package/dist/src/cards/receiptItem.d.ts +39 -0
  126. package/dist/src/cards/receiptItem.js +7 -0
  127. package/dist/src/cards/receiptItem.js.map +1 -0
  128. package/dist/src/cards/signinCard.d.ts +14 -0
  129. package/dist/src/cards/signinCard.js +5 -0
  130. package/dist/src/cards/signinCard.js.map +1 -0
  131. package/dist/src/cards/taskModuleAction.d.ts +43 -0
  132. package/dist/src/cards/taskModuleAction.js +30 -0
  133. package/dist/src/cards/taskModuleAction.js.map +1 -0
  134. package/dist/src/cards/thumbnailCard.d.ts +35 -0
  135. package/dist/src/cards/thumbnailCard.js +7 -0
  136. package/dist/src/cards/thumbnailCard.js.map +1 -0
  137. package/dist/src/cards/thumbnailUrl.d.ts +17 -0
  138. package/dist/src/cards/thumbnailUrl.js +7 -0
  139. package/dist/src/cards/thumbnailUrl.js.map +1 -0
  140. package/dist/src/cards/videoCard.d.ts +60 -0
  141. package/dist/src/cards/videoCard.js +7 -0
  142. package/dist/src/cards/videoCard.js.map +1 -0
  143. package/dist/src/claimsIdentity.d.ts +35 -0
  144. package/dist/src/claimsIdentity.js +43 -0
  145. package/dist/src/claimsIdentity.js.map +1 -0
  146. package/dist/src/cloudAdapter.d.ts +128 -0
  147. package/dist/src/cloudAdapter.js +376 -0
  148. package/dist/src/cloudAdapter.js.map +1 -0
  149. package/dist/src/connector-client/attachmentData.d.ts +25 -0
  150. package/dist/src/connector-client/attachmentData.js +7 -0
  151. package/dist/src/connector-client/attachmentData.js.map +1 -0
  152. package/dist/src/connector-client/attachmentInfo.d.ts +22 -0
  153. package/dist/src/connector-client/attachmentInfo.js +7 -0
  154. package/dist/src/connector-client/attachmentInfo.js.map +1 -0
  155. package/dist/src/connector-client/attachmentView.d.ts +17 -0
  156. package/dist/src/connector-client/attachmentView.js +7 -0
  157. package/dist/src/connector-client/attachmentView.js.map +1 -0
  158. package/dist/src/connector-client/connectorClient.d.ts +93 -0
  159. package/dist/src/connector-client/connectorClient.js +249 -0
  160. package/dist/src/connector-client/connectorClient.js.map +1 -0
  161. package/dist/src/connector-client/conversationMembers.d.ts +18 -0
  162. package/dist/src/connector-client/conversationMembers.js +7 -0
  163. package/dist/src/connector-client/conversationMembers.js.map +1 -0
  164. package/dist/src/connector-client/conversationParameters.d.ts +38 -0
  165. package/dist/src/connector-client/conversationParameters.js +7 -0
  166. package/dist/src/connector-client/conversationParameters.js.map +1 -0
  167. package/dist/src/connector-client/conversationResourceResponse.d.ts +21 -0
  168. package/dist/src/connector-client/conversationResourceResponse.js +7 -0
  169. package/dist/src/connector-client/conversationResourceResponse.js.map +1 -0
  170. package/dist/src/connector-client/conversationsResult.d.ts +18 -0
  171. package/dist/src/connector-client/conversationsResult.js +7 -0
  172. package/dist/src/connector-client/conversationsResult.js.map +1 -0
  173. package/dist/src/connector-client/index.d.ts +9 -0
  174. package/dist/src/connector-client/index.js +26 -0
  175. package/dist/src/connector-client/index.js.map +1 -0
  176. package/dist/src/connector-client/resourceResponse.d.ts +13 -0
  177. package/dist/src/connector-client/resourceResponse.js +7 -0
  178. package/dist/src/connector-client/resourceResponse.js.map +1 -0
  179. package/dist/src/index.d.ts +26 -0
  180. package/dist/src/index.js +45 -0
  181. package/dist/src/index.js.map +1 -0
  182. package/dist/src/invoke/adaptiveCardAuthentication.d.ts +10 -0
  183. package/dist/src/invoke/adaptiveCardAuthentication.js +7 -0
  184. package/dist/src/invoke/adaptiveCardAuthentication.js.map +1 -0
  185. package/dist/src/invoke/adaptiveCardInvokeResponse.d.ts +21 -0
  186. package/dist/src/invoke/adaptiveCardInvokeResponse.js +7 -0
  187. package/dist/src/invoke/adaptiveCardInvokeResponse.js.map +1 -0
  188. package/dist/src/invoke/adaptiveCardInvokeValue.d.ts +23 -0
  189. package/dist/src/invoke/adaptiveCardInvokeValue.js +7 -0
  190. package/dist/src/invoke/adaptiveCardInvokeValue.js.map +1 -0
  191. package/dist/src/invoke/index.d.ts +9 -0
  192. package/dist/src/invoke/index.js +26 -0
  193. package/dist/src/invoke/index.js.map +1 -0
  194. package/dist/src/invoke/invokeException.d.ts +24 -0
  195. package/dist/src/invoke/invokeException.js +35 -0
  196. package/dist/src/invoke/invokeException.js.map +1 -0
  197. package/dist/src/invoke/invokeResponse.d.ts +17 -0
  198. package/dist/src/invoke/invokeResponse.js +7 -0
  199. package/dist/src/invoke/invokeResponse.js.map +1 -0
  200. package/dist/src/invoke/searchInvokeOptions.d.ts +17 -0
  201. package/dist/src/invoke/searchInvokeOptions.js +7 -0
  202. package/dist/src/invoke/searchInvokeOptions.js.map +1 -0
  203. package/dist/src/invoke/searchInvokeResponse.d.ts +10 -0
  204. package/dist/src/invoke/searchInvokeResponse.js +7 -0
  205. package/dist/src/invoke/searchInvokeResponse.js.map +1 -0
  206. package/dist/src/invoke/searchInvokeValue.d.ts +26 -0
  207. package/dist/src/invoke/searchInvokeValue.js +7 -0
  208. package/dist/src/invoke/searchInvokeValue.js.map +1 -0
  209. package/dist/src/invoke/tokenExchangeInvokeRequest.d.ts +21 -0
  210. package/dist/src/invoke/tokenExchangeInvokeRequest.js +7 -0
  211. package/dist/src/invoke/tokenExchangeInvokeRequest.js.map +1 -0
  212. package/dist/src/logger.d.ts +12 -0
  213. package/dist/src/logger.js +42 -0
  214. package/dist/src/logger.js.map +1 -0
  215. package/dist/src/messageFactory.d.ts +62 -0
  216. package/dist/src/messageFactory.js +143 -0
  217. package/dist/src/messageFactory.js.map +1 -0
  218. package/dist/src/middlewareSet.d.ts +43 -0
  219. package/dist/src/middlewareSet.js +57 -0
  220. package/dist/src/middlewareSet.js.map +1 -0
  221. package/dist/src/oauth/index.d.ts +7 -0
  222. package/dist/src/oauth/index.js +24 -0
  223. package/dist/src/oauth/index.js.map +1 -0
  224. package/dist/src/oauth/oauthCard.d.ts +28 -0
  225. package/dist/src/oauth/oauthCard.js +5 -0
  226. package/dist/src/oauth/oauthCard.js.map +1 -0
  227. package/dist/src/oauth/signingResource.d.ts +19 -0
  228. package/dist/src/oauth/signingResource.js +5 -0
  229. package/dist/src/oauth/signingResource.js.map +1 -0
  230. package/dist/src/oauth/tokenExchangeRequest.d.ts +17 -0
  231. package/dist/src/oauth/tokenExchangeRequest.js +5 -0
  232. package/dist/src/oauth/tokenExchangeRequest.js.map +1 -0
  233. package/dist/src/oauth/tokenExchangeResource.d.ts +17 -0
  234. package/dist/src/oauth/tokenExchangeResource.js +5 -0
  235. package/dist/src/oauth/tokenExchangeResource.js.map +1 -0
  236. package/dist/src/oauth/tokenPostResource.d.ts +9 -0
  237. package/dist/src/oauth/tokenPostResource.js +5 -0
  238. package/dist/src/oauth/tokenPostResource.js.map +1 -0
  239. package/dist/src/oauth/userTokenClient.d.ts +49 -0
  240. package/dist/src/oauth/userTokenClient.js +117 -0
  241. package/dist/src/oauth/userTokenClient.js.map +1 -0
  242. package/dist/src/oauth/webChatOAuthFlow.d.ts +41 -0
  243. package/dist/src/oauth/webChatOAuthFlow.js +117 -0
  244. package/dist/src/oauth/webChatOAuthFlow.js.map +1 -0
  245. package/dist/src/state/agentState.d.ts +71 -0
  246. package/dist/src/state/agentState.js +122 -0
  247. package/dist/src/state/agentState.js.map +1 -0
  248. package/dist/src/state/agentStatePropertyAccesor.d.ts +39 -0
  249. package/dist/src/state/agentStatePropertyAccesor.js +60 -0
  250. package/dist/src/state/agentStatePropertyAccesor.js.map +1 -0
  251. package/dist/src/state/conversationState.d.ts +18 -0
  252. package/dist/src/state/conversationState.js +38 -0
  253. package/dist/src/state/conversationState.js.map +1 -0
  254. package/dist/src/state/index.d.ts +4 -0
  255. package/dist/src/state/index.js +21 -0
  256. package/dist/src/state/index.js.map +1 -0
  257. package/dist/src/state/userState.d.ts +18 -0
  258. package/dist/src/state/userState.js +38 -0
  259. package/dist/src/state/userState.js.map +1 -0
  260. package/dist/src/statusCodes.d.ts +19 -0
  261. package/dist/src/statusCodes.js +24 -0
  262. package/dist/src/statusCodes.js.map +1 -0
  263. package/dist/src/storage/index.d.ts +2 -0
  264. package/dist/src/storage/index.js +19 -0
  265. package/dist/src/storage/index.js.map +1 -0
  266. package/dist/src/storage/memoryStorage.d.ts +50 -0
  267. package/dist/src/storage/memoryStorage.js +100 -0
  268. package/dist/src/storage/memoryStorage.js.map +1 -0
  269. package/dist/src/storage/storage.d.ts +47 -0
  270. package/dist/src/storage/storage.js +7 -0
  271. package/dist/src/storage/storage.js.map +1 -0
  272. package/dist/src/tokenResponseEventName.d.ts +5 -0
  273. package/dist/src/tokenResponseEventName.js +9 -0
  274. package/dist/src/tokenResponseEventName.js.map +1 -0
  275. package/dist/src/transcript/consoleTranscriptLogger.d.ts +13 -0
  276. package/dist/src/transcript/consoleTranscriptLogger.js +21 -0
  277. package/dist/src/transcript/consoleTranscriptLogger.js.map +1 -0
  278. package/dist/src/transcript/index.d.ts +4 -0
  279. package/dist/src/transcript/index.js +21 -0
  280. package/dist/src/transcript/index.js.map +1 -0
  281. package/dist/src/transcript/transcriptLogger.d.ts +42 -0
  282. package/dist/src/transcript/transcriptLogger.js +3 -0
  283. package/dist/src/transcript/transcriptLogger.js.map +1 -0
  284. package/dist/src/transcript/transcriptLoggerMiddleware.d.ts +38 -0
  285. package/dist/src/transcript/transcriptLoggerMiddleware.js +126 -0
  286. package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -0
  287. package/dist/src/transcript/transcriptStore.d.ts +30 -0
  288. package/dist/src/transcript/transcriptStore.js +3 -0
  289. package/dist/src/transcript/transcriptStore.js.map +1 -0
  290. package/dist/src/turnContext.d.ts +160 -0
  291. package/dist/src/turnContext.js +286 -0
  292. package/dist/src/turnContext.js.map +1 -0
  293. package/dist/src/turnContextStateCollection.d.ts +29 -0
  294. package/dist/src/turnContextStateCollection.js +56 -0
  295. package/dist/src/turnContextStateCollection.js.map +1 -0
  296. package/package.json +48 -0
  297. package/src/activityHandler.ts +461 -0
  298. package/src/agent-client/agentClient.ts +84 -0
  299. package/src/agent-client/expressApi.ts +59 -0
  300. package/src/agent-client/index.ts +2 -0
  301. package/src/app/agentApplication.ts +401 -0
  302. package/src/app/appRoute.ts +13 -0
  303. package/src/app/applicationBuilder.ts +42 -0
  304. package/src/app/applicationOptions.ts +21 -0
  305. package/src/app/attachmentDownloader.ts +83 -0
  306. package/src/app/conversationUpdateEvents.ts +8 -0
  307. package/src/app/index.ts +10 -0
  308. package/src/app/inputFileDownloader.ts +17 -0
  309. package/src/app/memory.ts +14 -0
  310. package/src/app/oauth/authenticationOptions.ts +8 -0
  311. package/src/app/oauth/webChatOAuthFlowAppStyle.ts +90 -0
  312. package/src/app/routeHandler.ts +9 -0
  313. package/src/app/routeSelector.ts +10 -0
  314. package/src/app/turnEvents.ts +6 -0
  315. package/src/app/turnState.ts +338 -0
  316. package/src/app/turnStateEntry.ts +46 -0
  317. package/src/auth/authConfiguration.ts +68 -0
  318. package/src/auth/authProvider.ts +19 -0
  319. package/src/auth/index.ts +4 -0
  320. package/src/auth/jwt-middleware.ts +99 -0
  321. package/src/auth/msalTokenProvider.ts +202 -0
  322. package/src/auth/request.ts +20 -0
  323. package/src/baseAdapter.ts +174 -0
  324. package/src/cards/animationCard.ts +38 -0
  325. package/src/cards/audioCard.ts +38 -0
  326. package/src/cards/cardFactory.ts +276 -0
  327. package/src/cards/cardImage.ts +18 -0
  328. package/src/cards/fact.ts +14 -0
  329. package/src/cards/heroCard.ts +25 -0
  330. package/src/cards/index.ts +17 -0
  331. package/src/cards/mediaUrl.ts +18 -0
  332. package/src/cards/o365ConnectorCard.ts +37 -0
  333. package/src/cards/o365ConnectorCardActionBase.ts +24 -0
  334. package/src/cards/o365ConnectorCardFact.ts +18 -0
  335. package/src/cards/o365ConnectorCardImage.ts +18 -0
  336. package/src/cards/o365ConnectorCardSection.ts +60 -0
  337. package/src/cards/receiptCard.ts +46 -0
  338. package/src/cards/receiptItem.ts +41 -0
  339. package/src/cards/signinCard.ts +18 -0
  340. package/src/cards/taskModuleAction.ts +61 -0
  341. package/src/cards/thumbnailCard.ts +37 -0
  342. package/src/cards/thumbnailUrl.ts +18 -0
  343. package/src/cards/videoCard.ts +62 -0
  344. package/src/claimsIdentity.ts +47 -0
  345. package/src/cloudAdapter.ts +431 -0
  346. package/src/connector-client/attachmentData.ts +26 -0
  347. package/src/connector-client/attachmentInfo.ts +24 -0
  348. package/src/connector-client/attachmentView.ts +18 -0
  349. package/src/connector-client/connectorClient.ts +295 -0
  350. package/src/connector-client/conversationMembers.ts +20 -0
  351. package/src/connector-client/conversationParameters.ts +40 -0
  352. package/src/connector-client/conversationResourceResponse.ts +22 -0
  353. package/src/connector-client/conversationsResult.ts +20 -0
  354. package/src/connector-client/index.ts +9 -0
  355. package/src/connector-client/resourceResponse.ts +14 -0
  356. package/src/index.ts +31 -0
  357. package/src/invoke/adaptiveCardAuthentication.ts +13 -0
  358. package/src/invoke/adaptiveCardInvokeResponse.ts +22 -0
  359. package/src/invoke/adaptiveCardInvokeValue.ts +25 -0
  360. package/src/invoke/index.ts +9 -0
  361. package/src/invoke/invokeException.ts +33 -0
  362. package/src/invoke/invokeResponse.ts +18 -0
  363. package/src/invoke/searchInvokeOptions.ts +18 -0
  364. package/src/invoke/searchInvokeResponse.ts +11 -0
  365. package/src/invoke/searchInvokeValue.ts +28 -0
  366. package/src/invoke/tokenExchangeInvokeRequest.ts +22 -0
  367. package/src/logger.ts +43 -0
  368. package/src/messageFactory.ts +177 -0
  369. package/src/middlewareSet.ts +76 -0
  370. package/src/oauth/index.ts +7 -0
  371. package/src/oauth/oauthCard.ts +32 -0
  372. package/src/oauth/signingResource.ts +23 -0
  373. package/src/oauth/tokenExchangeRequest.ts +20 -0
  374. package/src/oauth/tokenExchangeResource.ts +20 -0
  375. package/src/oauth/tokenPostResource.ts +12 -0
  376. package/src/oauth/userTokenClient.ts +116 -0
  377. package/src/oauth/webChatOAuthFlow.ts +123 -0
  378. package/src/state/agentState.ts +142 -0
  379. package/src/state/agentStatePropertyAccesor.ts +61 -0
  380. package/src/state/conversationState.ts +42 -0
  381. package/src/state/index.ts +4 -0
  382. package/src/state/userState.ts +43 -0
  383. package/src/statusCodes.ts +20 -0
  384. package/src/storage/index.ts +2 -0
  385. package/src/storage/memoryStorage.ts +105 -0
  386. package/src/storage/storage.ts +52 -0
  387. package/src/tokenResponseEventName.ts +6 -0
  388. package/src/transcript/consoleTranscriptLogger.ts +20 -0
  389. package/src/transcript/index.ts +4 -0
  390. package/src/transcript/transcriptLogger.ts +45 -0
  391. package/src/transcript/transcriptLoggerMiddleware.ts +151 -0
  392. package/src/transcript/transcriptStore.ts +38 -0
  393. package/src/turnContext.ts +335 -0
  394. 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,6 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type TurnEvents = 'beforeTurn' | 'afterTurn'
@@ -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,4 @@
1
+ export * from './authConfiguration'
2
+ export * from './authProvider'
3
+ export * from './msalTokenProvider'
4
+ export * from './request'
@@ -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
+ }