botbuilder-core
Advanced tools
Comparing version 4.8.0-preview-109324 to 4.8.0
@@ -5,4 +5,6 @@ /** | ||
*/ | ||
import { MessageReaction, TurnContext } from '.'; | ||
import { MessageReaction } from 'botframework-schema'; | ||
import { ActivityHandlerBase } from './activityHandlerBase'; | ||
import { InvokeResponse } from './invokeResponse'; | ||
import { TurnContext } from './turnContext'; | ||
/** | ||
@@ -347,2 +349,4 @@ * Describes a bot activity event handler, for use with an [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. | ||
protected onMessageActivity(context: TurnContext): Promise<void>; | ||
protected onInvokeActivity(context: TurnContext): Promise<InvokeResponse>; | ||
protected onSignInInvoke(context: TurnContext): Promise<void>; | ||
/** | ||
@@ -349,0 +353,0 @@ * Runs all registered _endOfConversation_ handlers and then continues the event emission process. |
"use strict"; | ||
/** | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -12,2 +16,4 @@ return new (P || (P = Promise))(function (resolve, reject) { | ||
const activityHandlerBase_1 = require("./activityHandlerBase"); | ||
const signInConstants_1 = require("./signInConstants"); | ||
const statusCodes_1 = require("./statusCodes"); | ||
/** | ||
@@ -380,2 +386,45 @@ * Event-emitting activity handler for bots. Extends [ActivityHandlerBase](xref:botbuilder-core.ActivityHandlerBase). | ||
} | ||
/* | ||
* Provides default behavior for invoke activities. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
* The default logic is to check for a signIn invoke and handle that | ||
* and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). | ||
*/ | ||
onInvokeActivity(context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
if (context.activity.name && (context.activity.name === signInConstants_1.verifyStateOperationName || context.activity.name === signInConstants_1.tokenExchangeOperationName)) { | ||
yield this.onSignInInvoke(context); | ||
return { status: statusCodes_1.StatusCodes.OK }; | ||
} | ||
throw new Error('NotImplemented'); | ||
} | ||
catch (err) { | ||
if (err.message === 'NotImplemented') { | ||
return { status: statusCodes_1.StatusCodes.NOT_IMPLEMENTED }; | ||
} | ||
throw err; | ||
} | ||
finally { | ||
this.defaultNextEvent(context)(); | ||
} | ||
}); | ||
} | ||
/* | ||
* Handle _signin invoke activity type_. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
*/ | ||
onSignInInvoke(context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
throw new Error('NotImplemented'); | ||
}); | ||
} | ||
/** | ||
@@ -598,3 +647,3 @@ * Runs all registered _endOfConversation_ handlers and then continues the event emission process. | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (context.activity.name === 'tokens/response') { | ||
if (context.activity.name === signInConstants_1.tokenResponseEventName) { | ||
yield this.handle(context, 'TokenResponseEvent', this.defaultNextEvent(context)); | ||
@@ -601,0 +650,0 @@ } |
@@ -6,2 +6,4 @@ /** | ||
import { ChannelAccount, MessageReaction, TurnContext } from '.'; | ||
import { InvokeResponse } from './invokeResponse'; | ||
export declare const INVOKE_RESPONSE_KEY: symbol; | ||
/** | ||
@@ -43,2 +45,3 @@ * Defines the core behavior for event-emitting activity handlers for bots. | ||
* - Event activities | ||
* - Invoke activities | ||
* - _Unrecognized_ activities, ones that this class has not otherwise defined an _on event_ method for. | ||
@@ -100,2 +103,11 @@ */ | ||
/** | ||
* Provides a hook for invoke calls. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to handle particular invoke calls. | ||
*/ | ||
protected onInvokeActivity(context: TurnContext): Promise<InvokeResponse>; | ||
/** | ||
* Provides a hook for emitting the _end of conversation_ event. | ||
@@ -102,0 +114,0 @@ * |
@@ -16,2 +16,5 @@ "use strict"; | ||
const _1 = require("."); | ||
const statusCodes_1 = require("./statusCodes"); | ||
// This key is exported internally so that subclassed ActivityHandlers and BotAdapters will not overwrite any already set InvokeResponses. | ||
exports.INVOKE_RESPONSE_KEY = Symbol('invokeResponse'); | ||
/** | ||
@@ -53,2 +56,3 @@ * Defines the core behavior for event-emitting activity handlers for bots. | ||
* - Event activities | ||
* - Invoke activities | ||
* - _Unrecognized_ activities, ones that this class has not otherwise defined an _on event_ method for. | ||
@@ -71,2 +75,9 @@ */ | ||
break; | ||
case _1.ActivityTypes.Invoke: | ||
const invokeResponse = yield this.onInvokeActivity(context); | ||
// If onInvokeActivity has already sent an InvokeResponse, do not send another one. | ||
if (invokeResponse && !context.turnState.get(exports.INVOKE_RESPONSE_KEY)) { | ||
yield context.sendActivity({ value: invokeResponse, type: 'invokeResponse' }); | ||
} | ||
break; | ||
case _1.ActivityTypes.EndOfConversation: | ||
@@ -168,2 +179,15 @@ yield this.onEndOfConversationActivity(context); | ||
/** | ||
* Provides a hook for invoke calls. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to handle particular invoke calls. | ||
*/ | ||
onInvokeActivity(context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return { status: statusCodes_1.StatusCodes.NOT_IMPLEMENTED }; | ||
}); | ||
} | ||
/** | ||
* Provides a hook for emitting the _end of conversation_ event. | ||
@@ -170,0 +194,0 @@ * |
@@ -30,2 +30,4 @@ /** | ||
private turnError; | ||
readonly BotIdentityKey: Symbol; | ||
readonly OAuthScopeKey: Symbol; | ||
/** | ||
@@ -32,0 +34,0 @@ * Asynchronously sends a set of outgoing activities to a channel server. |
@@ -27,2 +27,4 @@ "use strict"; | ||
this.middleware = new middlewareSet_1.MiddlewareSet(); | ||
this.BotIdentityKey = Symbol('BotIdentity'); | ||
this.OAuthScopeKey = Symbol('OAuthScope'); | ||
} | ||
@@ -29,0 +31,0 @@ /** |
@@ -5,3 +5,3 @@ /** | ||
*/ | ||
import { AnimationCard, Attachment, AudioCard, CardAction, CardImage, HeroCard, MediaUrl, O365ConnectorCard, ReceiptCard, ThumbnailCard, VideoCard } from 'botframework-schema'; | ||
import { AnimationCard, Attachment, AudioCard, CardAction, CardImage, HeroCard, MediaUrl, O365ConnectorCard, ReceiptCard, ThumbnailCard, TokenExchangeResource, VideoCard } from 'botframework-schema'; | ||
/** | ||
@@ -128,3 +128,3 @@ * Provides methods for formatting the various card types a bot can return. | ||
*/ | ||
static oauthCard(connectionName: string, title: string, text?: string, link?: string): Attachment; | ||
static oauthCard(connectionName: string, title: string, text?: string, link?: string, tokenExchangeResource?: TokenExchangeResource): Attachment; | ||
/** | ||
@@ -131,0 +131,0 @@ * Returns an attachment for an Office 365 connector card. |
@@ -110,3 +110,3 @@ "use strict"; | ||
*/ | ||
static oauthCard(connectionName, title, text, link) { | ||
static oauthCard(connectionName, title, text, link, tokenExchangeResource) { | ||
const card = { | ||
@@ -116,3 +116,4 @@ buttons: [ | ||
], | ||
connectionName: connectionName | ||
connectionName, | ||
tokenExchangeResource | ||
}; | ||
@@ -119,0 +120,0 @@ if (text) { |
@@ -9,2 +9,4 @@ /** | ||
export * from 'botframework-schema'; | ||
export * from './activityFactory'; | ||
export * from './coreAppCredentials'; | ||
export * from './activityHandler'; | ||
@@ -21,2 +23,4 @@ export * from './activityHandlerBase'; | ||
export * from './conversationState'; | ||
export * from './invokeResponse'; | ||
export * from './extendedUserTokenProvider'; | ||
export * from './memoryStorage'; | ||
@@ -30,3 +34,6 @@ export * from './memoryTranscriptStore'; | ||
export * from './showTypingMiddleware'; | ||
export * from './signInConstants'; | ||
export { BotFrameworkSkill, BotFrameworkClient, SkillConversationIdFactoryBase, SkillConversationReference, SkillConversationIdFactoryOptions } from './skills'; | ||
export * from './skypeMentionNormalizeMiddleware'; | ||
export * from './statusCodes'; | ||
export * from './storage'; | ||
@@ -33,0 +40,0 @@ export * from './telemetryLoggerMiddleware'; |
@@ -14,2 +14,3 @@ "use strict"; | ||
__export(require("botframework-schema")); | ||
__export(require("./activityFactory")); | ||
__export(require("./activityHandler")); | ||
@@ -32,3 +33,7 @@ __export(require("./activityHandlerBase")); | ||
__export(require("./showTypingMiddleware")); | ||
__export(require("./signInConstants")); | ||
var skills_1 = require("./skills"); | ||
exports.SkillConversationIdFactoryBase = skills_1.SkillConversationIdFactoryBase; | ||
__export(require("./skypeMentionNormalizeMiddleware")); | ||
__export(require("./statusCodes")); | ||
__export(require("./storage")); | ||
@@ -35,0 +40,0 @@ __export(require("./telemetryLoggerMiddleware")); |
@@ -154,3 +154,3 @@ "use strict"; | ||
const properties = {}; | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from.id || ''; | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from ? activity.from.id : ''; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name || ''; | ||
@@ -162,4 +162,5 @@ properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
if (this.logPersonalInformation) { | ||
if (activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from.name; | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from ? activity.from.name : ''; | ||
; | ||
} | ||
@@ -166,0 +167,0 @@ if (activity.text && activity.text.trim()) { |
@@ -1,5 +0,5 @@ | ||
import { Activity, ConversationReference, ResourceResponse, TokenResponse } from 'botframework-schema'; | ||
import { Activity, ConversationReference, ResourceResponse, TokenResponse, TokenExchangeRequest, SignInUrlResponse } from 'botframework-schema'; | ||
import { BotAdapter } from './botAdapter'; | ||
import { ExtendedUserTokenProvider } from './extendedUserTokenProvider'; | ||
import { TurnContext } from './turnContext'; | ||
import { IUserTokenProvider } from './userTokenProvider'; | ||
/** | ||
@@ -34,3 +34,3 @@ * Signature for a function that can be used to inspect individual activities returned by a bot | ||
*/ | ||
export declare class TestAdapter extends BotAdapter implements IUserTokenProvider { | ||
export declare class TestAdapter extends BotAdapter implements ExtendedUserTokenProvider { | ||
private logic; | ||
@@ -214,2 +214,6 @@ /** | ||
}>; | ||
private exchangeableTokens; | ||
addExchangeableToken(connectionName: string, channelId: string, userId: string, exchangeableItem: string, token: string): void; | ||
getSignInResource(context: TurnContext, connectionName: string, userId?: string, finalRedirect?: string): Promise<SignInUrlResponse>; | ||
exchangeToken(context: TurnContext, connectionName: string, userId: string, tokenExchangeRequest: TokenExchangeRequest): Promise<TokenResponse>; | ||
/** | ||
@@ -216,0 +220,0 @@ * Indicates if the activity is a reply from the bot (role == 'bot') |
@@ -94,2 +94,3 @@ "use strict"; | ||
this._magicCodes = []; | ||
this.exchangeableTokens = {}; | ||
this.sendTraceActivities = sendTraceActivities || false; | ||
@@ -338,2 +339,42 @@ this.template = Object.assign({ channelId: 'test', serviceUrl: 'https://test.com', from: { id: 'user', name: 'User1' }, recipient: { id: 'bot', name: 'Bot' }, conversation: { id: 'Convo1' } }, template); | ||
} | ||
addExchangeableToken(connectionName, channelId, userId, exchangeableItem, token) { | ||
const key = new ExchangeableToken(); | ||
key.ChannelId = channelId; | ||
key.ConnectionName = connectionName; | ||
key.UserId = userId; | ||
key.exchangeableItem = exchangeableItem; | ||
key.Token = token; | ||
this.exchangeableTokens[key.toKey()] = key; | ||
} | ||
getSignInResource(context, connectionName, userId, finalRedirect) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return { | ||
signInLink: `https://botframeworktestadapter.com/oauthsignin/${connectionName}/${context.activity.channelId}/${userId}`, | ||
tokenExchangeResource: { | ||
id: String(Math.random()), | ||
providerId: null, | ||
uri: `api://${connectionName}/resource` | ||
} | ||
}; | ||
}); | ||
} | ||
exchangeToken(context, connectionName, userId, tokenExchangeRequest) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const exchangeableValue = tokenExchangeRequest.token ? tokenExchangeRequest.token : tokenExchangeRequest.uri; | ||
const key = new ExchangeableToken(); | ||
key.ChannelId = context.activity.channelId; | ||
key.ConnectionName = connectionName; | ||
key.exchangeableItem = exchangeableValue; | ||
key.UserId = userId; | ||
const tokenExchangeResponse = this.exchangeableTokens[key.toKey()]; | ||
return tokenExchangeResponse ? | ||
{ | ||
channelId: key.ChannelId, | ||
connectionName: key.ConnectionName, | ||
token: tokenExchangeResponse.Token, | ||
expiration: null | ||
} : | ||
null; | ||
}); | ||
} | ||
/** | ||
@@ -367,2 +408,12 @@ * Indicates if the activity is a reply from the bot (role == 'bot') | ||
} | ||
class ExchangeableToken extends UserToken { | ||
EqualsKey(rhs) { | ||
return rhs != null && | ||
this.exchangeableItem === rhs.exchangeableItem && | ||
super.EqualsKey(rhs); | ||
} | ||
toKey() { | ||
return this.exchangeableItem; | ||
} | ||
} | ||
/** | ||
@@ -369,0 +420,0 @@ * Support class for `TestAdapter` that allows for the simple construction of a sequence of tests. |
@@ -251,2 +251,6 @@ /** | ||
/** | ||
* List of activities to send when `context.activity.deliveryMode == 'expectReplies'`. | ||
*/ | ||
readonly bufferedReplyActivities: Partial<Activity>[]; | ||
/** | ||
* Asynchronously sends an activity to the sender of the incoming activity. | ||
@@ -253,0 +257,0 @@ * |
@@ -30,2 +30,6 @@ "use strict"; | ||
this._onDeleteActivity = []; | ||
/** | ||
* List of activities to send when `context.activity.deliveryMode == 'expectReplies'`. | ||
*/ | ||
this.bufferedReplyActivities = []; | ||
if (adapterOrContext instanceof TurnContext) { | ||
@@ -336,4 +340,9 @@ adapterOrContext.copyTo(this); | ||
return this.emit(this._onSendActivities, output, () => { | ||
return this.adapter.sendActivities(this, output) | ||
.then((responses) => { | ||
if (this.activity.deliveryMode === botframework_schema_1.DeliveryModes.ExpectReplies) { | ||
// Append activities to buffer | ||
const responses = []; | ||
output.forEach((a) => { | ||
this.bufferedReplyActivities.push(a); | ||
responses.push({ id: undefined }); | ||
}); | ||
// Set responded flag | ||
@@ -343,4 +352,14 @@ if (sentNonTraceActivity) { | ||
} | ||
return responses; | ||
}); | ||
return Promise.resolve(responses); | ||
} | ||
else { | ||
return this.adapter.sendActivities(this, output) | ||
.then((responses) => { | ||
// Set responded flag | ||
if (sentNonTraceActivity) { | ||
this.responded = true; | ||
} | ||
return responses; | ||
}); | ||
} | ||
}); | ||
@@ -347,0 +366,0 @@ } |
@@ -25,4 +25,5 @@ /** | ||
* @param connectionName Name of the auth connection to use. | ||
* @param userId User id of user to sign out. | ||
*/ | ||
signOutUser(context: TurnContext, connectionName: string): Promise<void>; | ||
signOutUser(context: TurnContext, connectionName: string, userId?: string): Promise<void>; | ||
/** | ||
@@ -29,0 +30,0 @@ * Gets a signin link from the token server that can be sent as part of a SigninCard. |
@@ -17,3 +17,3 @@ "use strict"; | ||
*/ | ||
exports.TokenPollingSettingsKey = "tokenPollingSettings"; | ||
exports.TokenPollingSettingsKey = 'tokenPollingSettings'; | ||
/** | ||
@@ -20,0 +20,0 @@ * Default amount of time an OAuthCard will remain active (clickable and actively waiting for a token). |
@@ -5,3 +5,3 @@ { | ||
"description": "Core components for Microsoft Bot Builder. Components in this library can run either in a browser or on the server.", | ||
"version": "4.8.0-preview-109324", | ||
"version": "4.8.0", | ||
"license": "MIT", | ||
@@ -25,3 +25,3 @@ "keywords": [ | ||
"assert": "^1.4.1", | ||
"botframework-schema": "4.8.0-preview-109324" | ||
"botframework-schema": "4.8.0" | ||
}, | ||
@@ -32,7 +32,7 @@ "devDependencies": { | ||
"mocha": "^5.2.0", | ||
"nyc": "^11.4.1", | ||
"nyc": "^15.0.0", | ||
"source-map-support": "^0.5.3", | ||
"ts-node": "^4.1.0", | ||
"typescript": "3.5.3", | ||
"unzip": "^0.1.11" | ||
"unzipper": "^0.10.9" | ||
}, | ||
@@ -44,3 +44,3 @@ "scripts": { | ||
"clean": "erase /q /s .\\lib", | ||
"set-version": "npm version --allow-same-version 4.8.0-preview-109324" | ||
"set-version": "npm version --allow-same-version 4.8.0" | ||
}, | ||
@@ -47,0 +47,0 @@ "files": [ |
@@ -5,4 +5,9 @@ /** | ||
*/ | ||
import { ChannelAccount, MessageReaction, TurnContext } from '.'; | ||
import { MessageReaction } from 'botframework-schema'; | ||
import { ActivityHandlerBase } from './activityHandlerBase'; | ||
import { InvokeResponse } from './invokeResponse'; | ||
import { verifyStateOperationName, tokenExchangeOperationName, tokenResponseEventName } from './signInConstants'; | ||
import { StatusCodes } from './statusCodes'; | ||
import { TurnContext } from './turnContext'; | ||
@@ -401,2 +406,43 @@ /** | ||
/* | ||
* Provides default behavior for invoke activities. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
* The default logic is to check for a signIn invoke and handle that | ||
* and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). | ||
*/ | ||
protected async onInvokeActivity(context: TurnContext): Promise<InvokeResponse> { | ||
try { | ||
if (context.activity.name && (context.activity.name === verifyStateOperationName || context.activity.name === tokenExchangeOperationName)) { | ||
await this.onSignInInvoke(context); | ||
return { status: StatusCodes.OK }; | ||
} | ||
throw new Error('NotImplemented'); | ||
} | ||
catch (err) { | ||
if (err.message === 'NotImplemented') { | ||
return { status: StatusCodes.NOT_IMPLEMENTED }; | ||
} | ||
throw err; | ||
} | ||
finally { | ||
this.defaultNextEvent(context)(); | ||
} | ||
} | ||
/* | ||
* Handle _signin invoke activity type_. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to support channel-specific behavior across multiple channels. | ||
*/ | ||
protected async onSignInInvoke(context: TurnContext): Promise<void> { | ||
throw new Error('NotImplemented'); | ||
} | ||
/** | ||
@@ -602,3 +648,3 @@ * Runs all registered _endOfConversation_ handlers and then continues the event emission process. | ||
protected async dispatchEventActivity(context: TurnContext): Promise<void> { | ||
if (context.activity.name === 'tokens/response') { | ||
if (context.activity.name === tokenResponseEventName) { | ||
await this.handle(context, 'TokenResponseEvent', this.defaultNextEvent(context)); | ||
@@ -605,0 +651,0 @@ } else { |
@@ -10,3 +10,8 @@ /** | ||
TurnContext } from '.'; | ||
import { InvokeResponse } from './invokeResponse'; | ||
import { StatusCodes } from './statusCodes'; | ||
// This key is exported internally so that subclassed ActivityHandlers and BotAdapters will not overwrite any already set InvokeResponses. | ||
export const INVOKE_RESPONSE_KEY: symbol = Symbol('invokeResponse'); | ||
/** | ||
@@ -48,2 +53,3 @@ * Defines the core behavior for event-emitting activity handlers for bots. | ||
* - Event activities | ||
* - Invoke activities | ||
* - _Unrecognized_ activities, ones that this class has not otherwise defined an _on event_ method for. | ||
@@ -65,2 +71,9 @@ */ | ||
break; | ||
case ActivityTypes.Invoke: | ||
const invokeResponse = await this.onInvokeActivity(context); | ||
// If onInvokeActivity has already sent an InvokeResponse, do not send another one. | ||
if (invokeResponse && !context.turnState.get(INVOKE_RESPONSE_KEY)) { | ||
await context.sendActivity({ value: invokeResponse, type: 'invokeResponse' }); | ||
} | ||
break; | ||
case ActivityTypes.EndOfConversation: | ||
@@ -156,2 +169,14 @@ await this.onEndOfConversationActivity(context); | ||
/** | ||
* Provides a hook for invoke calls. | ||
* | ||
* @param context The context object for the current turn. | ||
* | ||
* @remarks | ||
* Overwrite this method to handle particular invoke calls. | ||
*/ | ||
protected async onInvokeActivity(context: TurnContext): Promise<InvokeResponse> { | ||
return { status: StatusCodes.NOT_IMPLEMENTED }; | ||
} | ||
/** | ||
* Provides a hook for emitting the _end of conversation_ event. | ||
@@ -158,0 +183,0 @@ * |
@@ -32,2 +32,4 @@ /** | ||
private turnError: (context: TurnContext, error: Error) => Promise<void>; | ||
public readonly BotIdentityKey: Symbol = Symbol('BotIdentity'); | ||
public readonly OAuthScopeKey: Symbol = Symbol('OAuthScope'); | ||
@@ -34,0 +36,0 @@ /** |
@@ -5,3 +5,3 @@ /** | ||
*/ | ||
import { ActionTypes, AnimationCard, Attachment, AudioCard, CardAction, CardImage, HeroCard, MediaUrl, OAuthCard, O365ConnectorCard, ReceiptCard, SigninCard, ThumbnailCard, VideoCard } from 'botframework-schema'; | ||
import { ActionTypes, AnimationCard, Attachment, AudioCard, CardAction, CardImage, HeroCard, MediaUrl, OAuthCard, O365ConnectorCard, ReceiptCard, SigninCard, ThumbnailCard, TokenExchangeResource, VideoCard } from 'botframework-schema'; | ||
@@ -183,3 +183,3 @@ /** | ||
*/ | ||
public static oauthCard(connectionName: string, title: string, text?: string, link?: string): Attachment { | ||
public static oauthCard(connectionName: string, title: string, text?: string, link?: string, tokenExchangeResource?: TokenExchangeResource): Attachment { | ||
const card: Partial<OAuthCard> = { | ||
@@ -189,3 +189,4 @@ buttons: [ | ||
], | ||
connectionName: connectionName | ||
connectionName, | ||
tokenExchangeResource | ||
}; | ||
@@ -192,0 +193,0 @@ if (text) { card.text = text; } |
@@ -10,2 +10,4 @@ /** | ||
export * from 'botframework-schema'; | ||
export * from './activityFactory'; | ||
export * from './coreAppCredentials'; | ||
export * from './activityHandler'; | ||
@@ -22,2 +24,4 @@ export * from './activityHandlerBase'; | ||
export * from './conversationState'; | ||
export * from './invokeResponse'; | ||
export * from './extendedUserTokenProvider'; | ||
export * from './memoryStorage'; | ||
@@ -31,3 +35,11 @@ export * from './memoryTranscriptStore'; | ||
export * from './showTypingMiddleware'; | ||
export * from './signInConstants'; | ||
export { | ||
BotFrameworkSkill, | ||
BotFrameworkClient, | ||
SkillConversationIdFactoryBase, | ||
SkillConversationReference, | ||
SkillConversationIdFactoryOptions } from './skills'; | ||
export * from './skypeMentionNormalizeMiddleware'; | ||
export * from './statusCodes'; | ||
export * from './storage'; | ||
@@ -40,2 +52,2 @@ export * from './telemetryLoggerMiddleware'; | ||
export * from './userTokenProvider'; | ||
export * from './userTokenSettings'; | ||
export * from './userTokenSettings'; |
@@ -191,3 +191,3 @@ // Copyright (c) Microsoft Corporation. All rights reserved. | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from.id || ''; | ||
properties[this.telemetryConstants.fromIdProperty] = activity.from ? activity.from.id : ''; | ||
properties[this.telemetryConstants.conversationNameProperty] = activity.conversation.name || ''; | ||
@@ -201,4 +201,4 @@ properties[this.telemetryConstants.localeProperty] = activity.locale || ''; | ||
if (activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from.name; | ||
if (activity.from && activity.from.name && activity.from.name.trim()) { | ||
properties[this.telemetryConstants.fromNameProperty] = activity.from ? activity.from.name : '';; | ||
} | ||
@@ -205,0 +205,0 @@ |
@@ -10,6 +10,8 @@ /** | ||
import assert from 'assert'; | ||
import { Activity, ActivityTypes, ConversationReference, ResourceResponse, TokenResponse } from 'botframework-schema'; | ||
import { Activity, ActivityTypes, ConversationReference, ResourceResponse, TokenResponse, TokenExchangeRequest, SignInUrlResponse } from 'botframework-schema'; | ||
import { BotAdapter } from './botAdapter'; | ||
import {ExtendedUserTokenProvider} from './extendedUserTokenProvider'; | ||
import { TurnContext } from './turnContext'; | ||
import { IUserTokenProvider } from './userTokenProvider'; | ||
import { basename } from 'path'; | ||
import { stringify } from 'querystring'; | ||
@@ -46,3 +48,3 @@ /** | ||
*/ | ||
export class TestAdapter extends BotAdapter implements IUserTokenProvider { | ||
export class TestAdapter extends BotAdapter implements ExtendedUserTokenProvider { | ||
/** | ||
@@ -396,2 +398,47 @@ * @private | ||
private exchangeableTokens : {[key: string]: ExchangeableToken} = {}; | ||
public addExchangeableToken(connectionName: string, channelId: string, userId: string, exchangeableItem: string, token: string) { | ||
const key: ExchangeableToken = new ExchangeableToken(); | ||
key.ChannelId = channelId; | ||
key.ConnectionName = connectionName; | ||
key.UserId = userId; | ||
key.exchangeableItem = exchangeableItem; | ||
key.Token = token; | ||
this.exchangeableTokens[key.toKey()] = key; | ||
} | ||
public async getSignInResource(context: TurnContext, connectionName: string, userId?: string, finalRedirect?: string): Promise<SignInUrlResponse> { | ||
return { | ||
signInLink: `https://botframeworktestadapter.com/oauthsignin/${connectionName}/${context.activity.channelId}/${userId}`, | ||
tokenExchangeResource: { | ||
id: String(Math.random()), | ||
providerId: null, | ||
uri: `api://${connectionName}/resource` | ||
} | ||
} | ||
} | ||
public async exchangeToken(context: TurnContext, connectionName: string, userId: string, tokenExchangeRequest: TokenExchangeRequest): Promise<TokenResponse> { | ||
const exchangeableValue: string = tokenExchangeRequest.token ? tokenExchangeRequest.token : tokenExchangeRequest.uri; | ||
const key = new ExchangeableToken(); | ||
key.ChannelId = context.activity.channelId; | ||
key.ConnectionName = connectionName; | ||
key.exchangeableItem = exchangeableValue; | ||
key.UserId = userId; | ||
const tokenExchangeResponse = this.exchangeableTokens[key.toKey()]; | ||
return tokenExchangeResponse ? | ||
{ | ||
channelId: key.ChannelId, | ||
connectionName: key.ConnectionName, | ||
token: tokenExchangeResponse.Token, | ||
expiration: null | ||
} : | ||
null; | ||
} | ||
/** | ||
@@ -433,2 +480,16 @@ * Indicates if the activity is a reply from the bot (role == 'bot') | ||
class ExchangeableToken extends UserToken { | ||
public exchangeableItem: string; | ||
public EqualsKey(rhs: ExchangeableToken): boolean { | ||
return rhs != null && | ||
this.exchangeableItem === rhs.exchangeableItem && | ||
super.EqualsKey(rhs); | ||
} | ||
public toKey(): string { | ||
return this.exchangeableItem; | ||
} | ||
} | ||
/** | ||
@@ -435,0 +496,0 @@ * Support class for `TestAdapter` that allows for the simple construction of a sequence of tests. |
@@ -5,3 +5,3 @@ /** | ||
*/ | ||
import { Activity, ActivityTypes, ConversationReference, InputHints, ResourceResponse, Mention } from 'botframework-schema'; | ||
import { Activity, ActivityTypes, ConversationReference, DeliveryModes, InputHints, ResourceResponse, Mention } from 'botframework-schema'; | ||
import { BotAdapter } from './botAdapter'; | ||
@@ -346,2 +346,7 @@ import { shallowCopy } from './internal'; | ||
/** | ||
* List of activities to send when `context.activity.deliveryMode == 'expectReplies'`. | ||
*/ | ||
public readonly bufferedReplyActivities: Partial<Activity>[] = []; | ||
/** | ||
* Asynchronously sends an activity to the sender of the incoming activity. | ||
@@ -462,9 +467,23 @@ * | ||
return this.emit(this._onSendActivities, output, () => { | ||
return this.adapter.sendActivities(this, output) | ||
.then((responses: ResourceResponse[]) => { | ||
// Set responded flag | ||
if (sentNonTraceActivity) { this.responded = true; } | ||
if (this.activity.deliveryMode === DeliveryModes.ExpectReplies) { | ||
// Append activities to buffer | ||
const responses: ResourceResponse[] = []; | ||
output.forEach((a) => { | ||
this.bufferedReplyActivities.push(a); | ||
responses.push({ id: undefined }); | ||
}); | ||
return responses; | ||
}); | ||
// Set responded flag | ||
if (sentNonTraceActivity) { this.responded = true; } | ||
return Promise.resolve(responses); | ||
} else { | ||
return this.adapter.sendActivities(this, output) | ||
.then((responses: ResourceResponse[]) => { | ||
// Set responded flag | ||
if (sentNonTraceActivity) { this.responded = true; } | ||
return responses; | ||
}); | ||
} | ||
}); | ||
@@ -471,0 +490,0 @@ } |
@@ -28,4 +28,5 @@ /** | ||
* @param connectionName Name of the auth connection to use. | ||
* @param userId User id of user to sign out. | ||
*/ | ||
signOutUser(context: TurnContext, connectionName: string): Promise<void>; | ||
signOutUser(context: TurnContext, connectionName: string, userId?: string): Promise<void>; | ||
@@ -48,2 +49,1 @@ /** | ||
} | ||
@@ -12,4 +12,3 @@ /** | ||
*/ | ||
export interface TokenPollingSettings | ||
{ | ||
export interface TokenPollingSettings { | ||
/** | ||
@@ -34,4 +33,3 @@ * Polling timeout time in milliseconds. This is equivalent to login flow timeout. | ||
*/ | ||
export const TokenPollingSettingsKey: string = "tokenPollingSettings"; | ||
export const TokenPollingSettingsKey: string = 'tokenPollingSettings'; | ||
@@ -44,2 +42,2 @@ /** | ||
*/ | ||
export const OAuthLoginTimeoutMsValue: number = 900000; | ||
export const OAuthLoginTimeoutMsValue: number = 900000; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
769685
217
15101
1
+ Addedbotframework-schema@4.8.0(transitive)
- Removedbotframework-schema@4.8.0-preview-109324(transitive)
Updatedbotframework-schema@4.8.0