@microsoft/agents-hosting 1.6.0-beta.8.g226709c215 → 1.6.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 (94) hide show
  1. package/dist/package.json +4 -9
  2. package/dist/src/agent-client/agentClient.js +2 -2
  3. package/dist/src/agent-client/agentClient.js.map +1 -1
  4. package/dist/src/agent-client/agentResponseHandler.js +2 -2
  5. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  6. package/dist/src/app/agentApplication.js +28 -2
  7. package/dist/src/app/agentApplication.js.map +1 -1
  8. package/dist/src/app/agentApplicationOptions.d.ts +10 -0
  9. package/dist/src/app/attachmentDownloader.js +5 -10
  10. package/dist/src/app/attachmentDownloader.js.map +1 -1
  11. package/dist/src/app/auth/authorizationManager.d.ts +4 -0
  12. package/dist/src/app/auth/authorizationManager.js +94 -67
  13. package/dist/src/app/auth/authorizationManager.js.map +1 -1
  14. package/dist/src/app/auth/handlers/azureBotAuthorization.js +2 -2
  15. package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -1
  16. package/dist/src/app/proactive/createConversationOptionsBuilder.js +10 -6
  17. package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
  18. package/dist/src/app/proactive/proactive.d.ts +1 -0
  19. package/dist/src/app/proactive/proactive.js +30 -15
  20. package/dist/src/app/proactive/proactive.js.map +1 -1
  21. package/dist/src/app/teamsAttachmentDownloader.js +6 -8
  22. package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
  23. package/dist/src/auth/authConfiguration.d.ts +2 -143
  24. package/dist/src/auth/authConfiguration.js +301 -257
  25. package/dist/src/auth/authConfiguration.js.map +1 -1
  26. package/dist/src/auth/jwt-middleware.js +2 -1
  27. package/dist/src/auth/jwt-middleware.js.map +1 -1
  28. package/dist/src/auth/msalConnectionManager.js +27 -14
  29. package/dist/src/auth/msalConnectionManager.js.map +1 -1
  30. package/dist/src/auth/msalTokenProvider.d.ts +7 -0
  31. package/dist/src/auth/msalTokenProvider.js +188 -44
  32. package/dist/src/auth/msalTokenProvider.js.map +1 -1
  33. package/dist/src/auth/settings.d.ts +327 -0
  34. package/dist/src/auth/settings.js +158 -0
  35. package/dist/src/auth/settings.js.map +1 -0
  36. package/dist/src/cloudAdapter.d.ts +58 -1
  37. package/dist/src/cloudAdapter.js +232 -52
  38. package/dist/src/cloudAdapter.js.map +1 -1
  39. package/dist/src/connector-client/connectorClient.d.ts +12 -8
  40. package/dist/src/connector-client/connectorClient.js +99 -82
  41. package/dist/src/connector-client/connectorClient.js.map +1 -1
  42. package/dist/src/errorHelper.js +85 -7
  43. package/dist/src/errorHelper.js.map +1 -1
  44. package/dist/src/getProductInfo.d.ts +23 -0
  45. package/dist/src/getProductInfo.js +71 -1
  46. package/dist/src/getProductInfo.js.map +1 -1
  47. package/dist/src/headerPropagation.d.ts +17 -2
  48. package/dist/src/headerPropagation.js +46 -24
  49. package/dist/src/headerPropagation.js.map +1 -1
  50. package/dist/src/httpClient.d.ts +60 -0
  51. package/dist/src/httpClient.js +173 -0
  52. package/dist/src/httpClient.js.map +1 -0
  53. package/dist/src/index.d.ts +2 -1
  54. package/dist/src/index.js +7 -2
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/oauth/userTokenClient.d.ts +5 -4
  57. package/dist/src/oauth/userTokenClient.js +97 -78
  58. package/dist/src/oauth/userTokenClient.js.map +1 -1
  59. package/dist/src/observability/traces.d.ts +11 -4
  60. package/dist/src/observability/traces.js +39 -7
  61. package/dist/src/observability/traces.js.map +1 -1
  62. package/dist/src/utils/env.d.ts +50 -0
  63. package/dist/src/utils/env.js +113 -0
  64. package/dist/src/utils/env.js.map +1 -0
  65. package/dist/src/utils.d.ts +10 -0
  66. package/dist/src/utils.js +18 -0
  67. package/dist/src/utils.js.map +1 -0
  68. package/package.json +4 -9
  69. package/src/agent-client/agentClient.ts +2 -2
  70. package/src/agent-client/agentResponseHandler.ts +2 -2
  71. package/src/app/agentApplication.ts +30 -3
  72. package/src/app/agentApplicationOptions.ts +11 -0
  73. package/src/app/attachmentDownloader.ts +6 -8
  74. package/src/app/auth/authorizationManager.ts +84 -41
  75. package/src/app/auth/handlers/azureBotAuthorization.ts +2 -2
  76. package/src/app/proactive/createConversationOptionsBuilder.ts +8 -4
  77. package/src/app/proactive/proactive.ts +39 -23
  78. package/src/app/teamsAttachmentDownloader.ts +7 -6
  79. package/src/auth/authConfiguration.ts +317 -356
  80. package/src/auth/jwt-middleware.ts +1 -1
  81. package/src/auth/msalConnectionManager.ts +27 -10
  82. package/src/auth/msalTokenProvider.ts +180 -42
  83. package/src/auth/settings.ts +323 -0
  84. package/src/cloudAdapter.ts +291 -12
  85. package/src/connector-client/connectorClient.ts +116 -94
  86. package/src/errorHelper.ts +96 -7
  87. package/src/getProductInfo.ts +79 -1
  88. package/src/headerPropagation.ts +55 -23
  89. package/src/httpClient.ts +223 -0
  90. package/src/index.ts +5 -1
  91. package/src/oauth/userTokenClient.ts +103 -84
  92. package/src/observability/traces.ts +39 -8
  93. package/src/utils/env.ts +105 -0
  94. package/src/utils.ts +14 -0
