@microsoft/agents-hosting 1.8.1 → 1.9.0-beta.18.g6b8111bba5

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 (101) hide show
  1. package/README.md +179 -9
  2. package/dist/package.json +4 -4
  3. package/dist/src/app/agentApplication.d.ts +3 -3
  4. package/dist/src/app/agentApplication.js +6 -16
  5. package/dist/src/app/agentApplication.js.map +1 -1
  6. package/dist/src/app/agentApplicationOptions.d.ts +6 -0
  7. package/dist/src/app/auth/authorization.d.ts +54 -0
  8. package/dist/src/app/auth/authorization.js +63 -2
  9. package/dist/src/app/auth/authorization.js.map +1 -1
  10. package/dist/src/app/auth/authorizationManager.d.ts +0 -8
  11. package/dist/src/app/auth/authorizationManager.js +104 -178
  12. package/dist/src/app/auth/authorizationManager.js.map +1 -1
  13. package/dist/src/auth/authConfiguration.d.ts +10 -3
  14. package/dist/src/auth/authConfiguration.js +292 -259
  15. package/dist/src/auth/authConfiguration.js.map +1 -1
  16. package/dist/src/auth/delegatedTokenCredential.d.ts +29 -0
  17. package/dist/src/auth/delegatedTokenCredential.js +49 -0
  18. package/dist/src/auth/delegatedTokenCredential.js.map +1 -0
  19. package/dist/src/auth/msal/msalTokenCredential.js +1 -1
  20. package/dist/src/auth/msal/msalTokenCredential.js.map +1 -1
  21. package/dist/src/auth/settings.d.ts +8 -70
  22. package/dist/src/auth/settings.js +5 -67
  23. package/dist/src/auth/settings.js.map +1 -1
  24. package/dist/src/cloudAdapter.d.ts +5 -0
  25. package/dist/src/cloudAdapter.js +13 -103
  26. package/dist/src/cloudAdapter.js.map +1 -1
  27. package/dist/src/configuration/botFrameworkEnvironmentCompatibility.d.ts +23 -0
  28. package/dist/src/configuration/botFrameworkEnvironmentCompatibility.js +183 -0
  29. package/dist/src/configuration/botFrameworkEnvironmentCompatibility.js.map +1 -0
  30. package/dist/src/configuration/configuration.d.ts +83 -0
  31. package/dist/src/configuration/configuration.js +836 -0
  32. package/dist/src/configuration/configuration.js.map +1 -0
  33. package/dist/src/configuration/configurationSource.d.ts +57 -0
  34. package/dist/src/configuration/configurationSource.js +7 -0
  35. package/dist/src/configuration/configurationSource.js.map +1 -0
  36. package/dist/src/configuration/environmentConfiguration.d.ts +14 -0
  37. package/dist/src/configuration/environmentConfiguration.js +271 -0
  38. package/dist/src/configuration/environmentConfiguration.js.map +1 -0
  39. package/dist/src/configuration/index.d.ts +7 -0
  40. package/dist/src/configuration/index.js +14 -0
  41. package/dist/src/configuration/index.js.map +1 -0
  42. package/dist/src/configuration/jsonFileConfigurationSource.d.ts +15 -0
  43. package/dist/src/configuration/jsonFileConfigurationSource.js +58 -0
  44. package/dist/src/configuration/jsonFileConfigurationSource.js.map +1 -0
  45. package/dist/src/createCloudAdapter.d.ts +30 -5
  46. package/dist/src/createCloudAdapter.js +17 -10
  47. package/dist/src/createCloudAdapter.js.map +1 -1
  48. package/dist/src/errorHelper.js +90 -2
  49. package/dist/src/errorHelper.js.map +1 -1
  50. package/dist/src/index.d.ts +1 -0
  51. package/dist/src/index.js +1 -0
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/src/outboundHostValidator.d.ts +4 -1
  54. package/dist/src/outboundHostValidator.js +25 -48
  55. package/dist/src/outboundHostValidator.js.map +1 -1
  56. package/dist/src/storage/fileStorage.d.ts +5 -2
  57. package/dist/src/storage/fileStorage.js +41 -3
  58. package/dist/src/storage/fileStorage.js.map +1 -1
  59. package/dist/src/storage/index.d.ts +1 -0
  60. package/dist/src/storage/index.js +1 -0
  61. package/dist/src/storage/index.js.map +1 -1
  62. package/dist/src/storage/memoryStorage.d.ts +4 -2
  63. package/dist/src/storage/memoryStorage.js +32 -6
  64. package/dist/src/storage/memoryStorage.js.map +1 -1
  65. package/dist/src/storage/storage.d.ts +14 -1
  66. package/dist/src/storage/storageExpiry.d.ts +6 -0
  67. package/dist/src/storage/storageExpiry.js +20 -0
  68. package/dist/src/storage/storageExpiry.js.map +1 -0
  69. package/dist/src/utils/env.d.ts +43 -0
  70. package/dist/src/utils/env.js +42 -6
  71. package/dist/src/utils/env.js.map +1 -1
  72. package/dist/src/utils.d.ts +1 -0
  73. package/dist/src/utils.js +10 -1
  74. package/dist/src/utils.js.map +1 -1
  75. package/package.json +4 -4
  76. package/src/app/agentApplication.ts +11 -14
  77. package/src/app/agentApplicationOptions.ts +7 -0
  78. package/src/app/auth/authorization.ts +67 -2
  79. package/src/app/auth/authorizationManager.ts +126 -204
  80. package/src/auth/authConfiguration.ts +415 -260
  81. package/src/auth/delegatedTokenCredential.ts +49 -0
  82. package/src/auth/msal/msalTokenCredential.ts +1 -1
  83. package/src/auth/settings.ts +5 -82
  84. package/src/cloudAdapter.ts +38 -113
  85. package/src/configuration/botFrameworkEnvironmentCompatibility.ts +245 -0
  86. package/src/configuration/configuration.ts +1076 -0
  87. package/src/configuration/configurationSource.ts +76 -0
  88. package/src/configuration/environmentConfiguration.ts +377 -0
  89. package/src/configuration/index.ts +19 -0
  90. package/src/configuration/jsonFileConfigurationSource.ts +74 -0
  91. package/src/createCloudAdapter.ts +52 -9
  92. package/src/errorHelper.ts +110 -2
  93. package/src/index.ts +1 -0
  94. package/src/outboundHostValidator.ts +37 -44
  95. package/src/storage/fileStorage.ts +43 -5
  96. package/src/storage/index.ts +1 -0
  97. package/src/storage/memoryStorage.ts +34 -8
  98. package/src/storage/storage.ts +15 -1
  99. package/src/storage/storageExpiry.ts +21 -0
  100. package/src/utils/env.ts +63 -0
  101. package/src/utils.ts +10 -0
