Skip to content

Commit ab1dd11

Browse files
author
sachin-maheshwari
authored
Merge pull request #53 from topcoder-platform/dev
Changes for custom domain
2 parents 5875cd1 + b55efe9 commit ab1dd11

File tree

5 files changed

+505
-109
lines changed

5 files changed

+505
-109
lines changed

src/connector-wrapper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ const proxyCall = function() {
5353
iframe.contentWindow.postMessage(payload, url)
5454
}) */
5555
return new Promise((resolve, reject) => {
56-
const token = getToken('tcjwt')
57-
token ? resolve({ token: token }) : reject("tcjwt cookie not found")
56+
const token = getToken('v3jwt')
57+
token ? resolve({ token: token }) : reject("v3jwt cookie not found")
5858
})
5959
}
6060

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
var script = document.createElement('script');
2+
script.src = "https://cdn.auth0.com/js/auth0-spa-js/1.10/auth0-spa-js.production.js";
3+
script.type = 'text/javascript';
4+
script.defer = true;
5+
document.getElementsByTagName('head').item(0).appendChild(script);
6+
7+
/**
8+
* read query string
9+
*
10+
*/
11+
const qs = (function (a) {
12+
if (a == "") return {};
13+
let b = {};
14+
for (let i = 0; i < a.length; ++i) {
15+
let p = a[i].split('=', 2);
16+
if (p.length == 1)
17+
b[p[0]] = "";
18+
else
19+
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
20+
}
21+
return b;
22+
})(window.location.search.substr(1).split('&'));
23+
24+
const authSetup = function () {
25+
26+
let domain = 'auth.topcoder-dev.com';
27+
const clientId = 'BXWXUWnilVUPdN01t2Se29Tw2ZYNGZvH';
28+
const useLocalStorage = false;
29+
const useRefreshTokens = false;
30+
const v3JWTCookie = 'v3jwt';
31+
const tcJWTCookie = 'tcjwt';
32+
const tcSSOCookie = 'tcsso';
33+
const cookieExpireIn = 12 * 60; // 12 hrs
34+
const refreshTokenInterval = 60000; // in milliseconds
35+
const refreshTokenOffset = 65; // in seconds
36+
const shouldLogout = qs['logout'];
37+
const regSource = qs['regSource'];
38+
const utmSource = qs['utm_source'];
39+
const utmMedium = qs['utm_medium'];
40+
const utmCampaign = qs['utm_campaign'];
41+
const appUrl = qs['appUrl'] || false;
42+
const loggerMode = "dev";
43+
const IframeLogoutRequestType = "LOGOUT_REQUEST";
44+
const enterpriseCustomers = ['wipro', 'topgear', 'zurich', 'cs'];
45+
let returnAppUrl = qs['retUrl'];
46+
47+
if (utmSource &&
48+
(utmSource != 'undefined') &&
49+
(enterpriseCustomers.indexOf(utmSource) > -1)) {
50+
domain = "topcoder-dev.auth0.com";
51+
returnAppUrl += '&utm_source=' + utmSource;
52+
}
53+
54+
55+
var auth0 = null;
56+
var isAuthenticated = false;
57+
var idToken = null;
58+
var callRefreshTokenFun = null;
59+
var host = window.location.protocol + "//" + window.location.host
60+
const registerSuccessUrl = host + '/register_success.html';
61+
62+
const init = function () {
63+
correctOldUrl();
64+
createAuth0Client({
65+
domain: domain,
66+
client_id: clientId,
67+
cacheLocation: useLocalStorage
68+
? 'localstorage'
69+
: 'memory',
70+
useRefreshTokens: useRefreshTokens
71+
}).then(_init);
72+
window.addEventListener("message", receiveMessage, false);
73+
};
74+
75+
const _init = function (authObj) {
76+
auth0 = authObj
77+
if (qs['code'] && qs['state']) {
78+
auth0.handleRedirectCallback().then(function (data) {
79+
logger('handleRedirectCallback() success: ', data);
80+
showAuth0Info();
81+
storeToken();
82+
}).catch(function (e) {
83+
logger('handleRedirectCallback() error: ', e);
84+
});
85+
} else if (shouldLogout) {
86+
host = returnAppUrl ? returnAppUrl : host;
87+
logout();
88+
return;
89+
} else if (!isLoggedIn() && returnAppUrl) {
90+
login();
91+
} else {
92+
logger("User already logged in", true);
93+
postLogin();
94+
}
95+
showAuthenticated();
96+
};
97+
98+
const showAuthenticated = function () {
99+
auth0.isAuthenticated().then(function (isAuthenticated) {
100+
isAuthenticated = isAuthenticated;
101+
logger("_init:isAuthenticated", isAuthenticated);
102+
});
103+
};
104+
105+
const refreshToken = function () {
106+
let d = new Date();
107+
logger('checking token status at: ', `${d.getHours()}::${d.getMinutes()}::${d.getSeconds()} `);
108+
var token = getCookie(tcJWTCookie);
109+
if (!token || isTokenExpired(token)) {
110+
logger('refreshing token... at: ', `${d.getHours()}::${d.getMinutes()}::${d.getSeconds()} `);
111+
auth0.getTokenSilently().then(function (token) {
112+
showAuth0Info();
113+
storeToken();
114+
}).catch(function (e) {
115+
logger("Error in refreshing token: ", e)
116+
if (e.error && ((e.error == "login_required") || (e.error == "timeout"))) {
117+
clearInterval(callRefreshTokenFun);
118+
}
119+
}
120+
);
121+
}
122+
};
123+
124+
const showAuth0Info = function () {
125+
auth0.getUser().then(function (user) {
126+
logger("User Profile: ", user);
127+
});
128+
auth0.getIdTokenClaims().then(function (claims) {
129+
idToken = claims.__raw;
130+
logger("JWT Token: ", idToken);
131+
});
132+
};
133+
134+
const login = function () {
135+
auth0
136+
.loginWithRedirect({
137+
redirect_uri: host + '?appUrl=' + returnAppUrl,
138+
regSource: regSource,
139+
utmSource: utmSource,
140+
utmCampaign: utmCampaign,
141+
utmMedium: utmMedium,
142+
returnUrl: returnAppUrl
143+
})
144+
.then(function () {
145+
auth0.isAuthenticated().then(function (isAuthenticated) {
146+
isAuthenticated = isAuthenticated;
147+
if (isAuthenticated) {
148+
showAuth0Info();
149+
storeToken();
150+
postLogin();
151+
}
152+
});
153+
});
154+
};
155+
156+
const logout = function () {
157+
auth0.logout({
158+
returnTo: host
159+
});
160+
// TODO
161+
setCookie(tcJWTCookie, "", -1);
162+
setCookie(v3JWTCookie, "", -1);
163+
setCookie(tcSSOCookie, "", -1);
164+
};
165+
166+
const isLoggedIn = function () {
167+
var token = getCookie(tcJWTCookie);
168+
return token ? !isTokenExpired(token) : false;
169+
};
170+
171+
const redirectToApp = function () {
172+
logger("redirect to app", appUrl);
173+
if (appUrl) {
174+
window.location = appUrl;
175+
}
176+
};
177+
178+
const postLogin = function () {
179+
if (isLoggedIn() && returnAppUrl) {
180+
auth0.isAuthenticated().then(function (isAuthenticated) {
181+
if (isAuthenticated) {
182+
window.location = returnAppUrl;
183+
} else {
184+
login(); // old session exist case
185+
}
186+
});
187+
}
188+
logger('calling postLogin: ', true);
189+
logger('callRefreshTokenFun: ', callRefreshTokenFun);
190+
if (callRefreshTokenFun != null) {
191+
clearInterval(callRefreshTokenFun);
192+
}
193+
refreshToken();
194+
callRefreshTokenFun = setInterval(refreshToken, refreshTokenInterval);
195+
}
196+
197+
const storeToken = function () {
198+
auth0.getIdTokenClaims().then(function (claims) {
199+
idToken = claims.__raw;
200+
let userActive = false;
201+
Object.keys(claims).findIndex(function (key) {
202+
if (key.includes('active')) {
203+
userActive = claims[key];
204+
return true;
205+
}
206+
return false;
207+
});
208+
if (userActive) {
209+
let tcsso = '';
210+
Object.keys(claims).findIndex(function (key) {
211+
if (key.includes(tcSSOCookie)) {
212+
tcsso = claims[key];
213+
return true;
214+
}
215+
return false;
216+
});
217+
logger('Storing token...', true);
218+
setCookie(tcJWTCookie, idToken, cookieExpireIn);
219+
setCookie(v3JWTCookie, idToken, cookieExpireIn);
220+
setCookie(tcSSOCookie, tcsso, cookieExpireIn);
221+
redirectToApp();
222+
} else {
223+
logger("User active ? ", userActive);
224+
host = registerSuccessUrl;
225+
logout();
226+
}
227+
}).catch(function (e) {
228+
logger("Error in fetching token from auth0: ", e);
229+
});
230+
};
231+
232+
/////// Token.js
233+
234+
function getTokenExpirationDate(token) {
235+
const decoded = decodeToken(token);
236+
if (typeof decoded.exp === 'undefined') {
237+
return null;
238+
}
239+
const d = new Date(0); // The 0 here is the key, which sets the date to the epoch
240+
d.setUTCSeconds(decoded.exp);
241+
return d;
242+
}
243+
244+
function decodeToken(token) {
245+
const parts = token.split('.');
246+
247+
if (parts.length !== 3) {
248+
throw new Error('The token is invalid');
249+
}
250+
251+
const decoded = urlBase64Decode(parts[1])
252+
253+
if (!decoded) {
254+
throw new Error('Cannot decode the token');
255+
}
256+
257+
// covert base64 token in JSON object
258+
let t = JSON.parse(decoded);
259+
return t;
260+
}
261+
262+
function isTokenExpired(token, offsetSeconds = refreshTokenOffset) {
263+
const d = getTokenExpirationDate(token)
264+
265+
if (d === null) {
266+
return false;
267+
}
268+
269+
// Token expired?
270+
return !(d.valueOf() > (new Date().valueOf() + (offsetSeconds * 1000)));
271+
}
272+
273+
function urlBase64Decode(str) {
274+
let output = str.replace(/-/g, '+').replace(/_/g, '/')
275+
276+
switch (output.length % 4) {
277+
case 0:
278+
break;
279+
280+
case 2:
281+
output += '=='
282+
break;
283+
284+
case 3:
285+
output += '='
286+
break;
287+
288+
default:
289+
throw 'Illegal base64url string!';
290+
}
291+
return decodeURIComponent(escape(atob(output))); //polyfill https://github.com/davidchambers/Base64.js
292+
}
293+
294+
function setCookie(cname, cvalue, exMins) {
295+
const cdomain = getHostDomain();
296+
297+
let d = new Date();
298+
d.setTime(d.getTime() + (exMins * 60 * 1000));
299+
300+
let expires = ";expires=" + d.toUTCString();
301+
document.cookie = cname + "=" + cvalue + cdomain + expires + ";path=/";
302+
}
303+
304+
function getCookie(name) {
305+
const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
306+
return v ? v[2] : undefined;
307+
}
308+
// end token.js
309+
310+
function getHostDomain() {
311+
let hostDomain = "";
312+
if (location.hostname !== 'localhost') {
313+
hostDomain = ";domain=." +
314+
location.hostname.split('.').reverse()[1] +
315+
"." + location.hostname.split('.').reverse()[0];
316+
}
317+
return hostDomain;
318+
}
319+
320+
function correctOldUrl() {
321+
const pattern = '#!/member';
322+
const sso_pattern = '/#!/sso-login';
323+
const logout_pattern = '/#!/logout?';
324+
325+
if (window.location.href.indexOf(pattern) > -1) {
326+
window.location.href = window.location.href.replace(pattern, '');
327+
}
328+
329+
if (window.location.href.indexOf(sso_pattern) > -1) {
330+
window.location.href = window.location.href.replace(sso_pattern, '');
331+
}
332+
333+
if (window.location.href.indexOf(logout_pattern) > -1) {
334+
window.location.href = window.location.href.replace(logout_pattern, '/?logout=true&');
335+
}
336+
}
337+
338+
function logger(label, message) {
339+
if (loggerMode === "dev") {
340+
console.log(label, message);
341+
}
342+
}
343+
344+
/**
345+
* will receive message from iframe
346+
*/
347+
function receiveMessage(e) {
348+
logger("received Event:", e);
349+
if (e.data && e.data.type && e.origin) {
350+
if (e.data.type === IframeLogoutRequestType) {
351+
host = e.origin;
352+
logout();
353+
}
354+
}
355+
356+
}
357+
358+
// execute
359+
init();
360+
};

0 commit comments

Comments
 (0)