Refactor giai đoạn 1: test các tính năng vừa thay đổi như tour, scene...

This commit is contained in:
2026-06-10 21:58:45 +07:00
parent 3f1b31b233
commit 358a98b21b
31 changed files with 1391 additions and 638 deletions
+41 -9
View File
@@ -3,6 +3,7 @@ const router = express.Router();
const path = require('path');
const fs = require('fs');
const sharp = require('sharp');
const jwt = require('jsonwebtoken');
const Asset = require('../models/Asset');
const Scene = require('../models/Scene');
@@ -26,20 +27,51 @@ router.get('/assets/view/:assetId', verifyReferer, optionalAuth, async (req, res
const asset = await Asset.findById(req.params.assetId);
if (!asset) return res.status(404).json({ message: 'Asset not found' });
// [FIX] Luôn kiểm tra JWT từ query string ngay cả khi optionalAuth đã chạy
let user = req.user;
const isGuest = !user || user.role === 'guest';
if (isGuest && req.query.token) {
try {
const decoded = jwt.verify(req.query.token, process.env.JWT_SECRET || 'your_jwt_secret');
if (decoded && decoded.id) {
const User = require('../models/User');
const authenticatedUser = await User.findById(decoded.id);
if (authenticatedUser) user = authenticatedUser;
}
} catch (e) {
}
}
const isAdmin = user && (user.role === 'admin' || user.role === 'moderator');
const userIdStr = user && user._id ? user._id.toString() : null;
const userEmail = user ? user.email : null;
// Kiểm tra quyền truy cập dựa trên Privacy của Scene liên kết
const scene = await Scene.findOne({ assetId: asset._id });
const scene = await Scene.findOne({ assetId: asset._id }).populate('tourId');
if (!scene) {
// Asset mồ côi, chỉ chủ sở hữu được xem
if (!req.user || req.user._id.toString() !== asset.uploadedBy.toString()) {
if (!isAdmin && (!userIdStr || userIdStr !== asset.uploadedBy.toString())) {
return res.status(403).json({ message: 'Bạn không được phép di chuyển đến cảnh này' });
}
} else {
const isTokenValid = scene.shareToken && (!scene.shareTokenExpires || new Date() < scene.shareTokenExpires);
const userEmail = req.user ? req.user.email : null;
let hasAccess = scene.privacy === 'public' ||
(scene.privacy === 'member' && req.user && (scene.sharedWith.includes(req.user._id) || (userEmail && scene.sharedEmails.includes(userEmail)))) ||
(req.user && scene.createdBy.toString() === req.user._id.toString()) ||
(scene.privacy === 'shared' && req.query.token === scene.shareToken && isTokenValid);
const isSceneTokenValid = scene.shareToken && (!scene.shareTokenExpires || new Date() < scene.shareTokenExpires);
const tour = scene.tourId;
const isTourTokenValid = tour && tour.shareToken && (!tour.shareTokenExpires || new Date() < tour.shareTokenExpires);
// Chuẩn hóa ID người tạo để so sánh
const sceneOwnerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;
const isOwner = userIdStr && sceneOwnerId && sceneOwnerId.toString() === userIdStr;
let hasAccess = isAdmin ||
scene.privacy === 'public' ||
(scene.privacy === 'member' && userIdStr && (scene.sharedWith.some(id => id.toString() === userIdStr) || (userEmail && scene.sharedEmails.includes(userEmail)))) ||
isOwner ||
(scene.privacy === 'shared' && req.query.token === scene.shareToken && isSceneTokenValid) ||
(tour && tour.privacy === 'shared' && req.query.token === tour.shareToken && isTourTokenValid);
if (scene.status === 'processing' && !hasAccess) {
return res.status(403).json({ message: 'Ảnh đang được xử lý và bạn không có quyền xem tạm thời' });
}
// [BRIDGE ACCESS LOGIC]
// Áp dụng tương tự cho Asset để đảm bảo hiển thị được ảnh khi di chuyển liên kết chéo
@@ -131,7 +163,7 @@ router.get('/assets/view_avatar/:filename', async (req, res) => {
*/
router.get('/me/assets', protect, async (req, res) => {
try {
const query = (req.user.role === 'admin' || req.user.role === 'Chủ sở hữu') ? {} : { uploadedBy: req.user._id };
const query = (req.user.role === 'admin') ? {} : { uploadedBy: req.user._id };
const assets = await Asset.aggregate([
{ $match: query },