@microsoft/teamsfx 2.2.0-alpha.d2fbcaf19.0 → 2.2.0-alpha.ecf7bf89a.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.
Files changed (2) hide show
  1. package/README.md +171 -37
  2. package/package.json +5 -4
package/README.md CHANGED
@@ -41,20 +41,34 @@ TeamsFx SDK is built to be used in browser and NodeJS environment. Common scenar
41
41
  - Azure Function
42
42
  - Teams bot
43
43
 
44
- ### Create and authenticate a service like `MicrosoftGraphClient`
44
+ ### Create and authenticate a service using `createMicrosoftGraphClientWithCredential` or `createMicrosoftGraphClient`
45
+
46
+ > [!NOTE] `createMicrosoftGraphClient` function has been deprecated. It is recommended that you to use `createMicrosoftGraphClientWithCredential` instead, for better coding experience.
45
47
 
46
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:
47
49
 
48
50
  #### Invoke Graph API on behalf of Teams User (User Identity)
49
51
 
50
- Use the snippet below:
52
+ Use the snippet below (Recommended):
53
+ ```ts
54
+ const authConfig: TeamsUserCredentialAuthConfig = {
55
+ clientId: process.env.REACT_APP_CLIENT_ID,
56
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
57
+ };
58
+
59
+ const teamsUserCredential = new TeamsUserCredential(authConfig);
60
+ const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User. Read"]);
61
+ const profile = await graphClient.api("/me").get();
62
+ ```
63
+
64
+ or use `createMicrosoftGraphClient` as below (Deprecated):
51
65
 
52
66
  ```ts
53
67
  // Equivalent to:
54
68
  // const teamsfx = new TeamsFx(IdentityType.User, {
55
69
  // initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
56
70
  // clientId: process.env.REACT_APP_CLIENT_ID,
57
- // }
71
+ // });
58
72
  const teamsfx = new TeamsFx();
59
73
  const graphClient = createMicrosoftGraphClient(teamsfx, ["User.Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
60
74
  const profile = await graphClient.api("/me").get(); // Get the profile of current user
@@ -63,7 +77,22 @@ const profile = await graphClient.api("/me").get(); // Get the profile of curren
63
77
  #### Invoke Graph API without user (Application Identity)
64
78
 
65
79
  It doesn't require the interaction with Teams user. You can call Microsoft Graph as application identity.
66
- Use the snippet below:
80
+
81
+ Use the snippet below (Recommended):
82
+ ```ts
83
+ 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,
88
+ };
89
+
90
+ const appCredential = new AppCredential(appAuthConfig);
91
+ const graphClient = createMicrosoftGraphClientWithCredential(appCredential);
92
+ const profile = await graphClient.api("/users/{object_id_of_another_people}").get();
93
+ ```
94
+
95
+ or use `createMicrosoftGraphClient` as below (Deprecated):
67
96
 
68
97
  ```ts
69
98
  // Equivalent to:
@@ -80,6 +109,8 @@ const profile = await graphClient.api("/users/{object_id_of_another_people}").ge
80
109
 
81
110
  ### TeamsFx class
82
111
 
112
+ > [!NOTE] `TeamsFx` class has been deprecated. It is recommended that you to use different credentials (`TeamsUserCredential`, `AppCredential`, `OnBehalfOfUserCredential`) instead, for better coding experience.
113
+
83
114
  `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.
84
115
 
85
116
  When creating a TeamsFx instance, you also need to specify the identity type. There are 2 identity types:
@@ -114,19 +145,54 @@ Here's the corresponding scenarios that each credential class targets.
114
145
 
115
146
  `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.
116
147
 
117
- Required configuration: initiateLoginEndpoint, clientId.
148
+ The following code is an an example to create TeamsUserCredential:
149
+ ```ts
150
+ const authConfig: TeamsUserCredentialAuthConfig = {
151
+ clientId: process.env.REACT_APP_CLIENT_ID,
152
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
153
+ };
154
+
155
+ const credential = new TeamsUserCredential(authConfig);
156
+ ```
157
+
158
+ Required configurations are initiateLoginEndpoint and clientId which can be found inside type TeamsUserCredentialAuthConfig.
118
159
 
119
160
  #### User Identity in NodeJS environment
120
161
 
