/
authRedirect.js
177 lines (147 loc) · 6.05 KB
/
authRedirect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);
let accountId = "";
let username = "";
let accessToken = null;
myMSALObj.handleRedirectPromise()
.then(response => {
if (response) {
/**
* For the purpose of setting an active account for UI update, we want to consider only the auth response resulting
* from SUSI flow. "tfp" claim in the id token tells us the policy (NOTE: legacy policies may use "acr" instead of "tfp").
* To learn more about B2C tokens, visit https://docs.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview
*/
if (response.idTokenClaims['tfp'].toUpperCase() === b2cPolicies.names.signUpSignIn.toUpperCase()) {
handleResponse(response);
}
}
})
.catch(error => {
console.log(error);
});
function setAccount(account) {
accountId = account.homeAccountId;
username = account.username;
welcomeUser(username);
}
function selectAccount() {
/**
* See here for more information on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
const currentAccounts = myMSALObj.getAllAccounts();
if (currentAccounts.length < 1) {
return;
} else if (currentAccounts.length > 1) {
/**
* Due to the way MSAL caches account objects, the auth response from initiating a user-flow
* is cached as a new account, which results in more than one account in the cache. Here we make
* sure we are selecting the account with homeAccountId that contains the sign-up/sign-in user-flow,
* as this is the default flow the user initially signed-in with.
*/
const accounts = currentAccounts.filter(account =>
account.homeAccountId.toUpperCase().includes(b2cPolicies.names.signUpSignIn.toUpperCase())
&&
account.idTokenClaims.iss.toUpperCase().includes(b2cPolicies.authorityDomain.toUpperCase())
&&
account.idTokenClaims.aud === msalConfig.auth.clientId
);
if (accounts.length > 1) {
// localAccountId identifies the entity for which the token asserts information.
if (accounts.every(account => account.localAccountId === accounts[0].localAccountId)) {
// All accounts belong to the same user
setAccount(accounts[0]);
} else {
// Multiple users detected. Logout all to be safe.
signOut();
};
} else if (accounts.length === 1) {
setAccount(accounts[0]);
}
} else if (currentAccounts.length === 1) {
setAccount(currentAccounts[0]);
}
}
// in case of page refresh
selectAccount();
async function handleResponse(response) {
/**
* To see the full list of response object properties, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
*/
if (response !== null) {
setAccount(response.account);
} else {
selectAccount();
}
}
function signIn() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
myMSALObj.loginRedirect(loginRequest);
}
function signOut() {
/**
* You can pass a custom request object below. This will override the initial configuration. For more information, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
*/
const logoutRequest = {
postLogoutRedirectUri: msalConfig.auth.redirectUri,
};
myMSALObj.logoutRedirect(logoutRequest);
}
function getTokenRedirect(request) {
/**
* See here for more info on account retrieval:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
*/
request.account = myMSALObj.getAccountByHomeId(accountId);
/**
*
*/
return myMSALObj.acquireTokenSilent(request)
.then((response) => {
// In case the response from B2C server has an empty accessToken field
// throw an error to initiate token acquisition
if (!response.accessToken || response.accessToken === "") {
throw new msal.InteractionRequiredAuthError;
} else {
console.log("access_token acquired at: " + new Date().toString());
accessToken = response.accessToken;
passTokenToApi();
}
}).catch(error => {
console.log("Silent token acquisition fails. Acquiring token using popup. \n", error);
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
return myMSALObj.acquireTokenRedirect(request);
} else {
console.log(error);
}
});
}
// Acquires and access token and then passes it to the API call
function passTokenToApi() {
if (!accessToken) {
getTokenRedirect(tokenRequest);
} else {
try {
callApi(apiConfig.webApi, accessToken);
} catch(error) {
console.log(error);
}
}
}
/**
* To initiate a B2C user-flow, simply make a login request using
* the full authority string of that user-flow e.g.
* https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/B2C_1_edit_profile_v2
*/
function editProfile() {
const editProfileRequest = b2cPolicies.authorities.editProfile;
editProfileRequest.loginHint = myMSALObj.getAccountByHomeId(accountId).username;
myMSALObj.loginRedirect(editProfileRequest);
}