PluginProbe ʕ •ᴥ•ʔ
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode / trunk
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode vtrunk
4.7.2 4.7.1 trunk 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 3.0.0 3.0.1 3.1.0 3.10.0 3.10.1 3.11.1 3.11.2 3.11.3 3.2.0 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.5 3.6.6 3.7.0 3.7.1 3.8.0 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.2.0 4.2.1 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.3.10 4.3.11 4.3.12 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.7.1 4.3.8 4.3.9 4.3.9.1 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.10 4.5.11 4.5.2 4.5.3 4.5.4 4.5.5 4.5.6 4.5.7 4.5.8 4.5.9 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.6.6 4.6.7 4.7.0
cookiebot / assets / js / backend / account.js
cookiebot / assets / js / backend Last commit date
gutenberg 2 weeks ago account-static.js 10 months ago account.js 10 months ago amplitude.js 1 year ago consent-mapping.js 1 year ago cookiebot-admin-script.js 6 months ago dashboard.js 1 year ago jquery.tipTip.js 3 years ago multiple-page.js 3 years ago network-settings-page.js 4 months ago ppg-page.js 4 months ago prior-consent-settings.js 3 years ago settings-page.js 4 months ago support-page.js 1 year ago
account.js
510 lines
1 const API_BASE_URL = 'https://api.ea.prod.usercentrics.cloud/v1';
2 let authToken = '';
3
4 // Helper function to create FormData for AJAX calls
5 const createFormData = (action, data = {}) => {
6 const formData = new FormData();
7 formData.append('action', action);
8 formData.append('nonce', cookiebot_account.nonce);
9
10 Object.entries(data).forEach(([key, value]) => {
11 formData.append(key, value);
12 });
13
14 return formData;
15 };
16
17 // Function to check scan status
18 async function checkScanStatus(scanId) {
19 try {
20 const response = await fetch(`${API_BASE_URL}/scan/${scanId}`, {
21 method: 'GET',
22 headers: {
23 'Accept': 'application/json',
24 'Content-Type': 'application/json',
25 'Authorization': `Bearer ${authToken}`
26 }
27 });
28
29 const data = await response.json();
30
31 if (data.status?.toLowerCase() === 'done') {
32 await fetch(cookiebot_account.ajax_url, {
33 method: 'POST',
34 body: createFormData('cookiebot_store_scan_details', {
35 scan_id: scanId,
36 scan_status: 'DONE'
37 }),
38 credentials: 'same-origin'
39 });
40 return;
41 }
42
43 // Store both scan ID and status
44 await fetch(cookiebot_account.ajax_url, {
45 method: 'POST',
46 body: createFormData('cookiebot_store_scan_details', {
47 scan_id: scanId,
48 scan_status: 'IN_PROGRESS'
49 }),
50 credentials: 'same-origin'
51 });
52
53 if (response.status !== 200 && response.status !== 202 && response.status !== 404 || data.status === 'FAILED') {
54 await fetch(cookiebot_account.ajax_url, {
55 method: 'POST',
56 body: createFormData('cookiebot_store_scan_details', {
57 scan_id: scanId,
58 scan_status: 'FAILED'
59 }),
60 credentials: 'same-origin'
61 });
62 }
63 } catch (error) {
64 console.error('Error checking scan status:', error);
65 }
66 }
67
68 const checkUserData = async () => {
69 try {
70 let userData = await fetch(`${API_BASE_URL}/accounts`, {
71 headers: {
72 'Accept': 'application/json',
73 'Authorization': `Bearer ${authToken}`,
74 }
75 }).then(r => r.json()).then(data => data[0]);
76
77 if (!userData) throw new Error('No user data received');
78
79 const storedUserData = await fetch(cookiebot_account.ajax_url, {
80 method: 'POST',
81 body: createFormData('cookiebot_get_user_data'),
82 credentials: 'same-origin'
83 }).then(r => r.json());
84
85 if (storedUserData.data.subscriptions['active'].subscription_status.includes('trial') && !userData.subscriptions['active'].subscription_status.includes('trial')) {
86 // window.trackAmplitudeEvent('Pricing Plan Chosen', {
87 // plan: userData.subscriptions['active'].price_plan,
88 // subscription_status: userData.subscriptions['active'].subscription_status
89 // });
90 }
91
92 // Store user data
93 userResponseData = await fetch(cookiebot_account.ajax_url, {
94 method: 'POST',
95 body: createFormData('cookiebot_post_user_data', {
96 data: JSON.stringify(userData)
97 }),
98 credentials: 'same-origin'
99 }).then(r => r.json());
100
101 if (!userResponseData.success) {
102 throw new Error('Failed to store user data');
103 }
104
105 return userResponseData;
106 } catch (error) {
107 console.error('Failed to fetch user data:', error);
108 return;
109 }
110 }
111
112 const isAuthenticated = async () => {
113 try {
114 const response = await fetch(`${API_BASE_URL}/accounts`, {
115 headers: {
116 'Accept': 'application/json',
117 'Authorization': `Bearer ${authToken}`
118 }
119 });
120 if (response.status === 401 && cookiebot_account.has_user_data) {
121 await fetch(cookiebot_account.ajax_url, {
122 method: 'POST',
123 body: createFormData('cookiebot_delete_auth_token'),
124 credentials: 'same-origin'
125 });
126 if (!window.prevent_default && canReload()) {
127 window.location.reload();
128 }
129 }
130 return response.status !== 401;
131 } catch (error) {
132 console.error('Failed to check authentication:', error);
133 return false;
134 }
135 };
136
137 // Function to fetch configuration details
138 async function fetchConfigurationDetails(configId) {
139 try {
140 const response = await fetch(`${API_BASE_URL}/configurations/${configId}`, {
141 method: 'GET',
142 headers: {
143 'Accept': 'application/json',
144 'Content-Type': 'application/json',
145 'Authorization': `Bearer ${authToken}`
146 }
147 });
148
149 if (!response.ok) {
150 throw new Error('Failed to fetch configuration details');
151 }
152
153 const data = await response.json();
154
155 // Store full configuration data
156 await fetch(cookiebot_account.ajax_url, {
157 method: 'POST',
158 body: createFormData('cookiebot_store_configuration', {
159 configuration: JSON.stringify(data)
160 }),
161 credentials: 'same-origin'
162 });
163
164 return data;
165 } catch (error) {
166 console.error('Error fetching configuration details:', error);
167 throw error;
168 }
169 }
170
171 function canReload() {
172 const itemStr = localStorage.getItem('dashboard_reload');
173 const now = new Date();
174 const numTimes = 3;
175 const ttl = 30000;
176 let count = 0;
177
178 if (itemStr) {
179 const item = JSON.parse(itemStr);
180
181 if (now.getTime() < item.exp) {
182 if (item.count > numTimes) {
183 return false;
184 }
185 count = item.count + 1;
186 }
187 }
188
189 const item = {
190 count: count,
191 exp: now.getTime() + ttl,
192 }
193 localStorage.setItem('dashboard_reload', JSON.stringify(item));
194 return true;
195 }
196
197 document.addEventListener('DOMContentLoaded', async () => {
198 const urlParams = new URLSearchParams(window.location.search);
199 const ucApiCode = urlParams.get('uc_api_code');
200 const companyId = urlParams.get('company_id');
201
202 // if (!cookiebot_account.has_cbid) {
203 // window.trackAmplitudeEvent('Get Started Page Visited');
204 // }
205 // For existing users, no account registration workflow is needed
206 if (cookiebot_account.has_cbid && !cookiebot_account.has_user_data && !cookiebot_account.was_onboarded) {
207 return;
208 }
209
210 if (cookiebot_account.cbid !== cookiebot_account.scan_id) {
211 await fetch(cookiebot_account.ajax_url, {
212 method: 'POST',
213 body: createFormData('cookiebot_update_scan_id', {
214 scan_id: cookiebot_account.cbid
215 }),
216 credentials: 'same-origin'
217 });
218 if (canReload()) {
219 window.location.reload();
220 }
221 }
222
223 // For previously onboarded users that disconnected the account, no new account registration workflow is needed
224 // if (!cookiebot_account.has_cbid && cookiebot_account.was_onboarded) {
225 // return;
226 // }
227
228 try {
229 authToken = await fetch(cookiebot_account.ajax_url, {
230 method: 'POST',
231 body: createFormData('cookiebot_get_auth_token'),
232 credentials: 'same-origin'
233 }).then(r => r.json()).then(data => data.data);
234
235 if (ucApiCode) {
236
237 const isNewUser = urlParams.get('is_new_user');
238
239 if (cookiebot_account.has_cbid) {
240 try {
241 const response = await fetch(cookiebot_account.ajax_url, {
242 method: 'POST',
243 body: createFormData('cookiebot_process_auth_code', { code: ucApiCode }),
244 credentials: 'same-origin'
245 });
246
247 authToken = await fetch(cookiebot_account.ajax_url, {
248 method: 'POST',
249 body: createFormData('cookiebot_get_auth_token'),
250 credentials: 'same-origin'
251 }).then(r => r.json()).then(data => data.data);
252
253 if (!response.ok) throw new Error(`Auth failed: ${response.status}`);
254 if (canReload()) {
255 const newUrl = new URL(window.location.href);
256 newUrl.searchParams.delete('uc_api_code');
257 newUrl.searchParams.delete('is_new_user');
258 window.location.href = newUrl;
259 }
260 return;
261 } catch (error) {
262 console.error('Failed to process authentication:', error);
263 return;
264 }
265 }
266
267
268 if (isNewUser === 'false' && !cookiebot_account.has_user_data) {
269 await fetch(cookiebot_account.ajax_url, {
270 method: 'POST',
271 body: createFormData('cookiebot_process_auth_code', { code: ucApiCode }),
272 credentials: 'same-origin'
273 });
274
275 if (canReload()) {
276 const settingsUrl = window.location.protocol + '//' + window.location.hostname + '/wp-admin/admin.php?page=cookiebot_settings';
277 window.location.href = settingsUrl;
278 return;
279 }
280 }
281
282 // Add loading state
283 const loadingOverlay = document.createElement('div');
284 loadingOverlay.className = 'loading-overlay';
285 loadingOverlay.innerHTML = `
286 <div class="loading-content">
287 <div class="loading-spinner"></div>
288 <h2>Creating your account</h2>
289 <p>This should only take about a minute. Keep this window open while we set things up.</p>
290 </div>
291 `;
292 document.body.classList.add('has-loading-overlay');
293 document.body.appendChild(loadingOverlay);
294
295 try {
296 const response = await fetch(cookiebot_account.ajax_url, {
297 method: 'POST',
298 body: createFormData('cookiebot_process_auth_code', { code: ucApiCode }),
299 credentials: 'same-origin'
300 });
301
302 authToken = await fetch(cookiebot_account.ajax_url, {
303 method: 'POST',
304 body: createFormData('cookiebot_get_auth_token'),
305 credentials: 'same-origin'
306 }).then(r => r.json()).then(data => data.data);
307
308 if (!response.ok) throw new Error(`Auth failed: ${response.status}`);
309 } catch (error) {
310 console.error('Failed to process authentication:', error);
311 // Remove loading state on error
312 document.body.classList.remove('has-loading-overlay');
313 loadingOverlay.remove();
314 return;
315 }
316 }
317
318 // Check for existing CBID
319 const cbid = await fetch(cookiebot_account.ajax_url, {
320 method: 'POST',
321 body: createFormData('cookiebot_get_cbid'),
322 credentials: 'same-origin'
323 }).then(r => r.json()).then(data => data.success ? data.data : null);
324
325 // Skip if user data exists and is authenticated
326 const isAuthenticatedCondition = await isAuthenticated();
327 if (cookiebot_account.has_user_data && isAuthenticatedCondition) {
328 // Check scan status before returning
329 await checkScanStatus(cbid);
330 await checkUserData();
331 return;
332 }
333
334 if (!cbid) {
335 try {
336 if (!companyId) {
337 // Without company ID we cannot create the other config params, so stop the workflow right here.
338 return;
339 }
340
341 // Create new configuration
342 const siteDomain = window.location.hostname;
343 const formattedDomain = siteDomain.startsWith('http') ? siteDomain : `https://${siteDomain}`;
344
345 const configResponse = await fetch(`${API_BASE_URL}/configurations`, {
346 method: 'POST',
347 headers: {
348 'Accept': 'application/json',
349 'Content-Type': 'application/json',
350 'Authorization': `Bearer ${authToken}`
351 },
352 body: JSON.stringify({
353 configuration_name: "",
354 data_controller: "",
355 legal_framework_template: "gdpr",
356 domains: [formattedDomain],
357 company_id: companyId
358 })
359 });
360
361 if (!configResponse.ok) throw new Error(`Config creation failed: ${configResponse.status}`);
362
363 const configData = await configResponse.json();
364 if (!configData?.configuration_id) throw new Error('No configuration ID');
365
366 // Store CBID
367 await fetch(cookiebot_account.ajax_url, {
368 method: 'POST',
369 body: createFormData('cookiebot_store_cbid', { cbid: configData.configuration_id }),
370 credentials: 'same-origin'
371 });
372
373 // Now that we have a CBID, initiate the scan
374 const scanResponse = await fetch(`${API_BASE_URL}/scan`, {
375 method: 'POST',
376 headers: {
377 'Accept': 'application/json',
378 'Content-Type': 'application/json',
379 'Authorization': `Bearer ${authToken}`
380 },
381 body: JSON.stringify({
382 domains: [formattedDomain],
383 configuration_id: configData.configuration_id
384 })
385 });
386
387 const scanData = await scanResponse.json();
388
389 // Check for scan ID in different possible response structures
390 const scanId = scanData?.scan?.scan_id || scanData?.scan_id || scanData?.id;
391 if (!scanId) {
392 console.error('Scan response structure:', scanData);
393 throw new Error('No scan ID received in response');
394 }
395
396 // Store scan ID in WordPress without status initially
397 await fetch(cookiebot_account.ajax_url, {
398 method: 'POST',
399 body: createFormData('cookiebot_store_scan_details', {
400 scan_id: scanId
401 }),
402 credentials: 'same-origin'
403 });
404
405 // Start checking scan status
406 await checkScanStatus(scanId);
407
408 // fetch configuration details
409 await fetchConfigurationDetails(configData.configuration_id);
410
411 } catch (error) {
412 console.error('Failed to create configuration:', error);
413 return;
414 }
415 } else {
416 // If we already have a CBID, check if there's an ongoing scan
417 const scanDetails = await fetch(cookiebot_account.ajax_url, {
418 method: 'POST',
419 body: createFormData('cookiebot_get_scan_details'),
420 credentials: 'same-origin'
421 }).then(r => r.json());
422
423 if (scanDetails.success && scanDetails.data.scan_id) {
424 await checkScanStatus(scanDetails.data.scan_id);
425 }
426 // And fetch configuration details
427 if (cbid) {
428 await fetchConfigurationDetails(cbid);
429 await checkUserData();
430 }
431 }
432
433 // Check and fetch user data if needed
434 let userResponseData = await fetch(cookiebot_account.ajax_url, {
435 method: 'POST',
436 body: createFormData('cookiebot_get_user_data'),
437 credentials: 'same-origin'
438 }).then(r => r.json());
439
440 try {
441 let userData = await fetch(`${API_BASE_URL}/accounts`, {
442 headers: {
443 'Accept': 'application/json',
444 'Authorization': `Bearer ${authToken}`,
445 }
446 }).then(r => r.json()).then(data => data[0]);
447
448 // Track account creation in Amplitude
449 // window.trackAmplitudeEvent('Account Created');
450
451 // Store user data
452 userResponseData = await fetch(cookiebot_account.ajax_url, {
453 method: 'POST',
454 body: createFormData('cookiebot_post_user_data', {
455 data: JSON.stringify(userData)
456 }),
457 credentials: 'same-origin'
458 }).then(r => r.json());
459
460 // Store onboarding status separately
461 await fetch(cookiebot_account.ajax_url, {
462 method: 'POST',
463 body: createFormData('cookiebot_store_onboarding_status', {
464 onboarded: true
465 }),
466 credentials: 'same-origin'
467 });
468
469 } catch (error) {
470 console.error('Failed to fetch user data:', error);
471 return;
472 }
473
474 if (userResponseData.data && canReload()) {
475 const newUrl = new URL(window.location.href);
476 newUrl.searchParams.delete('uc_api_code');
477 window.location.href = newUrl;
478 }
479 } catch (error) {
480 console.error('An unexpected error occurred:', error);
481 }
482 });
483
484 // Event Listeners
485 document.getElementById('banner-close-btn')?.addEventListener('click', async () => {
486 try {
487 const response = await fetch(cookiebot_account.ajax_url, {
488 method: 'POST',
489 body: createFormData('cookiebot_dismiss_banner'),
490 credentials: 'same-origin'
491 });
492
493 if (!response.ok) throw new Error(`Failed to dismiss banner: ${response.status}`);
494 const banner = document.getElementById('banner-live-notice');
495 if (banner) banner.remove();
496 } catch (error) {
497 console.error('Failed to dismiss banner:', error);
498 }
499 });
500
501 document.getElementById('get-started-button')?.addEventListener('click', async (e) => {
502 // window.trackAmplitudeEvent('Sign Up Flow Started');
503 e.preventDefault();
504 try {
505 const callbackUrl = window.location.href;
506 window.location.href = `${API_BASE_URL}/auth/auth0/authorize?origin=wordpress_plugin&callback_domain=${encodeURIComponent(callbackUrl)}`;
507 } catch (error) {
508 console.error('Failed to start authentication process:', error);
509 }
510 });