121
162
  `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.
122
163
 
123
- Required configuration: authorityHost, tenantId, clientId, clientSecret / certificateContent.
164
+ The following code is an example to create OnBehalfOfUserCredential:
165
+ ```ts
166
+ const oboAuthConfig: OnBehalfOfCredentialAuthConfig = {
167
+ authorityHost: process.env.M365_AUTHORITY_HOST,
168
+ clientId: process.env.M365_CLIENT_ID,
169
+ tenantId: process.env.M365_TENANT_ID,
170
+ clientSecret: process.env.M365_CLIENT_SECRET,
171
+ };
172
+
173
+ const oboCredential = new OnBehalfOfUserCredential(ssoToken, oboAuthConfig);
174
+ ```
175
+
176
+ Required configurations are authorityHost, tenantId, clientId, clientSecret, or certificateContent which can be found inside type OnBehalfOfCredentialAuthConfig.
124
177
 
125
178
  #### Application Identity in NodeJS environment
126
179
 
127
180
  `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.
128
181
 
129
- Required configuration: tenantId, clientId, clientSecret / certificateContent.
182
+
183
+ The following code is an example to create `AppCredential`:
184
+
185
+ ```ts
186
+ const appAuthConfig: AppCredentialAuthConfig = {
187
+ authorityHost: process.env.M365_AUTHORITY_HOST,
188
+ clientId: process.env.M365_CLIENT_ID,
189
+ tenantId: process.env.M365_TENANT_ID,
190
+ clientSecret: process.env.M365_CLIENT_SECRET,
191
+ };
192
+ const appCredential = new AppCredential(appAuthConfig);
193
+ ```
194
+
195
+ Required configurations are authorityHost, tenantId, clientId, clientSecret, or certificateContent which can be found inside type AppCredentialAuthConfig.
130
196
 
131
197
  ### Bot SSO
132
198
 
@@ -134,7 +200,26 @@ Bot related classes are stored under [bot](src/bot) folder.
134
200
 
135
201
  `TeamsBotSsoPrompt` has a good integration with Bot framework. It simplifies the authentication process when you develops bot application and want to leverage the Bot SSO.
136
202
 
137
- Required configuration: initiateLoginEndpoint, tenantId, clientId, applicationIdUri.
203
+ The following code is an example to create `TeamsBotSsoPrompt`:
204
+
205
+ ```ts
206
+ const TeamsBotSsoPromptId = "TEAMS_BOT_SSO_PROMPT";
207
+
208
+ const settings: TeamsBotSsoPromptSettings = {
209
+ scopes: ["User.Read"],
210
+ timeout: 900000,
211
+ endOnInvalidMessage: true,
212
+ };
213
+
214
+ const authConfig: OnBehalfOfCredentialAuthConfig = {
215
+ authorityHost: process.env.M365_AUTHORITY_HOST,
216
+ clientId: process.env.M365_CLIENT_ID,
217
+ tenantId: process.env.M365_TENANT_ID,
218
+ clientSecret: process.env.M365_CLIENT_SECRET,
219
+ };
220
+ const loginUrl = process.env.INITIATE_LOGIN_ENDPOINT;
221
+ const ssoPrompt = new TeamsBotSsoPrompt(authConfig, loginUrl, TeamsBotSsoPromptId, settings);
222
+ ```
138
223
 
139
224
  ### Helper Function
140
225
 
@@ -142,7 +227,7 @@ TeamsFx SDK provides several helper functions to ease the configuration for thir
142
227
 
143
228
  #### Microsoft Graph Service
144
229
 
145
- `createMicrosoftGraphClient` and `MsGraphAuthProvider` help to create authenticated Graph instance.
230
+ `createMicrosoftGraphClientWithCredential`, `createMicrosoftGraphClient`(deprecated) and `MsGraphAuthProvider` help to create authenticated Graph instance.
146
231
 
147
232
  #### SQL
148
233
 
@@ -161,8 +246,13 @@ For example, to filter out specific error, you could use the following check:
161
246
 
