fix: show post and comment actions only to the verified author
Deploy EG-BIM QA Gateway / deploy (push) Successful in 40s

This commit is contained in:
root committed 2026-10-30 15:58:41 +09:00
1 parent 688d16555e
commit dbf5dc3611
8 files changed
+89 -30

No files matched your search

+25 -20
View File
@@ -266,13 +266,16 @@
localStorage.setItem(STORAGE_KEY, JSON.stringify(posts));
}
function isPostOwner(post, user) {
if (!post || !user) return false;
function matchesAuthorId(authorId, user) {
if (!user) return false;
const normalizeId = function (id) { return String(id || '').trim().toLowerCase(); };
const postIds = [post.requesterId, post.requesterUuid].map(normalizeId).filter(Boolean);
const userIds = [user.requesterId, user.ssoSubject, user.userUuid].map(normalizeId).filter(Boolean);
if (postIds.length && userIds.length) return postIds.some(function (id) { return userIds.indexOf(id) > -1; });
return Boolean(post.author && [user.name, user.loginId, user.email].filter(Boolean).indexOf(post.author) > -1);
const ownerId = normalizeId(authorId);
const userId = normalizeId(user.requesterId || user.ssoSubject || user.userUuid);
return Boolean(ownerId && userId && ownerId === userId);
}
function isPostOwner(post, user) {
return Boolean(post) && matchesAuthorId(post.requesterId || post.requesterUuid, user);
}
function normalizeStatus(value) {
@@ -405,15 +408,15 @@
if (tenantId && tenantIds.indexOf(tenantId) === -1) tenantIds.unshift(tenantId);
const primaryTenant = tenantList.find(function (tenant) { return typeof tenant !== 'string' && (tenant.id || tenant.tenantId) === tenantId; }) || tenantList[0] || {};
const tenantName = raw.tenantName || raw.tenant_name || custom.tenantName || custom.tenant_name || claims.tenantName || claims.tenant_name || getTenantName(primaryTenant);
const ssoSubject = raw.ssoSubject || raw.oauthSubject || raw.subject || claims.sub || claims.subject || raw.userId || sessionStorage.getItem('descopeUserId') || '';
const userUuid = raw.userUuid || raw.userId || claims.userId || claims.user_id || sessionStorage.getItem('descopeUserId') || '';
const ssoSubject = raw.ssoSubject || raw.oauthSubject || raw.subject || claims.sub || claims.subject || raw.requesterId || raw.userUuid || raw.userId || sessionStorage.getItem('descopeUserId') || '';
const userUuid = raw.userUuid || raw.userId || claims.userId || claims.user_id || ssoSubject || sessionStorage.getItem('descopeUserId') || '';
const loginId = raw.loginId || (raw.loginIds || [])[0] || raw.email || claims.email || claimProfile.email || sessionStorage.getItem('loginId') || readCookie('descope_login_id') || '';
const email = raw.email || claims.email || claimProfile.email || sessionStorage.getItem('loginId') || '';
const company = raw.company || custom.company || claims.company || sessionStorage.getItem('company') || getCompanyNameFromEmail(email) || '';
return {
userUuid: userUuid,
ssoSubject: ssoSubject,
requesterId: ssoSubject,
requesterId: raw.requesterId || ssoSubject,
tenantId: tenantId,
requesterTenantId: tenantId,
tenantIds: tenantIds,
@@ -463,7 +466,12 @@
const response = await fetch(config.ssoSessionEndpoint, { credentials: 'include', headers: { Accept: 'application/json' } });
if (!response.ok) throw new Error('SSO 세션 확인에 실패했습니다.');
const body = await response.json();
const remoteUser = normalizeAuthUser(body.user || body, body.claims || body.scope || {});
const rawUser = body.user || body;
if (body.authenticated === false || !rawUser || !(rawUser.requesterId || rawUser.ssoSubject || rawUser.userUuid || rawUser.userId || rawUser.subject)) {
resolvedAuthUser = null;
return null;
}
const remoteUser = normalizeAuthUser(rawUser, body.claims || body.scope || {});
if (remoteUser.loginId || remoteUser.ssoSubject) {
resolvedAuthUser = remoteUser;
return remoteUser;
@@ -471,8 +479,8 @@
} catch (error) {
console.warn('[QA] SSO session bridge unavailable:', error.message);
}
resolvedAuthUser = localUser;
return localUser;
resolvedAuthUser = null;
return null;
}
function renderAuth(user) {
@@ -727,7 +735,7 @@
renderDetailStatus();
qs('[data-detail-date]').textContent = post.dateTime || post.date;
qs('[data-detail-author]').textContent = post.author;
let detailUser = getAuthUser();
const detailUser = await (authReady || Promise.resolve(getAuthUser()));
qs('[data-detail-company]').textContent = getPostCompanyLabel(post, detailUser);
qs('[data-detail-department]').textContent = post.department;
qs('[data-detail-content]').textContent = post.content;
@@ -747,20 +755,19 @@
const completionDoneNotice = qs("#completionDoneNotice");
const completionButton = qs("#completionButton");
const renderCompletionNotice = function () {
const owner = isPostOwner(post, detailUser || getAuthUser());
const owner = isPostOwner(post, detailUser);
const completed = normalizeStatus(post.status) === "완료" || post.completionConfirmed;
const visible = owner && !completed && post.completionRequested;
if (completionNotice) completionNotice.hidden = !visible;
if (completionDoneNotice) completionDoneNotice.hidden = !(owner && completed);
};
const ownerActions = function () {
const owner = isPostOwner(post, detailUser || getAuthUser());
const owner = isPostOwner(post, detailUser);
if (editButton) editButton.hidden = !owner;
if (deleteButton) deleteButton.hidden = !owner;
renderCompletionNotice();
};
ownerActions();
if (authReady) authReady.then(function (user) { detailUser = user || detailUser; ownerActions(); renderCompletionNotice(); comments = renderComments(comments); });
if (completionButton) completionButton.addEventListener("click", async function () {
if (!post.completionRequested || post.completionConfirmed) return;
completionButton.disabled = true;
@@ -890,15 +897,13 @@
let editingCommentId = null;
function isCommentOwner(comment, user) {
const authorId = String(comment.authorId || '').trim().toLowerCase();
const userIds = [user && user.requesterId, user && user.ssoSubject, user && user.userUuid].map(function (id) { return String(id || '').trim().toLowerCase(); }).filter(Boolean);
return Boolean(authorId && userIds.indexOf(authorId) !== -1);
return matchesAuthorId(comment.authorId, user);
}
function renderComments(comments) {
comments = (comments || []).map(normalizeComment).filter(function (comment) { return comment.content; });
qs('#commentCount').textContent = comments.length;
const user = detailUser || getAuthUser();
const user = detailUser;
qs('#comments').innerHTML = comments.length ? comments.map(function (comment) {
const owner = Boolean(comment.id) && isCommentOwner(comment, user);
const editing = Boolean(editingCommentId) && editingCommentId === comment.id && owner;