1/** 2 * Shared authentication utilities for ExtraChill Users blocks. 3 * 4 * Exposes ECAuthUtils global object with common functions used across 5 * login-register, onboarding, and google-signin modules. 6 */ 7(function () { 8 'use strict'; 9 10 function normalizeRestRoot(root) { 11 if (!root) { 12 return ''; 13 } 14 15 try { 16 const url = new URL(root, window.location.origin); 17 if (!url.pathname.endsWith('/')) { 18 url.pathname += '/'; 19 } 20 return url.toString(); 21 } catch { 22 return ''; 23 } 24 } 25 26 function getRestRoot() { 27 if (window.wpApiSettings && window.wpApiSettings.root) { 28 const normalized = normalizeRestRoot(window.wpApiSettings.root); 29 if (normalized) { 30 return normalized; 31 } 32 } 33 34 const link = document.querySelector('link[rel="https://api.w.org/"]'); 35 if (link && link.href) { 36 const linkRoot = normalizeRestRoot(link.href); 37 if (linkRoot) { 38 return linkRoot; 39 } 40 } 41 42 return normalizeRestRoot(new URL('/wp-json/', window.location.origin).toString()); 43 } 44 45 function uuidv4() { 46 if (!window.crypto || !window.crypto.getRandomValues) { 47 return ''; 48 } 49 50 const bytes = new Uint8Array(16); 51 window.crypto.getRandomValues(bytes); 52 53 // Set RFC 4122 version (4) and variant (10xx) bits â bitwise required by spec. 54 // eslint-disable-next-line no-bitwise 55 bytes[6] = (bytes[6] & 0x0f) | 0x40; 56 // eslint-disable-next-line no-bitwise 57 bytes[8] = (bytes[8] & 0x3f) | 0x80; 58 59 const hex = Array.from(bytes, function (b) { 60 return b.toString(16).padStart(2, '0'); 61 }); 62 63 return ( 64 hex.slice(0, 4).join('') + 65 '-' + 66 hex.slice(4, 6).join('') + 67 '-' + 68 hex.slice(6, 8).join('') + 69 '-' + 70 hex.slice(8, 10).join('') + 71 '-' + 72 hex.slice(10, 16).join('') 73 ); 74 } 75 76 function getDeviceId() { 77 try { 78 const key = 'extrachill_device_id'; 79 const existing = window.localStorage.getItem(key); 80 if (existing) { 81 return existing; 82 } 83 84 const generated = uuidv4(); 85 if (!generated) { 86 return ''; 87 } 88 89 window.localStorage.setItem(key, generated); 90 return generated; 91 } catch { 92 return ''; 93 } 94 } 95 96 function renderNotice(container, type, message, allowHtml) { 97 if (!container) { 98 return; 99 } 100 101 let notice = container.querySelector('[data-ec-auth-notice="1"]'); 102 if (!notice) { 103 notice = document.createElement('div'); 104 notice.dataset.ecAuthNotice = '1'; 105 notice.className = 'ec-auth-notice'; 106 container.prepend(notice); 107 } 108 109 notice.className = 'ec-auth-notice ec-auth-notice--' + type; 110 notice.innerHTML = ''; 111 112 const p = document.createElement('p'); 113 if (allowHtml) { 114 p.innerHTML = message; 115 } else { 116 p.textContent = message; 117 } 118 notice.appendChild(p); 119 } 120 121 function clearNotice(container) { 122 if (!container) { 123 return; 124 } 125 126 const notice = container.querySelector('[data-ec-auth-notice="1"]'); 127 if (notice) { 128 notice.remove(); 129 } 130 } 131 132 function setSubmitting(button, label) { 133 if (!button) { 134 return function () {}; 135 } 136 137 const original = button.value !== undefined ? button.value : button.textContent; 138 button.disabled = true; 139 140 if (button.value !== undefined) { 141 button.value = label; 142 } else { 143 button.textContent = label; 144 } 145 146 return function () { 147 button.disabled = false; 148 if (button.value !== undefined) { 149 button.value = original || ''; 150 } else { 151 button.textContent = original || ''; 152 } 153 }; 154 } 155 156 function getFormValue(form, selector) { 157 const el = form.querySelector(selector); 158 return el ? el.value || '' : ''; 159 } 160 161 function getFormChecked(form, selector) { 162 const el = form.querySelector(selector); 163 return el ? !!el.checked : false;
164 } 165 166 function getCommunityUrl() { 167 return 'https://community.extrachill.com'; 168 } 169 170 window.ECAuthUtils = { 171 getRestRoot, 172 getDeviceId, 173 renderNotice, 174 clearNotice, 175 setSubmitting, 176 getFormValue, 177 getFormChecked, 178 getCommunityUrl 179 }; 180})();
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.