Introduce MSAL with UMI and FIC support#387
Merged
Merged
Conversation
This was referenced Nov 7, 2025
heyitsaamir
marked this pull request as ready for review
November 7, 2025 23:26
rido-min
previously approved these changes
Nov 11, 2025
heyitsaamir
force-pushed
the
aamirj/addMsal
branch
from
November 11, 2025 17:51
180badd to
5cc524a
Compare
heyitsaamir
force-pushed
the
aamirj/addMsal
branch
from
November 11, 2025 20:07
5cc524a to
fe0ae29
Compare
heyitsaamir
requested review from
Jesperholmbergmsft and
ydogandjiev
as code owners
November 11, 2025 20:30
lilyydu
previously approved these changes
Nov 11, 2025
rido-min
reviewed
Nov 11, 2025
rido-min
approved these changes
Nov 11, 2025
heyitsaamir
added a commit
that referenced
this pull request
Nov 17, 2025
I added `type: 'clientSecrets'` and `type: 'token'` in #387 . Looks like ATK is using `TokenCredentials` directly which breaks since they don't provide the value of `type` by default. In this PR, I am removing those type fields and inferring them from the actual values. skip-test-verification
heyitsaamir
added a commit
that referenced
this pull request
Dec 9, 2025
In v2.0.3, `app.name` was changed from reading
`tokens.bot?.appDisplayName` to `manifest.name?.full`. The `send()`
method's validation check `if (!this.id || !this.name)` now throws "app
not started" when `manifest.name` is not provided, even when the app has
started successfully.
## Changes
- **Removed `!this.name` validation** in `send()` method - only
`!this.id` is required
- **Fallback to app ID for bot name** when `manifest.name` is undefined
(`name: this.name || this.id`)
- **Added tests** covering send with/without manifest.name, and proper
error when app ID is missing
## Example
```typescript
// This now works without requiring manifest.name
const app = new App({
clientId: "...",
clientSecret: "...",
tenantId: "...",
// No manifest.name needed
});
await app.start();
await app.send(conversationId, "Hello"); // ✓ Works (uses app ID as bot name)
```
The `app.name` getter is already marked `@deprecated` and should not be
used for validation.
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[Bug]: Misleading "app not started" error when
manifest.name is not configured (breaking change in
v2.0.3)</issue_title>
> <issue_description>### Bug Description
>
> After upgrading from `@microsoft/teams.apps` v2.0.2 to v2.0.4, calls
to `app.send()` fail with the error `"app not started"` even though the
> app has successfully started.
>
> The root cause is a breaking change introduced in [PR
#387](#387)
(released in v2.0.3). The
> `app.name` getter was changed from reading the bot's display name from
tokens to reading from the `manifest.name` constructor option:
>
> **Before (v2.0.2)** - [`app.ts`
L136-L138](https://github.com/microsoft/teams.ts/blob/ece19d488f7975b11f702676b1c6b02e692f66e0/packages/apps/src/app.ts#L136-L138):
> ```typescript
> get name() {
> return this.tokens.bot?.appDisplayName;
> }
> ```
>
> **After (v2.0.3+)** - [`app.ts`
L175-L177](https://github.com/microsoft/teams.ts/blob/8638fbfd3e4e253d04b2e7514ef373ef66ed9546/packages/apps/src/app.ts#L175-L177):
> ```typescript
> get name() {
> return this._manifest.name?.full;
> }
> ```
> The
[send()](https://github.com/microsoft/teams.ts/blob/33c95aee06f5583083c2e456d45666fa3e43242c/packages/apps/src/app.ts#L403-L405)
method checks if (!this.id || !this.name) and throws "app not started",
but this error message is misleading because:
>
> 1. The app is started (app.start() completed successfully)
> 2. The actual issue is that manifest.name was not provided in the
constructor
>
> This is a breaking change that affects any code I had using app.send()
for proactive messaging.
>
> ### Steps to Reproduce
>
> 1. Install @microsoft/teams.apps v2.0.3 or later
> 2. Create an App instance without the manifest.name option:
> ```typescript
> const app = new App({
> clientId: "...",
> clientSecret: "...",
> tenantId: "...",
> });
> ```
> 3. Start the app and call app.send():
> `await app.start(3978);`
> `await app.send(conversationId, "Hello"); // Throws "app not started"`
>
> ### Expected Behavior
>
> Either:
> - The error message should indicate the actual problem (e.g.,
"manifest.name is required for app.send()")
> - Or the SDK should fall back to this.tokens.bot?.appDisplayName for
backwards compatibility
>
>
> ### Actual Behavior
>
> Throws Error: app not started which is misleading
>
> Workaround: Add manifest.name to the App constructor:
> ```typescript
> const app = new App({
> clientId: "...",
> clientSecret: "...",
> tenantId: "...",
> manifest: {
> name: { short: "MyApp", full: "My Application" },
> },
> });
> ```
>
> ### SDK Version
>
> 2.0.4
>
> ### Node.js Version
>
> 24.5.0
>
> ### Additional Context
>
> _No response_</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@heyitsaamir</author><body>
> Thanks! Yeah that is indeed a bug. We should not be looking at the
name when preparing to send. </body></comment_new>
> </comments>
>
</details>
- Fixes #415
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/microsoft/teams.ts/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: heyitsaamir <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR introduces MSAL as a dependency and switches our supported bot authentication to use it. It also includes support for User Managed Identity support and FIC such that we don't need to provide custom code to do that anymore as we had previously suggested. Instead, we can do that simply by the environment variables.
Changes to note:
tokenManager.getBotToken.idandnamefields because those used to depend on the token being present. Now that we are not proactively fetching the token, those are not as useful (or reliable). For now, I have chosen to simply use the value from the manifest to populate them. I don't think these fields were that useful anyway, so opting to deprecate.PR Dependency Tree
This tree was auto-generated by Charcoal