@@ -13,9 +13,11 @@ Object.defineProperty(exports, "AuthType", { enumerable: true, get: function ()
13
13
  Object.defineProperty(exports, "resolveAuthority", { enumerable: true, get: function () { return settings_2.resolveAuthority; } });
14
14
  Object.defineProperty(exports, "resolveAuthType", { enumerable: true, get: function () { return settings_2.resolveAuthType; } });
15
15
  const utils_1 = require("../utils");
16
- const env_1 = require("../utils/env");
17
16
  const agents_activity_1 = require("@microsoft/agents-activity");
18
17
  const errorHelper_1 = require("../errorHelper");
18
+ const configuration_1 = require("../configuration/configuration");
19
+ const environmentConfiguration_1 = require("../configuration/environmentConfiguration");
20
+ const botFrameworkEnvironmentCompatibility_1 = require("../configuration/botFrameworkEnvironmentCompatibility");
19
21
  const logger = (0, agents_telemetry_1.debug)('agents:authConfiguration');
20
22
  /**
21
23
  * 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.
@@ -70,253 +72,254 @@ function summarizeAuthConfiguration(authConfig) {
70
72
  * Environment variables for connections map should be in the format ConnectionsMap__<index>__<property>, e.g. ConnectionsMap__0__ServiceUrl, ConnectionsMap__0__Connection, etc.
71
73
  */
72
74
  const connectionsEnv = {
73
- connections: new Map(),
74
- parser: (0, settings_1.envParser)({
75
- authType: settings_1.envParserUtils.bypass,
76
- tenantId: settings_1.envParserUtils.bypass,
77
- clientId: settings_1.envParserUtils.bypass,
78
- clientSecret: settings_1.envParserUtils.bypass,
79
- certPemFile: settings_1.envParserUtils.bypass,
80
- certKeyFile: settings_1.envParserUtils.bypass,
81
- connectionName: settings_1.envParserUtils.bypass,
82
- federatedClientId: settings_1.envParserUtils.bypass,
83
- FICClientId(value) {
84
- logger.warn('Connections__<id>__Settings__FICClientId is deprecated, please use Connections__<id>__Settings__FederatedClientId instead.');
85
- return { key: 'federatedClientId', value }; // redirect
86
- },
87
- authorityEndpoint: settings_1.envParserUtils.bypass,
88
- authority(value) {
89
- logger.warn('Connections__<id>__Settings__Authority is deprecated, please use Connections__<id>__Settings__AuthorityEndpoint instead.');
90
- return { key: 'authorityEndpoint', value }; // redirect
91
- },
92
- scopes(value) {
93
- return this.issuers(value); // scopes can be comma or space separated list, same as issuers.
94
- },
95
- scope(value) {
96
- var _a;
97
- logger.warn('Connections__<id>__Settings__Scope is deprecated, please use Connections__<id>__Settings__Scopes instead.');
98
- return { key: 'scopes', value: (_a = this.scopes(value)) === null || _a === void 0 ? void 0 : _a.value }; // redirect with single scope
99
- },
100
- altBlueprintConnectionName: settings_1.envParserUtils.bypass,
101
- alternateBlueprintConnectionName: (value) => ({ key: 'altBlueprintConnectionName', value }), // .NET parity alias
102
- WIDAssertionFile: settings_1.envParserUtils.bypass,
103
- federatedTokenFile: settings_1.envParserUtils.bypass,
104
- idpmResource: settings_1.envParserUtils.bypass,
105
- azureRegion: settings_1.envParserUtils.bypass,
106
- sendX5C: (value) => ({ value: value === 'true' }),
107
- msalRetryCount: (value) => {
108
- const n = parseInt(value, 10);
109
- return { value: Number.isFinite(n) && n >= 0 ? n : undefined };
110
- },
111
- sidecarBaseUrl: settings_1.envParserUtils.bypass,
112
- serviceName: settings_1.envParserUtils.bypass,
113
- blueprintServiceName: settings_1.envParserUtils.bypass,
114
- bypassLocalNetworkRestriction: (value) => ({ value: value === 'true' }),
115
- requestTimeout: (value) => {
116
- const n = parseInt(value, 10);
117
- return { value: Number.isFinite(n) && n > 0 ? n : undefined };
118
- },
119
- retryCount: (value) => {
120
- const n = parseInt(value, 10);
121
- return { value: Number.isFinite(n) && n >= 0 ? n : undefined };
122
- },
123
- issuers(value) {
124
- if (value.includes(',')) {
125
- return { value: value.split(',').map(s => s.trim()).filter(Boolean) };
126
- }
127
- return { value: value.split(/\s+/).filter(Boolean) };
128
- },
129
- validateIssuer: (value) => ({ value: (0, env_1.parseBooleanEnv)(value) }),
130
- }),
131
- default(connections, connectionsMap) {
132
- var _a;
133
- const conn = connections !== null && connections !== void 0 ? connections : this.connections;
134
- const map = connectionsMap !== null && connectionsMap !== void 0 ? connectionsMap : connectionsMapEnv.connectionsMap;
135
- const name = (_a = map === null || map === void 0 ? void 0 : map.find((item) => item.serviceUrl === '*')) === null || _a === void 0 ? void 0 : _a.connection;
136
- if (!name) {
137
- throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.NoDefaultConnectionFound);
138
- }
139
- const connection = conn === null || conn === void 0 ? void 0 : conn.get(name !== null && name !== void 0 ? name : '');
140
- if (!connection) {
141
- throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.ConnectionNotFoundInEnvironment, undefined, { connectionName: name });
142
- }
143
- return (0, settings_1.applyDefaultSettings)({ ...connection, connections: conn, connectionsMap: map });
144
- },
145
- process(key, value) {
146
- var _a;
147
- const format = 'Connections__<id>__Settings__<property>';
148
- const parts = key.split('__');
149
- const [connections, id, settings, prop] = parts;
150
- if (`${connections}/${settings}`.toUpperCase() !== 'CONNECTIONS/SETTINGS') {
151
- return false;
152
- }
153
- if (parts.length !== 4) {
154
- logger.warn(`Invalid connection environment variable: ${key}. Expected format: ${format}.`);
155
- return false;
156
- }
157
- if (!(id === null || id === void 0 ? void 0 : id.trim())) {
158
- logger.warn(`Invalid connection <id> in environment variable: ${key}. Expected format: ${format}.`);
159
- return false;
160
- }
161
- if (!(prop === null || prop === void 0 ? void 0 : prop.trim())) {
162
- logger.warn(`Invalid connection <property> in environment variable: ${key}. Expected format: ${format}.`);
163
- return false;
164
- }
165
- const result = this.parser.parse(prop, value);
166
- if (!result.key) {
167
- return false;
168
- }
169
- const config = (_a = this.connections.get(id)) !== null && _a !== void 0 ? _a : {};
170
- config[result.key] = result.value;
171
- this.connections.set(id, config);
172
- return true;
173
- },
75
+ connections: new Map()
174
76
  };
