sửa lỗi privacy cho nhiều scene con, không cho phép ghi hoặc nhận sai

This commit is contained in:
2026-06-10 09:35:00 +07:00
parent 37d1b0095d
commit 02cd68f23c
12 changed files with 162 additions and 20 deletions
+25 -3
View File
@@ -1098,12 +1098,22 @@ async function openScene(sceneId, privacy, shareToken, force = false, initialPit
const scene = await sceneRes.json();
const hotspots = await hotspotsRes.json();
console.log("DEBUG: Hotspots raw data from API:", hotspots);
if (!sceneRes.ok) throw new Error(scene.message || 'Failed to fetch scene details');
// Lấy ID người tạo (createdBy) để phân quyền chuột phải trong viewer
// [FIX CRITICAL] Kiểm tra bảo mật Client-side:
// Nếu scene là private, chỉ cho phép chủ sở hữu xem (ngay cả khi backend vô tình trả về dữ liệu qua token cũ)
const sceneOwnerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;
const currentUserId = localStorage.getItem('userId');
const userRole = localStorage.getItem('role');
const isOwner = currentUserId && sceneOwnerId && currentUserId.toString() === sceneOwnerId.toString();
const isAdmin = userRole === 'admin' || userRole === 'Chủ sở hữu';
if (scene.privacy === 'private' && !isOwner && !isAdmin) {
throw new Error("Cảnh này đã được chủ sở hữu chuyển sang chế độ riêng tư.");
}
console.log("DEBUG: Hotspots raw data from API:", hotspots);
// Tự động focus bản đồ vào vị trí của Scene
if (map) {
@@ -2012,6 +2022,7 @@ window.openEditFromMedia = function(scene, isChild = false) {
window.openEditMetadataModal = function(scene, isChildArg = null) {
// Ưu tiên isChildScene từ object scene, hoặc giá trị truyền vào thủ công
const isChild = isChildArg !== null ? isChildArg : (!!scene.isChildScene);
const modalTitle = document.getElementById('edit-metadata-modal-title');
currentEditingScene = scene; // Lưu lại để dùng cho chia sẻ
// Load dữ liệu chia sẻ hiện tại
@@ -2035,10 +2046,13 @@ window.openEditMetadataModal = function(scene, isChildArg = null) {
privacySelect.value = scene.privacy;
privacySelect.disabled = true;
childInfo.style.display = 'block';
if (modalTitle) modalTitle.innerText = "Chi tiết Cảnh con (Kế thừa)";
childInfo.innerHTML = `️ Cảnh này thuộc một tour. Quyền riêng tư được quản lý bởi Cảnh gốc.`;
} else {
privacySelect.value = scene.privacy;
privacySelect.disabled = false;
childInfo.style.display = 'none';
if (modalTitle) modalTitle.innerText = "Sửa 3D Scene (Cảnh gốc)";
}
handleEditPrivacyChange(); // Cập nhật hiển thị nút bánh răng
@@ -2241,10 +2255,18 @@ async function submitEditScene(e) {
headers: { 'Authorization': `Bearer ${token}` },
body: formData
});
const data = await res.json();
if (!res.ok) throw new Error(data.message);
showNotification("Đã cập nhật thông tin cảnh thành công!", 'success');
// [FIX CRITICAL] Nếu chuyển sang Private, xóa token lưu cục bộ nếu là scene đang xem
const newPrivacy = document.getElementById('edit-modal-privacy').value;
if (newPrivacy === 'private' && localStorage.getItem('activeSceneId') === id) {
localStorage.removeItem('activeSceneToken');
localStorage.setItem('activeScenePrivacy', 'private');
}
showNotification("Cập nhật thành công! Các liên kết chia sẻ cũ đã bị vô hiệu hóa.", 'success');
closeEditMetadataModal();
loadScenes();
} catch (err) {