@microsoft/agents-hosting 1.10.0-beta.9.g18d68b903e → 1.10.1

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 (169) hide show
  1. package/README.md +41 -2
  2. package/dist/package.json +3 -3
  3. package/dist/src/activityHandler.js +6 -3
  4. package/dist/src/activityHandler.js.map +1 -1
  5. package/dist/src/agent-client/agentResponseHandler.d.ts +7 -0
  6. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  7. package/dist/src/agent-client/createAgentResponseHandler.d.ts +2 -0
  8. package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -1
  9. package/dist/src/app/adaptiveCards/adaptiveCardsActions.d.ts +1 -0
  10. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +1 -0
  11. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
  12. package/dist/src/app/attachmentDownloadHttpClient.d.ts +13 -0
  13. package/dist/src/app/attachmentDownloadHttpClient.js +80 -0
  14. package/dist/src/app/attachmentDownloadHttpClient.js.map +1 -0
  15. package/dist/src/app/attachmentDownloader.d.ts +2 -0
  16. package/dist/src/app/attachmentDownloader.js +6 -11
  17. package/dist/src/app/attachmentDownloader.js.map +1 -1
  18. package/dist/src/app/auth/authorization.d.ts +58 -0
  19. package/dist/src/app/auth/authorization.js.map +1 -1
  20. package/dist/src/app/proactive/conversation.d.ts +18 -0
  21. package/dist/src/app/proactive/conversation.js +6 -0
  22. package/dist/src/app/proactive/conversation.js.map +1 -1
  23. package/dist/src/app/proactive/conversationBuilder.js +2 -1
  24. package/dist/src/app/proactive/conversationBuilder.js.map +1 -1
  25. package/dist/src/app/proactive/conversationReferenceBuilder.js +8 -4
  26. package/dist/src/app/proactive/conversationReferenceBuilder.js.map +1 -1
  27. package/dist/src/app/proactive/createConversationOptionsBuilder.d.ts +1 -0
  28. package/dist/src/app/proactive/createConversationOptionsBuilder.js +2 -1
  29. package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
  30. package/dist/src/app/proactive/proactive.d.ts +6 -0
  31. package/dist/src/app/proactive/proactive.js +32 -1
  32. package/dist/src/app/proactive/proactive.js.map +1 -1
  33. package/dist/src/app/routeList.d.ts +21 -0
  34. package/dist/src/app/routeList.js +27 -3
  35. package/dist/src/app/routeList.js.map +1 -1
  36. package/dist/src/app/teamsAttachmentDownloader.d.ts +8 -0
  37. package/dist/src/app/teamsAttachmentDownloader.js +17 -12
  38. package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
  39. package/dist/src/auth/authConfiguration.d.ts +1 -0
  40. package/dist/src/auth/authConfiguration.js.map +1 -1
  41. package/dist/src/auth/authConstants.d.ts +7 -0
  42. package/dist/src/auth/authConstants.js +7 -0
  43. package/dist/src/auth/authConstants.js.map +1 -1
  44. package/dist/src/auth/authProvider.d.ts +36 -0
  45. package/dist/src/auth/connectionManager.js +2 -1
  46. package/dist/src/auth/connectionManager.js.map +1 -1
  47. package/dist/src/auth/connections.d.ts +1 -0
  48. package/dist/src/auth/msal/msalConnectionManager.d.ts +7 -0
  49. package/dist/src/auth/msal/msalConnectionManager.js +7 -0
  50. package/dist/src/auth/msal/msalConnectionManager.js.map +1 -1
  51. package/dist/src/auth/msal/msalTokenProvider.d.ts +44 -0
  52. package/dist/src/auth/msal/msalTokenProvider.js +43 -0
  53. package/dist/src/auth/msal/msalTokenProvider.js.map +1 -1
  54. package/dist/src/auth/settings.d.ts +28 -0
  55. package/dist/src/auth/settings.js +23 -0
  56. package/dist/src/auth/settings.js.map +1 -1
  57. package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +3 -0
  58. package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -1
  59. package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +0 -8
  60. package/dist/src/auth/sidecar/sidecarHttpClient.js +2 -68
  61. package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -1
  62. package/dist/src/cards/taskModuleAction.d.ts +6 -0
  63. package/dist/src/cards/taskModuleAction.js +6 -0
  64. package/dist/src/cards/taskModuleAction.js.map +1 -1
  65. package/dist/src/cloudAdapter.js +16 -8
  66. package/dist/src/cloudAdapter.js.map +1 -1
  67. package/dist/src/configuration/configuration.d.ts +1 -0
  68. package/dist/src/configuration/configuration.js +2 -1
  69. package/dist/src/configuration/configuration.js.map +1 -1
  70. package/dist/src/configuration/environmentConfiguration.js +1 -1
  71. package/dist/src/configuration/environmentConfiguration.js.map +1 -1
  72. package/dist/src/connector-client/connectorClient.d.ts +8 -0
  73. package/dist/src/connector-client/connectorClient.js +8 -0
  74. package/dist/src/connector-client/connectorClient.js.map +1 -1
  75. package/dist/src/createCloudAdapter.d.ts +2 -0
  76. package/dist/src/createCloudAdapter.js.map +1 -1
  77. package/dist/src/errorHelper.d.ts +1 -0
  78. package/dist/src/errorHelper.js +9 -0
  79. package/dist/src/errorHelper.js.map +1 -1
  80. package/dist/src/headerPropagation.d.ts +38 -0
  81. package/dist/src/headerPropagation.js +33 -0
  82. package/dist/src/headerPropagation.js.map +1 -1
  83. package/dist/src/httpClient.d.ts +58 -0
  84. package/dist/src/httpClient.js +40 -0
  85. package/dist/src/httpClient.js.map +1 -1
  86. package/dist/src/interfaces/webResponse.d.ts +7 -0
  87. package/dist/src/middlewareSet.d.ts +6 -0
  88. package/dist/src/middlewareSet.js.map +1 -1
  89. package/dist/src/oauth/userTokenClient.d.ts +6 -0
  90. package/dist/src/oauth/userTokenClient.js +12 -0
  91. package/dist/src/oauth/userTokenClient.js.map +1 -1
  92. package/dist/src/outboundHostValidator.d.ts +33 -1
  93. package/dist/src/outboundHostValidator.js +60 -25
  94. package/dist/src/outboundHostValidator.js.map +1 -1
  95. package/dist/src/storage/fileStorage.d.ts +26 -0
  96. package/dist/src/storage/fileStorage.js +35 -6
  97. package/dist/src/storage/fileStorage.js.map +1 -1
  98. package/dist/src/storage/memoryStorage.d.ts +34 -0
  99. package/dist/src/storage/memoryStorage.js +41 -4
  100. package/dist/src/storage/memoryStorage.js.map +1 -1
  101. package/dist/src/storage/storage.d.ts +20 -0
  102. package/dist/src/storage/storage.js +7 -0
  103. package/dist/src/storage/storage.js.map +1 -1
  104. package/dist/src/storage/storageCompatibility.js +12 -6
  105. package/dist/src/storage/storageCompatibility.js.map +1 -1
  106. package/dist/src/storage/storageExpiry.d.ts +7 -0
  107. package/dist/src/storage/storageExpiry.js +7 -0
  108. package/dist/src/storage/storageExpiry.js.map +1 -1
  109. package/dist/src/turnContext.d.ts +10 -0
  110. package/dist/src/turnContext.js +5 -0
  111. package/dist/src/turnContext.js.map +1 -1
  112. package/dist/src/utils/env.js +22 -11
  113. package/dist/src/utils/env.js.map +1 -1
  114. package/dist/src/utils/ipAddress.d.ts +6 -0
  115. package/dist/src/utils/ipAddress.js +64 -0
  116. package/dist/src/utils/ipAddress.js.map +1 -0
  117. package/dist/src/utils/outboundUrl.d.ts +7 -0
  118. package/dist/src/utils/outboundUrl.js +52 -0
  119. package/dist/src/utils/outboundUrl.js.map +1 -0
  120. package/dist/src/utils.js +2 -1
  121. package/dist/src/utils.js.map +1 -1
  122. package/package.json +3 -3
  123. package/src/activityHandler.ts +9 -3
  124. package/src/agent-client/agentResponseHandler.ts +7 -0
  125. package/src/agent-client/createAgentResponseHandler.ts +2 -0
  126. package/src/app/adaptiveCards/adaptiveCardsActions.ts +1 -0
  127. package/src/app/attachmentDownloadHttpClient.ts +80 -0
  128. package/src/app/attachmentDownloader.ts +6 -9
  129. package/src/app/auth/authorization.ts +58 -0
  130. package/src/app/proactive/conversation.ts +24 -0
  131. package/src/app/proactive/conversationBuilder.ts +3 -1
  132. package/src/app/proactive/conversationReferenceBuilder.ts +12 -4
  133. package/src/app/proactive/createConversationOptionsBuilder.ts +5 -1
  134. package/src/app/proactive/proactive.ts +33 -1
  135. package/src/app/routeList.ts +30 -3
  136. package/src/app/teamsAttachmentDownloader.ts +17 -10
  137. package/src/auth/authConfiguration.ts +1 -0
  138. package/src/auth/authConstants.ts +7 -0
  139. package/src/auth/authProvider.ts +36 -0
  140. package/src/auth/connectionManager.ts +3 -1
  141. package/src/auth/connections.ts +1 -0
  142. package/src/auth/msal/msalConnectionManager.ts +7 -0
  143. package/src/auth/msal/msalTokenProvider.ts +59 -0
  144. package/src/auth/settings.ts +28 -0
  145. package/src/auth/sidecar/sidecarAuthProvider.ts +4 -0
  146. package/src/auth/sidecar/sidecarHttpClient.ts +2 -62
  147. package/src/cards/taskModuleAction.ts +6 -0
  148. package/src/cloudAdapter.ts +30 -10
  149. package/src/configuration/configuration.ts +4 -2
  150. package/src/configuration/environmentConfiguration.ts +7 -1
  151. package/src/connector-client/connectorClient.ts +8 -0
  152. package/src/createCloudAdapter.ts +2 -0
  153. package/src/errorHelper.ts +11 -0
  154. package/src/headerPropagation.ts +38 -0
  155. package/src/httpClient.ts +58 -0
  156. package/src/interfaces/webResponse.ts +7 -0
  157. package/src/middlewareSet.ts +6 -0
  158. package/src/oauth/userTokenClient.ts +13 -0
  159. package/src/outboundHostValidator.ts +84 -23
  160. package/src/storage/fileStorage.ts +46 -6
  161. package/src/storage/memoryStorage.ts +45 -4
  162. package/src/storage/storage.ts +20 -0
  163. package/src/storage/storageCompatibility.ts +18 -6
  164. package/src/storage/storageExpiry.ts +7 -0
  165. package/src/turnContext.ts +11 -0
  166. package/src/utils/env.ts +33 -11
  167. package/src/utils/ipAddress.ts +63 -0
  168. package/src/utils/outboundUrl.ts +50 -0
  169. package/src/utils.ts +3 -1
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isPrivateOrLoopbackAddress = isPrivateOrLoopbackAddress;
8
+ exports.isBlockedOutboundAddress = isBlockedOutboundAddress;
9
+ const node_net_1 = require("node:net");
10
+ function normalizeAddress(address) {
11
+ const unwrapped = address.startsWith('[') && address.endsWith(']') ? address.slice(1, -1) : address;
12
+ const version = (0, node_net_1.isIP)(unwrapped);
13
+ if (version === 0) {
14
+ return undefined;
15
+ }
16
+ return version === 6 ? new URL(`http://[${unwrapped}]`).hostname.slice(1, -1) : unwrapped;
17
+ }
18
+ function mappedIPv4(address) {
19
+ const match = address.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
20
+ if (!match) {
21
+ return undefined;
22
+ }
23
+ const high = parseInt(match[1], 16);
24
+ const low = parseInt(match[2], 16);
25
+ return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`;
26
+ }
27
+ function isPrivateOrLoopbackAddress(address) {
28
+ var _a;
29
+ const normalized = normalizeAddress(address);
30
+ if (!normalized) {
31
+ return false;
32
+ }
33
+ const ipv4 = (_a = mappedIPv4(normalized)) !== null && _a !== void 0 ? _a : normalized;
34
+ if ((0, node_net_1.isIP)(ipv4) === 4) {
35
+ const bytes = ipv4.split('.').map(Number);
36
+ return bytes[0] === 127 ||
37
+ bytes[0] === 10 ||
38
+ (bytes[0] === 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
39
+ (bytes[0] === 192 && bytes[1] === 168) ||
40
+ (bytes[0] === 169 && bytes[1] === 254);
41
+ }
42
+ if (normalized === '::1') {
43
+ return true;
44
+ }
45
+ const firstHextet = parseInt(normalized.split(':')[0], 16);
46
+ return (firstHextet & 0xfe00) === 0xfc00 ||
47
+ (firstHextet & 0xffc0) === 0xfe80 ||
48
+ (firstHextet & 0xffc0) === 0xfec0;
49
+ }
50
+ function isBlockedOutboundAddress(address) {
51
+ var _a;
52
+ const normalized = normalizeAddress(address);
53
+ if (!normalized) {
54
+ return true;
55
+ }
56
+ const ipv4 = (_a = mappedIPv4(normalized)) !== null && _a !== void 0 ? _a : normalized;
57
+ const [first, second] = ipv4.split('.').map(Number);
58
+ // RFC 6598 shared space is outbound-only; it must not become trusted sidecar space.
59
+ return normalized === '::' ||
60
+ ipv4 === '0.0.0.0' ||
61
+ (first === 100 && second >= 64 && second <= 127) ||
62
+ isPrivateOrLoopbackAddress(normalized);
63
+ }
64
+ //# sourceMappingURL=ipAddress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipAddress.js","sourceRoot":"","sources":["../../../src/utils/ipAddress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export declare function getHttpsUrl(input: string | URL | null | undefined): URL | undefined;
6
+ export declare function isLocalOrBlockedHost(host: string): boolean;
7
+ export declare function hasAllowedOutboundAddresses(url: URL, allowPrivateNetworkAddresses?: boolean): Promise<boolean>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getHttpsUrl = getHttpsUrl;
8
+ exports.isLocalOrBlockedHost = isLocalOrBlockedHost;
9
+ exports.hasAllowedOutboundAddresses = hasAllowedOutboundAddresses;
10
+ const node_dns_1 = require("node:dns");
11
+ const node_net_1 = require("node:net");
12
+ const agents_telemetry_1 = require("@microsoft/agents-telemetry");
13
+ const ipAddress_1 = require("./ipAddress");
14
+ const logger = (0, agents_telemetry_1.debug)('agents:outboundHostValidator');
15
+ function getHttpsUrl(input) {
16
+ if (!input) {
17
+ return undefined;
18
+ }
19
+ try {
20
+ const url = input instanceof URL ? input : new URL(input);
21
+ return url.protocol === 'https:' && !url.username && !url.password ? url : undefined;
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ function isLocalOrBlockedHost(host) {
28
+ const unwrapped = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host;
29
+ return host === 'localhost' || host.endsWith('.localhost') ||
30
+ ((0, node_net_1.isIP)(unwrapped) !== 0 && (0, ipAddress_1.isBlockedOutboundAddress)(unwrapped));
31
+ }
32
+ async function hasAllowedOutboundAddresses(url, allowPrivateNetworkAddresses = false) {
33
+ if (allowPrivateNetworkAddresses) {
34
+ return true;
35
+ }
36
+ const host = url.hostname.replace(/^\[|\]$/g, '').replace(/\.$/, '');
37
+ if (isLocalOrBlockedHost(host)) {
38
+ return false;
39
+ }
40
+ if ((0, node_net_1.isIP)(host) !== 0) {
41
+ return true;
42
+ }
43
+ try {
44
+ const addresses = await node_dns_1.promises.lookup(host, { all: true });
45
+ return addresses.length > 0 && addresses.every(({ address }) => !(0, ipAddress_1.isBlockedOutboundAddress)(address));
46
+ }
47
+ catch {
48
+ logger.warn(`Attachment destination DNS lookup failed. Host='${host}'`);
49
+ return false;
50
+ }
51
+ }
52
+ //# sourceMappingURL=outboundUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outboundUrl.js","sourceRoot":"","sources":["../../../src/utils/outboundUrl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH,uCAA0C;AAC1C,uCAA+B;AAC/B,kEAAmD;AACnD,2CAAsD;AAEtD,MAAM,MAAM,GAAG,IAAA,wBAAK,EAAC,8BAA8B,CAAC,CAAA;AAEpD,qBAA6B,KAAsC;IACjE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;QACzD,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,8BAAsC,IAAY;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACvF,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxD,CAAC,IAAA,eAAI,EAAC,SAAS,CAAC,KAAK,CAAC,IAAI,IAAA,oCAAwB,EAAC,SAAS,CAAC,CAAC,CAAA;AAClE,CAAC;AAEM,KAAK,sCAAuC,GAAQ,EAAE,4BAA4B,GAAG,KAAK;IAC/F,IAAI,4BAA4B,EAAE,CAAC;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACpE,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,IAAA,eAAI,EAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,mBAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;QACvD,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC,CAAA;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,mDAAmD,IAAI,GAAG,CAAC,CAAA;QACvE,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
package/dist/src/utils.js CHANGED
@@ -18,8 +18,9 @@ exports.prune = prune;
18
18
  const mergeDefined = (...layers) => {
19
19
  const result = {};
20
20
  for (const layer of layers) {
21
- if (layer)
21
+ if (layer) {
22
22
  Object.assign(result, (0, exports.prune)(layer));
23
+ }
23
24
  }
24
25
  return result;
25
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AACI,MAAM,KAAK,GAAG,CAAgC,GAAM,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IAC9E,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAM,CAAA;AACzC,CAAC,CAAA;AAHY,QAAA,KAAK,GAAL,KAAK,CAGjB;AAEM,MAAM,YAAY,GAAG,CAC1B,GAAG,MAA2C,EAC3C,EAAE;IACL,MAAM,MAAM,GAAe,EAAE,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK;YAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAA,QAAA,KAAK,EAAC,KAAK,CAAC,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,MAAW,CAAA;AACpB,CAAC,CAAA;AARY,QAAA,YAAY,GAAZ,YAAY,CAQxB"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;GAIG;AACI,MAAM,KAAK,GAAG,CAAgC,GAAM,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IAC9E,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAM,CAAA;AACzC,CAAC,CAAA;AAHY,QAAA,KAAK,GAAL,KAAK,CAGjB;AAEM,MAAM,YAAY,GAAG,CAC1B,GAAG,MAA2C,EAC3C,EAAE;IACL,MAAM,MAAM,GAAe,EAAE,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAA,QAAA,KAAK,EAAC,KAAK,CAAC,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IACD,OAAO,MAAW,CAAA;AACpB,CAAC,CAAA;AAVY,QAAA,YAAY,GAAZ,YAAY,CAUxB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@microsoft/agents-hosting",
4
- "version": "1.10.0-beta.9.g18d68b903e",
4
+ "version": "1.10.1",
5
5
  "homepage": "https://github.com/microsoft/Agents-for-js",
6
6
  "repository": {
7
7
  "type": "git",
@@ -21,8 +21,8 @@
21
21
  "dependencies": {
22
22
  "@azure/core-auth": "1.10.1",
23
23
  "@azure/msal-node": "5.6.0",
24
- "@microsoft/agents-activity": "1.10.0-beta.9.g18d68b903e",
25
- "@microsoft/agents-telemetry": "1.10.0-beta.9.g18d68b903e",
24
+ "@microsoft/agents-activity": "1.10.1",
25
+ "@microsoft/agents-telemetry": "1.10.1",
26
26
  "jsonwebtoken": "9.0.3",
27
27
  "jwks-rsa": "4.0.1",
28
28
  "zod": "3.25.75"
@@ -255,9 +255,15 @@ export class ActivityHandler {
255
255
  * @throws Error if context is missing, activity is missing, or activity type is missing
256
256
  */
257
257
  async run (context: TurnContext): Promise<void> {
258
- if (!context) throw ExceptionHelper.generateException(Error, Errors.MissingTurnContext)
259
- if (!context.activity) throw ExceptionHelper.generateException(Error, Errors.TurnContextMissingActivity)
260
- if (!context.activity.type) throw ExceptionHelper.generateException(Error, Errors.ActivityMissingType)
258
+ if (!context) {
259
+ throw ExceptionHelper.generateException(Error, Errors.MissingTurnContext)
260
+ }
261
+ if (!context.activity) {
262
+ throw ExceptionHelper.generateException(Error, Errors.TurnContextMissingActivity)
263
+ }
264
+ if (!context.activity.type) {
265
+ throw ExceptionHelper.generateException(Error, Errors.ActivityMissingType)
266
+ }
261
267
 
262
268
  await this.handle(context, 'Turn', async () => {
263
269
  await this.onTurnActivity(context)
@@ -24,6 +24,13 @@ import { AGENT_RESPONSE_ROUTE_PATH, createAgentResponseHandler } from './createA
24
24
  * `post(path, handler)` method structurally matches satisfies it.
25
25
  */
26
26
  export interface WebApp {
27
+ /**
28
+ * Registers a handler for HTTP POST requests at the specified path.
29
+ *
30
+ * @param path - Route path to register.
31
+ * @param handler - Request handler invoked for matching requests.
32
+ * @returns A framework-specific registration result.
33
+ */
27
34
  post (
28
35
  path: string,
29
36
  handler: (req: any, res: any) => unknown | Promise<unknown>
@@ -33,7 +33,9 @@ interface DelegatedConversationState {
33
33
  * the framework's URL path parser.
34
34
  */
35
35
  export interface AgentResponseHandlerParams {
36
+ /** ID of the conversation receiving the callback activity. */
36
37
  conversationId: string
38
+ /** ID to assign to the callback activity. */
37
39
  activityId: string
38
40
  }
39
41
 
@@ -13,6 +13,7 @@ import { AdaptiveCard } from '../../cards/adaptiveCard'
13
13
  import { Query } from './query'
14
14
  import { Errors } from '../../errorHelper'
15
15
 
16
+ /** Invoke activity name used for Adaptive Card actions. */
16
17
  export const ACTION_INVOKE_NAME = 'adaptiveCard/action'
17
18
  const ACTION_EXECUTE_TYPE = 'Action.Execute'
18
19
  const DEFAULT_ACTION_SUBMIT_FILTER = 'verb'
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ExceptionHelper } from '@microsoft/agents-activity'
7
+ import { debug } from '@microsoft/agents-telemetry'
8
+ import { Errors } from '../errorHelper'
9
+ import { HttpClient, HttpError, HttpResponse } from '../httpClient'
10
+ import { OutboundHostValidator, OutboundUrlPolicy } from '../outboundHostValidator'
11
+ import { getHttpsUrl, hasAllowedOutboundAddresses } from '../utils/outboundUrl'
12
+
13
+ const logger = debug('agents:attachmentDownloader')
14
+ const REDIRECT_STATUSES = new Set([300, 301, 302, 303, 307, 308])
15
+ const MAX_REDIRECTS = 50
16
+
17
+ export class AttachmentDownloadHttpClient {
18
+ public constructor (
19
+ private readonly httpClient: HttpClient,
20
+ private readonly hostValidator: OutboundUrlPolicy
21
+ ) {}
22
+
23
+ public async get (url: string, headers: Record<string, string> = {}): Promise<HttpResponse<ArrayBuffer> | undefined> {
24
+ if (!this.hostValidator.enabled) {
25
+ if (!this.hostValidator.isAllowed(url)) {
26
+ return this.blocked(url)
27
+ }
28
+ return this.httpClient.get<ArrayBuffer>(url, { headers, responseType: 'arraybuffer' })
29
+ }
30
+
31
+ let currentUrl = url
32
+ for (let redirects = 0; ; redirects++) {
33
+ const parsed = getHttpsUrl(currentUrl)
34
+ const allowed = parsed && (this.hostValidator instanceof OutboundHostValidator
35
+ ? await this.hostValidator.isAllowedAsync(parsed)
36
+ : this.hostValidator.isAllowed(currentUrl) && await hasAllowedOutboundAddresses(parsed))
37
+ if (!allowed) {
38
+ return this.blocked(currentUrl)
39
+ }
40
+
41
+ const requestHeaders = new Headers(redirects === 0 ? headers : undefined)
42
+ const response = await fetch(currentUrl, { method: 'GET', headers: requestHeaders, redirect: 'manual' })
43
+ const location = response.headers.get('location')
44
+ if (REDIRECT_STATUSES.has(response.status) && location) {
45
+ await response.body?.cancel()
46
+ if (redirects >= MAX_REDIRECTS) {
47
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentDownloadRedirectLimit)
48
+ }
49
+ try {
50
+ currentUrl = new URL(location, currentUrl).href
51
+ } catch {
52
+ throw ExceptionHelper.generateException(Error, Errors.AttachmentDownloadInvalidRedirect)
53
+ }
54
+ continue
55
+ }
56
+
57
+ const config = { method: 'get', url: currentUrl, responseType: 'arraybuffer' as const }
58
+ const result: HttpResponse<ArrayBuffer> = {
59
+ data: await response.arrayBuffer(),
60
+ status: response.status,
61
+ statusText: response.statusText,
62
+ headers: response.headers,
63
+ config
64
+ }
65
+ if (!response.ok) {
66
+ throw new HttpError(`Request failed with status ${response.status}`, result, config)
67
+ }
68
+ return result
69
+ }
70
+ }
71
+
72
+ private blocked (input: string): undefined {
73
+ let host = '[invalid-url]'
74
+ try {
75
+ host = new URL(input).hostname
76
+ } catch { /* Invalid URLs have no safe host to log. */ }
77
+ logger.warn(`Attachment destination blocked by outbound policy or address validation. Host='${host}'`)
78
+ return undefined
79
+ }
80
+ }
@@ -13,6 +13,7 @@ import { debug } from '@microsoft/agents-telemetry'
13
13
  import { loadAuthConfigFromEnv, MsalTokenProvider } from '../auth'
14
14
  import { createOutboundHostValidator, OutboundUrlPolicy } from '../outboundHostValidator'
15
15
  import { Connections } from '../auth/connections'
16
+ import { AttachmentDownloadHttpClient } from './attachmentDownloadHttpClient'
16
17
 
17
18
  const logger = debug('agents:attachmentDownloader')
18
19
 
@@ -24,6 +25,8 @@ const logger = debug('agents:attachmentDownloader')
24
25
  * @remarks
25
26
  * This class provides functionality to filter and download attachments from a turn context,
26
27
  * supporting various content types and handling authentication for secure URLs.
28
+ * Enabled outbound validation requires HTTPS and validates addresses at every redirect.
29
+ * Initial request credentials are not forwarded to redirects when validation is enabled.
27
30
  *
28
31
  */
29
32
  export class AttachmentDownloader<TState extends TurnState = TurnState> implements InputFileDownloader<TState> {
@@ -103,18 +106,12 @@ export class AttachmentDownloader<TState extends TurnState = TurnState> implemen
103
106
  if (accessToken.length > 0) {
104
107
  headers.Authorization = `Bearer ${accessToken}`
105
108
  }
106
- if (!this._hostValidator.isAllowed(attachment.contentUrl)) {
107
- let host = '[invalid-url]'
108
- try { host = new URL(attachment.contentUrl).hostname } catch { /* invalid */ }
109
- logger.warn(`Attachment contentUrl host is not in the configured allowed hosts. Host='${host}'`)
109
+ const response = await new AttachmentDownloadHttpClient(this._httpClient, this._hostValidator)
110
+ .get(attachment.contentUrl, headers)
111
+ if (!response) {
110
112
  return undefined
111
113
  }
112
114
 
113
- const response = await this._httpClient.get(attachment.contentUrl, {
114
- headers,
115
- responseType: 'arraybuffer'
116
- })
117
-
118
115
  const content = Buffer.from(response.data as ArrayBuffer)
119
116
 
120
117
  let contentType = attachment.contentType
@@ -16,14 +16,72 @@ import { AuthorizationHandlerTokenOptions } from './types'
16
16
 
17
17
  const logger = debug('agents:authorization')
18
18
 
19
+ /** Provides user authorization, token exchange, and sign-in lifecycle operations. */
19
20
  export interface Authorization {
21
+ /**
22
+ * Gets the user token for an authorization handler.
23
+ *
24
+ * @param context - Context for the current turn.
25
+ * @param authHandlerId - Authorization handler ID.
26
+ * @returns The token response.
27
+ */
20
28
  getToken(context: TurnContext, authHandlerId: string): Promise<TokenResponse>
29
+ /**
30
+ * Creates a credential backed by the current turn's user token.
31
+ *
32
+ * @param context - Context for the current turn.
33
+ * @param authHandlerId - Authorization handler ID.
34
+ * @returns A turn-scoped token credential.
35
+ */
21
36
  getTokenAsTokenCredential?(context: TurnContext, authHandlerId: string): TokenCredential
37
+ /**
38
+ * Exchanges the user token for the requested scopes.
39
+ *
40
+ * @param context - Context for the current turn.
41
+ * @param scopes - Scopes requested for the exchanged token.
42
+ * @param authHandlerId - Authorization handler ID.
43
+ * @returns The exchanged token response.
44
+ * @deprecated Use the overload that accepts an authorization handler ID followed by options.
45
+ */
22
46
  exchangeToken(context: TurnContext, scopes: string[], authHandlerId: string): Promise<TokenResponse>
47
+ /**
48
+ * Exchanges the user token using an authorization handler.
49
+ *
50
+ * @param context - Context for the current turn.
51
+ * @param authHandlerId - Authorization handler ID.
52
+ * @param options - Optional connection and scope overrides.
53
+ * @returns The exchanged token response.
54
+ */
23
55
  exchangeToken(context: TurnContext, authHandlerId: string, options?: AuthorizationHandlerTokenOptions): Promise<TokenResponse>
56
+ /**
57
+ * Creates a credential that exchanges the current turn's user token.
58
+ *
59
+ * @param context - Context for the current turn.
60
+ * @param authHandlerId - Authorization handler ID.
61
+ * @param options - Optional connection and scope overrides.
62
+ * @returns A turn-scoped token credential.
63
+ */
24
64
  exchangeTokenAsTokenCredential?(context: TurnContext, authHandlerId: string, options?: AuthorizationHandlerTokenOptions): TokenCredential
65
+ /**
66
+ * Signs out the user from one or all authorization handlers.
67
+ *
68
+ * @param context - Context for the current turn.
69
+ * @param state - State for the current turn.
70
+ * @param authHandlerId - Handler to sign out from, or `undefined` for all handlers.
71
+ * @returns A promise that resolves after sign-out completes.
72
+ */
25
73
  signOut(context: TurnContext, state: TurnState, authHandlerId?: string): Promise<void>
74
+ /**
75
+ * Registers a callback for successful sign-in.
76
+ *
77
+ * @param handler - Callback invoked after sign-in succeeds.
78
+ */
26
79
  onSignInSuccess(handler: (context: TurnContext, state: TurnState, authHandlerId?: string) => Promise<void>): void
80
+ /**
81
+ * Registers a callback for failed sign-in.
82
+ *
83
+ * @param handler - Callback invoked after sign-in fails.
84
+ */
27
85
  onSignInFailure(handler: (context: TurnContext, state: TurnState, authHandlerId?: string, errorMessage?: string) => Promise<void>): void
28
86
  }
29
87
 
@@ -12,10 +12,15 @@ import { Errors } from '../../errorHelper'
12
12
  * `aud` (the agent's client ID) is required; all other fields are optional.
13
13
  */
14
14
  export interface ConversationClaims {
15
+ /** Audience identifying the agent client. */
15
16
  aud: string
17
+ /** Authorized-party client ID, when supplied by the token. */
16
18
  azp?: string
19
+ /** Calling application ID, when supplied by the token. */
17
20
  appid?: string
21
+ /** Microsoft Entra tenant ID, when supplied by the token. */
18
22
  tid?: string
23
+ /** Additional string-valued identity claims. */
19
24
  [key: string]: string | undefined
20
25
  }
21
26
 
@@ -28,11 +33,30 @@ export interface ConversationClaims {
28
33
  * `adapter.continueConversation()`.
29
34
  */
30
35
  export class Conversation {
36
+ /** Reference used to resume the conversation. */
31
37
  reference: ConversationReference
38
+ /** Identity claims used to authenticate proactive operations. */
32
39
  claims: ConversationClaims
33
40
 
41
+ /**
42
+ * Creates a conversation from the current turn.
43
+ *
44
+ * @param context - Turn context from which to capture the reference and identity.
45
+ */
34
46
  constructor (context: TurnContext)
47
+ /**
48
+ * Creates a conversation from explicit claims and a conversation reference.
49
+ *
50
+ * @param claims - Claims used to authenticate proactive operations.
51
+ * @param reference - Reference used to resume the conversation.
52
+ */
35
53
  constructor (claims: ConversationClaims, reference: ConversationReference)
54
+ /**
55
+ * Creates a conversation from a turn context or explicit claims and a reference.
56
+ *
57
+ * @param contextOrClaims - Turn context to capture, or authentication claims.
58
+ * @param reference - Reference paired with explicit claims.
59
+ */
36
60
  constructor (
37
61
  contextOrClaims: TurnContext | ConversationClaims,
38
62
  reference?: ConversationReference
@@ -55,7 +55,9 @@ export class ConversationBuilder {
55
55
  requestorId?: string
56
56
  ): ConversationBuilder {
57
57
  const claims: ConversationClaims = { aud: agentClientId }
58
- if (requestorId) claims.appid = requestorId
58
+ if (requestorId) {
59
+ claims.appid = requestorId
60
+ }
59
61
  return new ConversationBuilder(agentClientId, channelId, serviceUrl ?? '', claims, ConversationReferenceBuilder.create(agentClientId, channelId, serviceUrl).build())
60
62
  }
61
63
 
@@ -71,8 +71,12 @@ export class ConversationReferenceBuilder {
71
71
  * `https://{channelId}.botframework.com/` pattern (matching C# behavior).
72
72
  */
73
73
  static serviceUrlForChannel (channelId: string): string {
74
- if (!channelId) return ''
75
- if (channelId === Channels.Msteams) return TeamsServiceEndpoints.publicGlobal
74
+ if (!channelId) {
75
+ return ''
76
+ }
77
+ if (channelId === Channels.Msteams) {
78
+ return TeamsServiceEndpoints.publicGlobal
79
+ }
76
80
  if (!knownChannelIds.has(channelId)) {
77
81
  logger.warn(
78
82
  `serviceUrlForChannel: unrecognized channelId '${channelId}' — constructing fallback URL ` +
@@ -141,8 +145,12 @@ export class ConversationReferenceBuilder {
141
145
  user: this._user ?? { role: RoleTypes.User },
142
146
  }
143
147
 
144
- if (this._activityId !== undefined) ref.activityId = this._activityId
145
- if (this._locale !== undefined) ref.locale = this._locale
148
+ if (this._activityId !== undefined) {
149
+ ref.activityId = this._activityId
150
+ }
151
+ if (this._locale !== undefined) {
152
+ ref.locale = this._locale
153
+ }
146
154
 
147
155
  return ref
148
156
  }
@@ -81,6 +81,8 @@ export class CreateConversationOptionsBuilder {
81
81
 
82
82
  /** Adds a member (the target user) to `parameters.members`. */
83
83
  withUser (userId: string, userName?: string): this
84
+
85
+ /** Adds a channel account as a member in `parameters.members`. */
84
86
  withUser (account: ChannelAccount): this
85
87
  withUser (userIdOrAccount: string | ChannelAccount, userName?: string): this {
86
88
  const account: ChannelAccount =
@@ -125,7 +127,9 @@ export class CreateConversationOptionsBuilder {
125
127
  * Only has effect on `msteams` channels.
126
128
  */
127
129
  withTeamsChannelId (teamsChannelId: string): this {
128
- if (this._channelId !== Channels.Msteams) return this
130
+ if (this._channelId !== Channels.Msteams) {
131
+ return this
132
+ }
129
133
  this._parameters = { ...this._parameters, isGroup: true }
130
134
  this.withChannelData({ channel: { id: teamsChannelId } })
131
135
  return this
@@ -49,6 +49,12 @@ export class Proactive<TState extends TurnState> {
49
49
  private readonly _options: ProactiveOptions
50
50
  private readonly _storage?: StorageV2
51
51
 
52
+ /**
53
+ * Creates a proactive conversation manager.
54
+ *
55
+ * @param app - Application that owns the proactive operations.
56
+ * @param options - Proactive messaging configuration.
57
+ */
52
58
  constructor (app: AgentApplication<TState>, options: ProactiveOptions) {
53
59
  this._app = app
54
60
  this._options = options
@@ -113,6 +119,12 @@ export class Proactive<TState extends TurnState> {
113
119
  * ```
114
120
  */
115
121
  storeConversation (conversation: Conversation): Promise<string>
122
+ /**
123
+ * Stores a conversation captured from a turn context or supplied explicitly.
124
+ *
125
+ * @param contextOrConversation - Turn context or conversation to store.
126
+ * @returns The stored conversation ID.
127
+ */
116
128
  async storeConversation (contextOrConversation: TurnContext | Conversation): Promise<string> {
117
129
  return trace(ProactiveTraceDefinitions.storeConversation, async ({ record, actions }) => {
118
130
  const conv =
@@ -243,6 +255,14 @@ export class Proactive<TState extends TurnState> {
243
255
  * ```
244
256
  */
245
257
  sendActivity (adapter: BaseAdapter, conversation: Conversation, activity: Partial<Activity>): Promise<ResourceResponse>
258
+ /**
259
+ * Sends an activity to a stored or explicitly supplied conversation.
260
+ *
261
+ * @param adapter - Channel adapter used to continue the conversation.
262
+ * @param conversationOrId - Conversation or stored conversation ID.
263
+ * @param activity - Activity fields to send.
264
+ * @returns The channel resource response.
265
+ */
246
266
  async sendActivity (
247
267
  adapter: BaseAdapter,
248
268
  conversationOrId: Conversation | string,
@@ -285,7 +305,9 @@ export class Proactive<TState extends TurnState> {
285
305
  logger.warn('sendActivity: failed for conversation=%s: %s', id, caughtError)
286
306
  throw caughtError
287
307
  }
288
- if (response === undefined) throw ExceptionHelper.generateException(Error, Errors.ProactiveSendActivityNoResponse)
308
+ if (response === undefined) {
309
+ throw ExceptionHelper.generateException(Error, Errors.ProactiveSendActivityNoResponse)
310
+ }
289
311
  logger.debug('sendActivity: sent activity id=%s', response.id)
290
312
  return response
291
313
  })
@@ -359,6 +381,16 @@ export class Proactive<TState extends TurnState> {
359
381
  * ```
360
382
  */
361
383
  continueConversation (adapter: BaseAdapter, conversation: Conversation, handler: RouteHandler<TState>, autoSignInHandlers?: string[], continuationActivity?: Partial<Activity>): Promise<void>
384
+ /**
385
+ * Continues a stored or explicitly supplied conversation.
386
+ *
387
+ * @param adapter - Channel adapter used to continue the conversation.
388
+ * @param conversationOrId - Conversation or stored conversation ID.
389
+ * @param handler - Handler to execute in the continued turn.
390
+ * @param autoSignInHandlers - Connections for which tokens are acquired before the handler runs.
391
+ * @param continuationActivity - Activity fields merged into the continuation activity.
392
+ * @returns A promise that resolves after the continued turn completes.
393
+ */
362
394
  async continueConversation (
363
395
  adapter: BaseAdapter,
364
396
  conversationOrId: Conversation | string,
@@ -9,9 +9,25 @@ import { RouteRank } from './routeRank'
9
9
  import { RouteSelector } from './routeSelector'
10
10
  import { TurnState } from './turnState'
11
11
 
12
+ /**
13
+ * Maintains application routes in dispatch priority order.
14
+ *
15
+ * @typeParam TState - Turn state supplied to route handlers.
16
+ */
12
17
  export class RouteList<TState extends TurnState> {
13
18
  private _routes: Array<AppRoute<TState>> = []
14
19
 
20
+ /**
21
+ * Adds a route and orders it by route kind and rank.
22
+ *
23
+ * @param selector - Selector that determines whether the route matches.
24
+ * @param handler - Handler invoked for a matching route.
25
+ * @param isInvokeRoute - Whether the route handles invoke activities.
26
+ * @param rank - Rank used to order routes of the same kind.
27
+ * @param authHandlers - Authentication handlers required by the route.
28
+ * @param isAgenticRoute - Whether the route handles agentic requests.
29
+ * @returns This route list.
30
+ */
15
31
  public addRoute (
16
32
  selector: RouteSelector,
17
33
  handler: RouteHandler<TState>,
@@ -30,9 +46,15 @@ export class RouteList<TState extends TurnState> {
30
46
  // Then by Rank
31
47
  this._routes.sort((a, b) => {
32
48
  const getPriority = (route: AppRoute<TState>) => {
33
- if (route.isAgenticRoute && route.isInvokeRoute) return 0
34
- if (route.isInvokeRoute) return 1
35
- if (route.isAgenticRoute) return 2
49
+ if (route.isAgenticRoute && route.isInvokeRoute) {
50
+ return 0
51
+ }
52
+ if (route.isInvokeRoute) {
53
+ return 1
54
+ }
55
+ if (route.isAgenticRoute) {
56
+ return 2
57
+ }
36
58
  return 3
37
59
  }
38
60
 
@@ -50,6 +72,11 @@ export class RouteList<TState extends TurnState> {
50
72
  return this
51
73
  }
52
74
 
75
+ /**
76
+ * Iterates over routes in dispatch priority order.
77
+ *
78
+ * @returns An iterator over the registered routes.
79
+ */
53
80
  public [Symbol.iterator] (): Iterator<AppRoute<TState>> {
54
81
  return this._routes[Symbol.iterator]()
55
82
  }