175
77
  const connectionsMapEnv = {
176
- connectionsMap: [],
177
- parser: (0, settings_1.envParser)({
178
- serviceUrl: settings_1.envParserUtils.bypass,
179
- connection: settings_1.envParserUtils.bypass,
180
- audience: settings_1.envParserUtils.bypass,
181
- }),
182
- process(key, value) {
183
- var _a;
184
- const format = 'ConnectionsMap__<index>__<property>';
185
- const parts = key.split('__');
186
- const [connectionsMap, index, prop] = parts;
187
- if (connectionsMap.toUpperCase() !== 'CONNECTIONSMAP') {
188
- return false;
78
+ connectionsMap: new Map(),
79
+ finalized: []
80
+ };
81
+ const loadEnv = () => {
82
+ const modern = (0, environmentConfiguration_1.loadModernEnvironmentConfiguration)();
83
+ connectionsEnv.connections.clear();
84
+ for (const connection of modern.connections.values()) {
85
+ connectionsEnv.connections.set(connection.id, { ...connection.settings });
86
+ }
87
+ connectionsMapEnv.connectionsMap.clear();
88
+ for (const [index, item] of modern.connectionsMap) {
89
+ connectionsMapEnv.connectionsMap.set(index, { ...item });
90
+ }
91
+ if (connectionsEnv.connections.size === 0) {
92
+ logger.warn('No connections found in configuration.');
93
+ }
94
+ if (connectionsMapEnv.connectionsMap.size === 0 && connectionsEnv.connections.size > 0) {
95
+ logger.warn('No connections map found in configuration, assuming default connection map with serviceUrl "*" for the first connection.');
96
+ const [key] = connectionsEnv.connections.keys();
97
+ connectionsMapEnv.connectionsMap.set(0, { ...settings_1.DEFAULT_CONNECTION_MAP, connection: key });
98
+ }
99
+ return {
100
+ legacyBotFrameworkSettings: configurationLayerSettings((0, botFrameworkEnvironmentCompatibility_1.loadBotFrameworkEnvironmentConfiguration)()),
101
+ legacyPrefixSettings: configurationLayerSettings((0, botFrameworkEnvironmentCompatibility_1.loadBotFrameworkPrefixedEnvironmentConfiguration)(''))
102
+ };
103
+ };
104
+ function externalAuthOperation(layer) {
105
+ return {
106
+ connections: new Map([...layer.connections.values()].map(connection => [connection.id, connection.settings])),
107
+ connectionsMap: layer.connectionsMap
108
+ };
109
+ }
110
+ function configurationLayerSettings(layer, connectionName) {
111
+ const connection = connectionName
112
+ ? layer.connections.get(connectionName.toLowerCase())
113
+ : layer.connections.values().next().value;
114
+ return connection ? { ...connection.settings } : {};
115
+ }
116
+ function settingsOperation(settings, synthesizeFlatConnection = false, materializeRequestedConnection = false) {
117
+ const { connections, connectionsMap, ...flatSettings } = settings;
118
+ return {
119
+ flatSettings,
120
+ connections,
121
+ connectionsMap: connectionsMap
122
+ ? new Map(connectionsMap.map((item, index) => [index, item]))
123
+ : undefined,
124
+ synthesizeFlatConnection,
125
+ materializeRequestedConnection
126
+ };
127
+ }
128
+ function registryOperation(settings) {
129
+ return {
130
+ connections: settings.connections,
131
+ connectionsMap: settings.connectionsMap
132
+ ? new Map(settings.connectionsMap.map((item, index) => [index, item]))
133
+ : undefined,
134
+ replaceRegistry: true
135
+ };
136
+ }
137
+ function validateDirectIssuerConfiguration(config) {
138
+ var _a;
139
+ validateDirectIssuerValue(config, 'validateIssuer');
140
+ for (const [id, settings] of (_a = config.connections) !== null && _a !== void 0 ? _a : []) {
141
+ validateDirectIssuerValue(settings, `connections.${id}.settings.validateIssuer`);
142
+ }
143
+ }
144
+ function validateDirectIssuerValue(settings, path) {
145
+ if (settings.validateIssuer !== undefined && typeof settings.validateIssuer !== 'boolean') {
146
+ throw agents_activity_1.ExceptionHelper.generateException(TypeError, errorHelper_1.Errors.InvalidBooleanConfigurationValue, undefined, { sourceName: 'runtime configuration', path });
147
+ }
148
+ }
149
+ function environmentRegistryOperation() {
150
+ return {
151
+ connections: connectionsEnv.connections,
152
+ connectionsMap: connectionsMapEnv.connectionsMap
153
+ };
154
+ }
155
+ function environmentRouteOperation() {
156
+ return {
157
+ connectionsMap: connectionsMapEnv.connectionsMap
158
+ };
159
+ }
160
+ function applyConnectionOperation(connections, operation) {
161
+ var _a;
162
+ if (operation.replaceRegistry) {
163
+ const retained = retainedConnectionIds(operation);
164
+ for (const id of connections.keys()) {
165
+ if (!retained.has(id.toLowerCase())) {
166
+ connections.delete(id);
167
+ }
189
168
  }
190
- if (parts.length !== 3) {
191
- logger.warn(`Invalid connection map environment variable: ${key}. Expected format: ${format}.`);
192
- return false;
169
+ }
170
+ for (const [id, settings] of (_a = operation.connections) !== null && _a !== void 0 ? _a : []) {
171
+ const existingId = findConnectionKey(connections, id);
172
+ const targetId = existingId !== null && existingId !== void 0 ? existingId : id;
173
+ connections.set(targetId, { ...connections.get(targetId), ...settings });
174
+ }
175
+ }
176
+ function retainedConnectionIds(operation) {
177
+ var _a;
178
+ var _b;
179
+ return new Set([...(_b = (_a = operation.connections) === null || _a === void 0 ? void 0 : _a.keys()) !== null && _b !== void 0 ? _b : []].map(id => id.toLowerCase()));
180
+ }
181
+ function findConnectionKey(connections, requested) {
182
+ if (!connections || !requested) {
183
+ return undefined;
184
+ }
185
+ const normalized = requested.toLowerCase();
186
+ return [...connections.keys()].find(id => id.toLowerCase() === normalized);
187
+ }
188
+ function resolveConnectionsMap(operations) {
189
+ var _a;
190
+ const connectionsMap = new Map();
191
+ for (const operation of operations) {
192
+ if (operation.replaceRegistry) {
193
+ const retained = retainedConnectionIds(operation);
194
+ for (const [index, item] of connectionsMap) {
195
+ if (item.connection && !retained.has(item.connection.toLowerCase())) {
196
+ connectionsMap.delete(index);
197
+ }
198
+ }
193
199
  }
194
- const indexNumber = parseInt(index, 10);
195
- if (!(index === null || index === void 0 ? void 0 : index.trim()) || isNaN(indexNumber) || indexNumber < 0) {
196
- logger.warn(`Invalid connection map <index> in environment variable: ${key}. Expected format: ${format}, where <index> is a number.`);
197
- return false;
200
+ for (const [index, item] of (_a = operation.connectionsMap) !== null && _a !== void 0 ? _a : []) {
201
+ connectionsMap.set(index, { ...connectionsMap.get(index), ...item });
198
202
  }
199
- if (!(prop === null || prop === void 0 ? void 0 : prop.trim())) {
200
- logger.warn(`Invalid connection map <property> in environment variable: ${key}. Expected format: ${format}.`);
201
- return false;
203
+ }
204
+ return connectionsMap;
205
+ }
206
+ function finalizeConnectionsMap(patches, connections, synthesizeDefault = true) {
207
+ if (synthesizeDefault && patches.size === 0 && connections.size === 1) {
208
+ const [connection] = connections.keys();
209
+ return [{ ...settings_1.DEFAULT_CONNECTION_MAP, connection }];
210
+ }
211
+ return [...patches.entries()]
212
+ .sort(([left], [right]) => left - right)
213
+ .map(([index, item]) => {
214
+ if (!item.serviceUrl || !item.connection) {
215
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.InvalidConnectionMapEntry, undefined, { index: index.toString() });
202
216
  }
203
- const result = this.parser.parse(prop, value);
204
- if (!result.key) {
205
- return false;
217
+ const connection = findConnectionKey(connections, item.connection);
218
+ if (!connection) {
219
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.ConnectionNotFoundInEnvironment, undefined, { connectionName: item.connection });
206
220
  }
207
- const mapItem = (_a = this.connectionsMap[indexNumber]) !== null && _a !== void 0 ? _a : { ...settings_1.DEFAULT_CONNECTION_MAP };
208
- mapItem[result.key] = result.value;
209
- this.connectionsMap[indexNumber] = mapItem;
210
- return true;
211
- },
212
- };
213
- /**
214
- * Legacy BotFramework style-like authentication configuration loaded from environment variables, with support for hot-reloading in test mode.
215
- * Environment variables should be named MicrosoftAppTenantId, MicrosoftAppId, MicrosoftAppPassword, etc.
216
- */
217
- const legacyBotFrameworkEnv = {
218
- parser: (0, settings_1.envParser)({
219
- MicrosoftAppTenantId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'tenantId'),
220
- MicrosoftAppId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientId'),
221
- MicrosoftAppPassword: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientSecret'),
222
- certPemFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certPemFile'),
223
- certKeyFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certKeyFile'),
224
- connectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'connectionName'),
225
- MicrosoftAppClientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedClientId'),
226
- authorityEndpoint: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authorityEndpoint'),
227
- scope: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'scopes'),
228
- altBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
229
- alternateBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
230
- WIDAssertionFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'WIDAssertionFile'),
231
- azureRegion: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'azureRegion'),
232
- sendX5C: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sendX5C'),
233
- msalRetryCount: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'msalRetryCount'),
234
- authType: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authType'),
235
- federatedTokenFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedTokenFile'),
236
- idpmResource: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'idpmResource'),
237
- sidecarBaseUrl: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sidecarBaseUrl'),
238
- serviceName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'serviceName'),
239
- blueprintServiceName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'blueprintServiceName'),
240
- bypassLocalNetworkRestriction: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'bypassLocalNetworkRestriction'),
241
- requestTimeout: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'requestTimeout'),
242
- retryCount: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'retryCount'),
243
- validateIssuer: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'validateIssuer'),
244
- }),
245
- process(env) {
246
- return legacyPrefixEnv.process.call(this, env);
247
- },
248
- };
249
- /**
250
- * Legacy prefix-based authentication configuration loaded from environment variables, with support for hot-reloading in test mode.
251
- * Environment variables should be prefixed with the connection name, e.g. <CONNECTION_NAME>_ClientId, <CONNECTION_NAME>_TenantId, etc.
252
- */
253
- const legacyPrefixEnv = {
254
- parser: (0, settings_1.envParser)({
255
- tenantId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'tenantId'),
256
- clientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientId'),
257
- clientSecret: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'clientSecret'),
258
- certPemFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certPemFile'),
259
- certKeyFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'certKeyFile'),
260
- connectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'connectionName'),
261
- FICClientId: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedClientId'),
262
- authorityEndpoint: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authorityEndpoint'),
263
- scope: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'scopes'),
264
- altBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
265
- alternateBlueprintConnectionName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'altBlueprintConnectionName'),
266
- WIDAssertionFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'WIDAssertionFile'),
267
- azureRegion: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'azureRegion'),
268
- sendX5C: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sendX5C'),
269
- msalRetryCount: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'msalRetryCount'),
270
- authType: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'authType'),
271
- federatedTokenFile: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'federatedTokenFile'),
272
- idpmResource: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'idpmResource'),
273
- sidecarBaseUrl: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'sidecarBaseUrl'),
274
- serviceName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'serviceName'),
275
- blueprintServiceName: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'blueprintServiceName'),
276
- bypassLocalNetworkRestriction: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'bypassLocalNetworkRestriction'),
277
- requestTimeout: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'requestTimeout'),
278
- retryCount: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'retryCount'),
279
- validateIssuer: settings_1.envParserUtils.redirect(connectionsEnv.parser, 'validateIssuer'),
280
- }),
281
- process(env, prefix) {
282
- const settings = {};
283
- for (const key of this.parser.keys) {
284
- const k = prefix ? `${prefix}_${key}` : key;
285
- const envValue = env[k.toUpperCase()];
286
- if (!envValue) {
287
- continue;
221
+ return {
222
+ serviceUrl: item.serviceUrl,
223
+ connection,
224
+ ...(item.audience === undefined ? {} : { audience: item.audience })
225
+ };
226
+ });
227
+ }
228
+ function resolveAuthOperations(operations, connectionName) {
229
+ var _a, _b;
230
+ const connections = new Map();
231
+ for (const operation of operations) {
232
+ applyConnectionOperation(connections, operation);
233
+ }
234
+ if (connections.size === 0 &&
235
+ operations.some(operation => operation.synthesizeFlatConnection)) {
236
+ connections.set(settings_1.DEFAULT_CONNECTION_MAP.connection, {});
237
+ }
238
+ const requestedName = connectionName === null || connectionName === void 0 ? void 0 : connectionName.trim();
239
+ if (requestedName &&
240
+ !findConnectionKey(connections, requestedName) &&
241
+ operations.some(operation => operation.materializeRequestedConnection)) {
242
+ connections.set(requestedName, {});
243
+ }
244
+ const requestedConnection = connections.size > 0 ? requestedName : undefined;
245
+ const requiresDefaultRoute = operations.some(operation => operation.replaceRegistry);
246
+ let connectionsMap = finalizeConnectionsMap(resolveConnectionsMap(operations), connections, !requiresDefaultRoute);
247
+ if (connectionsMap.length === 0 && (requiresDefaultRoute || connections.size > 1)) {
248
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.NoDefaultConnectionFound);
249
+ }
250
+ const defaultConnection = (_a = connectionsMap.find(item => item.serviceUrl === '*')) === null || _a === void 0 ? void 0 : _a.connection;
251
+ if (connectionsMap.length > 0 && !requestedConnection && !defaultConnection) {
252
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.NoDefaultConnectionFound);
253
+ }
254
+ const selectedConnection = requestedConnection || defaultConnection || connections.keys().next().value;
255
+ if (connections.size > 0 && !selectedConnection) {
256
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.NoDefaultConnectionFound);
257
+ }
258
+ const selectedConnectionKey = findConnectionKey(connections, selectedConnection);
259
+ if (selectedConnection && !selectedConnectionKey) {
260
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.ConnectionNotFoundInEnvironment, undefined, { connectionName: selectedConnection });
261
+ }
262
+ if (requestedConnection) {
263
+ connectionsMap = [{ ...settings_1.DEFAULT_CONNECTION_MAP, connection: selectedConnectionKey !== null && selectedConnectionKey !== void 0 ? selectedConnectionKey : requestedConnection }];
264
+ }
265
+ if (selectedConnection) {
266
+ const selectedSettings = {};
267
+ for (const operation of operations) {
268
+ const operationConnectionKey = findConnectionKey(operation.connections, selectedConnection);
269
+ const connectionSettings = operationConnectionKey
270
+ ? (_b = operation.connections) === null || _b === void 0 ? void 0 : _b.get(operationConnectionKey)
271
+ : undefined;
272
+ if (connectionSettings) {
273
+ Object.assign(selectedSettings, connectionSettings);
288
274
  }
289
- const result = this.parser.parse(key, envValue.value);
290
- if (result.key) {
291
- settings[result.key] = result.value;
275
+ if (operation.flatSettings) {
276
+ Object.assign(selectedSettings, operation.flatSettings);
292
277
  }
293
278
  }
294
- return settings;
295
- },
296
- };
297
- const loadEnv = () => {
298
- connectionsEnv.connections = new Map();
299
- connectionsMapEnv.connectionsMap = [];
300
- const env = (0, settings_1.loadEnvSettings)((key, value) => {
301
- // Process the first parser that matches the environment variable key and value,
302
- // otherwise it continues to the next parser.
303
- return connectionsEnv.process(key, value) ||
304
- connectionsMapEnv.process(key, value);
305
- });
306
- if (connectionsEnv.connections.size === 0) {
307
- logger.warn('No connections found in configuration.');
279
+ const resolved = (0, settings_1.applyDefaultSettings)(selectedSettings);
280
+ const providerSettings = { ...resolved };
281
+ delete providerSettings.connections;
282
+ delete providerSettings.connectionsMap;
283
+ connections.set(selectedConnectionKey !== null && selectedConnectionKey !== void 0 ? selectedConnectionKey : selectedConnection, providerSettings);
284
+ return { ...providerSettings, connections, connectionsMap };
308
285
  }
309
- if (connectionsMapEnv.connectionsMap.length === 0 && connectionsEnv.connections.size > 0) {
310
- logger.warn('No connections map found in configuration, assuming default connection map with serviceUrl "*" for the first connection.');
311
- const [key] = connectionsEnv.connections.keys();
312
- connectionsMapEnv.connectionsMap.push({ ...settings_1.DEFAULT_CONNECTION_MAP, connection: key });
286
+ const flatSettings = {};
287
+ for (const operation of operations) {
288
+ Object.assign(flatSettings, operation.flatSettings);
313
289
  }
290
+ return (0, settings_1.applyDefaultSettings)(flatSettings);
291
+ }
292
+ function environmentOperation(legacySettings, connectionName) {
293
+ return connectionsEnv.connections.size > 0
294
+ ? environmentRegistryOperation()
295
+ : settingsOperation(legacySettings, false, Boolean((connectionName === null || connectionName === void 0 ? void 0 : connectionName.trim()) && Object.keys(legacySettings).length > 0));
296
+ }
297
+ function externalOperations(context) {
298
+ const snapshot = (0, configuration_1.getConfigurationSnapshot)(context);
314
299
  return {
315
- env,
316
- legacyBotFrameworkSettings: legacyBotFrameworkEnv.process(env),
317
- legacyPrefixSettings: legacyPrefixEnv.process(env)
300
+ hasAuth: ['fallback', 'overrideEnvironment', 'enforce'].some(mode => snapshot[mode].connections.size > 0 ||
301
+ snapshot[mode].connectionsMap.size > 0),
302
+ fallback: externalAuthOperation(snapshot.fallback),
303
+ overrideEnvironment: externalAuthOperation(snapshot.overrideEnvironment),
304
+ enforce: externalAuthOperation(snapshot.enforce)
318
305
  };
319
- };
306
+ }
307
+ function preserveEnvironmentRegistryIdentity(result, external, environmentRegistrySelected) {
308
+ var _a, _b;
309
+ if (external.hasAuth || !environmentRegistrySelected) {
310
+ return result;
311
+ }
312
+ for (const [id, settings] of (_a = result.connections) !== null && _a !== void 0 ? _a : []) {
313
+ const environmentId = findConnectionKey(connectionsEnv.connections, id);
314
+ if (environmentId) {
315
+ connectionsEnv.connections.set(environmentId, settings);
316
+ }
317
+ }
318
+ connectionsMapEnv.finalized.splice(0, connectionsMapEnv.finalized.length, ...((_b = result.connectionsMap) !== null && _b !== void 0 ? _b : []));
319
+ result.connections = connectionsEnv.connections;
320
+ result.connectionsMap = connectionsMapEnv.finalized;
321
+ return result;
322
+ }
320
323
  // Initial load of environment variables
