@microsoft/teamsfx 2.2.3-alpha.9b38c38b5.0 → 2.2.3-alpha.ebba7eb40.0

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/README.md CHANGED
@@ -43,22 +43,43 @@ TeamsFx SDK is built to be used in browser and NodeJS environment. Common scenar
43
43
 
44
44
  ### Create and authenticate a service using `createMicrosoftGraphClientWithCredential` or `createMicrosoftGraphClient`
45
45
 
46
- > [!NOTE] `createMicrosoftGraphClient` function has been deprecated. It is recommended that you to use `createMicrosoftGraphClientWithCredential` instead, for better coding experience.
46
+ > [!NOTE] `createMicrosoftGraphClient` and `createMicrosoftGraphClientWithCredential` function has been deprecated. It is recommended that you to use `Client` and `TokenCredentialAuthenticationProvider` from `@microsoft/microsoft-graph-client` instead, for better coding experience.
47
47
 
48
48
  To create a graph client object to access the Microsoft Graph API, you will need the credential to do authentication. The SDK provides APIs to configure for developers. Please choose the proper identity type and follow below steps:
49
49
 
50
50
  #### Invoke Graph API on behalf of Teams User (User Identity)
51
51
 
52
52
  Use the snippet below (Recommended):
53
+
53
54
  ```ts
54
- const authConfig: TeamsUserCredentialAuthConfig = {
55
- clientId: process.env.REACT_APP_CLIENT_ID,
56
- initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
57
- };
55
+ import { TeamsUserCredentialAuthConfig, TeamsUserCredential } from "@microsoft/teamsfx";
56
+ import { Client } from "@microsoft/microsoft-graph-client";
57
+ import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";
58
58
 
59
- const teamsUserCredential = new TeamsUserCredential(authConfig);
60
- const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User. Read"]);
61
- const profile = await graphClient.api("/me").get();
59
+ const authConfig: TeamsUserCredentialAuthConfig = {
60
+ clientId: process.env.REACT_APP_CLIENT_ID,
61
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
62
+ };
63
+
64
+ const teamsUserCredential = new TeamsUserCredential(authConfig);
65
+ const authProvider = new TokenCredentialAuthenticationProvider(credential, {
66
+ scopes: ["User.Read"],
67
+ });
68
+ const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
69
+ const profile = await graphClient.api("/me").get();
70
+ ```
71
+
72
+ or use `createMicrosoftGraphClientWithCredential` as below (Deprecated):
73
+
74
+ ```ts
75
+ const authConfig: TeamsUserCredentialAuthConfig = {
76
+ clientId: process.env.REACT_APP_CLIENT_ID,
77
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
78
+ };
79
+
80
+ const teamsUserCredential = new TeamsUserCredential(authConfig);
81
+ const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User.Read"]);
82
+ const profile = await graphClient.api("/me").get();
62
83
  ```
63
84
 
64
85
  or use `createMicrosoftGraphClient` as below (Deprecated):
@@ -79,12 +100,35 @@ const profile = await graphClient.api("/me").get(); // Get the profile of curren
79
100
  It doesn't require the interaction with Teams user. You can call Microsoft Graph as application identity.
80
101
 
81
102
  Use the snippet below (Recommended):
