1-
2- var graphAPIMeEndpoint = "https://graph.microsoft.com/v1.0/me" ;
1+ // Graph API endpoint to show user profile
2+ var graphApiEndpoint = "https://graph.microsoft.com/v1.0/me" ;
3+
4+ // Graph API scope used to obtain the access token to read user profile
35var graphAPIScopes = [ "https://graph.microsoft.com/user.read" ] ;
46
57// Initialize application
6- var userAgentApplication = new Msal . UserAgentApplication ( msalconfig . clientID , null , displayUserInfo , {
8+ var userAgentApplication = new Msal . UserAgentApplication ( msalconfig . clientID , null , loginCallback , {
79 redirectUri : msalconfig . redirectUri
810} ) ;
911
1012//Previous version of msal uses redirect url via a property
11- if ( userAgentApplication . redirectUri ) userAgentApplication . redirectUri = msalconfig . redirectUri ;
13+ if ( userAgentApplication . redirectUri ) {
14+ userAgentApplication . redirectUri = msalconfig . redirectUri ;
15+ }
1216
13- var user = userAgentApplication . getUser ( ) ;
1417window . onload = function ( ) {
15- //Add support to display user info in case of reload of the page
18+ // If page is refreshed, continue to display user info
1619 if ( ! userAgentApplication . isCallback ( window . location . hash ) && window . parent === window && ! window . opener ) {
20+ var user = userAgentApplication . getUser ( ) ;
1721 if ( user ) {
18- displayUserInfo ( ) ;
22+ callGraphApi ( ) ;
1923 }
2024 }
21-
2225}
2326
24- /**
25- * Display the results from Web API call in json format
26- *
27- * @param {object } data - Results from API call
28- * @param {object } token - The access token
29- * @param {object } responseElement - HTML element to show the results
30- * @param {object } showTokenElement - HTML element to show the RAW token
31- */
32- function showAPIResponse ( data , token , responseElement , showTokenElement ) {
33- console . log ( data ) ;
34- responseElement . innerHTML = JSON . stringify ( data , null , 4 ) ;
35- if ( showTokenElement ) {
36- showTokenElement . parentElement . classList . remove ( "hidden" ) ;
37- showTokenElement . innerHTML = token ;
38- }
39- }
40-
41- /**
42- * Show an error message in the page
43- * @param {any } endpoint - the endpoint used for the error message
44- * @param {any } error - the error string
45- * @param {any } errorElement - the HTML element in the page to display the error
46- */
47- function showError ( endpoint , error , errorElement ) {
48- console . error ( error ) ;
49- var formattedError = JSON . stringify ( error , null , 4 ) ;
50- if ( formattedError . length < 3 ) {
51- formattedError = error ;
52- }
53- errorElement . innerHTML = "Error calling " + endpoint + ": " + formattedError ;
54- }
5527
5628/**
57- * Displays user information based on the information contained in the id token
58- * And also calls the method to display the user profile via Microsoft Graph API
29+ * Call the Microsoft Graph API and display the results on the page
5930 */
60- function displayUserInfo ( ) {
31+ function callGraphApi ( ) {
6132 var user = userAgentApplication . getUser ( ) ;
6233 if ( ! user ) {
63- //If user is not signed in, then prompt user to sing-in via loginRedirect
34+ // If user is not signed in, then prompt user to sign in via loginRedirect.
35+ // This will redirect user to the Azure Active Directory v2 Endpoint
6436 userAgentApplication . loginRedirect ( graphAPIScopes ) ;
37+
38+ // The call to loginRedirect above frontloads the consent to query Graph API during the sign-in.
39+ // If you want to use dynamic consent, just remove the graphAPIScopes from loginRedirect call:
40+ // As such, user will be prompted to give consent as soon as the token for a resource that
41+ // he/she hasn't consented before is requested. In the case of this application -
42+ // the first time the Graph API call to obtain user's profile is executed.
6543 } else {
44+
6645 // If user is already signed in, display the user info
6746 var userInfoElement = document . getElementById ( "userInfo" ) ;
6847 userInfoElement . parentElement . classList . remove ( "hidden" ) ;
@@ -71,59 +50,60 @@ function displayUserInfo() {
7150 // Show Sign-Out button
7251 document . getElementById ( "signOutButton" ) . classList . remove ( "hidden" ) ;
7352
74- //Now Call Graph API to show the user profile information
75- callGraphAPI ( ) ;
53+ // Now Call Graph API to show the user profile information:
54+ var graphCallResponseElement = document . getElementById ( "graphResponse" ) ;
55+ graphCallResponseElement . parentElement . classList . remove ( "hidden" ) ;
56+ graphCallResponseElement . innerText = "Calling Graph ..." ;
57+
58+ // In order to call the Graph API, an access token needs to be acquired.
59+ // Try to acquire the token used to Query Graph API silently first
60+ userAgentApplication . acquireTokenSilent ( graphAPIScopes )
61+ . then ( function ( token ) {
62+ //After the access token is acquired, call the Web API, sending the acquired token
63+ callWebApiWithToken ( graphApiEndpoint , token , graphCallResponseElement , document . getElementById ( "accessToken" ) ) ;
64+
65+ } , function ( error ) {
66+ // If the acquireTokenSilent() method fails, then acquire the token interactively via acquireTokenRedirect().
67+ // In this case, the browser will redirect user back to the Azure Active Directory v2 Endpoint so the user
68+ // can re-type the current username and password and/ or give consent to new permissions your application is requesting.
69+ // After authentication/ authorization completes, this page will be reloaded again and callGraphApi() will be called.
70+ // Then, acquireTokenSilent will then acquire the token silently, the Graph API call results will be made and results will be displayed in the page.
71+ if ( error ) {
72+ userAgentApplication . acquireTokenRedirect ( graphAPIScopes ) ;
73+ }
74+ } ) ;
75+
7676 }
7777}
7878
7979/**
80- * Call the Microsoft Graph API and display the results on the page
80+ * Show an error message in the page
81+ * @param {string } endpoint - the endpoint used for the error message
82+ * @param {string } error - the error string
83+ * @param {object } errorElement - the HTML element in the page to display the error
8184 */
82- function callGraphAPI ( ) {
83- var user = userAgentApplication . getUser ( ) ;
84- if ( user ) {
85- var responseElement = document . getElementById ( "graphResponse" ) ;
86- responseElement . parentElement . classList . remove ( "hidden" ) ;
87- responseElement . innerText = "Calling Graph ..." ;
88- callWebApiWithScope ( graphAPIMeEndpoint ,
89- graphAPIScopes ,
90- responseElement ,
91- document . getElementById ( "errorMessage" ) ,
92- document . getElementById ( "accessToken" ) ) ;
93- } else {
94- showError ( graphAPIMeEndpoint , "User has not signed-in" , document . getElementById ( "errorMessage" ) ) ;
85+ function showError ( endpoint , error , errorDesc ) {
86+ var formattedError = JSON . stringify ( error , null , 4 ) ;
87+ if ( formattedError . length < 3 ) {
88+ formattedError = error ;
9589 }
90+ document . getElementById ( "errorMessage" ) . innerHTML = "An error has occurred:<br/>Endpoint: " + endpoint + "<br/>Error: " + formattedError + "<br/>" + errorDesc ;
91+ console . error ( error ) ;
9692}
9793
9894/**
99- * Call a Web API that requires scope, then display the response
100- *
101- * @param {string } endpoint - The Web API endpoint
102- * @param {object } scope - An array containing the API scopes
103- * @param {object } responseElement - HTML element used to display the results
104- * @param {object } errorElement = HTML element used to display an error message
105- * @param {object } showTokenElement = HTML element used to display the RAW access token
95+ * Callback method from sign-in: if no errors, call callGraphApi() to show results.
96+ * @param {string } errorDesc - If error occur, the error message
97+ * @param {object } token - The token received from login
98+ * @param {object } error - The error
99+ * @param {string } tokenType - the token type: usually id_token
106100 */
107- function callWebApiWithScope ( endpoint , scope , responseElement , errorElement , showTokenElement ) {
108- //Try to acquire the token silently first
109- userAgentApplication . acquireTokenSilent ( scope )
110- . then ( function ( token ) {
111- //After the access token is acquired, call the Web API, sending the acquired token
112- callWebApiWithToken ( endpoint , token , responseElement , errorElement , showTokenElement ) ;
113- } , function ( error ) {
114- //If the acquireTokenSilent fails, then acquire the token interactively via acquireTokenPopup
115- if ( error ) {
116- userAgentApplication . acquireTokenPopup ( scope ) . then ( function ( token ) {
117- //After the access token is acquired, call the Web API, sending the acquired token
118- callWebApiWithToken ( endpoint , token , responseElement , errorElement , showTokenElement ) ;
119- } ,
120- function ( error ) {
121- showError ( endpoint , error , errorElement ) ;
122- } ) ;
123- } else {
124- showError ( endpoint , error , errorElement ) ;
125- }
126- } ) ;
101+ function loginCallback ( errorDesc , token , error , tokenType ) {
102+ if ( errorDesc ) {
103+ showError ( msal . authority , error , errorDesc ) ;
104+ } else {
105+ callGraphApi ( ) ;
106+ }
127107}
128108
129109/**
@@ -132,10 +112,9 @@ function callWebApiWithScope(endpoint, scope, responseElement, errorElement, sho
132112 * @param {any } endpoint - Web API endpoint
133113 * @param {any } token - Access token
134114 * @param {object } responseElement - HTML element used to display the results
135- * @param {object } errorElement = HTML element used to display an error message
136115 * @param {object } showTokenElement = HTML element used to display the RAW access token
137116 */
138- function callWebApiWithToken ( endpoint , token , responseElement , errorElement , showTokenElement ) {
117+ function callWebApiWithToken ( endpoint , token , responseElement , showTokenElement ) {
139118 var headers = new Headers ( ) ;
140119 var bearer = "Bearer " + token ;
141120 headers . append ( "Authorization" , bearer ) ;
@@ -144,35 +123,40 @@ function callWebApiWithToken(endpoint, token, responseElement, errorElement, sho
144123 headers : headers
145124 } ;
146125
147- // Note that fetch API is not available in all browsers
148126 fetch ( endpoint , options )
149127 . then ( function ( response ) {
150128 var contentType = response . headers . get ( "content-type" ) ;
151129 if ( response . status === 200 && contentType && contentType . indexOf ( "application/json" ) !== - 1 ) {
152130 response . json ( )
153131 . then ( function ( data ) {
154132 // Display response in the page
155- showAPIResponse ( data , token , responseElement , showTokenElement ) ;
133+ console . log ( data ) ;
134+ responseElement . innerHTML = JSON . stringify ( data , null , 4 ) ;
135+ if ( showTokenElement ) {
136+ showTokenElement . parentElement . classList . remove ( "hidden" ) ;
137+ showTokenElement . innerHTML = token ;
138+ }
156139 } )
157140 . catch ( function ( error ) {
158- showError ( endpoint , error , errorElement ) ;
141+ showError ( endpoint , error ) ;
159142 } ) ;
160143 } else {
161144 response . json ( )
162145 . then ( function ( data ) {
163- // Display response in the page
164- showError ( endpoint , data , errorElement ) ;
146+ // Display response as error in the page
147+ showError ( endpoint , data ) ;
165148 } )
166149 . catch ( function ( error ) {
167- showError ( endpoint , error , errorElement ) ;
150+ showError ( endpoint , error ) ;
168151 } ) ;
169152 }
170153 } )
171154 . catch ( function ( error ) {
172- showError ( endpoint , error , errorElement ) ;
155+ showError ( endpoint , error ) ;
173156 } ) ;
174157}
175158
159+
176160/**
177161 * Sign-out the user
178162 */
0 commit comments