1"use strict"; 2 3/** Access settings modal â mode picker, cap link apply/revoke. */ 4(function (global) { 5 let ctx = null; 6 let wired = false; 7 let accessDraftMode = "one_time"; 8 let accessDraftAction = "bundle"; 9 const ACCESS_PANEL_IDS = ["one_time", "action", "fixed_term", "trusted"]; 10 11 function c() { 12 return ctx && typeof ctx === "object" ? ctx : {}; 13 } 14 15 function ax(v, fb) { 16 const fn = c().ax; 17 return fn ? fn(v, fb) : String(v || fb || "trusted"); 18 } 19 20 function axIs(a, b) { 21 const fn = c().axIs; 22 return fn ? fn(a, b) : ax(a) === ax(b); 23 } 24 25 function AX() { 26 const fn = c().AX; 27 return fn ? fn() : null; 28 } 29 30 function policy() { 31 const g = c().getPolicy; 32 return g && typeof g === "function" ? g() || {} : {}; 33 } 34 35 function setPolicy(p) { 36 if (c().setPolicy) c().setPolicy(p); 37 } 38 39 function readSpaceAccessGuestPerms() { 40 const GP = global.GriGsiCapGuestPerms; 41 if (!GP || !GP.readCheckedPerms) return []; 42 return GP.readCheckedPerms("[data-access-guest-perm]"); 43 } 44 45 function applyGuestPermsToCheckboxes(perms) { 46 const GP = global.GriGsiCapGuestPerms; 47 const root = document.getElementById("space-access-guest-perms"); 48 if (GP && GP.applyPermsToGroup && root) { 49 GP.applyPermsToGroup(root, perms); 50 return; 51 } 52 const set = new Set(GP ? GP.normalizeCapPerms(perms) : []); 53 document.querySelectorAll("[data-access-guest-perm]").forEach((el) => { 54 const key = String(el.getAttribute("data-access-guest-perm") || "").toLowerCase(); 55 if (key) el.checked = set.has(key); 56 }); 57 } 58 59 function syncAccessGuestPermsPanelVisible() { 60 const box = document.getElementById("space-access-guest-perms"); 61 if (!box) return; 62 const mode = ax(accessDraftMode || policy().mode, "trusted"); 63 const show = AX() ? !AX().is(mode, AX().IDS.TRUSTED) : mode !== "trusted"; 64 box.classList.toggle("hidden", !show); 65 box.hidden = !show; 66 box.setAttribute("aria-hidden", show ? "false" : "true"); 67 } 68 69 function setAccessModeUi(mode) { 70 accessDraftMode = ax(mode, "one_time"); 71 document.querySelectorAll("[data-access-mode]").forEach((btn) => { 72 const on = axIs(btn.getAttribute("data-access-mode"), accessDraftMode); 73 btn.classList.toggle("is-on", on); 74 btn.setAttribute("aria-checked", on ? "true" : "false"); 75 }); 76 (AX()?.ALL_IDS || ACCESS_PANEL_IDS).forEach((name) => { 77 const panel = document.getElementById("space-access-panel-" + name); 78 if (!panel) return; 79 const show = axIs(name, accessDraftMode); 80 panel.classList.toggle("hidden", !show); 81 panel.setAttribute("aria-hidden", show ? "false" : "true"); 82 }); 83 syncAccessGuestPermsPanelVisible(); 84 } 85 86 function setAccessActionUi(action) { 87 const act = String(action || "chat").toLowerCase(); 88 accessDraftAction = act === "all" ? "bundle" : act; 89 document.querySelectorAll("[data-access-action]").forEach((btn) => { 90 const on = btn.getAttribute("data-access-action") === accessDraftAction; 91 btn.classList.toggle("is-on", on); 92 }); 93 } 94 95 function initAccessDateInputs() { 96 const now = Date.now(); 97 const tempUntil = new Date(now + 24 * 60 * 60 * 1000); 98 const tempInput = document.getElementById("space-access-temp-until"); 99 if (tempInput && !tempInput.value) { 100 const localIso = new Date(tempUntil.getTime() - tempUntil.getTimezoneOffset() * 60000) 101 .toISOString() 102 .slice(0, 16); 103 tempInput.value = localIso; 104 } 105 const bizUntil = new Date(now + 30 * 24 * 60 * 60 * 1000); 106 const bizInput = document.getElementById("space-access-business-until"); 107 if (bizInput && !bizInput.value) { 108 const yyyy = bizUntil.getFullYear(); 109 const mm = String(bizUntil.getMonth() + 1).padStart(2, "0"); 110 const dd = String(bizUntil.getDate()).padStart(2, "0"); 111 bizInput.value = yyyy + "-" + mm + "-" + dd; 112 } 113 } 114 115 async function open() { 116 const modal = document.getElementById("access-settings-modal"); 117 if (!modal) return; 118 const guestPerm = c().guestHasDelegatePerm; 119 const toast = c().showToast; 120 if (typeof guestPerm === "function" && !guestPerm("settings")) { 121 if (typeof toast === "function") { 122 toast("You do not have permission to change access settings for this Space.", "warning"); 123 } 124 return; 125 } 126 modal.classList.add("active"); 127 const urlHasCap = c().urlHasCapParam; 128 try { 129 if (urlHasCap && urlHasCap(global.location.href)) {
130 if (c().hydrateAccessPolicyFromUrl) await c().hydrateAccessPolicyFromUrl(); 131 if (c().loadCapPayloadForLimits) await c().loadCapPayloadForLimits(); 132 if (c().bindActionLimitContext) c().bindActionLimitContext(); 133 } else if (c().ensureCapInviteLinkForHostPolicy) { 134 await c().ensureCapInviteLinkForHostPolicy(); 135 } 136 } catch (_) {} 137 initAccessDateInputs(); 138 if (global.GriGsiConnectModeLabels) { 139 global.GriGsiConnectModeLabels.syncTempFromPair("space-access-temp-hours", "space-access-temp-until"); 140 global.GriGsiConnectModeLabels.syncBusinessFromDateInput("space-access-business-until"); 141 } 142 const p = policy(); 143 setAccessModeUi(p.mode || "one_time"); 144 setAccessActionUi(p.action || "bundle"); 145 applyGuestPermsToCheckboxes(p.guest_perms || p.cap_perms || []); 146 syncAccessGuestPermsPanelVisible(); 147 const summary = c().accessSummary; 148 const currentEl = document.getElementById("space-access-current"); 149 const linkEl = document.getElementById("space-access-link"); 150 if (currentEl && typeof summary === "function") { 151 currentEl.textContent = "Current: " + summary(p); 152 } 153 const joinLink = c().getJoinLink ? c().getJoinLink() : ""; 154 if (linkEl) linkEl.value = String(p.link || joinLink || ""); 155 } 156 157 function close() { 158 const modal = document.getElementById("access-settings-modal"); 159 if (modal) modal.classList.remove("active"); 160 } 161 162 async function applyFromModal() { 163 const SB = global.GriGsiSpaceBook || global.GriGsiConnectLocalMode; 164 const toast = c().showToast; 165 if (!SB || !SB.createLocalLink) { 166 if (typeof toast === "function") toast("Access policy is unavailable on this device.", "warning"); 167 return; 168 } 169 const getQuality = c().getActiveSpaceVideoQuality; 170 const buildJoin = c().buildJoinLinkString; 171 let nextLink = 172 typeof buildJoin === "function" ? buildJoin(getQuality ? getQuality() : "default") : ""; 173 let nextExpires = null; 174 let nextCapJti = ""; 175 const mode = ax(accessDraftMode, "trusted"); 176 const guestPerms = readSpaceAccessGuestPerms(); 177 const scopeFor = c().scopeForAccessAction; 178 const withMod = c().withShareModule; 179 const modFor = c().moduleForAccessAction; 180 const readTemp = c().readAccessTempTtlMs; 181 const readBiz = c().readAccessBusinessTtlMs; 182 const secretFn = c().getSpaceSecret; 183 const secret = secretFn && typeof secretFn === "function" ? secretFn() : ""; 184 185 if (axIs(mode, "action")) { 186 const scope = scopeFor ? scopeFor(accessDraftAction) : "action:join_once"; 187 const link = await SB.createLocalLink(secret, { 188 kind: "action", 189 scope, 190 ttl_ms: 24 * 60 * 60 * 1000, 191 perms: guestPerms, 192 }); 193 if (!link || !link.ok || !link.url) { 194 if (typeof toast === "function") toast("Could not create action link.", "warning"); 195 return; 196 } 197 const draftAct = String(accessDraftAction || "chat").toLowerCase(); 198 nextLink = 199 draftAct === "bundle" || draftAct === "all" 200 ? link.url 201 : withMod 202 ? withMod(link.url, modFor ? modFor(draftAct) : "chat") 203 : link.url; 204 nextExpires = Number(link.expires_at) || null; 205 nextCapJti = String(link.jti || ""); 206 } else if (axIs(mode, "one_time")) { 207 const link = await SB.createLocalLink(secret, { 208 kind: "temporary", 209 ttl_ms: readTemp ? readTemp() : 15 * 60 * 1000, 210 perms: guestPerms, 211 }); 212 if (!link || !link.ok || !link.url) { 213 if (typeof toast === "function") toast("Could not create one-time link.", "warning"); 214 return; 215 } 216 nextLink = link.url; 217 nextExpires = Number(link.expires_at) || null; 218 nextCapJti = String(link.jti || ""); 219 } else if (axIs(mode, "fixed_term")) { 220 const link = await SB.createLocalLink(secret, { 221 kind: "business", 222 ttl_ms: readBiz ? readBiz() : 30 * 24 * 60 * 60 * 1000, 223 perms: guestPerms, 224 }); 225 if (!link || !link.ok || !link.url) { 226 if (typeof toast === "function") toast("Could not create fixed-term link.", "warning"); 227 return; 228 } 229 nextLink = link.url; 230 nextExpires = Number(link.expires_at) || null; 231 nextCapJti = String(link.jti || ""); 232 } 233 234 const nextPolicy = { 235 mode, 236 action: axIs(mode, "action") ? accessDraftAction : accessDraftAction || "bundle", 237 guest_perms: guestPerms, 238 cap_perms: guestPerms, 239 expires_at: nextExpires, 240 cap_jti: nextCapJti, 241 source: "space_modal", 242 link: nextLink, 243 }; 244 setPolicy(nextPolicy); 245 if (c().setJoinLink) c().setJoinLink(nextLink); 246 247 const summary = c().accessSummary; 248 const currentEl = document.getElementById("space-access-current"); 249 const linkEl = document.getElementById("space-access-link"); 250 if (currentEl && typeof summary === "function") { 251 currentEl.textContent = "Current: " + summary(nextPolicy); 252 } 253 if (linkEl) linkEl.value = nextLink; 254 if (c().renderAccessChip) c().renderAccessChip();
255 if (c().saveAccessPolicyLocal) c().saveAccessPolicyLocal(); 256 if (c().clearAccessLimitExhaustedSignaling) c().clearAccessLimitExhaustedSignaling(); 257 if (c().startAccessPolicyExpiryWatch) c().startAccessPolicyExpiryWatch(); 258 if (typeof toast === "function") toast("Access policy updated. Share the new link.", "success"); 259 } 260 261 async function revokeCurrentCap() { 262 const SB = global.GriGsiSpaceBook || global.GriGsiConnectLocalMode; 263 const p = policy(); 264 const jti = String(p.cap_jti || ""); 265 const toast = c().showToast; 266 const signal = c().signalAccessLimitExhausted; 267 if (!SB || !SB.markCapJtiConsumed || !jti) { 268 if (typeof toast === "function") toast("Current link has no revocable cap.", "warning"); 269 return; 270 } 271 try { 272 await SB.markCapJtiConsumed(jti); 273 const next = { ...p, cap_jti: "", expires_at: Date.now() }; 274 setPolicy(next); 275 if (c().saveAccessPolicyLocal) c().saveAccessPolicyLocal(); 276 if (c().renderAccessChip) c().renderAccessChip(); 277 const currentEl = document.getElementById("space-access-current"); 278 if (currentEl) currentEl.textContent = "Current: revoked cap (create a new link)"; 279 if (typeof signal === "function") signal({ reason: "revoked" }); 280 } catch (_) { 281 if (typeof toast === "function") toast("Could not revoke this cap link.", "warning"); 282 } 283 } 284 285 function wireControls(chipEl) { 286 if (wired) return; 287 wired = true; 288 const modal = document.getElementById("access-settings-modal"); 289 document.getElementById("close-access-settings")?.addEventListener("click", () => close()); 290 modal?.addEventListener("click", (e) => { 291 if (e.target === modal) close(); 292 }); 293 function onChipActivate(e) { 294 e.preventDefault(); 295 e.stopPropagation(); 296 void open(); 297 } 298 let lastTouchAt = 0; 299 chipEl?.addEventListener( 300 "touchend", 301 (e) => { 302 lastTouchAt = Date.now(); 303 onChipActivate(e); 304 }, 305 { passive: false } 306 ); 307 chipEl?.addEventListener("click", (e) => { 308 if (Date.now() - lastTouchAt < 500) { 309 e.preventDefault(); 310 e.stopPropagation(); 311 return; 312 } 313 onChipActivate(e); 314 }); 315 document.querySelectorAll("[data-access-mode]").forEach((btn) => { 316 btn.addEventListener("click", () => setAccessModeUi(btn.getAttribute("data-access-mode") || "one_time")); 317 }); 318 document.querySelectorAll("[data-access-action]").forEach((btn) => { 319 btn.addEventListener("click", () => setAccessActionUi(btn.getAttribute("data-access-action") || "chat")); 320 }); 321 document.getElementById("space-access-guest-perms")?.addEventListener("grigsi-guest-perms-ch
321ange", () => { 322 syncAccessGuestPermsPanelVisible(); 323 }); 324 document.getElementById("btn-access-apply")?.addEventListener("click", () => void applyFromModal()); 325 document.getElementById("btn-access-copy-link")?.addEventListener("click", async () => { 326 const linkEl = document.getElementById("space-access-link"); 327 const val = String((linkEl && linkEl.value) || "").trim(); 328 const toast = c().showToast; 329 if (!val) { 330 if (typeof toast === "function") toast("No generated link yet.", "warning"); 331 return; 332 } 333 try { 334 await navigator.clipboard.writeText(val); 335 if (typeof toast === "function") toast("Access link copied.", "success"); 336 } catch (_) { 337 if (typeof toast === "function") toast(val, "info"); 338 } 339 }); 340 document.getElementById("btn-access-revoke-current")?.addEventListener("click", () => void revokeCurrentCap()); 341 } 342 343 function init(context) { 344 ctx = context && typeof context === "object" ? context : {}; 345 const chip = c().getAccessChipEl ? c().getAccessChipEl() : document.getElementById("space-access-chip"); 346 wireControls(chip); 347 return global.GriGsiSpaceAccessSettingsUi; 348 } 349 350 global.GriGsiSpaceAccessSettingsUi = { 351 init, 352 open, 353 close, 354 applyFromModal, 355 revokeCurrentCap, 356 setAccessModeUi, 357 setAccessActionUi, 358 syncAccessGuestPermsPanelVisible, 359 }; 360})(typeof window !== "undefined" ? window : globalThis);
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.