@microsoft/agents-hosting 1.1.0-alpha.5 → 1.1.0-alpha.75

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 (144) hide show
  1. package/dist/package.json +10 -6
  2. package/dist/src/activityWireCompat.d.ts +1 -1
  3. package/dist/src/activityWireCompat.js +11 -3
  4. package/dist/src/activityWireCompat.js.map +1 -1
  5. package/dist/src/agent-client/agentClient.js +7 -3
  6. package/dist/src/agent-client/agentClient.js.map +1 -1
  7. package/dist/src/agent-client/agentResponseHandler.js +6 -2
  8. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  9. package/dist/src/app/agentApplication.d.ts +28 -13
  10. package/dist/src/app/agentApplication.js +93 -82
  11. package/dist/src/app/agentApplication.js.map +1 -1
  12. package/dist/src/app/agentApplicationBuilder.d.ts +2 -2
  13. package/dist/src/app/agentApplicationBuilder.js.map +1 -1
  14. package/dist/src/app/agentApplicationOptions.d.ts +9 -2
  15. package/dist/src/app/appRoute.d.ts +7 -0
  16. package/dist/src/app/{authorization.d.ts → auth/authorization.d.ts} +33 -139
  17. package/dist/src/app/auth/authorization.js +188 -0
  18. package/dist/src/app/auth/authorization.js.map +1 -0
  19. package/dist/src/app/auth/authorizationManager.d.ts +71 -0
  20. package/dist/src/app/auth/authorizationManager.js +170 -0
  21. package/dist/src/app/auth/authorizationManager.js.map +1 -0
  22. package/dist/src/app/auth/handlerStorage.d.ts +36 -0
  23. package/dist/src/app/auth/handlerStorage.js +62 -0
  24. package/dist/src/app/auth/handlerStorage.js.map +1 -0
  25. package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +93 -0
  26. package/dist/src/app/auth/handlers/agenticAuthorization.js +134 -0
  27. package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -0
  28. package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +222 -0
  29. package/dist/src/app/auth/handlers/azureBotAuthorization.js +428 -0
  30. package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -0
  31. package/dist/src/app/auth/handlers/index.d.ts +2 -0
  32. package/dist/src/app/auth/handlers/index.js +19 -0
  33. package/dist/src/app/auth/handlers/index.js.map +1 -0
  34. package/dist/src/app/auth/index.d.ts +2 -0
  35. package/dist/src/app/auth/index.js +19 -0
  36. package/dist/src/app/auth/index.js.map +1 -0
  37. package/dist/src/app/auth/types.d.ts +104 -0
  38. package/dist/src/app/auth/types.js +24 -0
  39. package/dist/src/app/auth/types.js.map +1 -0
  40. package/dist/src/app/index.d.ts +2 -3
  41. package/dist/src/app/index.js +2 -3
  42. package/dist/src/app/index.js.map +1 -1
  43. package/dist/src/app/routeList.d.ts +1 -1
  44. package/dist/src/app/routeList.js +22 -5
  45. package/dist/src/app/routeList.js.map +1 -1
  46. package/dist/src/app/streaming/streamingResponse.js +2 -1
  47. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  48. package/dist/src/auth/MemoryCache.d.ts +16 -0
  49. package/dist/src/auth/MemoryCache.js +58 -0
  50. package/dist/src/auth/MemoryCache.js.map +1 -0
  51. package/dist/src/auth/authConfiguration.d.ts +44 -2
  52. package/dist/src/auth/authConfiguration.js +209 -53
  53. package/dist/src/auth/authConfiguration.js.map +1 -1
  54. package/dist/src/auth/authConstants.d.ts +11 -0
  55. package/dist/src/auth/authConstants.js +15 -0
  56. package/dist/src/auth/authConstants.js.map +1 -0
  57. package/dist/src/auth/authProvider.d.ts +23 -0
  58. package/dist/src/auth/connections.d.ts +41 -0
  59. package/dist/src/auth/connections.js +7 -0
  60. package/dist/src/auth/connections.js.map +1 -0
  61. package/dist/src/auth/index.d.ts +2 -0
  62. package/dist/src/auth/index.js +2 -0
  63. package/dist/src/auth/index.js.map +1 -1
  64. package/dist/src/auth/jwt-middleware.js +31 -18
  65. package/dist/src/auth/jwt-middleware.js.map +1 -1
  66. package/dist/src/auth/msalConnectionManager.d.ts +64 -0
  67. package/dist/src/auth/msalConnectionManager.js +148 -0
  68. package/dist/src/auth/msalConnectionManager.js.map +1 -0
  69. package/dist/src/auth/msalTokenProvider.d.ts +31 -0
  70. package/dist/src/auth/msalTokenProvider.js +167 -16
  71. package/dist/src/auth/msalTokenProvider.js.map +1 -1
  72. package/dist/src/baseAdapter.d.ts +10 -25
  73. package/dist/src/baseAdapter.js +2 -15
  74. package/dist/src/baseAdapter.js.map +1 -1
  75. package/dist/src/cloudAdapter.d.ts +40 -23
  76. package/dist/src/cloudAdapter.js +128 -60
  77. package/dist/src/cloudAdapter.js.map +1 -1
  78. package/dist/src/connector-client/connectorClient.d.ts +15 -0
  79. package/dist/src/connector-client/connectorClient.js +49 -15
  80. package/dist/src/connector-client/connectorClient.js.map +1 -1
  81. package/dist/src/index.d.ts +0 -1
  82. package/dist/src/index.js +0 -1
  83. package/dist/src/index.js.map +1 -1
  84. package/dist/src/oauth/customUserTokenAPI.d.ts +1 -0
  85. package/dist/src/oauth/customUserTokenAPI.js +11 -0
  86. package/dist/src/oauth/customUserTokenAPI.js.map +1 -0
  87. package/dist/src/oauth/index.d.ts +0 -1
  88. package/dist/src/oauth/index.js +0 -1
  89. package/dist/src/oauth/index.js.map +1 -1
  90. package/dist/src/oauth/userTokenClient.d.ts +30 -13
  91. package/dist/src/oauth/userTokenClient.js +60 -26
  92. package/dist/src/oauth/userTokenClient.js.map +1 -1
  93. package/dist/src/oauth/userTokenClient.types.d.ts +19 -6
  94. package/dist/src/turnContext.d.ts +7 -1
  95. package/dist/src/turnContext.js +11 -4
  96. package/dist/src/turnContext.js.map +1 -1
  97. package/package.json +10 -6
  98. package/src/activityWireCompat.ts +12 -4
  99. package/src/agent-client/agentClient.ts +9 -3
  100. package/src/agent-client/agentResponseHandler.ts +5 -2
  101. package/src/app/agentApplication.ts +98 -77
  102. package/src/app/agentApplicationBuilder.ts +2 -2
  103. package/src/app/agentApplicationOptions.ts +10 -2
  104. package/src/app/appRoute.ts +8 -0
  105. package/src/app/auth/authorization.ts +252 -0
  106. package/src/app/auth/authorizationManager.ts +213 -0
  107. package/src/app/auth/handlerStorage.ts +61 -0
  108. package/src/app/auth/handlers/agenticAuthorization.ts +182 -0
  109. package/src/app/auth/handlers/azureBotAuthorization.ts +599 -0
  110. package/src/app/auth/handlers/index.ts +2 -0
  111. package/src/app/auth/index.ts +2 -0
  112. package/src/app/auth/types.ts +111 -0
  113. package/src/app/index.ts +2 -3
  114. package/src/app/routeList.ts +24 -5
  115. package/src/app/streaming/streamingResponse.ts +2 -1
  116. package/src/auth/MemoryCache.ts +59 -0
  117. package/src/auth/authConfiguration.ts +245 -52
  118. package/src/auth/authConstants.ts +11 -0
  119. package/src/auth/authProvider.ts +31 -0
  120. package/src/auth/connections.ts +47 -0
  121. package/src/auth/index.ts +2 -0
  122. package/src/auth/jwt-middleware.ts +38 -21
  123. package/src/auth/msalConnectionManager.ts +175 -0
  124. package/src/auth/msalTokenProvider.ts +209 -9
  125. package/src/baseAdapter.ts +10 -29
  126. package/src/cloudAdapter.ts +189 -71
  127. package/src/connector-client/connectorClient.ts +59 -15
  128. package/src/index.ts +0 -1
  129. package/src/oauth/customUserTokenAPI.ts +5 -0
  130. package/src/oauth/index.ts +0 -1
  131. package/src/oauth/userTokenClient.ts +74 -22
  132. package/src/oauth/userTokenClient.types.ts +20 -8
  133. package/src/turnContext.ts +16 -5
  134. package/dist/src/app/authorization.js +0 -387
  135. package/dist/src/app/authorization.js.map +0 -1
  136. package/dist/src/claimsIdentity.d.ts +0 -35
  137. package/dist/src/claimsIdentity.js +0 -43
  138. package/dist/src/claimsIdentity.js.map +0 -1
  139. package/dist/src/oauth/oAuthFlow.d.ts +0 -119
  140. package/dist/src/oauth/oAuthFlow.js +0 -316
  141. package/dist/src/oauth/oAuthFlow.js.map +0 -1
  142. package/src/app/authorization.ts +0 -432
  143. package/src/claimsIdentity.ts +0 -47
  144. package/src/oauth/oAuthFlow.ts +0 -378
