@@ -122,40 +122,40 @@ You now have a small webserver to serve your SPA. The folder structure you shoul
122
122
123
123
1. Create an *app* folder in your project directory, and in it create an *index.html* file for your JavaScript SPA. This file implements a UI built with the **Bootstrap 4 Framework** and imports script files for configuration, authentication, and API calls.
124
124
125
- In the *index.html* file, add the following code:
125
+ In the *index.html* file, add the following code:
126
126
127
- ```html
128
- <!DOCTYPE html>
129
- <html lang="en">
127
+ ```html
128
+ <!DOCTYPE html>
129
+ <html lang="en">
130
130
<head>
131
- <meta charset="UTF-8">
132
- <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
133
- <title>Tutorial | MSAL.js JavaScript SPA</title>
131
+ <meta charset="UTF-8">
132
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
133
+ <title>Quickstart | MSAL.JS Vanilla JavaScript SPA</title>
134
134
135
- <!-- IE support: add promises polyfill before msal.js -->
136
- <script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected] /js/browser/bluebird.min.js"></script>
137
- <script type="text/javascript" src="https://alcdn.msauth.net/browser/2.0.0-beta.0/js/msal-browser.js"></script>
135
+ <!-- IE support: add promises polyfill before msal.js -->
136
+ <script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected] /js/browser/bluebird.min.js"></script>
137
+ <script type="text/javascript" src="https://alcdn.msauth.net/browser/2.0.0-beta.0/js/msal-browser.js"></script>
138
138
139
- <!-- adding Bootstrap 4 for UI components -->
140
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
141
- <link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
139
+ <!-- adding Bootstrap 4 for UI components -->
140
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
141
+ <link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
142
142
</head>
143
143
<body>
144
- <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
145
- <a class="navbar-brand" href="/">Microsoft identity platform </a>
146
- <div class="btn-group ml-auto dropleft">
147
- <button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()">
148
- Sign In
149
- </button>
150
- </div>
151
- </nav>
152
- <br>
153
- <h5 class="card-header text-center">Vanilla JavaScript SPA calling Microsoft Graph API with MSAL.JS</h5>
154
- <br>
155
- <div class="row" style="margin:auto" >
156
- <div id="card-div" class="col-md-3" style="display:none">
157
- <div class="card text-center">
158
- <div class="card-body">
144
+ <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
145
+ <a class="navbar-brand" href="/">MS Identity Platform </a>
146
+ <div class="btn-group ml-auto dropleft">
147
+ <button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()">
148
+ Sign In
149
+ </button>
150
+ </div>
151
+ </nav>
152
+ <br>
153
+ <h5 class="card-header text-center">Vanilla JavaScript SPA calling MS Graph API with MSAL.JS</h5>
154
+ <br>
155
+ <div class="row" style="margin:auto" >
156
+ <div id="card-div" class="col-md-3" style="display:none">
157
+ <div class="card text-center">
158
+ <div class="card-body">
159
159
<h5 class="card-title" id="WelcomeMessage">Please sign-in to see your profile and read your mails</h5>
160
160
<div id="profile-div"></div>
161
161
<br>
@@ -164,112 +164,117 @@ You now have a small webserver to serve your SPA. The folder structure you shoul
164
164
<br>
165
165
<br>
166
166
<button class="btn btn-primary" id="readMail" onclick="readMail()">Read Mails</button>
167
- </div>
168
- </div>
169
- </div>
170
- <br>
171
- <br>
172
- <div class="col-md-4">
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <br>
171
+ <br>
172
+ <div class="col-md-4">
173
173
<div class="list-group" id="list-tab" role="tablist">
174
174
</div>
175
+ </div>
176
+ <div class="col-md-5">
177
+ <div class="tab-content" id="nav-tabContent">
175
178
</div>
176
- <div class="col-md-5">
177
- <div class="tab-content" id="nav-tabContent">
178
- </div>
179
- </div>
180
- </div>
181
- <br>
182
- <br>
183
-
184
- <!-- importing bootstrap.js and supporting js libraries -->
185
- <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
186
- <script src="https://cdn.jsdelivr.net/npm/[email protected] /dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
187
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
188
-
189
- <!-- importing app scripts (load order is important) -->
190
- <script type="text/javascript" src="./authConfig.js"></script>
191
- <script type="text/javascript" src="./graphConfig.js"></script>
192
- <script type="text/javascript" src="./ui.js"></script>
193
-
194
- <!-- <script type="text/javascript" src="./authRedirect.js"></script> -->
195
- <!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
196
- <script type="text/javascript" src="./authPopup.js"></script>
197
- <script type="text/javascript" src="./graph.js"></script>
179
+ </div>
180
+ </div>
181
+ <br>
182
+ <br>
183
+
184
+ <!-- importing bootstrap.js and supporting js libraries -->
185
+ <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
186
+ <script src="https://cdn.jsdelivr.net/npm/[email protected] /dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
187
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
188
+
189
+ <!-- importing app scripts (load order is important) -->
190
+ <script type="text/javascript" src="./authConfig.js"></script>
191
+ <script type="text/javascript" src="./graphConfig.js"></script>
192
+ <script type="text/javascript" src="./ui.js"></script>
193
+
194
+ <!-- <script type="text/javascript" src="./authRedirect.js"></script> -->
195
+ <!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
196
+ <script type="text/javascript" src="./authPopup.js"></script>
197
+ <script type="text/javascript" src="./graph.js"></script>
198
198
</body>
199
- </html>
200
- ```
199
+ </html>
200
+ ```
201
201
202
202
2. Next, also in the *app* folder, create a file named *ui.js* and add the following code. This file will access and update DOM elements.
203
203
204
- ```JavaScript
205
- // Select DOM elements to work with
206
- const welcomeDiv = document.getElementById("welcomeMessage");
207
- const signInButton = document.getElementById("signIn");
208
- const signOutButton = document.getElementById('signOut');
209
- const cardDiv = document.getElementById("card-div");
210
- const mailButton = document.getElementById("readMail");
211
- const profileButton = document.getElementById("seeProfile");
212
- const profileDiv = document.getElementById("profile-div");
213
-
214
- function showWelcomeMessage(account) {
215
- // Reconfiguring DOM elements
216
- cardDiv.classList.remove('d-none');
217
- welcomeDiv.innerHTML = `Welcome ${account.name}`;
218
- signInButton.classList.add('d-none');
219
- signOutButton.classList.remove('d-none');
220
- }
204
+ ```JavaScript
205
+ // Select DOM elements to work with
206
+ const welcomeDiv = document.getElementById("WelcomeMessage");
207
+ const signInButton = document.getElementById("SignIn");
208
+ const cardDiv = document.getElementById("card-div");
209
+ const mailButton = document.getElementById("readMail");
210
+ const profileButton = document.getElementById("seeProfile");
211
+ const profileDiv = document.getElementById("profile-div");
212
+
213
+ function showWelcomeMessage(account) {
214
+
215
+ // Reconfiguring DOM elements
216
+ cardDiv.classList.remove('d-none');
217
+ welcomeDiv.innerHTML = `Welcome ${account.name}`;
218
+
219
+ // Reconfiguring DOM elements
220
+ cardDiv.style.display = 'initial';
221
+ welcomeDiv.innerHTML = `Welcome ${account.name}`;
222
+ signInButton.setAttribute("onclick", "signOut();");
223
+ signInButton.setAttribute('class', "btn btn-success")
224
+ signInButton.innerHTML = "Sign Out";
225
+ }
221
226
222
- function updateUI(data, endpoint) {
223
- console.log('Graph API responded at: ' + new Date().toString());
224
-
225
- if (endpoint === graphConfig.graphMeEndpoint) {
226
- const title = document.createElement('p');
227
- title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
228
- const email = document.createElement('p');
229
- email.innerHTML = "<strong>Mail: </strong>" + data.mail;
230
- const phone = document.createElement('p');
231
- phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
232
- const address = document.createElement('p');
233
- address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
234
- profileDiv.appendChild(title);
235
- profileDiv.appendChild(email);
236
- profileDiv.appendChild(phone);
237
- profileDiv.appendChild(address);
238
-
239
- } else if (endpoint === graphConfig.graphMailEndpoint) {
240
- if (data.value.length < 1) {
241
- alert("Your mailbox is empty!")
242
- } else {
243
- const tabList = document.getElementById("list-tab");
244
- tabList.innerHTML = ''; // clear tabList at each readMail call
245
- const tabContent = document.getElementById("nav-tabContent");
246
-
247
- data.value.map((d, i) => {
248
- // Keeping it simple
249
- if (i < 10) {
250
- const listItem = document.createElement("a");
251
- listItem.setAttribute("class", "list-group-item list-group-item-action")
252
- listItem.setAttribute("id", "list" + i + "list")
253
- listItem.setAttribute("data-toggle", "list")
254
- listItem.setAttribute("href", "#list" + i)
255
- listItem.setAttribute("role", "tab")
256
- listItem.setAttribute("aria-controls", i)
257
- listItem.innerHTML = d.subject;
258
- tabList.appendChild(listItem)
259
-
260
- const contentItem = document.createElement("div");
261
- contentItem.setAttribute("class", "tab-pane fade")
262
- contentItem.setAttribute("id", "list" + i)
263
- contentItem.setAttribute("role", "tabpanel")
264
- contentItem.setAttribute("aria-labelledby", "list" + i + "list")
265
- contentItem.innerHTML = "<strong> from: " + d.from.emailAddress.address + "</strong><br><br>" + d.bodyPreview + "...";
266
- tabContent.appendChild(contentItem);
267
- }
268
- });
269
- }
270
- }
271
- }
272
- ```
227
+ function updateUI(data, endpoint) {
228
+ console.log('Graph API responded at: ' + new Date().toString());
229
+
230
+ if (endpoint === graphConfig.graphMeEndpoint) {
231
+ const title = document.createElement('p');
232
+ title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
233
+ const email = document.createElement('p');
234
+ email.innerHTML = "<strong>Mail: </strong>" + data.mail;
235
+ const phone = document.createElement('p');
236
+ phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
237
+ const address = document.createElement('p');
238
+ address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
239
+ profileDiv.appendChild(title);
240
+ profileDiv.appendChild(email);
241
+ profileDiv.appendChild(phone);
242
+ profileDiv.appendChild(address);
243
+
244
+ } else if (endpoint === graphConfig.graphMailEndpoint) {
245
+ if (data.value.length < 1) {
246
+ alert("Your mailbox is empty!")
247
+ } else {
248
+ const tabList = document.getElementById("list-tab");
249
+ tabList.innerHTML = ''; // clear tabList at each readMail call
250
+ const tabContent = document.getElementById("nav-tabContent");
251
+
252
+ data.value.map((d, i) => {
253
+ // Keeping it simple
254
+ if (i < 10) {
255
+ const listItem = document.createElement("a");
256
+ listItem.setAttribute("class", "list-group-item list-group-item-action")
257
+ listItem.setAttribute("id", "list" + i + "list")
258
+ listItem.setAttribute("data-toggle", "list")
259
+ listItem.setAttribute("href", "#list" + i)
260
+ listItem.setAttribute("role", "tab")
261
+ listItem.setAttribute("aria-controls", i)
262
+ listItem.innerHTML = d.subject;
263
+ tabList.appendChild(listItem)
264
+
265
+ const contentItem = document.createElement("div");
266
+ contentItem.setAttribute("class", "tab-pane fade")
267
+ contentItem.setAttribute("id", "list" + i)
268
+ contentItem.setAttribute("role", "tabpanel")
269
+ contentItem.setAttribute("aria-labelledby", "list" + i + "list")
270
+ contentItem.innerHTML = "<strong> from: " + d.from.emailAddress.address + "</strong><br><br>" + d.bodyPreview + "...";
271
+ tabContent.appendChild(contentItem);
272
+ }
273
+ });
274
+ }
275
+ }
276
+ }
277
+ ```
273
278
274
279
## Register your application
275
280
0 commit comments