Skip to content

Commit 22b204a

Browse files
feat: allow TeamsfxProvider to be constructed with TeamssUerCredential (#1954)
* [teamsfx-provider] Allow use TeamsUserCredential to construct instance * Update README.md Co-authored-by: turenlong <[email protected]> Co-authored-by: Gavin Barron <[email protected]>
1 parent 1b67cf6 commit 22b204a

File tree

2 files changed

+87
-30
lines changed

2 files changed

+87
-30
lines changed

packages/providers/mgt-teamsfx-provider/README.md

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,61 @@ To learn more about authentication providers, see [Providers](./providers.md).
1616
npm install @microsoft/mgt-element @microsoft/mgt-teamsfx-provider @microsoft/teamsfx
1717
```
1818

19-
1. Initialize the provider inside your component.
20-
21-
```ts
22-
// Import the providers and credential at the top of the page
23-
import {Providers} from '@microsoft/mgt-element';
24-
import {TeamsFxProvider} from '@microsoft/mgt-teamsfx-provider';
25-
import {TeamsUserCredential} from "@microsoft/teamsfx";
26-
27-
const scope = ["User.Read"];
28-
const teamsfx = new TeamsFx();
29-
const provider = new TeamsFxProvider(teamsfx, scope);
30-
Providers.globalProvider = provider;
31-
```
32-
33-
1. Use the `teamsfx.login(scopes)` method to get the required access token.
34-
35-
```ts
36-
// Put these code in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups.
37-
await teamsfx.login(this.scope);
38-
Providers.globalProvider.setState(ProviderState.SignedIn);
39-
```
40-
41-
1. Now you can add any component in your HTML page or in your `render()` method when using React and it will use the TeamsFx context to access Microsoft Graph.
19+
1. Initialize the provider and login to get the required access token
20+
21+
### Use TeamsUserCredential (Recommended)
22+
23+
1. Initialize the provider inside your component.
24+
```ts
25+
// Import the providers and credential at the top of the page
26+
import {Providers} from '@microsoft/mgt-element';
27+
import {TeamsFxProvider} from '@microsoft/mgt-teamsfx-provider';
28+
import {TeamsUserCredential, TeamsUserCredentialAuthConfig} from "@microsoft/teamsfx";
29+
30+
const authConfig: TeamsUserCredentialAuthConfig = {
31+
clientId: process.env.REACT_APP_CLIENT_ID,
32+
initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL,
33+
};
34+
const scope = ["User.Read"];
35+
36+
const credential = new TeamsUserCredential(authConfig);
37+
const provider = new TeamsFxProvider(credential, scope);
38+
Providers.globalProvider = provider;
39+
```
40+
1. Use the `credential.login(scopes)` method to get the required access token.
41+
42+
```ts
43+
// Put these code in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups.
44+
await credential.login(this.scope);
45+
Providers.globalProvider.setState(ProviderState.SignedIn);
46+
```
47+
48+
### Use TeamsFx class
49+
> Note: TeamsFx class will be deprecated and removed from future release of TeamsFx SDK, and it is recommended to use `TeamsUserCredential` instead
50+
51+
1. Initialize the provider inside your component.
52+
53+
```ts
54+
// Import the providers and credential at the top of the page
55+
import {Providers} from '@microsoft/mgt-element';
56+
import {TeamsFxProvider} from '@microsoft/mgt-teamsfx-provider';
57+
import {TeamsUserCredential} from "@microsoft/teamsfx";
58+
59+
const scope = ["User.Read"];
60+
const teamsfx = new TeamsFx();
61+
const provider = new TeamsFxProvider(teamsfx, scope);
62+
Providers.globalProvider = provider;
63+
```
64+
65+
1. Use the `teamsfx.login(scopes)` method to get the required access token.
66+
67+
```ts
68+
// Put these code in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups.
69+
await teamsfx.login(this.scope);
70+
Providers.globalProvider.setState(ProviderState.SignedIn);
71+
```
72+
73+
1. Now you can add any component in your HTML page or in your `render()` method when using React and it will use the TeamsFx context to access Microsoft Graph.
4274
4375
```html
4476
<!-- Using HTML -->

packages/providers/mgt-teamsfx-provider/src/TeamsFxProvider.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import { IProvider, ProviderState, createFromProvider } from '@microsoft/mgt-element';
9-
import { TeamsFx } from '@microsoft/teamsfx';
9+
import { TeamsFx, TeamsUserCredential } from '@microsoft/teamsfx';
1010

1111
/**
1212
* TeamsFx Provider handler
@@ -27,7 +27,7 @@ export class TeamsFxProvider extends IProvider {
2727
}
2828

2929
/**
30-
* returns teamsfx instance
30+
* returns teamsfx instance, if you construct TeamsFxProvider with TeamsUserCredential, this value should be null
3131
*
3232
* @readonly
3333
* @memberof TeamsFxProvider
@@ -46,6 +46,14 @@ export class TeamsFxProvider extends IProvider {
4646
*/
4747
private scopes: string | string[] = [];
4848

49+
/**
50+
* TeamsUserCredential instance
51+
*
52+
* @type {TeamsFx}
53+
* @memberof TeamsFxProvider
54+
*/
55+
private readonly _credential: TeamsUserCredential;
56+
4957
/**
5058
* TeamsFx instance
5159
*
@@ -62,11 +70,19 @@ export class TeamsFxProvider extends IProvider {
6270
*/
6371
private _accessToken: string = '';
6472

65-
constructor(teamsfx: TeamsFx, scopes: string | string[]) {
73+
constructor(teamsfx: TeamsFx, scopes: string | string[]);
74+
constructor(teamsUserCredential: TeamsUserCredential, scopes: string | string[]);
75+
constructor(authConfig: TeamsFx | TeamsUserCredential, scopes: string | string[]) {
6676
super();
6777

68-
if (!this._teamsfx) {
69-
this._teamsfx = teamsfx;
78+
if (!this._teamsfx && !this._credential) {
79+
if ((authConfig as TeamsFx).getCredential) {
80+
this._teamsfx = authConfig as TeamsFx;
81+
this._credential = null;
82+
} else {
83+
this._credential = authConfig as TeamsUserCredential;
84+
this._teamsfx = null;
85+
}
7086
}
7187

7288
this.validateScopesType(scopes);
@@ -90,7 +106,12 @@ export class TeamsFxProvider extends IProvider {
90106
*/
91107
public async getAccessToken(): Promise<string> {
92108
try {
93-
const accessToken = await this.teamsfx.getCredential().getToken(this.scopes);
109+
let accessToken;
110+
if (this._teamsfx) {
111+
accessToken = await this._teamsfx.getCredential().getToken(this.scopes);
112+
} else {
113+
accessToken = await this._credential.getToken(this.scopes);
114+
}
94115
this._accessToken = accessToken ? accessToken.token : '';
95116
if (!this._accessToken) {
96117
throw new Error('Access token is null');
@@ -113,7 +134,11 @@ export class TeamsFxProvider extends IProvider {
113134
const token: string = await this.getAccessToken();
114135

115136
if (!token) {
116-
await this.teamsfx.login(this.scopes);
137+
if (this._teamsfx) {
138+
await this._teamsfx.login(this.scopes);
139+
} else {
140+
await this._credential.login(this.scopes);
141+
}
117142
}
118143

119144
this._accessToken = token ?? (await this.getAccessToken());

0 commit comments

Comments
 (0)