diff --git a/index.html b/index.html index f86e55c..91fc5df 100644 --- a/index.html +++ b/index.html @@ -465,6 +465,30 @@ })(); const baseOrder = new Map(baseLinks.map((l, i) => [l.id, i])); + // Access levels (same as script.js) + const ACCESS_ANON_IDS = new Set(["dsyoon-ncue-net", "family-ncue-net", "link-ncue-net"]); + const ACCESS_USER_IDS = new Set([ + "dsyoon-ncue-net", + "family-ncue-net", + "tts-ncue-net", + "meeting-ncue-net", + "link-ncue-net", + "dreamgirl-ncue-net", + ]); + const ACCESS_ADMIN_EMAILS = new Set(["dosangyoon@gmail.com", "dsyoon@ncue.net"]); + let sessionEmail = ""; + + function isAdminEmail(email) { + return ACCESS_ADMIN_EMAILS.has(String(email || "").trim().toLowerCase()); + } + function canAccessLink(link) { + const id = String(link && link.id ? link.id : ""); + const email = String(sessionEmail || "").trim().toLowerCase(); + if (email && isAdminEmail(email)) return true; + if (email) return ACCESS_USER_IDS.has(id); + return ACCESS_ANON_IDS.has(id); + } + const state = { store: loadStore(), query: "", @@ -525,11 +549,17 @@ const u = esc(link.url); const desc = esc(link.description || ""); const star = link.favorite ? "star on" : "star"; + const accessible = canAccessLink(link); const tags = (link.tags || []).slice(0, 8).map((x) => `#${esc(x)}`).join(""); const favTag = link.favorite ? `★ 즐겨찾기` : ""; + const lockTag = accessible ? "" : `접근 제한`; const letter = esc((link.title || d || "L").trim().slice(0, 1).toUpperCase()); + const openHtml = accessible + ? `열기` + : ``; + const copyAttrs = accessible ? "" : ` disabled aria-disabled="true" title="이 링크는 현재 권한으로 접근할 수 없습니다."`; return ` -
+
@@ -543,10 +573,10 @@
${desc || " "}
-
${favTag}${tags}
+
${favTag}${lockTag}${tags}
- 열기 - + ${openHtml} +
@@ -771,10 +801,12 @@ } const isAuthed = await client.isAuthenticated(); auth.user = isAuthed ? await client.getUser() : null; + sessionEmail = auth.user && auth.user.email ? String(auth.user.email).trim().toLowerCase() : ""; if (el.btnLogout) el.btnLogout.hidden = !auth.user; if (el.snsLogin) el.snsLogin.hidden = Boolean(auth.user); if (el.user) el.user.hidden = !auth.user; if (el.userText && auth.user) el.userText.textContent = auth.user.email || auth.user.name || "로그인됨"; + render(); } async function loginWithConnection(provider) { @@ -795,6 +827,7 @@ async function logout() { const client = await ensureAuthClient(); if (!client) return; + sessionEmail = ""; await client.logout({ logoutParams: { returnTo: location.origin === "null" ? location.href : location.origin + location.pathname }, }); @@ -870,6 +903,11 @@ const card = e.target.closest(".card"); if (!card) return; const id = card.getAttribute("data-id"); + if ((btn.getAttribute("data-act") === "copy" || btn.getAttribute("data-act") === "open") && card.getAttribute("data-access") === "0") { + toast("이 링크는 현재 권한으로 접근할 수 없습니다."); + e.preventDefault(); + return; + } const act = btn.getAttribute("data-act"); const link = id ? getById(id) : null; if (!link) return;