103
+
82
104
  ```ts
105
+ import { AppCredentialAuthConfig, AppCredential } from "@microsoft/teamsfx";
106
+ import { Client } from "@microsoft/microsoft-graph-client";
107
+ import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";
108
+
83
109
  const appAuthConfig: AppCredentialAuthConfig = {
84
- authorityHost: process.env.M365_AUTHORITY_HOST,
85
- clientId: process.env.M365_CLIENT_ID,
86
- tenantId: process.env.M365_TENANT_ID,
87
- clientSecret: process.env.M365_CLIENT_SECRET,
110
+ authorityHost: process.env.M365_AUTHORITY_HOST,
111
+ clientId: process.env.M365_CLIENT_ID,
112
+ tenantId: process.env.M365_TENANT_ID,
113
+ clientSecret: process.env.M365_CLIENT_SECRET,
114
+ };
115
+
116
+ const appCredential = new AppCredential(appAuthConfig);
117
+ const authProvider = new TokenCredentialAuthenticationProvider(appCredential, {
118
+ scopes: ["https://graph.microsoft.com/.default"],
119
+ });
120
+ const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
121
+ const profile = await graphClient.api("/users/{object_id_of_another_people}").get();
122
+ ```
123
+
124
+ or use `createMicrosoftGraphClientWithCredential` as below (Deprecated):
125
+
126
+ ```ts
127
+ const appAuthConfig: AppCredentialAuthConfig = {
128
+ authorityHost: process.env.M365_AUTHORITY_HOST,
129
+ clientId: process.env.M365_CLIENT_ID,
130
+ tenantId: process.env.M365_TENANT_ID,
131
+ clientSecret: process.env.M365_CLIENT_SECRET,
88
132
  };
89
133
 
90
134
  const appCredential = new AppCredential(appAuthConfig);
@@ -109,7 +153,7 @@ const profile = await graphClient.api("/users/{object_id_of_another_people}").ge
109
153
 
110
154
  ### TeamsFx class
111
155
 
112
- > [!NOTE] `TeamsFx` class has been deprecated. It is recommended that you to use different credentials (`TeamsUserCredential`, `AppCredential`, `OnBehalfOfUserCredential`) instead, for better coding experience.
156
+ > [!NOTE] `TeamsFx` class has been deprecated. It is recommended that you to use different credentials (`TeamsUserCredential`, `AppCredential`, `OnBehalfOfUserCredential`) instead, for better coding experience.
113
157
 
114
158
  `TeamsFx` class instance reads all TeamsFx settings from environment variables by default. You can also set customized configuration values to override the default values. Please check [Override configuration](#override-configuration) for details.
115
159
 
@@ -146,6 +190,7 @@ Here's the corresponding scenarios that each credential class targets.
146
190
  `TeamsUserCredential` represents Teams current user's identity. Using this credential will request user consent at the first time. It leverages the Teams SSO and On-Behalf-Of flow to do token exchange. SDK uses this credential when developer choose "User" identity in browser environment.
147
191
 
148
192
  The following code is an an example to create TeamsUserCredential:
193
+
149
194
  ```ts