321
324
  let globalEnv = loadEnv();
322
325
  /**
@@ -345,16 +348,21 @@ let globalEnv = loadEnv();
345
348
  * ```
346
349
  *
347
350
  */
348
- const loadAuthConfigFromEnv = (cnxName) => {
351
+ const loadAuthConfigFromEnv = (cnxName, options) => {
349
352
  var _a;
350
353
  if (process.env.TEST_MODE === 'true') {
351
354
  globalEnv = loadEnv();
352
355
  }
353
- if (connectionsEnv.connections.size > 0) {
354
- return (cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim()) ? connectionsEnv.default(undefined, [{ ...settings_1.DEFAULT_CONNECTION_MAP, connection: cnxName }]) : connectionsEnv.default();
355
- }
356
- // No connections provided, we need to populate the connections map with the old config settings
357
- const result = (0, settings_1.applyDefaultSettings)((cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim()) ? legacyPrefixEnv.process(globalEnv.env, cnxName) : globalEnv.legacyPrefixSettings);
356
+ const legacySettings = (cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim())
357
+ ? configurationLayerSettings((0, botFrameworkEnvironmentCompatibility_1.loadBotFrameworkPrefixedEnvironmentConfiguration)(cnxName), cnxName)
358
+ : globalEnv.legacyPrefixSettings;
359
+ const external = externalOperations(options === null || options === void 0 ? void 0 : options.configurationContext);
360
+ const result = preserveEnvironmentRegistryIdentity(resolveAuthOperations([
361
+ external.fallback,
362
+ environmentOperation(legacySettings, cnxName),
363
+ external.overrideEnvironment,
364
+ external.enforce
365
+ ], cnxName), external, connectionsEnv.connections.size > 0 && !(cnxName === null || cnxName === void 0 ? void 0 : cnxName.trim()));
358
366
  if (cnxName && !result.clientId) {
359
367
  throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.ClientIdNotFoundForConnection, undefined, { connectionName: cnxName });
360
368
  }
@@ -379,18 +387,17 @@ exports.loadAuthConfigFromEnv = loadAuthConfigFromEnv;
379
387
  * ```
380
388
  *
381
389
  */
382
- const loadPrevAuthConfigFromEnv = () => {
390
+ const loadPrevAuthConfigFromEnv = (options) => {
383
391
  if (process.env.TEST_MODE === 'true') {
384
392
  globalEnv = loadEnv();
385
393
  }
386
- let result;
387
- if (connectionsEnv.connections.size > 0) {
388
- result = connectionsEnv.default();
389
- }
390
- else {
391
- // No connections provided, we need to populate the connection map with the old config settings
392
- result = (0, settings_1.applyDefaultSettings)(globalEnv.legacyBotFrameworkSettings);
393
- }
394
+ const external = externalOperations(options === null || options === void 0 ? void 0 : options.configurationContext);
395
+ const result = preserveEnvironmentRegistryIdentity(resolveAuthOperations([
396
+ external.fallback,
397
+ environmentOperation(globalEnv.legacyBotFrameworkSettings),
398
+ external.overrideEnvironment,
399
+ external.enforce
400
+ ]), external, connectionsEnv.connections.size > 0);
394
401
  logger.info('Legacy auth settings loaded from environment', summarizeAuthConfiguration(result), result.connectionsMap);
395
402
  return result;
396
403
  };
@@ -419,22 +426,48 @@ exports.loadPrevAuthConfigFromEnv = loadPrevAuthConfigFromEnv;
419
426
  * ```
420
427
  *
421
428
  */
422
- function getAuthConfigWithDefaults(config) {
423
- var _a;
429
+ function getAuthConfigWithDefaults(config, options) {
430
+ var _a, _b, _c, _d, _e, _f;
431
+ if (config) {
432
+ validateDirectIssuerConfiguration(config);
433
+ }
424
434
  if (process.env.TEST_MODE === 'true') {
425
435
  globalEnv = loadEnv();
426
436
  }
427
- let result;
428
- if (!config) {
429
- result = (0, exports.loadAuthConfigFromEnv)();
437
+ const external = externalOperations(options === null || options === void 0 ? void 0 : options.configurationContext);
438
+ const operations = [external.fallback];
439
+ if ((_a = config === null || config === void 0 ? void 0 : config.connections) === null || _a === void 0 ? void 0 : _a.size) {
440
+ operations.push(settingsOperation(globalEnv.legacyPrefixSettings));
441
+ if (!((_b = config.connectionsMap) === null || _b === void 0 ? void 0 : _b.length)) {
442
+ operations.push(environmentRouteOperation());
443
+ }
444
+ operations.push(external.overrideEnvironment);
445
+ operations.push(registryOperation(config));
446
+ }
447
+ else if (connectionsEnv.connections.size > 0) {
448
+ if (config) {
449
+ operations.push(settingsOperation(globalEnv.legacyPrefixSettings));
450
+ }
451
+ operations.push(environmentRegistryOperation());
452
+ operations.push(external.overrideEnvironment);
430
453
  }
431
454
  else {
432
- const { connections, connectionsMap } = ((_a = config.connections) === null || _a === void 0 ? void 0 : _a.size) ? config : { connections: connectionsEnv.connections, connectionsMap: connectionsMapEnv.connectionsMap };
433
- if (connections === null || connections === void 0 ? void 0 : connections.size) {
434
- result = { ...globalEnv.legacyPrefixSettings, ...connectionsEnv.default(connections, connectionsMap) };
455
+ operations.push(settingsOperation(globalEnv.legacyPrefixSettings));
456
+ operations.push(external.overrideEnvironment);
457
+ if (config) {
458
+ operations.push(settingsOperation(config, true));
459
+ }
460
+ }
461
+ operations.push(external.enforce);
462
+ const result = preserveEnvironmentRegistryIdentity(resolveAuthOperations(operations), external, !((_c = config === null || config === void 0 ? void 0 : config.connections) === null || _c === void 0 ? void 0 : _c.size) && connectionsEnv.connections.size > 0);
463
+ const directParticipates = Boolean((_d = config === null || config === void 0 ? void 0 : config.connections) === null || _d === void 0 ? void 0 : _d.size) ||
464
+ connectionsEnv.connections.size === 0;
465
+ if (!external.hasAuth && config && directParticipates) {
466
+ if ((_e = config.connections) === null || _e === void 0 ? void 0 : _e.size) {
467
+ result.connections = config.connections;
435
468
  }
436
- else {
437
- result = (0, settings_1.applyDefaultSettings)({ ...globalEnv.legacyPrefixSettings, ...config });
469
+ if ((_f = config.connectionsMap) === null || _f === void 0 ? void 0 : _f.length) {
470
+ result.connectionsMap = config.connectionsMap;
438
471
  }
439
472
  }
440
473
  logger.info('Auth settings loaded from runtime configuration', summarizeAuthConfiguration(result), result.connectionsMap);