@@ -2,45 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { TurnContext } from '../turnContext';
6
- import { TurnState } from './turnState';
7
- import { Storage } from '../storage';
8
- import { OAuthFlow, TokenResponse, UserTokenClient } from '../oauth';
9
- import { Activity } from '@microsoft/agents-activity';
10
- /**
11
- * Represents the state of a sign-in process.
12
- * @interface SignInState
13
- */
14
- export interface SignInState {
15
- /** Optional activity to continue with after sign-in completion. */
16
- continuationActivity?: Activity;
17
- /** Identifier of the auth handler being used. */
18
- handlerId?: string;
19
- /** Whether the sign-in process has been completed. */
20
- completed?: boolean;
21
- }
22
- /**
23
- * Interface defining an authorization handler for OAuth flows.
24
- * @interface AuthHandler
25
- */
26
- export interface AuthHandler {
27
- /** Connection name for the auth provider. */
28
- name?: string;
29
- /** The OAuth flow implementation. */
30
- flow?: OAuthFlow;
31
- /** Title to display on auth cards/UI. */
32
- title?: string;
33
- /** Text to display on auth cards/UI. */
34
- text?: string;
35
- cnxPrefix?: string;
36
- }
37
- /**
38
- * Options for configuring user authorization.
39
- * Contains settings to configure OAuth connections.
40
- * @interface AuthorizationHandlers
41
- */
42
- export interface AuthorizationHandlers extends Record<string, AuthHandler> {
43
- }
5
+ import { TokenResponse } from '../../oauth';
6
+ import { TurnContext } from '../../turnContext';
7
+ import { TurnState } from '../turnState';
8
+ import { AuthorizationManager } from './authorizationManager';
9
+ import { AuthorizationHandlerTokenOptions } from './types';
44
10
  /**
45
11
  * Class responsible for managing authorization and OAuth flows.
46
12
  * Handles multiple OAuth providers and manages the complete authentication lifecycle.
@@ -57,58 +23,14 @@ export interface AuthorizationHandlers extends Record<string, AuthHandler> {
57
23
  * - Sign-in success/failure event handling
58
24
  * - Automatic configuration from environment variables
59
25
  *
60
- * @example
61
- * ```typescript
62
- * const auth = new Authorization(storage, {
63
- * 'microsoft': {
64
- * name: 'Microsoft',
65
- * title: 'Sign in with Microsoft',
66
- * text: 'Please sign in'
67
- * }
68
- * });
69
- *
70
- * auth.onSignInSuccess(async (context, state) => {
71
- * await context.sendActivity('Welcome! You are now signed in.');
72
- * });
73
- * ```
74
- *
75
26
  */