@@ -3,18 +3,271 @@
3
3
  * Copyright (c) Microsoft Corporation. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
6
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.envParserUtils = exports.loadPrevAuthConfigFromEnv = exports.loadAuthConfigFromEnv = void 0;
7
+ exports.loadPrevAuthConfigFromEnv = exports.loadAuthConfigFromEnv = exports.resolveAuthority = exports.AuthType = void 0;
11
8
  exports.getAuthConfigWithDefaults = getAuthConfigWithDefaults;
12
- exports.resolveAuthority = resolveAuthority;
13
- exports.envParser = envParser;
14
9
  const agents_telemetry_1 = require("@microsoft/agents-telemetry");
15
- const object_path_1 = __importDefault(require("object-path"));
10
+ const settings_1 = require("./settings");
11
+ var settings_2 = require("./settings");
12
+ Object.defineProperty(exports, "AuthType", { enumerable: true, get: function () { return settings_2.AuthType; } });
13
+ Object.defineProperty(exports, "resolveAuthority", { enumerable: true, get: function () { return settings_2.resolveAuthority; } });
14
+ const utils_1 = require("../utils");
16
15
  const logger = (0, agents_telemetry_1.debug)('agents:authConfiguration');
17
- const DEFAULT_CONNECTION = 'serviceConnection';
16
+ /**
17
+ * Summarizes the authentication configuration for logging by redacting sensitive information and pruning undefined values. This is used to log the loaded authentication settings without exposing secrets or personally identifiable information.
18
+ * @remarks AuthConfiguration properties can change its shape, since this function is intended for logging, e.g. `scopes` will be a string instead of an array.
19
+ */
20
+ function summarizeAuthConfiguration(authConfig) {
21
+ var _a, _b;
22
+ return [...(_b = (_a = authConfig.connections) === null || _a === void 0 ? void 0 : _a.entries()) !== null && _b !== void 0 ? _b : []].reduce((summary, [name, config]) => {
23
+ var _a, _b;
24
+ summary[name] = (0, utils_1.prune)({
25
+ clientId: (0, agents_telemetry_1.redactString)(config.clientId, true),
26
+ tenantId: (0, agents_telemetry_1.redactString)(config.tenantId, true),
27
+ clientSecret: (0, agents_telemetry_1.redactString)(config.clientSecret),
28
+ authorityEndpoint: config.authorityEndpoint ? (0, agents_telemetry_1.redactUrl)(config.authorityEndpoint) : undefined,
29
+ scopes: (config.scopes ? (0, agents_telemetry_1.redactScopes)(config.scopes) : undefined),
30
+ issuers: (_a = config.issuers) === null || _a === void 0 ? void 0 : _a.map(agents_telemetry_1.redactUrl).filter(e => e !== undefined),
31
+ federatedClientId: (0, agents_telemetry_1.redactString)(config.federatedClientId, true),
32
+ certPemFile: (0, agents_telemetry_1.redactString)(config.certPemFile),
33
+ certKeyFile: (0, agents_telemetry_1.redactString)(config.certKeyFile),
34
+ WIDAssertionFile: (0, agents_telemetry_1.redactString)(config.WIDAssertionFile),
35
+ federatedTokenFile: config.federatedTokenFile ? (0, agents_telemetry_1.redactString)(config.federatedTokenFile) : undefined,
36
+ authType: (_b = config.authType) !== null && _b !== void 0 ? _b : undefined,
37
+ idpmResource: config.idpmResource ? (0, agents_telemetry_1.redactUrl)(config.idpmResource) : undefined,
38
+ connectionName: config.connectionName,
39
+ altBlueprintConnectionName: config.altBlueprintConnectionName,
40
+ azureRegion: config.azureRegion,
41
+ sendX5C: config.sendX5C,
42
+ // Don't log the following properties
43
+ authority: undefined, // Deprecated, same as authorityEndpoint, avoid logging duplicate info
44
+ FICClientId: undefined, // Deprecated, same as federatedClientId, avoid logging duplicate info
45
+ scope: undefined, // Deprecated, same as scopes, avoid logging duplicate info
46
+ connections: undefined, // Avoid logging nested connections
47
+ connectionsMap: undefined, // Avoid logging nested connections map
48
+ });
49
+ return summary;
50
+ }, {});
51
+ }
52
+ /**
53
+ * Latest authentication configuration loaded from environment variables, with support for hot-reloading in test mode.
54
+ * Environment variables for connections should be in the format Connections__<id>__Settings__<property>, e.g. Connections__MyConnection__Settings__ClientId, Connections__MyConnection__Settings__TenantId, etc.
55
+ * Environment variables for connections map should be in the format ConnectionsMap__<index>__<property>, e.g. ConnectionsMap__0__ServiceUrl, ConnectionsMap__0__Connection, etc.
56
+ */
57
+ const connectionsEnv = {
58
+ connections: new Map(),
59
+ parser: (0, settings_1.envParser)({
60
+ authType: settings_1.envParserUtils.bypass,
61
+ tenantId: settings_1.envParserUtils.bypass,
62
+ clientId: settings_1.envParserUtils.bypass,
63
+ clientSecret: settings_1.envParserUtils.bypass,
64
+ certPemFile: settings_1.envParserUtils.bypass,
65
+ certKeyFile: settings_1.envParserUtils.bypass,
66
+ connectionName: settings_1.envParserUtils.bypass,
67
+ federatedClientId: settings_1.envParserUtils.bypass,
68
+ FICClientId(value) {
69
+ logger.warn('Connections__<id>__Settings__FICClientId is deprecated, please use Connections__<id>__Settings__FederatedClientId instead.');
70
+ return { key: 'federatedClientId', value }; // redirect
71
+ },
72
+ authorityEndpoint: settings_1.envParserUtils.bypass,
73
+ authority(value) {
74
+ logger.warn('Connections__<id>__Settings__Authority is deprecated, please use Connections__<id>__Settings__AuthorityEndpoint instead.');
75
+ return { key: 'authorityEndpoint', value }; // redirect
76
+ },
77
+ scopes(value) {
78
+ return this.issuers(value); // scopes can be comma or space separated list, same as issuers.
79
+ },
80
+ scope(value) {
81
+ var _a;
82
+ logger.warn('Connections__<id>__Settings__Scope is deprecated, please use Connections__<id>__Settings__Scopes instead.');
83
+ return { key: 'scopes', value: (_a = this.scopes(value)) === null || _a === void 0 ? void 0 : _a.value }; // redirect with single scope
84
+ },
85
+ altBlueprintConnectionName: settings_1.envParserUtils.bypass,
86
+ WIDAssertionFile: settings_1.envParserUtils.bypass,
87
+ federatedTokenFile: settings_1.envParserUtils.bypass,
88
+ idpmResource: settings_1.envParserUtils.bypass,
89
+ azureRegion: settings_1.envParserUtils.bypass,
90
+ sendX5C: (value) => ({ value: value === 'true' }),
91
+ issuers(value) {
92
+ if (value.includes(',')) {
93
+ return { value: value.split(',').map(s => s.trim()).filter(Boolean) };
94
+ }
95
+ return { value: value.split(/\s+/).filter(Boolean) };
96
+ },
97
+ }),
98
+ default(connections, connectionsMap) {
99
+ var _a;
100
+ const conn = connections !== null && connections !== void 0 ? connections : this.connections;
101
+ const map = connectionsMap !== null && connectionsMap !== void 0 ? connectionsMap : connectionsMapEnv.connectionsMap;
102
+ const name = (_a = map === null || map === void 0 ? void 0 : map.find((item) => item.serviceUrl === '*')) === null || _a === void 0 ? void 0 : _a.connection;
103
+ if (!name) {
104
+ throw new Error('No default connection found in environment connections.');
105
+ }
106
+ const connection = conn === null || conn === void 0 ? void 0 : conn.get(name !== null && name !== void 0 ? name : '');
107
+ if (!connection) {
108
+ throw new Error(`Connection "${name}" not found in environment connections.`);
109
+ }
110
+ return (0, settings_1.applyDefaultSettings)({ ...connection, connections: conn, connectionsMap: map });
111
+ },
112
+ process(key, value) {
113
+ var _a;
114
+ const format = 'Connections__<id>__Settings__<property>';
115
+ const parts = key.split('__');
116
+ const [connections, id, settings, prop] = parts;
117
+ if (`${connections}/${settings}`.toUpperCase() !== 'CONNECTIONS/SETTINGS') {
118
+ return false;
119
+ }
120
+ if (parts.length !== 4) {
121
+ logger.warn(`Invalid connection environment variable: ${key}. Expected format: ${format}.`);
122
+ return false;
123
+ }
124
+ if (!(id === null || id === void 0 ? void 0 : id.trim())) {
125
+ logger.warn(`Invalid connection <id> in environment variable: ${key}. Expected format: ${format}.`);
126
+ return false;
127
+ }
128
+ if (!(prop === null || prop === void 0 ? void 0 : prop.trim())) {
129
+ logger.warn(`Invalid connection <property> in environment variable: ${key}. Expected format: ${format}.`);
130
+ return false;
131
+ }
132
+ const result = this.parser.parse(prop, value);
133
+ if (!result.key) {
134
+ return false;
135
+ }
136
+ const config = (_a = this.connections.get(id)) !== null && _a !== void 0 ? _a : {};
137
+ config[result.key] = result.value;
138
+ this.connections.set(id, config);
139
+ return true;
140
+ },
141
+ };
142
+ const connectionsMapEnv = {
143
+ connectionsMap: [],
144
+ parser: (0, settings_1.envParser)({
145
+ serviceUrl: settings_1.envParserUtils.bypass,
146
+ connection: settings_1.envParserUtils.bypass,
147
+ audience: settings_1.envParserUtils.bypass,
148
+ }),
149
+ process(key, value) {
150
+ var _a;
151
+ const format = 'ConnectionsMap__<index>__<property>';
152
+ const parts = key.split('__');
153
+ const [connectionsMap, index, prop] = parts;
154
+ if (connectionsMap.toUpperCase() !== 'CONNECTIONSMAP') {
155
+ return false;
156
+ }
157
+ if (parts.length !== 3) {
158
+ logger.warn(`Invalid connection map environment variable: ${key}. Expected format: ${format}.`);
159
+ return false;
160
+ }
161
+ const indexNumber = parseInt(index, 10);
162
+ if (!(index === null || index === void 0 ? void 0 : index.trim()) || isNaN(indexNumber) || indexNumber < 0) {
163
+ logger.warn(`Invalid connection map <index> in environment variable: ${key}. Expected format: ${format}, where <index> is a number.`);
164
+ return false;
165
+ }
166
+ if (!(prop === null || prop === void 0 ? void 0 : prop.trim())) {
167
+ logger.warn(`Invalid connection map <property> in environment variable: ${key}. Expected format: ${format}.`);
168
+ return false;
169
+ }
170
+ const result = this.parser.parse(prop, value);
171
+ if (!result.key) {
172
+ return false;
173
+ }
174
+ const mapItem = (_a = this.connectionsMap[indexNumber]) !== null && _a !== void 0 ? _a : { ...settings_1.DEFAULT_CONNECTION_MAP };
175
+ mapItem[result.key] = result.value;
176
+ this.connectionsMap[indexNumber] = mapItem;
177
+ return true;
178
+ },
179
+ };
180
+ /**
181
+ * Legacy BotFramework style-like authentication configuration loaded from environment variables, with support for hot-reloading in test mode.
182
+ * Environment variables should be named MicrosoftAppTenantId, MicrosoftAppId, MicrosoftAppPassword, etc.
183
+ */
184
+ const legacyBotFrameworkEnv = {
185
+ parser: (0, settings_1.envParser)({
186
+ MicrosoftAppTenantId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'tenantId'),
187
+ MicrosoftAppId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientId'),
188
+ MicrosoftAppPassword: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientSecret'),
189
+ certPemFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certPemFile'),
190
+ certKeyFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certKeyFile'),
191
+ connectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'connectionName'),
192
+ MicrosoftAppClientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedClientId'),
193
+ authorityEndpoint: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authorityEndpoint'),
194
+ scope: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'scopes'),
195
+ altBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
196
+ WIDAssertionFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'WIDAssertionFile'),
197
+ azureRegion: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'azureRegion'),
198
+ sendX5C: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sendX5C'),
199
+ authType: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authType'),
200
+ federatedTokenFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedTokenFile'),
201
+ idpmResource: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'idpmResource'),
202
+ }),
203
+ process(env) {
204
+ return legacyPrefixEnv.process.call(this, env);
205
+ },
206
+ };
207
+ /**
208
+ * Legacy prefix-based authentication configuration loaded from environment variables, with support for hot-reloading in test mode.
209
+ * Environment variables should be prefixed with the connection name, e.g. <CONNECTION_NAME>_ClientId, <CONNECTION_NAME>_TenantId, etc.
210
+ */
211
+ const legacyPrefixEnv = {
212
+ parser: (0, settings_1.envParser)({
213
+ tenantId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'tenantId'),
214
+ clientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientId'),
215
+ clientSecret: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientSecret'),
216
+ certPemFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certPemFile'),
217
+ certKeyFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certKeyFile'),
218
+ connectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'connectionName'),
219
+ FICClientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedClientId'),
220
+ authorityEndpoint: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authorityEndpoint'),
221
+ scope: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'scopes'),
222
+ altBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
223
+ WIDAssertionFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'WIDAssertionFile'),
224
+ azureRegion: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'azureRegion'),
225
+ sendX5C: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sendX5C'),
226
+ authType: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authType'),
227
+ federatedTokenFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedTokenFile'),
228
+ idpmResource: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'idpmResource'),
229
+ }),
230
+ process(env, prefix) {
231
+ const settings = {};
232
+ for (const key of this.parser.keys) {
233
+ const k = prefix ? `${prefix}_${key}` : key;
234
+ const envValue = env[k.toUpperCase()];
235
+ if (!envValue) {
236
+ continue;
237
+ }
238
+ const result = this.parser.parse(key, envValue.value);
239
+ if (result.key) {
240
+ settings[result.key] = result.value;
241
+ }
242
+ }
243
+ return settings;
244
+ },
245
+ };
246
+ const loadEnv = () => {
247
+ connectionsEnv.connections = new Map();
248
+ connectionsMapEnv.connectionsMap = [];
249
+ const env = (0, settings_1.loadEnvSettings)((key, value) => {
250
+ // Process the first parser that matches the environment variable key and value,
251
+ // otherwise it continues to the next parser.
252
+ return connectionsEnv.process(key, value) ||
253
+ connectionsMapEnv.process(key, value);
254
+ });
255
+ if (connectionsEnv.connections.size === 0) {
256
+ logger.warn('No connections found in configuration.');
257
+ }
258
+ if (connectionsMapEnv.connectionsMap.length === 0 && connectionsEnv.connections.size > 0) {
259
+ logger.warn('No connections map found in configuration, assuming default connection map with serviceUrl "*" for the first connection.');
260
+ const [key] = connectionsEnv.connections.keys();
261
+ connectionsMapEnv.connectionsMap.push({ ...settings_1.DEFAULT_CONNECTION_MAP, connection: key });
262
+ }
263
+ return {
264
+ env,
265
+ legacyBotFrameworkSettings: legacyBotFrameworkEnv.process(env),
266
+ legacyPrefixSettings: legacyPrefixEnv.process(env)
267
+ };
268
+ };
269
+ // Initial load of environment variables
270
+ let globalEnv = loadEnv();
18
271
  /**
19
272
  * Loads the authentication configuration from environment variables.
20
273
  *
@@ -42,44 +295,23 @@ const DEFAULT_CONNECTION = 'serviceConnection';
42
295
  *
43
296
  */
