microsoft / BotFramework-Emulator

A desktop application that allows users to locally test and debug chat bots built with the Bot Framework SDK.
https://aka.ms/botemulator
MIT License
1.82k stars 754 forks source link

POST /v3/conversations ➡ InternalServerError: Cannot read property 'appid' of undefined #1196

Closed mark-szabo closed 5 years ago

mark-szabo commented 5 years ago

Version

4.2.1

Describe the bug

Bot Framework emulator is throwing a 500 InternalServerError when posting to /v3/conversations, despite the same code works in a deployed bot with Microsoft Teams.

(1) The error message is Cannot read property 'appid' of undefined, when the request contains a valid JWT Bearer token in the Authorization header. (The JWT payload DOES contain a property called appid btw.)

(2) If I leave the Authorization header empty, I get another 500 InternalServerError and the error message is Cannot read property 'payload' of undefined.

(3) If I send some random text as the Bearer token in the Authorization header - as suggested here - I get a 401 Unauthorized (at least not another 500 InternalServerError 🙄).

Repro steps

  1. Start the Bot Framework Emulator.
  2. Open Postman.
  3. Make a POST request to the local serviceUrl's /v3/conversations endpoint (it should look like this: http://localhost:PORT/v3/conversations) with the request body included below and (1) a JWT generated by the .NET Bot Builder SDK v4 / (2) nothing / (3) some random text in the Authorization header.
  4. See error.

Expected behavior

Debug

I was able trace the issue back to this line in the Bot Framework Emulator: https://github.com/Microsoft/BotFramework-Emulator/blob/4b620e3367938243a70fada026654280727b7beb/packages/emulator/core/src/conversations/middleware/getBotEndpoint.ts#L64 But I'm not totally sure what is causing the issue here. Maybe something is broken in JWT parsing.

Additional context

Request body:

{
  "bot": {
    "id": "3",
    "name": "Bot",
    "role": "bot"
  },
  "members": [
    {
      "id": "3570b2c3-9377-4880-87a1-666bba16d0bb",
      "name": "User",
      "role": "user"
    }
  ],
  "channelData": {
    "clientActivityId": "1545857215036.8654911430483678.2"
  }
}

Parsed JWT token:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "nbCwW56w3KsB-xUaPlLOSLjODGQ",
  "kid": "nbCwW56w3KsB-xUaPlLOSLjODGQ"
}.{
  "aud": "https://api.botframework.com",
  "iss": "https://sts.windows.net/d6d49420-****-****-****-************/",
  "iat": 1545856906,
  "nbf": 1545856906,
  "exp": 1545860806,
  "aio": "42RgPOsZXnazy/hiHcpsJAVW1petAA==",
  "appid": "3e58d71d-****-****-****-************",
  "appidacr": "1",
  "idp": "https://sts.windows.net/d6d49420-****-****-****-************/",
  "tid": "d6d49420-****-****-****-************",
  "uti": "pL3r9YTz7EuFksrQefLsAA",
  "ver": "1.0"
}.[Signature]

Code used to make the request originally with the .NET Bot Builder SDK v4:

await _botFrameworkAdapter.CreateConversationAsync(
    "emulator",
    "http://localhost:31973",
    new MicrosoftAppCredentials(**appId**, **appPassword**),
    new ConversationParameters(bot: **botChannelAccount**, members: new List<ChannelAccount> { **userChannelAccount** }, channelData: **channelData**),
    Callback(),
    cancellationToken);

[bug]

justinwilaby commented 5 years ago

@mark-szabo -

To clarify, you are posting to the Emulator via Postman a request that was originally generated via a locally running bot as a response to an activity from the user?

mark-szabo commented 5 years ago

Hi @justinwilaby, almost correct. The original request was generated by the botbuilder-dotnet SDK v4 with the code above. But not as a response to an activity from a user, but a proactive message - a conversation initiated from the bot (createConversation).

Happy New Year! 🎉🎆

justinwilaby commented 5 years ago

@mark-szabo - Happy new year to you too!

I can't seem to repro this issue. All proactive messaging from my test bot seem to work as expected :(

If you have a free moment, I'd like to walk you through debugging on the Emulator to hunt down the culprit on a screen share or teams call. Feel free to reach out to me anytime and I look forward to talking with you!

mark-szabo commented 5 years ago

So while debugging with @justinwilaby, we discovered the following bugs/question marks:

  1. On the above mentioned line the payload property of jwt is not necessary, appid is directly contained in jwt.
- (req as any).botEndpoint = botEmulator.facilities.endpoints.getByAppId((req as any).jwt.payload.appid);
+ (req as any).botEndpoint = botEmulator.facilities.endpoints.getByAppId((req as any).jwt.appid);
  1. In createConversations.ts there is a check whether conversationParameters.activity is null. But it should rather check whether it is undefined...
- if (conversationParameters.activity !== null)
+ if (conversationParameters.activity)
  1. There is something spooky with another check in createConversations.ts: this does not have a property called botid. What is 'security bot id' by the way?
if (conversationParameters.bot.id !== this.botId) {
    throw createAPIException(HttpStatus.BAD_REQUEST, ErrorCodes.BadArgument,
    'conversationParameters.bot.id doesn\'t match security bot id');
}

When we fixed (1), (2), commented out the whole check in (3), we were able to get the 200 OK back with the conversation id. 🥳

image

  1. But sadly neither when the conversation created nor when I POSTed to /v3/conversations/:conversationId/activities happened anything at all on the emulator UI. What should happen in theory? A new tab should open in the emulator? The activity should appear in the current, open conversation in the emulator?

image

justinwilaby commented 5 years ago

Beginning work on this now.

mark-szabo commented 5 years ago

Awesome, thank you @justinwilaby for fixing this! 🙌

shubhamkarale7946 commented 4 months ago

getting error in ms bot framework emulator

Error: The bot is remote, but the service URL is localhost. Without tunneling software you will not receive replies.