Skip to content

Commit 0e6e9af

Browse files
committed
minor review changes
1 parent ea37dd3 commit 0e6e9af

File tree

11 files changed

+480
-422
lines changed

11 files changed

+480
-422
lines changed

2-Authorization-I/1-call-graph/App/authPopup.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ const myMSALObj = new msal.PublicClientApplication(msalConfig);
44

55
let username = '';
66

7+
/**
8+
* This method adds an event callback function to the MSAL object
9+
* to handle the response from redirect flow. For more information, visit:
10+
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md
11+
*/
712
myMSALObj.addEventCallback((event) => {
813
if (
914
(event.eventType === msal.EventType.LOGIN_SUCCESS ||
10-
event.eventType === msal.EventType.ACQUIRE_TOKEN_SUCCESS) &&
15+
event.eventType === msal.EventType.ACQUIRE_TOKEN_SUCCESS) &&
1116
event.payload.account
1217
) {
1318
const account = event.payload.account;
@@ -117,7 +122,6 @@ function signOut() {
117122
const account = myMSALObj.getAccountByUsername(username);
118123
const logoutRequest = {
119124
account: account,
120-
redirectUri: '/redirect',
121125
mainWindowRedirectUri: '/',
122126
};
123127
clearStorage(account);
@@ -133,7 +137,7 @@ function seeProfile() {
133137
graphConfig.graphMeEndpoint.uri,
134138
msal.InteractionType.Popup,
135139
myMSALObj
136-
);
140+
);
137141
}
138142

139143
function readContacts() {

2-Authorization-I/1-call-graph/App/authRedirect.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ const myMSALObj = new msal.PublicClientApplication(msalConfig);
44

55
let username = '';
66

7-
7+
/**
8+
* This method adds an event callback function to the MSAL object
9+
* to handle the response from redirect flow. For more information, visit:
10+
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md
11+
*/
812
myMSALObj.addEventCallback((event) => {
913
if (
1014
(event.eventType === msal.EventType.LOGIN_SUCCESS ||
@@ -48,7 +52,7 @@ function selectAccount() {
4852
// Add your account choosing logic here
4953
username = myMSALObj.getActiveAccount().username;
5054
showWelcomeMessage(username, currentAccounts);
51-
}
55+
}
5256
}
5357

5458
async function addAnotherAccount(event) {
@@ -111,7 +115,7 @@ function signIn() {
111115
}
112116

113117
function signOut() {
114-
118+
115119
/**
116120
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
117121
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
@@ -135,7 +139,7 @@ function seeProfile() {
135139
graphConfig.graphMeEndpoint.uri,
136140
msal.InteractionType.Redirect,
137141
myMSALObj
138-
);
142+
);
139143
}
140144

141145
function readContacts() {

2-Authorization-I/1-call-graph/App/fetch.js

Lines changed: 57 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,6 @@
33
* Licensed under the MIT License.
44
*/
55

6-
/**
7-
* This method inspects the HTTPS response from a fetch call for the "www-authenticate header"
8-
* If present, it grabs the claims challenge from the header and store it in the localStorage
9-
* For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/develop/claims-challenge#claims-challenge-header-format
10-
* @param {object} response
11-
* @returns response
12-
*/
13-
const handleClaimsChallenge = async (account, response, apiEndpoint) => {
14-
if (response.status === 200) {
15-
return response.json();
16-
} else if (response.status === 401) {
17-
if (response.headers.get('www-authenticate')) {
18-
const authenticateHeader = response.headers.get('www-authenticate');
19-
const claimsChallenge = parseChallenges(authenticateHeader);
20-
/**
21-
* This method stores the claim challenge to the session storage in the browser to be used when acquiring a token.
22-
* To ensure that we are fetching the correct claim from the storage, we are using the clientId
23-
* of the application and oid (user’s object id) as the key identifier of the claim with schema
24-
* cc.<clientId>.<oid>.<resource.hostname>
25-
*/
26-
addClaimsToStorage(
27-
claimsChallenge.claims,
28-
`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${new URL(apiEndpoint).hostname}`
29-
);
30-
return { error: 'claims_challenge_occurred', payload: claimsChallenge.claims };
31-
}
32-
33-
throw new Error(`Unauthorized: ${response.status}`);
34-
} else {
35-
throw new Error(`Something went wrong with the request: ${response.status}`);
36-
}
37-
};
38-
39-
/**
40-
* This method parses WWW-Authenticate authentication headers
41-
* @param header
42-
* @return {Object} challengeMap
43-
*/
44-
const parseChallenges = (header) => {
45-
const schemeSeparator = header.indexOf(' ');
46-
const challenges = header.substring(schemeSeparator + 1).split(',');
47-
const challengeMap = {};
48-
49-
challenges.forEach((challenge) => {
50-
const [key, value] = challenge.split('=');
51-
challengeMap[key.trim()] = window.decodeURI(value.replace(/['"]+/g, ''));
52-
});
53-
54-
return challengeMap;
55-
};
56-
576
/**
587
* This method calls the Graph API by utilizing the graph client instance.
598
* @param {String} username
@@ -74,6 +23,7 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
7423
.api(uri)
7524
.responseType('raw')
7625
.get();
26+
7727
response = await handleClaimsChallenge(account, response, uri);
7828
if (response && response.error === 'claims_challenge_occurred') throw response.error;
7929
updateUI(response, uri);
@@ -82,12 +32,12 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
8232
const resource = new URL(uri).hostname;
8333
const claims =
8434
account &&
85-
getClaimsFromStorage(`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${resource}`)
35+
getClaimsFromStorage(`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${resource}`)
8636
? window.atob(
87-
getClaimsFromStorage(
88-
`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${resource}`
89-
)
90-
)
37+
getClaimsFromStorage(
38+
`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${resource}`
39+
)
40+
)
9141
: undefined; // e.g {"access_token":{"xms_cc":{"values":["cp1"]}}}
9242
let request = {
9343
account: account,
@@ -96,7 +46,7 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
9646
};
9747
switch (interactionType) {
9848
case msal.InteractionType.Popup:
99-
49+
10050
await myMSALObj.acquireTokenPopup({
10151
...request,
10252
redirectUri: '/redirect',
@@ -117,10 +67,53 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
11767
}
11868
}
11969

120-
// exporting config object for jest
121-
if (typeof exports !== 'undefined') {
122-
module.exports = {
123-
handleClaimsChallenge: handleClaimsChallenge,
124-
callGraph: callGraph,
125-
};
126-
}
70+
/**
71+
* This method inspects the HTTPS response from a fetch call for the "www-authenticate header"
72+
* If present, it grabs the claims challenge from the header and store it in the localStorage
73+
* For more information, visit: https://docs.microsoft.com/en-us/azure/active-directory/develop/claims-challenge#claims-challenge-header-format
74+
* @param {object} response
75+
* @returns response
76+
*/
77+
const handleClaimsChallenge = async (account, response, apiEndpoint) => {
78+
if (response.status === 200) {
79+
return response.json();
80+
} else if (response.status === 401) {
81+
if (response.headers.get('WWW-Authenticate')) {
82+
const authenticateHeader = response.headers.get('WWW-Authenticate');
83+
const claimsChallenge = parseChallenges(authenticateHeader);
84+
/**
85+
* This method stores the claim challenge to the session storage in the browser to be used when acquiring a token.
86+
* To ensure that we are fetching the correct claim from the storage, we are using the clientId
87+
* of the application and oid (user’s object id) as the key identifier of the claim with schema
88+
* cc.<clientId>.<oid>.<resource.hostname>
89+
*/
90+
addClaimsToStorage(
91+
claimsChallenge.claims,
92+
`cc.${msalConfig.auth.clientId}.${account.idTokenClaims.oid}.${new URL(apiEndpoint).hostname}`
93+
);
94+
return { error: 'claims_challenge_occurred', payload: claimsChallenge.claims };
95+
}
96+
97+
throw new Error(`Unauthorized: ${response.status}`);
98+
} else {
99+
throw new Error(`Something went wrong with the request: ${response.status}`);
100+
}
101+
};
102+
103+
/**
104+
* This method parses WWW-Authenticate authentication headers
105+
* @param header
106+
* @return {Object} challengeMap
107+
*/
108+
const parseChallenges = (header) => {
109+
const schemeSeparator = header.indexOf(' ');
110+
const challenges = header.substring(schemeSeparator + 1).split(', ');
111+
const challengeMap = {};
112+
113+
challenges.forEach((challenge) => {
114+
const [key, value] = challenge.split('=');
115+
challengeMap[key.trim()] = window.decodeURI(value.replace(/(^"|"$)/g, ''));
116+
});
117+
118+
return challengeMap;
119+
}

2-Authorization-I/1-call-graph/App/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<body>
3636
<nav class="navbar navbar-expand-lg navbar-dark bg-primary navbarStyle">
3737
<a class="navbar-brand" href="/">Microsoft identity platform</a>
38-
<div class="collapse navbar-collapse justify-content-end">
38+
<div class="navbar navbar-collapse justify-content-end">
3939
<button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()">Sign In</button>
4040
<div class="dropdown">
4141
<button
@@ -66,7 +66,7 @@ <h5 class="card-header text-center">Vanilla JavaScript SPA calling MS Graph API
6666
<div class="card text-center">
6767
<div class="card-body">
6868
<h5 class="card-title" id="WelcomeMessage">
69-
Please sign-in to see your profile and read your mails
69+
Please sign-in to see your profile and contacts
7070
</h5>
7171
<div id="profile-div"></div>
7272
<br />
@@ -100,7 +100,7 @@ <h5 class="modal-title" id="exampleModalLabel">Set active account</h5>
100100
</div>
101101
<div class="modal-body">
102102
<ul class="list-group" id="list-group">
103-
<li class="list-group-item" onclick="addAnotherAccount(event)">Add Another account</li>
103+
<li class="list-group-item" onclick="addAnotherAccount(event)">Add another account</li>
104104
</ul>
105105
</div>
106106
<div class="modal-footer">

2-Authorization-I/1-call-graph/App/redirect.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@
33
we recommend setting the redirectUri to a blank page or a page that does not implement MSAL.
44
For more information, please follow this link:
55
https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/login-user.md#redirecturi-considerations
6-
-->
7-
<h1>MSAL Redirect</h1>
6+
-->

2-Authorization-I/1-call-graph/App/signout.html

Lines changed: 0 additions & 19 deletions
This file was deleted.

2-Authorization-I/1-call-graph/App/ui.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ function showWelcomeMessage(username, accounts) {
1414
signInButton.style.visibility = 'hidden';
1515
welcomeDiv.innerHTML = `Welcome ${username}`;
1616
dropdownButton.setAttribute('style', 'display:inline !important; visibility:visible');
17-
dropdownButton.innerHTML = username;
17+
dropdownButton.innerHTML = username;
1818
accounts.forEach(account => {
1919
let item = document.getElementById(account.username);
20-
if(!item) {
20+
if (!item) {
2121
const listItem = document.createElement('li');
2222
listItem.setAttribute('onclick', 'addAnotherAccount(event)');
2323
listItem.setAttribute('id', account.username);
2424
listItem.innerHTML = account.username;
2525
if (account.username === username) {
2626
listItem.setAttribute('class', 'list-group-item active');
27-
}else {
27+
} else {
2828
listItem.setAttribute('class', 'list-group-item');
2929
}
3030
listGroup.appendChild(listItem);
31-
}else {
31+
} else {
3232
if (account.username === username) {
3333
item.setAttribute('class', 'list-group-item active');
3434
} else {
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
/**
2-
* This method stores the claim challenge to the localStorage in the browser to be used when acquiring a token
2+
* This method stores the claim challenge to the localStorage in the browser to be used when acquiring a token
33
* @param {String} claimsChallenge
44
*/
55
const addClaimsToStorage = (claimsChallenge, claimsChallengeId) => {
66
sessionStorage.setItem(claimsChallengeId, claimsChallenge);
77
};
88

9+
/**
10+
* This method retrieves the claims challenge from the localStorage
11+
* @param {string} claimsChallengeId
12+
* @returns
13+
*/
914
const getClaimsFromStorage = (claimsChallengeId) => {
1015
return sessionStorage.getItem(claimsChallengeId);
1116
};
@@ -20,13 +25,3 @@ const clearStorage = (account) => {
2025
sessionStorage.removeItem(key);
2126
}
2227
};
23-
24-
25-
// exporting config object for jest
26-
if (typeof exports !== 'undefined') {
27-
module.exports = {
28-
addClaimsToStorage: addClaimsToStorage,
29-
getClaimsFromStorage: getClaimsFromStorage,
30-
clearStorage: clearStorage,
31-
};
32-
}

2-Authorization-I/1-call-graph/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ To manually register the apps, as a first step you'll need to:
152152
1. Select the **Add a permission** button and then:
153153
1. Ensure that the **Microsoft APIs** tab is selected.
154154
1. In the *Commonly used Microsoft APIs* section, select **Microsoft Graph**
155-
* Since this app signs-in users, we will now proceed to select **delegated permissions**, which is requested by apps that signs-in users.
156-
* In the **Delegated permissions** section, select **User.Read**, **Contacts.Read** in the list. Use the search box if necessary.
155+
1. In the **Delegated permissions** section, select **User.Read**, **Contacts.Read** in the list. Use the search box if necessary.
157156
1. Select the **Add permissions** button at the bottom.
158157

159158
##### Configure Optional Claims

0 commit comments

Comments
 (0)