Apply access gating in fallback mode
Mirror anonymous/user/admin link access tiers in the inline fallback app, disabling open/copy for restricted services and re-rendering after login/logout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
46
index.html
46
index.html
@@ -465,6 +465,30 @@
|
|||||||
})();
|
})();
|
||||||
const baseOrder = new Map(baseLinks.map((l, i) => [l.id, i]));
|
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 = {
|
const state = {
|
||||||
store: loadStore(),
|
store: loadStore(),
|
||||||
query: "",
|
query: "",
|
||||||
@@ -525,11 +549,17 @@
|
|||||||
const u = esc(link.url);
|
const u = esc(link.url);
|
||||||
const desc = esc(link.description || "");
|
const desc = esc(link.description || "");
|
||||||
const star = link.favorite ? "star on" : "star";
|
const star = link.favorite ? "star on" : "star";
|
||||||
|
const accessible = canAccessLink(link);
|
||||||
const tags = (link.tags || []).slice(0, 8).map((x) => `<span class="tag">#${esc(x)}</span>`).join("");
|
const tags = (link.tags || []).slice(0, 8).map((x) => `<span class="tag">#${esc(x)}</span>`).join("");
|
||||||
const favTag = link.favorite ? `<span class="tag fav">★ 즐겨찾기</span>` : "";
|
const favTag = link.favorite ? `<span class="tag fav">★ 즐겨찾기</span>` : "";
|
||||||
|
const lockTag = accessible ? "" : `<span class="tag lock">접근 제한</span>`;
|
||||||
const letter = esc((link.title || d || "L").trim().slice(0, 1).toUpperCase());
|
const letter = esc((link.title || d || "L").trim().slice(0, 1).toUpperCase());
|
||||||
|
const openHtml = accessible
|
||||||
|
? `<a class="btn mini" href="${u}" target="_blank" rel="noopener noreferrer">열기</a>`
|
||||||
|
: `<button class="btn mini" type="button" disabled aria-disabled="true" title="이 링크는 현재 권한으로 접근할 수 없습니다.">열기</button>`;
|
||||||
|
const copyAttrs = accessible ? "" : ` disabled aria-disabled="true" title="이 링크는 현재 권한으로 접근할 수 없습니다."`;
|
||||||
return `
|
return `
|
||||||
<article class="card" data-id="${esc(link.id)}">
|
<article class="card${accessible ? "" : " disabled"}" data-id="${esc(link.id)}" data-access="${accessible ? "1" : "0"}">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<div class="favicon" aria-hidden="true"><div class="letter">${letter}</div></div>
|
<div class="favicon" aria-hidden="true"><div class="letter">${letter}</div></div>
|
||||||
@@ -543,10 +573,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-desc">${desc || " "}</div>
|
<div class="card-desc">${desc || " "}</div>
|
||||||
<div class="tags">${favTag}${tags}</div>
|
<div class="tags">${favTag}${lockTag}${tags}</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<a class="btn mini" href="${u}" target="_blank" rel="noopener noreferrer">열기</a>
|
${openHtml}
|
||||||
<button class="btn mini" type="button" data-act="copy">URL 복사</button>
|
<button class="btn mini" type="button" data-act="copy"${copyAttrs}>URL 복사</button>
|
||||||
<button class="btn mini" type="button" data-act="edit">편집</button>
|
<button class="btn mini" type="button" data-act="edit">편집</button>
|
||||||
<button class="btn mini mini-danger" type="button" data-act="del">삭제</button>
|
<button class="btn mini mini-danger" type="button" data-act="del">삭제</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -771,10 +801,12 @@
|
|||||||
}
|
}
|
||||||
const isAuthed = await client.isAuthenticated();
|
const isAuthed = await client.isAuthenticated();
|
||||||
auth.user = isAuthed ? await client.getUser() : null;
|
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.btnLogout) el.btnLogout.hidden = !auth.user;
|
||||||
if (el.snsLogin) el.snsLogin.hidden = Boolean(auth.user);
|
if (el.snsLogin) el.snsLogin.hidden = Boolean(auth.user);
|
||||||
if (el.user) el.user.hidden = !auth.user;
|
if (el.user) el.user.hidden = !auth.user;
|
||||||
if (el.userText && auth.user) el.userText.textContent = auth.user.email || auth.user.name || "로그인됨";
|
if (el.userText && auth.user) el.userText.textContent = auth.user.email || auth.user.name || "로그인됨";
|
||||||
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loginWithConnection(provider) {
|
async function loginWithConnection(provider) {
|
||||||
@@ -795,6 +827,7 @@
|
|||||||
async function logout() {
|
async function logout() {
|
||||||
const client = await ensureAuthClient();
|
const client = await ensureAuthClient();
|
||||||
if (!client) return;
|
if (!client) return;
|
||||||
|
sessionEmail = "";
|
||||||
await client.logout({
|
await client.logout({
|
||||||
logoutParams: { returnTo: location.origin === "null" ? location.href : location.origin + location.pathname },
|
logoutParams: { returnTo: location.origin === "null" ? location.href : location.origin + location.pathname },
|
||||||
});
|
});
|
||||||
@@ -870,6 +903,11 @@
|
|||||||
const card = e.target.closest(".card");
|
const card = e.target.closest(".card");
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
const id = card.getAttribute("data-id");
|
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 act = btn.getAttribute("data-act");
|
||||||
const link = id ? getById(id) : null;
|
const link = id ? getById(id) : null;
|
||||||
if (!link) return;
|
if (!link) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user