162
247
  ```ts
163
248
  try {
164
- const teamsfx = new TeamsFx();
165
- await teamsfx.login("User.Read");
249
+ const authConfig: TeamsUserCredentialAuthConfig = {
250
+ clientId: process.env.REACT_APP_CLIENT_ID,
251
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
252
+ };
253
+
254
+ const credential = new TeamsUserCredential(authConfig);
255
+ await credential.login("User.Read");
166
256
  } catch (err: unknown) {
167
257
  if (err instanceof ErrorWithCode && err.code !== ErrorCode.ConsentFailed) {
168
258
  throw err;
@@ -177,8 +267,13 @@ And if credential instance is used in other library like Microsoft Graph, it's p
177
267
 
178
268
  ```ts
179
269
  try {
180
- const teamsfx = new TeamsFx();
181
- const graphClient = createMicrosoftGraphClient(teamsfx, ["User.Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
270
+ const authConfig: TeamsUserCredentialAuthConfig = {
271
+ clientId: process.env.REACT_APP_CLIENT_ID,
272
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
273
+ };
274
+
275
+ const credential = new TeamsUserCredential(authConfig);
276
+ const graphClient = createMicrosoftGraphClientWithCredential(credential, ["User.Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
182
277
  const profile = await graphClient.api("/me").get();
183
278
  } catch (err: unknown) {
184
279
  // ErrorWithCode is handled by Graph client
@@ -202,12 +297,29 @@ The following sections provide several code snippets covering some of the most c
202
297
 
203
298
  ### Use Graph API in tab app
204
299
 
205
- Use `TeamsFx` and `createMicrosoftGraphClient`.
300
+ Use `createMicrosoftGraphClientWithCredential`.
206
301
 
207
302
  ```ts
208
- const teamsfx = new TeamsFx();
209
- const graphClient = createMicrosoftGraphClient(teamsfx, ["User.Read"]);
210
- const profile = await graphClient.api("/me").get();
303
+ const authConfig: TeamsUserCredentialAuthConfig = {
304
+ clientId: process.env.REACT_APP_CLIENT_ID,
305
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
306
+ };
307
+
308
+ const teamsUserCredential = new TeamsUserCredential(authConfig);
309
+
310
+ // Put login code in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups.
311
+ await teamsUserCredential.login(["User.Read"]); // Login with scope
312
+
313
+ try {
314
+ const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User. Read"]); // Initializes MS Graph SDK using our MsGraphAuthProvider
315
+ const profile = await graphClient.api("/me").get();
316
+ } 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
+ }
321
+ }
322
+
211
323
  ```
212
324
 
213
325
  ### Call Azure Function in tab app
@@ -215,15 +327,21 @@ const profile = await graphClient.api("/me").get();
215
327
  Use `axios` library to make HTTP request to Azure Function.
216
328
 
217
329
  ```ts
218
- const teamsfx = new TeamsFx();
219
- const credential = teamsfx.getCredential();
220
- // Create an API client that uses SSO token to authenticate requests
221
- const apiClient = createApiClient(
222
- teamsfx.getConfig("apiEndpoint"),
223
- new BearerTokenAuthProvider(async () => (await credential.getToken(""))!.token)
224
- );
225
- // Call API hosted in Azure Functions on behalf of user
226
- const response = await apiClient.get("/api/" + functionName);
330
+ async function callFunction() {
331
+ const authConfig: TeamsUserCredentialAuthConfig = {
332
+ clientId: process.env.REACT_APP_CLIENT_ID,
333
+ initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
334
+ };
335
+ const teamsUserCredential = new TeamsUserCredential(authConfig);
336
+ const accessToken = await teamsUserCredential.getToken(""); // Get SSO token
337
+ const endpoint = "https://YOUR_API_ENDPOINT";
338
+ const response = await axios.default.get(endpoint + "/api/" + functionName, {
339
+ headers: {
340
+ authorization: "Bearer " + accessToken.token,
341
+ },
342
+ });
343
+ return response.data;
344
+ }
227
345
  ```
228
346
 
229
347
  ### Access SQL database in Azure Function
@@ -256,10 +374,14 @@ connection.on("connect", (error) => {
256
374
  ### Use certificate-based authentication in Azure Function
257
375
 
258
376
  ```ts
259
- const teamsfx = new TeamsFx(IdentityType.App, {
260
- certificateContent: "The content of a PEM-encoded public/private key certificate",
261
- });
262
- const token = teamsfx.getCredential().getToken();
377
+ const appAuthConfig: AppCredentialAuthConfig = {
378
+ authorityHost: process.env.M365_AUTHORITY_HOST,
379
+ clientId: process.env.M365_CLIENT_ID,
380
+ tenantId: process.env.M365_TENANT_ID,
381
+ certificateContent: 'PEM-encoded key certificate',
382
+ };
383
+ const appCredential = new AppCredential(appAuthConfig);
384
+ const token = appCredential.getToken();
263
385
  ```
264
386
 
265
387
  ### Use Graph API in Bot application
@@ -269,18 +391,30 @@ Add `TeamsBotSsoPrompt` to dialog set.
269
391
  ```ts
270
392
  const { ConversationState, MemoryStorage } = require("botbuilder");
271
393
  const { DialogSet, WaterfallDialog } = require("botbuilder-dialogs");
272
- const { TeamsBotSsoPrompt } = require("@microsoft/teamsfx");
394
+ const { TeamsBotSsoPrompt, OnBehalfOfCredentialAuthConfig, TeamsBotSsoPromptSettings } = require("@microsoft/teamsfx");
273
395
 
274
396
  const convoState = new ConversationState(new MemoryStorage());
275
397
  const dialogState = convoState.createProperty("dialogState");
276
398
  const dialogs = new DialogSet(dialogState);
277
399
 
278
- const teamsfx = new TeamsFx();
279
- dialogs.add(
280
- new TeamsBotSsoPrompt(teamsfx, "TeamsBotSsoPrompt", {
281
- scopes: ["User.Read"],
282
- })
283
- );
400
+ const TeamsBotSsoPromptId = "TEAMS_BOT_SSO_PROMPT";
401
+
402
+ const settings: TeamsBotSsoPromptSettings = {
403
+ scopes: ["User.Read"],
404
+ timeout: 900000,
405
+ endOnInvalidMessage: true,
406
+ };
407
+
408
+ 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,
413
+ };
414
+ const loginUrl = process.env.INITIATE_LOGIN_ENDPOINT;
415
+ const ssoPrompt = new TeamsBotSsoPrompt(authConfig, loginUrl, TeamsBotSsoPromptId, settings);
416
+
417
+ dialogs.add(ssoPrompt);
284
418
 
285
419
  dialogs.add(
286
420
  new WaterfallDialog("taskNeedingLogin", [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/teamsfx",
3
- "version": "2.2.0-alpha.d2fbcaf19.0",
3
+ "version": "2.2.0-alpha.ecf7bf89a.0",
4
4
  "description": "Microsoft Teams Framework for Node.js and browser.",
5
5
  "main": "dist/index.node.cjs.js",
6
6
  "browser": "dist/index.esm2017.js",
@@ -48,8 +48,8 @@
48
48
  "dependencies": {
49
49
  "@azure/identity": "^2.0.1",
50
50
  "@azure/msal-browser": "^2.21.0",
51
- "@azure/msal-node": "~1.1.0",
52
- "@microsoft/adaptivecards-tools": "1.2.2-alpha.d2fbcaf19.0",
51
+ "@azure/msal-node": "^1.14.6",
52
+ "@microsoft/adaptivecards-tools": "1.2.2-alpha.ecf7bf89a.0",
53
53
  "@microsoft/microsoft-graph-client": "^3.0.1",
54
54
  "axios": "^0.27.2",
55
55
  "botbuilder": ">=4.18.0 <5.0.0",
@@ -70,6 +70,7 @@
70
70
  "@istanbuljs/nyc-config-typescript": "^1.0.1",
71
71
  "@microsoft/api-documenter": "^7.14.1",
72
72
  "@microsoft/api-extractor": "^7.19.4",
73
+ "@microsoft/eslint-plugin-teamsfx": "0.0.2-alpha.ecf7bf89a.0",
73
74
  "@microsoft/teams-js": "^2.7.1",
74
75
  "@rollup/plugin-json": "^4.1.0",
75
76
  "@types/chai": "^4.2.22",
@@ -129,7 +130,7 @@
129
130
  "webpack": "^5.62.1",
130
131
  "yargs": "^17.2.1"
131
132
  },
132
- "gitHead": "a72d5e8d31f06fe6e205ae3ad5cf8f8d813fa2dc",
133
+ "gitHead": "3450f8bf22d66f5b5367cbc5dd4e21dbdea67512",
133
134
  "publishConfig": {
134
135
  "access": "public"
135
136
  },