diff --git a/src/inc/routeinc/f0cklib.mjs b/src/inc/routeinc/f0cklib.mjs index dff5b65..6c1b5b2 100644 --- a/src/inc/routeinc/f0cklib.mjs +++ b/src/inc/routeinc/f0cklib.mjs @@ -263,7 +263,22 @@ export default { const tmp = { user, tag: isTitleSearch ? _decodedTag : tag, hall: hallObj || hall, mime, page: actPage, mode: mode, view_mode: fav ? 'favs' : 'uploads', strict: strict, userHall: userHallObj || userHallSlug, userHallOwner, tagger }; // Multi-rating support: if `ratings` array provided, build an OR-based SQL fragment const multiRatingSQL = (Array.isArray(ratings) && ratings.length > 0) ? lib.getMultiRatingMode(ratings) : null; - const baseMode = multiRatingSQL ?? lib.getMode(mode ?? 0); + let baseMode = multiRatingSQL ?? lib.getMode(mode ?? 0); + if (!session) { + if ((mode === 3 || mode === undefined || mode === null) && !multiRatingSQL) { + if (cfg.websrv.public_nsfw) { + baseMode = cfg.websrv.public_untagged + ? "(items.id in (select item_id from tags_assign where tag_id in (1, 2)) or not exists (select 1 from tags_assign where item_id = items.id))" + : "items.id in (select item_id from tags_assign where tag_id in (1, 2))"; + } else { + baseMode = cfg.websrv.public_untagged + ? "(items.id in (select item_id from tags_assign where tag_id = 1) or not exists (select 1 from tags_assign where item_id = items.id))" + : "items.id in (select item_id from tags_assign where tag_id = 1)"; + } + } else if (!cfg.websrv.public_untagged && (mode === 2 || (Array.isArray(ratings) && ratings.length === 1 && ratings[0] === 'untagged'))) { + baseMode = "1 = 0"; + } + } const modequery = baseMode; let tagFilter = db``; @@ -884,7 +899,29 @@ export default { const isNsfl = cfg.enable_nsfl && tags.some(t => t.id == nsfl_id); const isNsfw = tags.some(t => t.id == 2); const isSfw = tags.some(t => t.id == 1); - const isTagged = tags.length > 0; + // Guest rating & untagged restriction check for public uploads (visibility === 0) + if (!session && !isOwnerOrAdmin && (actitem.visibility || 0) === 0) { + let guestBlocked = false; + if (!isTagged && !cfg.websrv.public_untagged) guestBlocked = true; + else if (isNsfw && !cfg.websrv.public_nsfw) guestBlocked = true; + else if (isNsfl) guestBlocked = true; + + if (guestBlocked) { + const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall; + return { + success: false, + message: "Sorry, this post is currently not visible.", + item: { + id: itemid, + og_thumbnail: `${cfg.websrv.paths.thumbnails}/${itemid}${isNsfw ? '_blur' : ''}.webp`, + og_url: hallSlug + ? `https://${cfg.main.url.domain}/h/${encodeURIComponent(hallSlug)}/${itemid}` + : `https://${cfg.main.url.domain}/${itemid}`, + og_description: `Content not visible in current mode` + } + }; + } + } // Mode-mismatch visibility check: // Only enforce for members (session users) with an explicit mode preference.