44
297
  const loadAuthConfigFromEnv = (cnxName) => {
45
- var _a, _b, _c;
46
- const envConnections = loadConnectionsMapFromEnv();
47
- let authConfig;
48
- if (envConnections.connectionsMap.length === 0) {
49
- // No connections provided, we need to populate the connections map with the old config settings
50
- authConfig = buildLegacyAuthConfig(cnxName);
51
- envConnections.connections.set(DEFAULT_CONNECTION, authConfig);
52
- envConnections.connectionsMap.push({
53
- serviceUrl: '*',
54
- connection: DEFAULT_CONNECTION,
55
- });
298
+ var _a;
299
+ if (process.env.TEST_MODE === 'true') {
300
+ globalEnv = loadEnv();
56
301
  }
57
- else {
58
- // There are connections provided, use the default or specified connection
59
- if (cnxName) {
60
- const entry = envConnections.connections.get(cnxName);
61
- if (entry) {
62
- authConfig = entry;
63
- }
64
- else {
65
- throw new Error(`Connection "${cnxName}" not found in environment.`);
66
- }
67
- }
68
- else {
69
- const defaultItem = envConnections.connectionsMap.find((item) => item.serviceUrl === '*');
70
- const defaultConn = defaultItem ? envConnections.connections.get(defaultItem.connection) : undefined;
71
- if (!defaultConn) {
72
- throw new Error('No default connection found in environment connections.');
73
- }
74
- authConfig = defaultConn;
75
- }
76
- (_a = authConfig.authority) !== null && _a !== void 0 ? _a : (authConfig.authority = 'https://login.microsoftonline.com');
77
- (_b = authConfig.issuers) !== null && _b !== void 0 ? _b : (authConfig.issuers = getDefaultIssuers((_c = authConfig.tenantId) !== null && _c !== void 0 ? _c : '', authConfig.authority));
302
+ if (connectionsEnv.connections.size > 0) {
303
+ return (cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim()) ? connectionsEnv.default(undefined, [{ ...settings_1.DEFAULT_CONNECTION_MAP, connection: cnxName }]) : connectionsEnv.default();
78
304
  }
79
- return {
80
- ...authConfig,
81
- ...envConnections,
82
- };
305
+ // No connections provided, we need to populate the connections map with the old config settings
306
+ const result = (0, settings_1.applyDefaultSettings)((cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim()) ? legacyPrefixEnv.process(globalEnv.env, cnxName) : globalEnv.legacyPrefixSettings);
307
+ if (cnxName && !result.clientId) {
308
+ throw new Error(`ClientId not found for connection: ${cnxName}`);
309
+ }
310
+ logger.info('Auth settings loaded from environment', {
311
+ connections: summarizeAuthConfiguration(result),
312
+ connectionsMap: (_a = result.connectionsMap) === null || _a === void 0 ? void 0 : _a.map(e => ({ ...e, serviceUrl: e.serviceUrl !== '*' ? (0, agents_telemetry_1.redactUrl)(e.serviceUrl) : e.serviceUrl })),
313
+ });
314
+ return result;
83
315
  };
84
316
  exports.loadAuthConfigFromEnv = loadAuthConfigFromEnv;
85
317
  /**
@@ -97,96 +329,21 @@ exports.loadAuthConfigFromEnv = loadAuthConfigFromEnv;
97
329
  *
98
330
  */
99
331
  const loadPrevAuthConfigFromEnv = () => {
100
- var _a, _b, _c, _d, _e;
101
- const envConnections = loadConnectionsMapFromEnv();
102
- let authConfig = {};
103
- if (envConnections.connectionsMap.length === 0) {
104
- // No connections provided, we need to populate the connection map with the old config settings
105
- if (process.env.MicrosoftAppId === undefined && process.env.NODE_ENV === 'production') {
106
- throw new Error('ClientId required in production');
107
- }
108
- const authority = (_a = process.env.authorityEndpoint) !== null && _a !== void 0 ? _a : 'https://login.microsoftonline.com';
109
- authConfig = {
110
- tenantId: process.env.MicrosoftAppTenantId,
111
- clientId: process.env.MicrosoftAppId,
112
- clientSecret: process.env.MicrosoftAppPassword,
113
- certPemFile: process.env.certPemFile,
114
- certKeyFile: process.env.certKeyFile,
115
- sendX5C: process.env.sendX5C === 'true',
116
- connectionName: process.env.connectionName,
117
- FICClientId: process.env.MicrosoftAppClientId,
118
- authority,
119
- scope: process.env.scope,
120
- issuers: getDefaultIssuers((_b = process.env.MicrosoftAppTenantId) !== null && _b !== void 0 ? _b : '', authority),
121
- altBlueprintConnectionName: process.env.altBlueprintConnectionName,
122
- WIDAssertionFile: process.env.WIDAssertionFile,
123
- azureRegion: process.env.azureRegion,
124
- };
125
- envConnections.connections.set(DEFAULT_CONNECTION, authConfig);
126
- envConnections.connectionsMap.push({
127
- serviceUrl: '*',
128
- connection: DEFAULT_CONNECTION,
129
- });
332
+ if (process.env.TEST_MODE === 'true') {
333
+ globalEnv = loadEnv();
334
+ }
335
+ let result;
336
+ if (connectionsEnv.connections.size > 0) {
337
+ result = connectionsEnv.default();
130
338
  }
131
339
  else {
132
- // There are connections provided, use the default one.
133
- const defaultItem = envConnections.connectionsMap.find((item) => item.serviceUrl === '*');
134
- const defaultConn = defaultItem ? envConnections.connections.get(defaultItem.connection) : undefined;
135
- if (!defaultConn) {
136
- throw new Error('No default connection found in environment connections.');
137
- }
138
- authConfig = defaultConn;
340
+ // No connections provided, we need to populate the connection map with the old config settings
341
+ result = (0, settings_1.applyDefaultSettings)(globalEnv.legacyBotFrameworkSettings);
139
342
  }
140
- (_c = authConfig.authority) !== null && _c !== void 0 ? _c : (authConfig.authority = 'https://login.microsoftonline.com');
141
- (_d = authConfig.issuers) !== null && _d !== void 0 ? _d : (authConfig.issuers = getDefaultIssuers((_e = authConfig.tenantId) !== null && _e !== void 0 ? _e : '', authConfig.authority));
142
- return { ...authConfig, ...envConnections };
343
+ logger.info('Legacy auth settings loaded from environment', summarizeAuthConfiguration(result), result.connectionsMap);
344
+ return result;
143
345
  };
144
346
  exports.loadPrevAuthConfigFromEnv = loadPrevAuthConfigFromEnv;
145
- function loadConnectionsMapFromEnv() {
146
- const envVars = process.env;
147
- const connectionsObj = {};
148
- const connectionsMap = [];
149
- const CONNECTIONS_PREFIX = 'connections__';
150
- const CONNECTIONS_MAP_PREFIX = 'connectionsMap__';
151
- for (const [key, rawValue] of Object.entries(envVars)) {
152
- if (key.startsWith(CONNECTIONS_PREFIX)) {
153
- // Convert to dot notation
154
- let path = key.substring(CONNECTIONS_PREFIX.length).replace(/__/g, '.');
155
- // Remove ".settings." from the path
156
- path = path.replace('.settings.', '.');
157
- // Convert "true"/"false" strings into boolean values
158
- const value = rawValue === 'true' ? true : rawValue === 'false' ? false : rawValue;
159
- object_path_1.default.set(connectionsObj, path, value);
160
- }
161
- else if (key.startsWith(CONNECTIONS_MAP_PREFIX)) {
162
- const path = key.substring(CONNECTIONS_MAP_PREFIX.length).replace(/__/g, '.');
163
- object_path_1.default.set(connectionsMap, path, rawValue);
164
- }
165
- }
166
- // Convert connectionsObj to Map<string, AuthConfiguration>
167
- const connections = new Map(Object.entries(connectionsObj));
168
- if (connections.size === 0) {
169
- logger.warn('No connections found in configuration.');
170
- }
171
- if (connectionsMap.length === 0) {
172
- logger.warn('No connections map found in configuration.');
173
- if (connections.size > 0) {
174
- const firstEntry = connections.entries().next().value;
175
- if (firstEntry) {
176
- const [firstKey] = firstEntry;
177
- // Provide a default connection map if none is specified
178
- connectionsMap.push({
179
- serviceUrl: '*',
180
- connection: firstKey,
181
- });
182
- }
183
- }
184
- }
185
- return {
186
- connections,
187
- connectionsMap,
188
- };
189
- }
190
347
  /**
191
348
  * Loads the authentication configuration from the provided config or from the environment variables
192
349
  * providing default values for authority and issuers.
@@ -212,137 +369,24 @@ function loadConnectionsMapFromEnv() {
212
369
  *
213
370
  */
214
371
  function getAuthConfigWithDefaults(config) {
215
- var _a, _b, _c, _d;
216
- if (!config)
217
- return (0, exports.loadAuthConfigFromEnv)();
218
- const providedConnections = config.connections && config.connectionsMap
219
- ? { connections: config.connections, connectionsMap: config.connectionsMap }
220
- : undefined;
221
- const connections = providedConnections !== null && providedConnections !== void 0 ? providedConnections : loadConnectionsMapFromEnv();
222
- let mergedConfig;
223
- if (connections && ((_a = connections.connectionsMap) === null || _a === void 0 ? void 0 : _a.length) === 0) {
224
- // No connections provided, we need to populate the connections map with the old config settings
225
- mergedConfig = buildLegacyAuthConfig(undefined, config);
226
- (_b = connections.connections) === null || _b === void 0 ? void 0 : _b.set(DEFAULT_CONNECTION, mergedConfig);
227
- connections.connectionsMap.push({ serviceUrl: '*', connection: DEFAULT_CONNECTION });
372
+ var _a;
373
+ if (process.env.TEST_MODE === 'true') {
374
+ globalEnv = loadEnv();
375
+ }
376
+ let result;
377
+ if (!config) {
378
+ result = (0, exports.loadAuthConfigFromEnv)();
228
379
  }
229
380
  else {
230
- // There are connections provided, use the default connection
231
- const defaultItem = (_c = connections.connectionsMap) === null || _c === void 0 ? void 0 : _c.find((item) => item.serviceUrl === '*');
232
- const defaultConn = defaultItem ? (_d = connections.connections) === null || _d === void 0 ? void 0 : _d.get(defaultItem.connection) : undefined;
233
- if (!defaultConn) {
234
- throw new Error('No default connection found in environment connections.');
381
+ const { connections, connectionsMap } = ((_a = config.connections) === null || _a === void 0 ? void 0 : _a.size) ? config : { connections: connectionsEnv.connections, connectionsMap: connectionsMapEnv.connectionsMap };
382
+ if (connections === null || connections === void 0 ? void 0 : connections.size) {
383
+ result = { ...globalEnv.legacyPrefixSettings, ...connectionsEnv.default(connections, connectionsMap) };
235
384
  }
236
- mergedConfig = buildLegacyAuthConfig(undefined, defaultConn);
237
- }
238
- return {
239
- ...mergedConfig,
240
- ...connections,
241
- };
242
- }
243
- function buildLegacyAuthConfig(envPrefix = '', customConfig) {
244
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
245
- const prefix = envPrefix ? `${envPrefix}_` : '';
246
- const authority = (_b = (_a = customConfig === null || customConfig === void 0 ? void 0 : customConfig.authority) !== null && _a !== void 0 ? _a : process.env[`${prefix}authorityEndpoint`]) !== null && _b !== void 0 ? _b : 'https://login.microsoftonline.com';
247
- const clientId = (_c = customConfig === null || customConfig === void 0 ? void 0 : customConfig.clientId) !== null && _c !== void 0 ? _c : process.env[`${prefix}clientId`];
248
- if (!clientId && !envPrefix && process.env.NODE_ENV === 'production') {
249
- throw new Error('ClientId required in production');
250
- }
251
- if (!clientId && envPrefix) {
252
- throw new Error(`ClientId not found for connection: ${envPrefix}`);
253
- }
254
- const tenantId = (_d = customConfig === null || customConfig === void 0 ? void 0 : customConfig.tenantId) !== null && _d !== void 0 ? _d : process.env[`${prefix}tenantId`];
255
- return {
256
- tenantId,
257
- clientId: clientId,
258
- clientSecret: (_e = customConfig === null || customConfig === void 0 ? void 0 : customConfig.clientSecret) !== null && _e !== void 0 ? _e : process.env[`${prefix}clientSecret`],
259
- certPemFile: (_f = customConfig === null || customConfig === void 0 ? void 0 : customConfig.certPemFile) !== null && _f !== void 0 ? _f : process.env[`${prefix}certPemFile`],
260
- certKeyFile: (_g = customConfig === null || customConfig === void 0 ? void 0 : customConfig.certKeyFile) !== null && _g !== void 0 ? _g : process.env[`${prefix}certKeyFile`],
261
- sendX5C: (_h = customConfig === null || customConfig === void 0 ? void 0 : customConfig.sendX5C) !== null && _h !== void 0 ? _h : (process.env[`${prefix}sendX5C`] === 'true'),
262
- connectionName: (_j = customConfig === null || customConfig === void 0 ? void 0 : customConfig.connectionName) !== null && _j !== void 0 ? _j : process.env[`${prefix}connectionName`],
263
- FICClientId: (_k = customConfig === null || customConfig === void 0 ? void 0 : customConfig.FICClientId) !== null && _k !== void 0 ? _k : process.env[`${prefix}FICClientId`],
264
- authority,
265
- scope: (_l = customConfig === null || customConfig === void 0 ? void 0 : customConfig.scope) !== null && _l !== void 0 ? _l : process.env[`${prefix}scope`],
266
- issuers: (_m = customConfig === null || customConfig === void 0 ? void 0 : customConfig.issuers) !== null && _m !== void 0 ? _m : getDefaultIssuers(tenantId, authority),
267
- altBlueprintConnectionName: (_o = customConfig === null || customConfig === void 0 ? void 0 : customConfig.altBlueprintConnectionName) !== null && _o !== void 0 ? _o : process.env[`${prefix}altBlueprintConnectionName`],
268
- WIDAssertionFile: (_p = customConfig === null || customConfig === void 0 ? void 0 : customConfig.WIDAssertionFile) !== null && _p !== void 0 ? _p : process.env[`${prefix}WIDAssertionFile`],
269
- azureRegion: (_q = customConfig === null || customConfig === void 0 ? void 0 : customConfig.azureRegion) !== null && _q !== void 0 ? _q : process.env[`${prefix}azureRegion`]
270
- };
271
- }
272
- /**
273
- * Resolves the full authority URL including the tenant ID.
274
- * Supports both patterns:
275
- * - Tenant embedded in authority: https://login.microsoftonline.com/my-tenant
276
- * - Authority + separate tenantId: https://login.microsoftonline.com + tenantId
277
- * Also handles trailing slashes on authority.
278
- */
279
- function resolveAuthority(authority, tenantId) {
280
- const base = (authority !== null && authority !== void 0 ? authority : 'https://login.microsoftonline.com').replace(/\/+$/, '');
281
- const url = new URL(base);
282
- const hasPathSegment = url.pathname !== '/';
283
- if (hasPathSegment) {
284
- return base;
285
- }
286
- return `${base}/${tenantId !== null && tenantId !== void 0 ? tenantId : 'botframework.com'}`;
287
- }
288
- function getDefaultIssuers(tenantId, authority) {
289
- // Convert empty string to undefined so resolveAuthority applies its 'botframework.com' default
290
- const t = tenantId || undefined;
291
- if (!t) {
292
- logger.warn('tenantId is not configured, defaulting to botframework.com');
293
- }
294
- return [
295
- 'https://api.botframework.com',
296
- `${resolveAuthority('https://sts.windows.net', t)}/`,
297
- `${resolveAuthority(authority, t)}/v2.0`
298
- ];
299
- }
300
- /**
301
- * Creates an environment variable parser that maps the variable keys to parsing functions.
302
- * @param settings An object where each key is an environment variable name and the value is a function
303
- * that takes the variable value as input and returns an object with optional `key` and `value` properties.
304
- * @remarks
305
- * The `key` property in the returned object can be used to rename the environment variable key,
306
- * while the `value` property contains the parsed value.
307
- * @returns An object with a `parse` method that takes an environment variable key and value,
308
- * and returns the parsed result.
309
- */
310
- function envParser(settings) {
311
- const keys = Object.keys(settings);
312
- return {
313
- /**
314
- * Parses the given environment variable key and value using the provided settings.
315
- * @param key The environment variable key.
316
- * @param value The environment variable value.
317
- * @returns The parsed result with optional renamed key and parsed value.
318
- */
319
- parse(key, value) {
320
- var _a;
321
- const match = keys.find(k => k.toUpperCase() === key.toUpperCase());
322
- if (!match) {
323
- return {};
324
- }
325
- const result = settings[match](value);
326
- return { key: (_a = result === null || result === void 0 ? void 0 : result.key) !== null && _a !== void 0 ? _a : match, value: result === null || result === void 0 ? void 0 : result.value };
385
+ else {
386
+ result = (0, settings_1.applyDefaultSettings)({ ...globalEnv.legacyPrefixSettings, ...config });
327
387
  }
328
- };
388
+ }
389
+ logger.info('Auth settings loaded from runtime configuration', summarizeAuthConfiguration(result), result.connectionsMap);
390
+ return result;
329
391
  }
330
- /**
331
- * Utility functions for environment variable parsers.
332
- */
333
- exports.envParserUtils = {
334
- /**
335
- * Bypass parser that returns the value as is.
336
- * @param value The environment variable value.
337
- * @returns An object with the original value.
338
- */
339
- bypass: (value) => ({ value }),
340
- /**
341
- * Redirects the parsing to another parser for a specific key.
342
- * @param parser The target parser to redirect to.
343
- * @param key The key to use in the target parser.
344
- * @returns A function that takes the environment variable value and returns the parsed result from the target parser.
345
- */
346
- redirect: (parser, key) => (value) => parser.parse(key, value)
347
- };
348
392
  //# sourceMappingURL=authConfiguration.js.map