150
195
  const authConfig: TeamsUserCredentialAuthConfig = {
151
196
  clientId: process.env.REACT_APP_CLIENT_ID,
@@ -162,6 +207,7 @@ Required configurations are initiateLoginEndpoint and clientId which can be foun
162
207
  `OnBehalfOfUserCredential` uses On-Behalf-Of flow and need Teams ssoToken. It's designed to be used in Azure Function or Bot scenarios. SDK uses this credential when developer choose "User" identity in NodeJS environment.
163
208
 
164
209
  The following code is an example to create OnBehalfOfUserCredential:
210
+
165
211
  ```ts
166
212
  const oboAuthConfig: OnBehalfOfCredentialAuthConfig = {
167
213
  authorityHost: process.env.M365_AUTHORITY_HOST,
@@ -179,7 +225,6 @@ Required configurations are authorityHost, tenantId, clientId, clientSecret, or
179
225
 
180
226
  `AppCredential` represents the application identity. It is usually used when user is not involved like time-triggered automation job. SDK uses this credential when developer choose "App" identity in NodeJS environment.
181
227
 
182
-
183
228
  The following code is an example to create `AppCredential`:
184
229
 
185
230
  ```ts
@@ -227,7 +272,7 @@ TeamsFx SDK provides several helper functions to ease the configuration for thir
227
272
 
228
273
  #### Microsoft Graph Service
229
274
 
230
- `createMicrosoftGraphClientWithCredential`, `createMicrosoftGraphClient`(deprecated) and `MsGraphAuthProvider` help to create authenticated Graph instance.
275
+ `createMicrosoftGraphClientWithCredential`, `createMicrosoftGraphClient` and `MsGraphAuthProvider` help to create authenticated Graph instance. These are now deprecated, we recommend you to use Microsoft Graph SDKs instead.
231
276
 
232
277
  #### SQL
233
278
 
@@ -251,7 +296,7 @@ try {
251
296
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
252
297
  };
253
298
 
254
- const credential = new TeamsUserCredential(authConfig);
299
+ const credential = new TeamsUserCredential(authConfig);
255
300
  await credential.login("User.Read");
256
301
  } catch (err: unknown) {
257
302
  if (err instanceof ErrorWithCode && err.code !== ErrorCode.ConsentFailed) {
@@ -272,8 +317,11 @@ try {
272
317
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
273
318
  };
274
319
 
275
- const credential = new TeamsUserCredential(authConfig);
276
- const graphClient = createMicrosoftGraphClientWithCredential(credential, ["User.Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
320
+ const credential = new TeamsUserCredential(authConfig);
321
+ const authProvider = new TokenCredentialAuthenticationProvider(credential, {
322
+ scopes: ["User.Read"],
323
+ });
324
+ const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
277
325
  const profile = await graphClient.api("/me").get();
278
326
  } catch (err: unknown) {
279
327
  // ErrorWithCode is handled by Graph client
@@ -297,7 +345,7 @@ The following sections provide several code snippets covering some of the most c
297
345
 
298
346
  ### Use Graph API in tab app
299
347
 
300
- Use `createMicrosoftGraphClientWithCredential`.
348
+ Use `createMicrosoftGraphClientWithCredential`. Thie API is now deprecated, we recommend you to use `Client` and `TokenCredentialAuthenticationProvider` from Microsoft Graph SDKs (`@microsoft/microsoft-graph-client`) instead.
301
349
 
302
350
  ```ts
303
351
  const authConfig: TeamsUserCredentialAuthConfig = {
@@ -311,15 +359,14 @@ const teamsUserCredential = new TeamsUserCredential(authConfig);
311
359
  await teamsUserCredential.login(["User.Read"]); // Login with scope
312
360
 
313
361
  try {
314
- const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User. Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
315
- const profile = await graphClient.api("/me").get();
362
+ const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User. Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
363
+ const profile = await graphClient.api("/me").get();
316
364
  } catch (err: unknown) {
317
- // ErrorWithCode is handled by Graph client
318
- if (err instanceof GraphError && err.code?.includes(ErrorCode.UiRequiredError)) {
319
- // Need to show login button to ask for user consent.
320
- }
365
+ // ErrorWithCode is handled by Graph client
366
+ if (err instanceof GraphError && err.code?.includes(ErrorCode.UiRequiredError)) {
367
+ // Need to show login button to ask for user consent.
368
+ }
321
369
  }
322
-
323
370
  ```
324
371
 
325
372
  ### Call Azure Function in tab app
@@ -333,7 +380,7 @@ async function callFunction() {
333
380
  initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
334
381
  };
335
382
  const teamsUserCredential = new TeamsUserCredential(authConfig);
336
- const accessToken = await teamsUserCredential.getToken(""); // Get SSO token
383
+ const accessToken = await teamsUserCredential.getToken(""); // Get SSO token
337
384
  const endpoint = "https://YOUR_API_ENDPOINT";
338
385
  const response = await axios.default.get(endpoint + "/api/" + functionName, {
339
386
  headers: {
@@ -341,7 +388,7 @@ async function callFunction() {
341
388
  },
342
389
  });
343
390
  return response.data;
344
- }
391
+ }
345
392
  ```
346
393
 
347
394
  ### Access SQL database in Azure Function
@@ -378,10 +425,10 @@ const appAuthConfig: AppCredentialAuthConfig = {
378
425
  authorityHost: process.env.M365_AUTHORITY_HOST,
379
426
  clientId: process.env.M365_CLIENT_ID,
380
427
  tenantId: process.env.M365_TENANT_ID,
381
- certificateContent: 'PEM-encoded key certificate',
428
+ certificateContent: "PEM-encoded key certificate",
382
429
  };
383
430
  const appCredential = new AppCredential(appAuthConfig);
384
- const token = appCredential.getToken();
431
+ const token = appCredential.getToken();
385
432
  ```
386
433
 
387
434
  ### Use Graph API in Bot application
@@ -391,7 +438,11 @@ Add `TeamsBotSsoPrompt` to dialog set.
391
438
  ```ts
392
439
  const { ConversationState, MemoryStorage } = require("botbuilder");
393
440
  const { DialogSet, WaterfallDialog } = require("botbuilder-dialogs");
394
- const { TeamsBotSsoPrompt, OnBehalfOfCredentialAuthConfig, TeamsBotSsoPromptSettings } = require("@microsoft/teamsfx");
441
+ const {
442
+ TeamsBotSsoPrompt,
443
+ OnBehalfOfCredentialAuthConfig,
444
+ TeamsBotSsoPromptSettings,
445
+ } = require("@microsoft/teamsfx");
395
446
 
396
447
  const convoState = new ConversationState(new MemoryStorage());
397
448
  const dialogState = convoState.createProperty("dialogState");
@@ -400,16 +451,16 @@ const dialogs = new DialogSet(dialogState);
400
451
  const TeamsBotSsoPromptId = "TEAMS_BOT_SSO_PROMPT";
401
452
 
402
453
  const settings: TeamsBotSsoPromptSettings = {
403
- scopes: ["User.Read"],
404
- timeout: 900000,
405
- endOnInvalidMessage: true,
454
+ scopes: ["User.Read"],
455
+ timeout: 900000,
456
+ endOnInvalidMessage: true,
406
457
  };
407
458
 
408
459
  const authConfig: OnBehalfOfCredentialAuthConfig = {
409
- authorityHost: process.env.M365_AUTHORITY_HOST,
410
- clientId: process.env.M365_CLIENT_ID,
411
- tenantId: process.env.M365_TENANT_ID,
412
- clientSecret: process.env.M365_CLIENT_SECRET,
460
+ authorityHost: process.env.M365_AUTHORITY_HOST,
461
+ clientId: process.env.M365_CLIENT_ID,
462
+ tenantId: process.env.M365_TENANT_ID,
463
+ clientSecret: process.env.M365_CLIENT_SECRET,
413
464
  };
414
465
  const loginUrl = process.env.INITIATE_LOGIN_ENDPOINT;
415
466
  const ssoPrompt = new TeamsBotSsoPrompt(authConfig, loginUrl, TeamsBotSsoPromptId, settings);
@@ -548,92 +599,90 @@ From `botbuilder@4.16.0`, `BotFrameworkAdapter` is deprecated, and `CloudAdapter
548
599
 
549
600
  1. Install `@microsoft/teamsfx @^2.2.0`, `botbuilder @^4.18.0`, (and `@types/node @^14.0.0` for TS projects) via `npm install` as follows.
550
601
 
551
- ```sh
552
- npm install @microsoft/teamsfx
553
- npm install botbuilder
554
-
555
- // For TS projects only
556
- npm install --save-dev @types/node
557
- ```
602
+ ```sh
603
+ npm install @microsoft/teamsfx
604
+ npm install botbuilder
605
+
606
+ // For TS projects only
607
+ npm install --save-dev @types/node
608
+ ```
558
609
 
559
610
  2. Update the import of `ConversationBot` and create a new `ConversationBot` as follows.
560
611
 
561
- ```ts
562
- import { HelloWorldCommandHandler } from "../helloworldCommandHandler";
563
- import { BotBuilderCloudAdapter } from "@microsoft/teamsfx";
564
- import ConversationBot = BotBuilderCloudAdapter.ConversationBot;
565
- import config from "./config";
566
-
567
- export const commandBot = new ConversationBot({
568
- // The bot id and password to create CloudAdapter.
569
- // See https://aka.ms/about-bot-adapter to learn more about adapters.
570
- adapterConfig: {
571
- MicrosoftAppId: config.botId,
572
- MicrosoftAppPassword: config.botPassword,
573
- MicrosoftAppType: "MultiTenant",
574
- },
575
- command: {
576
- enabled: true,
577
- commands: [new HelloWorldCommandHandler()],
578
- },
579
- });
580
- ```
612
+ ```ts
613
+ import { HelloWorldCommandHandler } from "../helloworldCommandHandler";
614
+ import { BotBuilderCloudAdapter } from "@microsoft/teamsfx";
615
+ import ConversationBot = BotBuilderCloudAdapter.ConversationBot;
616
+ import config from "./config";
617
+
618
+ export const commandBot = new ConversationBot({
619
+ // The bot id and password to create CloudAdapter.
620
+ // See https://aka.ms/about-bot-adapter to learn more about adapters.
621
+ adapterConfig: {
622
+ MicrosoftAppId: config.botId,
623
+ MicrosoftAppPassword: config.botPassword,
624
+ MicrosoftAppType: "MultiTenant",
625
+ },
626
+ command: {
627
+ enabled: true,
628
+ commands: [new HelloWorldCommandHandler()],
629
+ },
630
+ });
631
+ ```
581
632
 
582
633
  3. If the project is using `restify` to create a server, please add the following line after `restify.createServer()`.
583
634
 
584
- ```ts
585
- server.use(restify.plugins.bodyParser());
586
- ```
635
+ ```ts
636
+ server.use(restify.plugins.bodyParser());
637
+ ```
587
638
 
588
- The complete code will be like
639
+ The complete code will be like
589
640
 
590
- ```ts
591
- // Create HTTP server.
592
- const server = restify.createServer();
593
- server.use(restify.plugins.bodyParser());
594
- server.listen(process.env.port || process.env.PORT || 3978, () => {
595
- console.log(`\nApp Started, ${server.name} listening to ${server.url}`);
596
- });
597
- ```
641
+ ```ts
642
+ // Create HTTP server.
643
+ const server = restify.createServer();
644
+ server.use(restify.plugins.bodyParser());
645
+ server.listen(process.env.port || process.env.PORT || 3978, () => {
646
+ console.log(`\nApp Started, ${server.name} listening to ${server.url}`);
647
+ });
648
+ ```
598
649
 
599
650
  4. If the project has `responseWrapper.ts`, please update the class `responseWrapper` to the class below.
600
651
 
601
- ```ts
602
- import { Response } from "botbuilder";
603
-
604
- // A wrapper to convert Azure Functions Response to Bot Builder's Response.
605
- export class ResponseWrapper implements Response {
606
- socket: any;
607
- originalResponse?: any;
608
- headers?: any;
609
- body?: any;
610
-
611
- constructor(functionResponse?: { [key: string]: any }) {
612
- this.socket = undefined;
613
- this.originalResponse = functionResponse;
614
- }
615
-
616
- end(...args: any[]) {
617
- // do nothing since res.end() is deprecated in Azure Functions.
618
- }
619
-
620
- header(name: string, value: any) {
621
- this.headers[name] = value;
622
- }
623
-
624
- send(body: any) {
625
- // record the body to be returned later.
626
- this.body = body;
627
- this.originalResponse.body = body;
628
- }
629
- status(status: number) {
630
- // call Azure Functions' res.status().
631
- return this.originalResponse?.status(status);
632
- }
633
- }
634
- ```
635
-
636
-
652
+ ```ts
653
+ import { Response } from "botbuilder";
654
+
655
+ // A wrapper to convert Azure Functions Response to Bot Builder's Response.
656
+ export class ResponseWrapper implements Response {
657
+ socket: any;
658
+ originalResponse?: any;
659
+ headers?: any;
660
+ body?: any;
661
+
662
+ constructor(functionResponse?: { [key: string]: any }) {
663
+ this.socket = undefined;
664
+ this.originalResponse = functionResponse;
665
+ }
666
+
667
+ end(...args: any[]) {
668
+ // do nothing since res.end() is deprecated in Azure Functions.
669
+ }
670
+
671
+ header(name: string, value: any) {
672
+ this.headers[name] = value;
673
+ }
674
+
675
+ send(body: any) {
676
+ // record the body to be returned later.
677
+ this.body = body;
678
+ this.originalResponse.body = body;
679
+ }
680
+ status(status: number) {
681
+ // call Azure Functions' res.status().
682
+ return this.originalResponse?.status(status);
683
+ }
684
+ }
685
+ ```
637
686
 
638
687
  ## Next steps
639
688