Skip to content

Commit 76d9d03

Browse files
committed
Updated tutorial through step 4
1 parent aca8eee commit 76d9d03

File tree

8 files changed

+66
-59
lines changed

8 files changed

+66
-59
lines changed

tutorial/01-intro.md

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,7 @@ You should also have either a personal Microsoft account with a mailbox on Outlo
1515
- You can [sign up for the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program) to get a free Office 365 subscription.
1616

1717
> [!NOTE]
18-
> This tutorial was written with Node version 12.18.4. The steps in this guide may work with other versions, but that has not been tested.
19-
20-
## Watch the tutorial
21-
22-
This module has been recorded and is available in the Office Development YouTube channel.
23-
24-
<!-- markdownlint-disable MD033 MD034 -->
25-
<br/>
26-
27-
> [!VIDEO https://www.youtube-nocookie.com/embed/KUPRTTOUzz8]
28-
<!-- markdownlint-enable MD033 MD034 -->
18+
> This tutorial was written with Node version 14.15.0. The steps in this guide may work with other versions, but that has not been tested.
2919
3020
## Feedback
3121

tutorial/02-create-app.md

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ In this section, you'll create a new Angular project.
55
1. Open your command-line interface (CLI), navigate to a directory where you have rights to create files, and run the following commands to install the [Angular CLI](https://www.npmjs.com/package/@angular/cli) tool and create a new Angular app.
66

77
```Shell
8-
npm install -g @angular/cli@10.1.7
8+
npm install -g @angular/cli@11.2.9
99
ng new graph-tutorial
1010
```
1111

1212
1. The Angular CLI will prompt for more information. Answer the prompts as follows.
1313

1414
```Shell
15+
? Do you want to enforce stricter type checking and stricter bundle budgets in the workspace? Yes
1516
? Would you like to add Angular routing? Yes
1617
? Which stylesheet format would you like to use? CSS
1718
```
@@ -38,9 +39,10 @@ Before moving on, install some additional packages that you will use later:
3839
1. Run the following commands in your CLI.
3940
4041
```Shell
41-
42-
43-
npm install @microsoft/[email protected] @microsoft/[email protected]
42+
npm install [email protected] @ng-bootstrap/[email protected]
43+
npm install @azure/[email protected] @azure/[email protected]
44+
45+
npm install @microsoft/[email protected] @microsoft/[email protected]
4446
```
4547
4648
1. Run the following command in your CLI to add the Angular localization package (required by ng-bootstrap).
@@ -86,7 +88,7 @@ In this section you'll create the user interface for the app.
8688
8789
1. Create a new file in the **./src/app** folder named **user.ts** and add the following code.
8890
89-
:::code language="typescript" source="../demo/graph-tutorial/src/app/user.ts" id="user":::
91+
:::code language="typescript" source="../demo/graph-tutorial/src/app/user.ts" id="UserSnippet":::
9092
9193
1. Generate an Angular component for the top navigation on the page. In your CLI, run the following command.
9294
@@ -109,19 +111,15 @@ In this section you'll create the user interface for the app.
109111
export class NavBarComponent implements OnInit {
110112
111113
// Should the collapsed nav show?
112-
showNav: boolean;
114+
showNav: boolean = false;
113115
// Is a user logged in?
114-
authenticated: boolean;
116+
authenticated: boolean = false;
115117
// The user
116-
user: User;
118+
user?: User = undefined;
117119
118120
constructor() { }
119121
120-
ngOnInit() {
121-
this.showNav = false;
122-
this.authenticated = false;
123-
this.user = null;
124-
}
122+
ngOnInit() { }
125123
126124
// Used by the Bootstrap navbar-toggler button to hide/show
127125
// the nav in a collapsed state
@@ -135,14 +133,15 @@ In this section you'll create the user interface for the app.
135133
this.user = {
136134
displayName: 'Adele Vance',
137135
138-
avatar: null
136+
avatar: '',
137+
timeZone: ''
139138
};
140139
}
141140
142141
signOut(): void {
143142
// Temporary
144143
this.authenticated = false;
145-
this.user = null;
144+
this.user = undefined;
146145
}
147146
}
148147
```
@@ -172,23 +171,22 @@ In this section you'll create the user interface for the app.
172171
export class HomeComponent implements OnInit {
173172
174173
// Is a user logged in?
175-
authenticated: boolean;
174+
authenticated: boolean = false;
176175
// The user
177-
user: any;
176+
user?: User = undefined;
178177
179178
constructor() { }
180179
181-
ngOnInit() {
182-
this.authenticated = false;
183-
this.user = {};
184-
}
180+
ngOnInit() { }
185181
186182
signIn(): void {
187183
// Temporary
188184
this.authenticated = true;
189185
this.user = {
190186
displayName: 'Adele Vance',
191-
187+
188+
avatar: '',
189+
timeZone: ''
192190
};
193191
}
194192
}
@@ -200,7 +198,7 @@ In this section you'll create the user interface for the app.
200198
201199
1. Create a simple `Alert` class. Create a new file in the **./src/app** directory named **alert.ts** and add the following code.
202200
203-
:::code language="typescript" source="../demo/graph-tutorial/src/app/alert.ts" id="alert":::
201+
:::code language="typescript" source="../demo/graph-tutorial/src/app/alert.ts" id="AlertSnippet":::
204202
205203
1. Create an alert service that the app can use to display messages to the user. In your CLI, run the following command.
206204
@@ -220,11 +218,11 @@ In this section you'll create the user interface for the app.
220218
221219
1. Once the command completes, open **./src/app/alerts/alerts.component.ts** and replace its contents with the following.
222220
223-
:::code language="typescript" source="../demo/graph-tutorial/src/app/alerts/alerts.component.ts" id="alertComponent":::
221+
:::code language="typescript" source="../demo/graph-tutorial/src/app/alerts/alerts.component.ts" id="AlertsComponentSnippet":::
224222
225223
1. Open **./src/app/alerts/alerts.component.html** and replace its contents with the following.
226224
227-
:::code language="html" source="../demo/graph-tutorial/src/app/alerts/alerts.component.html" id="alertHtml":::
225+
:::code language="html" source="../demo/graph-tutorial/src/app/alerts/alerts.component.html" id="AlertHtml":::
228226
229227
1. Open **./src/app/app-routing.module.ts** and replace the `const routes: Routes = [];` line with the following code.
230228
@@ -238,7 +236,7 @@ In this section you'll create the user interface for the app.
238236
239237
1. Open **./src/app/app.component.html** and replace its entire contents with the following.
240238
241-
:::code language="html" source="../demo/graph-tutorial/src/app/app.component.html" id="appHtml":::
239+
:::code language="html" source="../demo/graph-tutorial/src/app/app.component.html" id="AppHtml":::
242240
243241
1. Add an image file of your choosing named **no-profile-photo.png** in the **./src/assets** directory. This image will be used as the user's photo when the user has no photo in Microsoft Graph.
244242

tutorial/03-register-app.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,10 @@ In this exercise, you will create a new Azure AD web application registration us
1212

1313
- Set **Name** to `Angular Graph Tutorial`.
1414
- Set **Supported account types** to **Accounts in any organizational directory and personal Microsoft accounts**.
15-
- Under **Redirect URI**, set the first drop-down to `Web` and set the value to `http://localhost:4200`.
15+
- Under **Redirect URI**, set the first drop-down to `Single-page application (SPA)` and set the value to `http://localhost:4200`.
1616

1717
![A screenshot of the Register an application page](./images/aad-register-an-app.png)
1818

1919
1. Select **Register**. On the **Angular Graph Tutorial** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step.
2020

2121
![A screenshot of the application ID of the new app registration](./images/aad-application-id.png)
22-
23-
1. Select **Authentication** under **Manage**. Locate the **Implicit grant** section and enable **Access tokens** and **ID tokens**. Select **Save**.
24-
25-
![A screenshot of the Implicit grant section](./images/aad-implicit-grant.png)

tutorial/04-add-aad-auth.md

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,26 @@ In this exercise you will extend the application from the previous exercise to s
1414
1. Open **./src/app/app.module.ts** and add the following `import` statements to the top of the file.
1515

1616
```typescript
17-
import { MsalModule } from '@azure/msal-angular';
17+
import { IPublicClientApplication,
18+
PublicClientApplication,
19+
BrowserCacheLocation } from '@azure/msal-browser';
20+
import { MsalModule,
21+
MsalService,
22+
MSAL_INSTANCE } from '@azure/msal-angular';
1823
import { OAuthSettings } from '../oauth';
1924
```
2025

21-
1. Add the `MsalModule` to the `imports` array inside the `@NgModule` declaration, and initialize it with the app ID.
26+
1. Add the following function below the `import` statements.
2227

23-
:::code language="typescript" source="../demo/graph-tutorial/src/app/app.module.ts" id="imports" highlight="6-11":::
28+
:::code language="typescript" source="../demo/graph-tutorial/src/app/app.module.ts" id="MSALFactorySnippet":::
29+
30+
1. Add the `MsalModule` to the `imports` array inside the `@NgModule` declaration.
31+
32+
:::code language="typescript" source="../demo/graph-tutorial/src/app/app.module.ts" id="ImportsSnippet" highlight="6":::
33+
34+
1. Add the `MSALInstanceFactory` and `MsalService` to the `providers` array inside the `@NgModule` declaration.
35+
36+
:::code language="typescript" source="../demo/graph-tutorial/src/app/app.module.ts" id="ProvidersSnippet" highlight="2-5":::
2437

2538
## Implement sign-in
2639

@@ -38,6 +51,7 @@ In this section you'll create an authentication service and implement sign-in an
3851

3952
```typescript
4053
import { Injectable } from '@angular/core';
54+
import { AccountInfo } from '@azure/msal-browser';
4155
import { MsalService } from '@azure/msal-angular';
4256
4357
import { AlertsService } from './alerts.service';
@@ -50,25 +64,29 @@ In this section you'll create an authentication service and implement sign-in an
5064
5165
export class AuthService {
5266
public authenticated: boolean;
53-
public user: User;
67+
public user?: User;
5468
5569
constructor(
5670
private msalService: MsalService,
5771
private alertsService: AlertsService) {
5872
5973
this.authenticated = false;
60-
this.user = null;
74+
this.user = undefined;
6175
}
6276
6377
// Prompt the user to sign in and
6478
// grant consent to the requested permission scopes
6579
async signIn(): Promise<void> {
66-
let result = await this.msalService.loginPopup(OAuthSettings)
80+
const result = await this.msalService
81+
.loginPopup(OAuthSettings)
82+
.toPromise()
6783
.catch((reason) => {
68-
this.alertsService.addError('Login failed', JSON.stringify(reason, null, 2));
84+
this.alertsService.addError('Login failed',
85+
JSON.stringify(reason, null, 2));
6986
});
7087
7188
if (result) {
89+
this.msalService.instance.setActiveAccount(result.account);
7290
this.authenticated = true;
7391
// Temporary placeholder
7492
this.user = new User();
@@ -79,15 +97,19 @@ In this section you'll create an authentication service and implement sign-in an
7997
}
8098
8199
// Sign out
82-
signOut(): void {
83-
this.msalService.logout();
84-
this.user = null;
100+
async signOut(): Promise<void> {
101+
await this.msalService.logout().toPromise();
102+
this.user = undefined;
85103
this.authenticated = false;
86104
}
87105
88106
// Silently request an access token
89107
async getAccessToken(): Promise<string> {
90-
let result = await this.msalService.acquireTokenSilent(OAuthSettings)
108+
const result = await this.msalService
109+
.acquireTokenSilent({
110+
scopes: OAuthSettings.scopes
111+
})
112+
.toPromise()
91113
.catch((reason) => {
92114
this.alertsService.addError('Get token failed', JSON.stringify(reason, null, 2));
93115
});
@@ -100,14 +122,14 @@ In this section you'll create an authentication service and implement sign-in an
100122
101123
// Couldn't get a token
102124
this.authenticated = false;
103-
return null;
125+
return '';
104126
}
105127
}
106128
```
107129

108130
1. Open **./src/app/nav-bar/nav-bar.component.ts** and replace its contents with the following.
109131

110-
:::code language="typescript" source="../demo/graph-tutorial/src/app/nav-bar/nav-bar.component.ts" id="navBarSnippet" highlight="3,15-22,24,26-28,36-38,40-42":::
132+
:::code language="typescript" source="../demo/graph-tutorial/src/app/nav-bar/nav-bar.component.ts" id="navBarSnippet" highlight="3,15-22,24,34-36,38-40":::
111133

112134
1. Open **./src/app/home/home.component.ts** and replace its contents with the following.
113135

@@ -128,7 +150,7 @@ Right now the authentication service sets constant values for the user's display
128150

129151
1. Add a new function to the `AuthService` class called `getUser`.
130152

131-
:::code language="typescript" source="../demo/graph-tutorial/src/app/auth.service.ts" id="getUserSnippet":::
153+
:::code language="typescript" source="../demo/graph-tutorial/src/app/auth.service.ts" id="GetUserSnippet":::
132154

133155
1. Locate and remove the following code in the `getAccessToken` method that adds an alert to display the access token.
134156

@@ -157,7 +179,7 @@ Right now the authentication service sets constant values for the user's display
157179

158180
1. Change the `constructor` for the `AuthService` class to check if the user is already logged in and load their details if so. Replace the existing `constructor` with the following.
159181

160-
:::code language="typescript" source="../demo/graph-tutorial/src/app/auth.service.ts" id="constructorSnippet" highlight="5-6":::
182+
:::code language="typescript" source="../demo/graph-tutorial/src/app/auth.service.ts" id="ConstructorSnippet" highlight="5-7":::
161183

162184
1. Remove the temporary code from the `HomeComponent` class. Open **./src/app/home/home.component.ts** and replace the existing `signIn` function with the following.
163185

-7.97 KB
Binary file not shown.
15.3 KB
Loading
2.13 KB
Loading

tutorial/snippets/snippets.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ import { User } from '../user';
1010
styleUrls: ['./home.component.css']
1111
})
1212
export class HomeComponent implements OnInit {
13+
1314
// Is a user logged in?
1415
get authenticated(): boolean {
1516
return this.authService.authenticated;
1617
}
1718
// The user
18-
get user(): User {
19+
get user(): User | undefined {
1920
return this.authService.user;
2021
}
2122

2223
constructor(private authService: AuthService) { }
2324

24-
ngOnInit() {}
25+
ngOnInit() { }
2526

2627
async signIn(): Promise<void> {
2728
await this.authService.signIn();

0 commit comments

Comments
 (0)