76
27
  export declare class Authorization {
77
- private storage;
78
- /**
79
- * Dictionary of configured authentication handlers.
80
- * @public
81
- */
82
- authHandlers: AuthorizationHandlers;
28
+ private manager;
83
29
  /**
84
30
  * Creates a new instance of Authorization.
85
- *
86
- * @remarks
87
- * The constructor initializes all configured auth handlers and sets up OAuth flows.
88
- * It automatically configures handler properties from environment variables if not provided:
89
- * - Connection name: {handlerId}_connectionName
90
- * - Connection title: {handlerId}_connectionTitle
91
- * - Connection text: {handlerId}_connectionText
92
- *
93
- * @example
94
- * ```typescript
95
- * const auth = new Authorization(storage, {
96
- * 'microsoft': {
97
- * name: 'Microsoft',
98
- * title: 'Sign in with Microsoft'
99
- * },
100
- * 'google': {
101
- * // Will use GOOGLE_connectionName from env vars
102
- * }
103
- * });
104
- * ```
105
- *
106
- * @param storage - The storage system to use for state management.
107
- * @param authHandlers - Configuration for OAuth providers.
108
- * @throws {Error} If storage is null/undefined or no auth handlers are provided.
109
- *
31
+ * @param manager The AuthorizationManager instance to manage handlers.
110
32
  */
111
- constructor(storage: Storage, authHandlers: AuthorizationHandlers, userTokenClient: UserTokenClient);
33
+ constructor(manager: AuthorizationManager);
112
34
  /**
113
35
  * Gets the token for a specific auth handler.
114
36
  *
@@ -133,15 +55,7 @@ export declare class Authorization {
133
55
  */
134
56
  getToken(context: TurnContext, authHandlerId: string): Promise<TokenResponse>;
135
57
  /**
136
- * Gets the auth handler by ID or throws an error if not found.
137
- *
138
- * @param authHandlerId - ID of the auth handler to retrieve.
139
- * @returns The auth handler instance.
140
- * @throws {Error} If the auth handler with the specified ID is not configured.
141
- * @private
142
- */
143
- private getAuthHandlerOrThrow;
144
- /**
58
+ * @deprecated
145
59
  * Exchanges a token for a new token with different scopes.
146
60
  *
147
61
  * @param context - The context object for the current turn.
@@ -168,53 +82,34 @@ export declare class Authorization {
168
82
  */
169
83
  exchangeToken(context: TurnContext, scopes: string[], authHandlerId: string): Promise<TokenResponse>;
170
84
  /**
171
- * Checks if a token is exchangeable for an on-behalf-of flow.
172
- *
173
- * @param token - The token to check.
174
- * @returns True if the token is exchangeable, false otherwise.
175
- * @private
176
- */
177
- private isExchangeable;
178
- /**
179
- * Handles on-behalf-of token exchange using MSAL.
180
- *
181
- * @param context - The context object for the current turn.
182
- * @param token - The token to exchange.
183
- * @param scopes - Array of scopes to request for the new token.
184
- * @returns A promise that resolves to the exchanged token response.
185
- * @private
186
- */
187
- private handleObo;
188
- /**
189
- * Begins or continues an OAuth flow.
85
+ * Exchanges a token for a new token with different scopes.
190
86
  *
191
87
  * @param context - The context object for the current turn.
192
- * @param state - The state object for the current turn.
193
88
  * @param authHandlerId - ID of the auth handler to use.
194
- * @returns A promise that resolves to the token response from the OAuth provider.
89
+ * @param options - Optional token options. If `connection` and `scopes` are NOT provided, the auth handler's configured options are used
90
+ * (`AgentApplication.authorization.obo.connection` and `AgentApplication.authorization.obo.scopes`), and the token exchange operation will happen automatically,
91
+ * meaning that this method should not be called, otherwise it will perform the token exchange operation twice.
92
+ * Provide `options` only when you need to override the `AgentApplication.authorization.obo` configuration for a specific call.
93
+ * @returns A promise that resolves to the exchanged token response.
195
94
  * @throws {Error} If the auth handler is not configured.
196
95
  *
197
96
  * @remarks
198
- * This method manages the complete OAuth authentication flow:
199
- * - If no flow is active, it begins a new OAuth flow and shows the sign-in card
200
- * - If a flow is active, it continues the flow and processes the authentication response
201
- * - Handles success/failure callbacks and updates the sign-in state accordingly
202
- *
203
- * The method automatically manages the sign-in state and continuation activities,
204
- * allowing the conversation to resume after successful authentication.
97
+ * This method handles token exchange scenarios, particularly for on-behalf-of (OBO) flows.
98
+ * It checks if the current token is exchangeable (e.g., has audience starting with 'api://')
99
+ * and performs the appropriate token exchange using MSAL.
205
100
  *
206
101
  * @example
207
102
  * ```typescript
208
- * const tokenResponse = await auth.beginOrContinueFlow(context, state, 'microsoft');
209
- * if (tokenResponse && tokenResponse.token) {
210
- * // User is now authenticated
211
- * await context.sendActivity('Authentication successful!');
212
- * }
103
+ * const exchangedToken = await auth.exchangeToken(
104
+ * context,
105
+ * 'microsoft',
106
+ * { connection: 'oboConnection', scopes: ['https://graph.microsoft.com/.default'] }
107
+ * });
213
108
  * ```
214
109
  *
215
110
  * @public
216
111
  */
217
- beginOrContinueFlow(context: TurnContext, state: TurnState, authHandlerId: string, secRoute?: boolean): Promise<TokenResponse>;
112
+ exchangeToken(context: TurnContext, authHandlerId: string, options?: AuthorizationHandlerTokenOptions): Promise<TokenResponse>;
218
113
  /**
219
114
  * Signs out the current user.
220
115
  *
@@ -241,11 +136,6 @@ export declare class Authorization {
241
136
  * @public
242
137
  */
243
138
  signOut(context: TurnContext, state: TurnState, authHandlerId?: string): Promise<void>;
244
- /**
245
- * Private handler for successful sign-in events.
246
- * @private
247
- */
248
- _signInSuccessHandler: ((context: TurnContext, state: TurnState, authHandlerId?: string) => Promise<void>) | null;
249
139
  /**
250
140
  * Sets a handler to be called when sign-in is successfully completed.
251
141
  *
@@ -267,11 +157,6 @@ export declare class Authorization {
267
157
  * @public
268
158
  */
269
159
  onSignInSuccess(handler: (context: TurnContext, state: TurnState, authHandlerId?: string) => Promise<void>): void;
270
- /**
271
- * Private handler for failed sign-in events.
272
- * @private
273
- */
274
- _signInFailureHandler: ((context: TurnContext, state: TurnState, authHandlerId?: string, errorMessage?: string) => Promise<void>) | null;
275
160
  /**
276
161
  * Sets a handler to be called when sign-in fails.
277
162
  *
@@ -299,4 +184,13 @@ export declare class Authorization {
299
184
  * @public
300
185
  */
301
186
  onSignInFailure(handler: (context: TurnContext, state: TurnState, authHandlerId?: string, errorMessage?: string) => Promise<void>): void;
187
+ /**
188
+ * Gets the auth handler by ID or throws an error if not found.
189
+ *
190
+ * @param id - ID of the auth handler to retrieve.
191
+ * @returns The auth handler instance.
192
+ * @throws {Error} If the auth handler with the specified ID is not configured.
193
+ * @private
194
+ */
195
+ private getHandler;
302
196
  }
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Authorization = void 0;
8
+ const logger_1 = require("@microsoft/agents-activity/logger");
9
+ const turnState_1 = require("../turnState");
10
+ const logger = (0, logger_1.debug)('agents:authorization');
11
+ /**
12
+ * Class responsible for managing authorization and OAuth flows.
13
+ * Handles multiple OAuth providers and manages the complete authentication lifecycle.
14
+ *
15
+ * @remarks
16
+ * The Authorization class provides a centralized way to handle OAuth authentication
17
+ * flows within the agent application. It supports multiple authentication handlers,
18
+ * token exchange, on-behalf-of flows, and provides event handlers for success/failure scenarios.
19
+ *
20
+ * Key features:
21
+ * - Multiple OAuth provider support
22
+ * - Token caching and exchange
23
+ * - On-behalf-of (OBO) token flows
24
+ * - Sign-in success/failure event handling
25
+ * - Automatic configuration from environment variables
26
+ *
27
+ */
28
+ class Authorization {
29
+ /**
30
+ * Creates a new instance of Authorization.
31
+ * @param manager The AuthorizationManager instance to manage handlers.
32
+ */
33
+ constructor(manager) {
34
+ this.manager = manager;
35
+ }
36
+ /**
37
+ * Gets the token for a specific auth handler.
38
+ *
39
+ * @param context - The context object for the current turn.
40
+ * @param authHandlerId - ID of the auth handler to use.
41
+ * @returns A promise that resolves to the token response from the OAuth provider.
42
+ * @throws {Error} If the auth handler is not configured.
43
+ *
44
+ * @remarks
45
+ * This method retrieves an existing token for the specified auth handler.
46
+ * The token may be cached and will be retrieved from the OAuth provider if needed.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const tokenResponse = await auth.getToken(context, 'microsoft');
51
+ * if (tokenResponse.token) {
52
+ * console.log('User is authenticated');
53
+ * }
54
+ * ```
55
+ *
56
+ * @public
57
+ */
58
+ async getToken(context, authHandlerId) {
59
+ const handler = this.getHandler(authHandlerId);
60
+ const { token } = await handler.token(context);
61
+ return { token };
62
+ }
63
+ /**
64
+ * @internal
65
+ * Internal implementation of exchangeToken method.
66
+ * Handles both overloads and performs the actual token exchange logic.
67
+ */
68
+ async exchangeToken(context, authHandlerId, options) {
69
+ if (authHandlerId instanceof Array && typeof options === 'string') {
70
+ logger.warn('Authorization.exchangeToken(context, scopes, authHandlerId) is deprecated. Use Authorization.exchangeToken(context, authHandlerId, options) instead.');
71
+ const [handlerId, handlerScopes] = [options, authHandlerId];
72
+ return this.exchangeToken(context, handlerId, { scopes: handlerScopes });
73
+ }
74
+ if (typeof authHandlerId === 'string' && typeof options !== 'string') {
75
+ const handler = this.getHandler(authHandlerId);
76
+ const { token } = await handler.token(context, options);
77
+ return { token };
78
+ }
79
+ throw new Error('Invalid parameters for exchangeToken method.');
80
+ }
81
+ /**
82
+ * Signs out the current user.
83
+ *
84
+ * @param context - The context object for the current turn.
85
+ * @param state - The state object for the current turn.
86
+ * @param authHandlerId - Optional ID of the auth handler to use for sign out. If not provided, signs out from all handlers.
87
+ * @returns A promise that resolves when sign out is complete.
88
+ * @throws {Error} If the specified auth handler is not configured.
89
+ *
90
+ * @remarks
91
+ * This method clears the user's token and resets the authentication state.
92
+ * If no specific authHandlerId is provided, it signs out from all configured handlers.
93
+ * This ensures complete cleanup of authentication state across all providers.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // Sign out from specific handler
98
+ * await auth.signOut(context, state, 'microsoft');
99
+ *
100
+ * // Sign out from all handlers
101
+ * await auth.signOut(context, state);
102
+ * ```
103
+ *
104
+ * @public
105
+ */
106
+ async signOut(context, state, authHandlerId) {
107
+ if (authHandlerId) {
108
+ await this.getHandler(authHandlerId).signout(context);
109
+ }
110
+ else {
111
+ for (const handler of Object.values(this.manager.handlers)) {
112
+ await handler.signout(context);
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Sets a handler to be called when sign-in is successfully completed.
118
+ *
119
+ * @param handler - The handler function to call on successful sign-in.
120
+ *
121
+ * @remarks
122
+ * This method allows you to register a callback that will be invoked whenever
123
+ * a user successfully completes the authentication process. The handler receives
124
+ * the turn context, state, and the ID of the auth handler that was used.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * auth.onSignInSuccess(async (context, state, authHandlerId) => {
129
+ * await context.sendActivity(`Welcome! You signed in using ${authHandlerId}.`);
130
+ * // Perform any post-authentication setup
131
+ * });
132
+ * ```
133
+ *
134
+ * @public
135
+ */
136
+ onSignInSuccess(handler) {
137
+ for (const authHandler of Object.values(this.manager.handlers)) {
138
+ authHandler.onSuccess((context) => handler(context, new turnState_1.TurnState(), authHandler.id));
139
+ }
140
+ }
141
+ /**
142
+ * Sets a handler to be called when sign-in fails.
143
+ *
144
+ * @param handler - The handler function to call on sign-in failure.
145
+ *
146
+ * @remarks
147
+ * This method allows you to register a callback that will be invoked whenever
148
+ * a user's authentication attempt fails. The handler receives the turn context,
149
+ * state, auth handler ID, and an optional error message describing the failure.
150
+ *
151
+ * Common failure scenarios include:
152
+ * - User cancels the authentication process
153
+ * - Invalid credentials or expired tokens
154
+ * - Network connectivity issues
155
+ * - OAuth provider errors
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * auth.onSignInFailure(async (context, state, authHandlerId, errorMessage) => {
160
+ * await context.sendActivity(`Sign-in failed: ${errorMessage || 'Unknown error'}`);
161
+ * await context.sendActivity('Please try signing in again.');
162
+ * });
163
+ * ```
164
+ *
165
+ * @public
166
+ */
167
+ onSignInFailure(handler) {
168
+ for (const authHandler of Object.values(this.manager.handlers)) {
169
+ authHandler.onFailure((context, reason) => handler(context, new turnState_1.TurnState(), authHandler.id, reason));
170
+ }
171
+ }
172
+ /**
173
+ * Gets the auth handler by ID or throws an error if not found.
174
+ *
175
+ * @param id - ID of the auth handler to retrieve.
176
+ * @returns The auth handler instance.
177
+ * @throws {Error} If the auth handler with the specified ID is not configured.
178
+ * @private
179
+ */
180
+ getHandler(id) {
181
+ if (!Object.prototype.hasOwnProperty.call(this.manager.handlers, id)) {
182
+ throw new Error(`Cannot find auth handler with ID '${id}'. Ensure it is configured in the agent application options.`);
183
+ }
184
+ return this.manager.handlers[id];
185
+ }
186
+ }
187
+ exports.Authorization = Authorization;
188
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../../src/app/auth/authorization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { Activity } from '@microsoft/agents-activity';
6
+ import { AgentApplication } from '../agentApplication';
7
+ import { TurnContext } from '../../turnContext';
8
+ import { AuthorizationHandler } from './types';
9
+ import { Connections } from '../../auth/connections';
10
+ /**
11
+ * Result of the authorization manager process.
12
+ */
13
+ export interface AuthorizationManagerProcessResult {
14
+ /**
15
+ * Indicates whether the authorization was successful.
16
+ */
17
+ authorized: boolean;
18
+ }
19
+ /**
20
+ * Function to retrieve handler IDs for the current activity.
21
+ */
22
+ export type GetHandlerIds = (activity: Activity) => string[] | Promise<string[]>;
23
+ /**
24
+ * Manages multiple authorization handlers and their interactions.
25
+ * Processes authorization requests and maintains handler states.
26
+ * @remarks
27
+ * This class is responsible for coordinating the authorization process
28
+ * across multiple handlers, ensuring that each handler is invoked in
29
+ * the correct order and with the appropriate context.
30
+ */
31
+ export declare class AuthorizationManager {
32
+ private app;
33
+ private _handlers;
34
+ /**
35
+ * Creates an instance of the AuthorizationManager.
36
+ * @param app The agent application instance.
37
+ */
38
+ constructor(app: AgentApplication<any>, connections: Connections);
39
+ /**
40
+ * Loads and validates the authorization handler options.
41
+ */
42
+ private loadOptions;
43
+ /**
44
+ * Gets the registered authorization handlers.
45
+ * @returns A record of authorization handlers by their IDs.
46
+ */
47
+ get handlers(): Record<string, AuthorizationHandler>;
48
+ /**
49
+ * Processes an authorization request.
50
+ * @param context The turn context.
51
+ * @param getHandlerIds A function to retrieve the handler IDs for the current activity.
52
+ * @returns The result of the authorization process.
53
+ */
54
+ process(context: TurnContext, getHandlerIds: GetHandlerIds): Promise<AuthorizationManagerProcessResult>;
55
+ /**
56
+ * Gets the active handler session from storage.
57
+ */
58
+ private active;
59
+ /**
60
+ * Attempts to sign in using the specified handler and options.
61
+ */
62
+ private signin;
63
+ /**
64
+ * Maps an array of handler IDs to their corresponding handler instances.
65
+ */
66
+ private mapHandlers;
67
+ /**
68
+ * Prefixes a message with the handler ID.
69
+ */
70
+ private prefix;
71
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.AuthorizationManager = void 0;
8
+ const agents_activity_1 = require("@microsoft/agents-activity");
9
+ const handlers_1 = require("./handlers");
10
+ const handlerStorage_1 = require("./handlerStorage");
11
+ const types_1 = require("./types");
12
+ const logger = (0, agents_activity_1.debug)('agents:authorization:manager');
13
+ /**
14
+ * Manages multiple authorization handlers and their interactions.
15
+ * Processes authorization requests and maintains handler states.
16
+ * @remarks
17
+ * This class is responsible for coordinating the authorization process
18
+ * across multiple handlers, ensuring that each handler is invoked in
19
+ * the correct order and with the appropriate context.
20
+ */
21
+ class AuthorizationManager {
22
+ /**
23
+ * Creates an instance of the AuthorizationManager.
24
+ * @param app The agent application instance.
25
+ */
26
+ constructor(app, connections) {
27
+ this.app = app;
28
+ this._handlers = {};
29
+ if (!app.options.storage) {
30
+ throw new Error('Storage is required for Authorization. Ensure that a storage provider is configured in the AgentApplication options.');
31
+ }
32
+ if (app.options.authorization === undefined || Object.keys(app.options.authorization).length === 0) {
33
+ throw new Error('The AgentApplication.authorization does not have any auth handlers');
34
+ }
35
+ const settings = { storage: app.options.storage, connections };
36
+ for (const [id, handler] of Object.entries(app.options.authorization)) {
37
+ const options = this.loadOptions(id, handler);
38
+ if (options.type === 'agentic') {
39
+ this._handlers[id] = new handlers_1.AgenticAuthorization(id, options, settings);
40
+ }
41
+ else {
42
+ this._handlers[id] = new handlers_1.AzureBotAuthorization(id, options, settings);
43
+ }
44
+ }
45
+ }
46
+ /**
47
+ * Loads and validates the authorization handler options.
48
+ */
49
+ loadOptions(id, options) {
50
+ var _a, _b;
51
+ const result = {
52
+ ...options,
53
+ type: (_b = ((_a = options.type) !== null && _a !== void 0 ? _a : process.env[`${id}_type`])) === null || _b === void 0 ? void 0 : _b.toLowerCase(),
54
+ };
55
+ // Validate supported types, agentic, and default (Azure Bot - undefined)
56
+ const supportedTypes = ['agentic', undefined];
57
+ if (!supportedTypes.includes(result.type)) {
58
+ throw new Error(`Unsupported authorization handler type: '${result.type}' for auth handler: '${id}'. Supported types are: '${supportedTypes.filter(Boolean).join('\', \'')}'.`);
59
+ }
60
+ return result;
61
+ }
62
+ /**
63
+ * Gets the registered authorization handlers.
64
+ * @returns A record of authorization handlers by their IDs.
65
+ */
66
+ get handlers() {
67
+ return this._handlers;
68
+ }
69
+ /**
70
+ * Processes an authorization request.
71
+ * @param context The turn context.
72
+ * @param getHandlerIds A function to retrieve the handler IDs for the current activity.
73
+ * @returns The result of the authorization process.
74
+ */
75
+ async process(context, getHandlerIds) {
76
+ var _a, _b, _c;
77
+ const storage = new handlerStorage_1.HandlerStorage(this.app.options.storage, context);
78
+ let active = await this.active(storage, getHandlerIds);
79
+ const handlers = (_c = (_a = active === null || active === void 0 ? void 0 : active.handlers) !== null && _a !== void 0 ? _a : this.mapHandlers((_b = await getHandlerIds(context.activity)) !== null && _b !== void 0 ? _b : [])) !== null && _c !== void 0 ? _c : [];
80
+ for (const handler of handlers) {
81
+ const status = await this.signin(storage, handler, context, active === null || active === void 0 ? void 0 : active.data);
82
+ logger.debug(this.prefix(handler.id, `Sign-in status: ${status}`));
83
+ if (status === types_1.AuthorizationHandlerStatus.IGNORED) {
84
+ await storage.delete();
85
+ return { authorized: true };
86
+ }
87
+ if (status === types_1.AuthorizationHandlerStatus.PENDING) {
88
+ return { authorized: false };
89
+ }
90
+ if (status === types_1.AuthorizationHandlerStatus.REJECTED) {
91
+ await storage.delete();
92
+ return { authorized: false };
93
+ }
94
+ if (status === types_1.AuthorizationHandlerStatus.REVALIDATE) {
95
+ await storage.delete();
96
+ return this.process(context, getHandlerIds);
97
+ }
98
+ if (status !== types_1.AuthorizationHandlerStatus.APPROVED) {
99
+ throw new Error(this.prefix(handler.id, `Unexpected registration status: ${status}`));
100
+ }
101
+ await storage.delete();
102
+ if (active) {
103
+ // Restore the original activity in the turn context for the next handler to process.
104
+ // This is done like this to avoid losing data that may be set in the turn context.
105
+ context._activity = agents_activity_1.Activity.fromObject(active.data.activity);
106
+ active = undefined;
107
+ }
108
+ }
109
+ return { authorized: true };
110
+ }
111
+ /**
112
+ * Gets the active handler session from storage.
113
+ */
114
+ async active(storage, getHandlerIds) {
115
+ var _a;
116
+ const data = await storage.read();
117
+ if (!data) {
118
+ return;
119
+ }
120
+ const handlerIds = await getHandlerIds(agents_activity_1.Activity.fromObject(data.activity));
121
+ let handlers = this.mapHandlers(handlerIds !== null && handlerIds !== void 0 ? handlerIds : []);
122
+ // Sort handlers to ensure the active handler is processed first, to ensure continuity.
123
+ handlers = (_a = handlers.sort((a, b) => {
124
+ if (a.id === data.id) {
125
+ return -1;
126
+ }
127
+ if (b.id === data.id) {
128
+ return 1;
129
+ }
130
+ return 0;
131
+ })) !== null && _a !== void 0 ? _a : [];
132
+ return { data, handlers };
133
+ }
134
+ /**
135
+ * Attempts to sign in using the specified handler and options.
136
+ */
137
+ async signin(storage, handler, context, active) {
138
+ try {
139
+ return await handler.signin(context, active);
140
+ }
141
+ catch (cause) {
142
+ await storage.delete();
143
+ throw new Error(this.prefix(handler.id, 'Failed to sign in'), { cause });
144
+ }
145
+ }
146
+ /**
147
+ * Maps an array of handler IDs to their corresponding handler instances.
148
+ */
149
+ mapHandlers(ids) {
150
+ let unknownHandlers = '';
151
+ const handlers = ids.map(id => {
152
+ if (!this._handlers[id]) {
153
+ unknownHandlers += ` ${id}`;
154
+ }
155
+ return this._handlers[id];
156
+ });
157
+ if (unknownHandlers) {
158
+ throw new Error(`Cannot find auth handlers with ID(s): ${unknownHandlers}`);
159
+ }
160
+ return handlers;
161
+ }
162
+ /**
163
+ * Prefixes a message with the handler ID.
164
+ */
165
+ prefix(id, message) {
166
+ return `[handler:${id}] ${message}`;
167
+ }
168
+ }
169
+ exports.AuthorizationManager = AuthorizationManager;
170
+ //# sourceMappingURL=authorizationManager.js.map