PageSourceSearch

https://www.ourbus.com/web_assets/scripts/commutercookie_es5.js?v=1.0.7

js ourbus.com collected 2026-09-24 09:23:59 UTC 10,712 bytes, 421 lines download raw bytes

1(function (root, factory) {
2 if (typeof module === "object" && module.exports) {
3   module.exports = factory(root);
4 } else if (typeof define === "function" && define.amd) {
5   define([], function () {
6     return factory(root);
7   });
8 } else {
9   var api = factory(root);
10   root.CommuterCookies = api;
11   root.callCommuterCookiesAPI = api.callCommuterCookiesAPI;
12 }
13})(typeof self !== "undefined" ? self : this, function (root) {
14 "use strict";
15
16
17 function getAllUrlParams() {
18   var search = window.location.search || "";
19   if (search.length > 1) {
20     return encodeURI(search.substring(1));
21   }
22   return "";
23 }
24
25
26 function getCookie(name) {
27   var value = "; " + document.cookie;
28   var parts = value.split("; " + name + "=");
29   if (parts.length === 2) {
30     return decodeURIComponent(parts.pop().split(";").shift());
31   }
32   return null;
33 }
34
35
36 // ---- retry helpers (NEW) ----
37 function sleep(ms) {
38   return new Promise(function (r) {
39     setTimeout(r, ms);
40   });
41 }
42
43
44 async function retryAsync(fn, opts) {
45   var retries = (opts && opts.retries) != null ? opts.retries : 2; // total extra retries
46   var baseDelayMs =
47     (opts && opts.baseDelayMs) != null ? opts.baseDelayMs : 600;
48   var jitterMs = (opts && opts.jitterMs) != null ? opts.jitterMs : 200;
49
50
51   var lastErr = null;
52
53
54   for (var attempt = 0; attempt <= retries; attempt++) {
55     try {
56       return await fn(attempt);
57     } catch (e) {
58       lastErr = e;
59       if (attempt === retries) break;
60
61
62       var backoff = baseDelayMs * Math.pow(2, attempt);
63       var jitter = Math.floor(Math.random() * jitterMs);
64       await sleep(backoff + jitter);
65     }
66   }
67   throw lastErr;
68 }
69
70
71 function generateUUIDv4() {
72   if (typeof crypto !== "undefined" && crypto.randomUUID) {
73     return crypto.randomUUID();
74   }
75
76
77   let buf;
78   if (typeof crypto !== "undefined" && crypto.getRandomValues) {
79     buf = new Uint8Array(16);
80     crypto.getRandomValues(buf);
81   } else {
82     // Fallback if crypto is not available
83     buf = new Array(16);
84     for (let i = 0; i < 16; i++) {
85       buf[i] = (Math.random() * 256) | 0;
86     }
87   }
88
89
90   // RFC4122 version 4
91   buf[6] = (buf[6] & 0x0f) | 0x40; // version
92   buf[8] = (buf[8] & 0x3f) | 0x80; // variant
93
94
95   const hex = Array.from(buf).map((b) => b.toString(16).padStart(2, "0"));
96
97
98   return (
99     hex.slice(0, 4).join("") +
100     "-" +
101     hex.slice(4, 6).join("") +
102     "-" +
103     hex.slice(6, 8).join("") +
104     "-" +
105     hex.slice(8, 10).join("") +
106     "-" +
107     hex.slice(10, 16).join("")
108   );
109 }
110
111
112 function isTripConfirmationPage() {
113   const path = window.location.pathname || "";
114   console.log(path);
115   // matches: /tripconfirmation and /tripconfirmation/anything
116   return (
117     path === "/tripconfirmation" || path.startsWith("/tripconfirmation/")
118   );
119 }
120
121
122 var SYNC_COOKIE = "commuterCookiesAPISuccess";
123 var COOKIE_LONG_ID = "commuterCookieID";
124
125
126 function readCookieId() {
127   var v = getCookie(COOKIE_LONG_ID);
128   if (v == null || v === "") return null;
129   var n = Number(v);
130   return Number.isFinite(n) ? n : null;
131 }
132
133
134 function writeCookieId(cookieId) {
135   if (cookieId == null) return;
136   setCookie(COOKIE_LONG_ID, String(cookieId));
137 }
138
139
140 function clearCookieId() {
141   deleteCookie(COOKIE_LONG_ID);
142 }
143
144
145 function readCommuterSyncState() {
146   try {
147     var raw = getCookie(SYNC_COOKIE);
148     if (!raw) return null;
149     return JSON.parse(raw);
150   } catch (e) {
151     return null;
152   }
153 }
154
155
156 function writeCommuterSyncState(userId, cookie) {
157   try {
158     // session-only cookie (no days)
159     setCookie(
160       SYNC_COOKIE,
161       JSON.stringify({ userId: userId, cookie: cookie }),
162     );
163   } catch (e) {
164     // ignore
165   }
166 }
167
168
169 function clearCommuterSyncState() {
170   deleteCookie(SYNC_COOKIE);
171 }
172
173
174 function callCommuterCookiesAPI(baseUrl, direct = false) {
175  if(direct) {
176    return syncCommuterCookies(baseUrl, null);
177  }
178
179   var stored = readCommuterSyncState();
180
181
182   var currentUserId = getCookie("_ourbususersessid") ?? "";
183   var currentCookie = getCookie("_ourbussessid");
184
185
186   var alreadySent =
187     isTripConfirmationPage() ||
188     (stored &&
189       typeof stored === "object" &&
190       stored.userId === currentUserId &&
191       stored.cookie === currentCookie);
192
193
194   if (alreadySent) {
195     const profileCookie = getCookie("profile");
196     const txnDone = getCookie("txnDone") === "true";
197     const onTripConfirmation = isTripConfirmationPage();
198
199
200     // NOTE: if profile cookie is JSON string, parse; if it's plain, adapt accordingly
201     let isGuestLogin = false;
202     if (profileCookie) {
203       try {
204         const profileObj = JSON.parse(profileCookie);
205         isGuestLogin = profileObj.isGuestLogin === 1;
206       } catch (e) {
207         // if it's not JSON, you can replace this logic with your actual format
208         // isGuestLogin = profileCookie === "1"; // example fallback
209       }
210     }
211
212
213     if (onTripConfirmation) {
214       setCookie("txnDone", "true");
215       clearCookieId();
216     } else if (isGuestLogin && txnDone && !onTripConfirmation) {
217       // guest user, txn already done, and we are NOT on tripconfirmation anymore
218       // -> clear txn-related cookie
219       clearCookieId();
220       logout();
221       return syncCommuterCookies(baseUrl, readCookieId());
222     } else if (!isGuestLogin && txnDone && !onTripConfirmation) {
223       setCookie("txnDone", "false");
224       // sessionStorage.clear();
225       clearCookieId();
226       clearCommuterSyncState();
227       return syncCommuterCookies(baseUrl, readCookieId());
228     }
229
230
231     return Promise.resolve(null);
232   }
233
234
235   // first time: actually hit backend
236   var previousCookieId = readCookieId();
237   return syncCommuterCookies(baseUrl, previousCookieId);
238 }
239
240
241 function getOrCreateDeviceId() {
242   // deviceId should always be saved in localStorage and fetched from it only.
243   try {
244     var existing = window.localStorage
245       ? window.localStorage.getItem("deviceId")
246       : null;
247     if (existing) {
248       return { deviceId: existing, isNew: false };
249     }
250     var deviceId = generateUUIDv4();
251     if (window.localStorage) {
252       window.localStorage.setItem("deviceId", deviceId);
253     }
254     return { deviceId: deviceId, isNew: true };
255   } catch (e) {
256     // Fallback (should be rare): still generate, but cannot persist without localStorage
257     var deviceIdFallback = generateUUIDv4();
258     return { deviceId: deviceIdFallback, isNew: true };
259   }
260 }
261
262
263 function getOrCreateSessionCookie() {
264   var existing = getCookie("_ourbussessid");
265   if (existing) return existing;
266
267
268   var newId = generateUUIDv4();
269
270
271   setCookie("_ourbussessid", newId, 365);
272   return newId;
273 }
274
275
276 async function syncCommuterCookies(baseUrl, previousCookieId) {
277   if (!baseUrl) {
278     var host = window.location.hostname || "";
279
280
281     if (host.includes("dev.ourbus.com")) {
282       baseUrl = "https://api.dev.ourbus.com";
283     } else if (host.includes("www.ourbus.com")) {
284       baseUrl = "https://api.ourbus.com";
285     } else {
286       baseUrl = "https://api.stg.ourbus.com"; // final fallback (UPDATED)
287     }
288   }
289   var params = getAllUrlParams();
290   var cookie = getOrCreateSessionCookie();
291   var userIdCookie = getCookie("auth")
292     ? getCookie("_ourbususersessid")
293     : null;
294   var url = baseUrl + "/wsapi/commuter/cookies";
295   if (params) {
296     url += "?" + params;
297   }
298   if (userIdCookie) {
299     url +=
300       (params ? "&" : "?") + "userid=" + encodeURIComponent(userIdCookie);
301   }
302
303
304   const { deviceId, isNew } = getOrCreateDeviceId();
305
306
307   var body = {
308     all_param: params,
309     cookie: cookie,
310     referrer: document.referrer || "",
311     deviceId: deviceId,
312   };
313
314
315   if (previousCookieId != null) {
316     body.cookieId = previousCookieId;
317   }
318
319
320   // Retry wrapper (NEW) - no storage updates unless status===200
321   return retryAsync(
322     async function () {
323       return fetch(url, {
324         method: "POST",
325         headers: {
326           "Content-Type": "application/json",
327         },
328         body: JSON.stringify(body),
329       }).then(async function (response) {
330         if (response.status === 200) {
331           let data = null;
332           try {
333             data = await response.json();
334           } catch (e) {
335             throw new Error(
336               "commuter/cookies sync failed: invalid JSON response",
337             );
338           }
339
340
341           if (data?.statusCode === 201) {
342             const ourbusUserSessId = getCookie("_ourbususersessid") ?? "";
343             writeCommuterSyncState(ourbusUserSessId, cookie);
344
345
346             writeCookieId(data.cookieId);
347           }
348
349
350           // deviceId is persisted in localStorage only; no cookie writes/removals
351
352
353           return true;
354         }
355         // Non-200 should be treated as failure to trigger retry
356         throw new Error(
357           "commuter/cookies sync failed with status " + response.status,
358         );
359       });
360     },
361     { retries: 2, baseDelayMs: 600, jitterMs: 200 },
362   )["catch"](function (error) {
363     if (typeof console !== "undefined" && console.error) {
364       console.error("API call error:", error);
365     }
366     return null;
367   });
368 }
369
370
371 function logout() {
372   // Log the exact URL from where logout was triggered
373   console.log("LOGOUT REQUEST FROM URL =", window.location.href);
374   //sessionStorage.removeItem("commuterCookiesAPISuccess");
375   // ---- Clear the full session (equivalent to session.invalidate()) ----
376   // sessionStorage.clear();
377
378
379   clearCommuterSyncState();
380
381
382   // ---- Delete cookies: auth, profile, _socialTokenCheck ----
383   deleteCookie("auth");
384   deleteCookie("profile");
385   deleteCookie("_socialTokenCheck");
386 }
387
388
389 // Utility: delete cookies correctly
390 function deleteCookie(name) {
391   document.cookie = `${name}=; Max-Age=0; path=/; SameSite=Lax; Secure`;
392 }
393
394
395 function setCookie(name, value, days) {
396   let expires = "";
397
398
399   // If expiry is provided (number of days)
400   if (typeof days === "number") {
401     const d = new Date();
402     d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
403     expires = "; expires=" + d.toUTCString();
404   }
405
406
407   document.cookie =
408     name +
409     "=" +
410     encodeURIComponent(value) +
411     expires +
412     "; path=/" +
413     "; SameSite=Lax" +
414     "; Secure";
415 }
416
417
418 return {
419   callCommuterCookiesAPI: callCommuterCookiesAPI,
420 };
421});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.