3
3
* Licensed under the MIT License.
4
4
*/
5
5
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
-
57
6
/**
58
7
* This method calls the Graph API by utilizing the graph client instance.
59
8
* @param {String } username
@@ -74,6 +23,7 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
74
23
. api ( uri )
75
24
. responseType ( 'raw' )
76
25
. get ( ) ;
26
+
77
27
response = await handleClaimsChallenge ( account , response , uri ) ;
78
28
if ( response && response . error === 'claims_challenge_occurred' ) throw response . error ;
79
29
updateUI ( response , uri ) ;
@@ -82,12 +32,12 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
82
32
const resource = new URL ( uri ) . hostname ;
83
33
const claims =
84
34
account &&
85
- getClaimsFromStorage ( `cc.${ msalConfig . auth . clientId } .${ account . idTokenClaims . oid } .${ resource } ` )
35
+ getClaimsFromStorage ( `cc.${ msalConfig . auth . clientId } .${ account . idTokenClaims . oid } .${ resource } ` )
86
36
? 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
+ )
91
41
: undefined ; // e.g {"access_token":{"xms_cc":{"values":["cp1"]}}}
92
42
let request = {
93
43
account : account ,
@@ -96,7 +46,7 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
96
46
} ;
97
47
switch ( interactionType ) {
98
48
case msal . InteractionType . Popup :
99
-
49
+
100
50
await myMSALObj . acquireTokenPopup ( {
101
51
...request ,
102
52
redirectUri : '/redirect' ,
@@ -117,10 +67,53 @@ const callGraph = async (username, scopes, uri, interactionType, myMSALObj) => {
117
67
}
118
68
}
119
69
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
+ }
0 commit comments