@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.
- package/dist/package.json +4 -9
- package/dist/src/agent-client/agentClient.js +2 -2
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.js +2 -2
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/app/agentApplication.js +28 -2
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/agentApplicationOptions.d.ts +10 -0
- package/dist/src/app/attachmentDownloader.js +5 -10
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/auth/authorizationManager.d.ts +4 -0
- package/dist/src/app/auth/authorizationManager.js +94 -67
- package/dist/src/app/auth/authorizationManager.js.map +1 -1
- package/dist/src/app/auth/handlers/azureBotAuthorization.js +2 -2
- package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -1
- package/dist/src/app/proactive/createConversationOptionsBuilder.js +10 -6
- package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
- package/dist/src/app/proactive/proactive.d.ts +1 -0
- package/dist/src/app/proactive/proactive.js +30 -15
- package/dist/src/app/proactive/proactive.js.map +1 -1
- package/dist/src/app/teamsAttachmentDownloader.js +6 -8
- package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
- package/dist/src/auth/authConfiguration.d.ts +2 -143
- package/dist/src/auth/authConfiguration.js +301 -257
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/jwt-middleware.js +2 -1
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msalConnectionManager.js +27 -14
- package/dist/src/auth/msalConnectionManager.js.map +1 -1
- package/dist/src/auth/msalTokenProvider.d.ts +7 -0
- package/dist/src/auth/msalTokenProvider.js +188 -44
- package/dist/src/auth/msalTokenProvider.js.map +1 -1
- package/dist/src/auth/settings.d.ts +327 -0
- package/dist/src/auth/settings.js +158 -0
- package/dist/src/auth/settings.js.map +1 -0
- package/dist/src/cloudAdapter.d.ts +58 -1
- package/dist/src/cloudAdapter.js +232 -52
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +12 -8
- package/dist/src/connector-client/connectorClient.js +99 -82
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/errorHelper.js +85 -7
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/getProductInfo.d.ts +23 -0
- package/dist/src/getProductInfo.js +71 -1
- package/dist/src/getProductInfo.js.map +1 -1
- package/dist/src/headerPropagation.d.ts +17 -2
- package/dist/src/headerPropagation.js +46 -24
- package/dist/src/headerPropagation.js.map +1 -1
- package/dist/src/httpClient.d.ts +60 -0
- package/dist/src/httpClient.js +173 -0
- package/dist/src/httpClient.js.map +1 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +5 -4
- package/dist/src/oauth/userTokenClient.js +97 -78
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/observability/traces.d.ts +11 -4
- package/dist/src/observability/traces.js +39 -7
- package/dist/src/observability/traces.js.map +1 -1
- package/dist/src/utils/env.d.ts +50 -0
- package/dist/src/utils/env.js +113 -0
- package/dist/src/utils/env.js.map +1 -0
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.js +18 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +4 -9
- package/src/agent-client/agentClient.ts +2 -2
- package/src/agent-client/agentResponseHandler.ts +2 -2
- package/src/app/agentApplication.ts +30 -3
- package/src/app/agentApplicationOptions.ts +11 -0
- package/src/app/attachmentDownloader.ts +6 -8
- package/src/app/auth/authorizationManager.ts +84 -41
- package/src/app/auth/handlers/azureBotAuthorization.ts +2 -2
- package/src/app/proactive/createConversationOptionsBuilder.ts +8 -4
- package/src/app/proactive/proactive.ts +39 -23
- package/src/app/teamsAttachmentDownloader.ts +7 -6
- package/src/auth/authConfiguration.ts +317 -356
- package/src/auth/jwt-middleware.ts +1 -1
- package/src/auth/msalConnectionManager.ts +27 -10
- package/src/auth/msalTokenProvider.ts +180 -42
- package/src/auth/settings.ts +323 -0
- package/src/cloudAdapter.ts +291 -12
- package/src/connector-client/connectorClient.ts +116 -94
- package/src/errorHelper.ts +96 -7
- package/src/getProductInfo.ts +79 -1
- package/src/headerPropagation.ts +55 -23
- package/src/httpClient.ts +223 -0
- package/src/index.ts +5 -1
- package/src/oauth/userTokenClient.ts +103 -84
- package/src/observability/traces.ts +39 -8
- package/src/utils/env.ts +105 -0
- 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.
|
|
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
|
|
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
|
-
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
//
|
|
133
|
-
|
|
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
|
-
(
|
|
141
|
-
|
|
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
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
|
|
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
|