This commit is contained in:
2026-09-11 19:40:30 +02:00
parent d72eae7509
commit 52ed9fd7bd
7 changed files with 67 additions and 30 deletions
+46 -22
View File
@@ -18,23 +18,35 @@ const computeBaseMode = (mode, ratings, session) => {
const effMode = Number(mode ?? 0);
const ratingsArr = (Array.isArray(ratings) && ratings.length > 0) ? ratings : null;
// For guest sessions, sanitize ratingsArr to only allow permitted ratings
let safeRatingsArr = ratingsArr;
if (!session && ratingsArr) {
const allowedRatings = ['sfw'];
if (cfg.websrv.public_nsfw) allowedRatings.push('nsfw');
if (cfg.websrv.public_untagged) allowedRatings.push('untagged');
safeRatingsArr = ratingsArr.filter(r => allowedRatings.includes(r));
if (safeRatingsArr.length === 0) {
return "1 = 0";
}
}
let baseMode;
if (effMode === 2) {
if (ratingsArr && ratingsArr.includes('untagged') && ratingsArr.length > 1) {
baseMode = lib.getMultiRatingMode(ratingsArr);
if (safeRatingsArr && safeRatingsArr.includes('untagged') && safeRatingsArr.length > 1) {
baseMode = lib.getMultiRatingMode(safeRatingsArr);
} else {
baseMode = lib.getMode(2);
}
} else if (effMode === 3) {
baseMode = (ratingsArr && ratingsArr.length > 1) ? lib.getMultiRatingMode(ratingsArr) : lib.getMode(3);
baseMode = (safeRatingsArr && safeRatingsArr.length > 1) ? lib.getMultiRatingMode(safeRatingsArr) : lib.getMode(3);
} else {
const multiRatingSQL = ratingsArr ? lib.getMultiRatingMode(ratingsArr) : null;
const multiRatingSQL = safeRatingsArr ? lib.getMultiRatingMode(safeRatingsArr) : null;
baseMode = multiRatingSQL ?? lib.getMode(effMode);
}
if (!session) {
const nsflId = parseInt(cfg.nsfl_tag_id, 10) || 3;
if ((effMode === 0 || effMode === 3 || mode === undefined || mode === null) && (!ratingsArr || ratingsArr.length <= 1)) {
if ((effMode === 0 || effMode === 3 || mode === undefined || mode === null) && (!safeRatingsArr || safeRatingsArr.length <= 1)) {
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 and tag_id in (1, 2, ${nsflId})))`
@@ -44,10 +56,16 @@ const computeBaseMode = (mode, ratings, session) => {
? `(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 and tag_id in (1, 2, ${nsflId})))`
: "items.id in (select item_id from tags_assign where tag_id = 1)";
}
} else if (!cfg.websrv.public_untagged) {
if (effMode === 2 || (ratingsArr && ratingsArr.length === 1 && ratingsArr[0] === 'untagged')) {
} else if (effMode === 2) {
if (!cfg.websrv.public_untagged) {
baseMode = "1 = 0";
}
} else if (effMode === 1) {
if (!cfg.websrv.public_nsfw) {
baseMode = "1 = 0";
}
} else if (effMode === 4) {
baseMode = "1 = 0";
}
}
return baseMode;
@@ -824,12 +842,7 @@ export default {
const effMode = Number(mode ?? 0);
const nsflId = parseInt(cfg.nsfl_tag_id, 10) || 3;
const itemModeQuery = session
? computeBaseMode(mode, ratings, session)
: (cfg.websrv.public_nsfw
? `not exists (select 1 from tags_assign where item_id = items.id and tag_id = ${nsflId})`
: `not exists (select 1 from tags_assign where item_id = items.id and tag_id in (2, ${nsflId}))`
);
const itemModeQuery = computeBaseMode(mode, ratings, session);
let tagFilter = db``;
let titleFilter = db``;
@@ -969,12 +982,22 @@ export default {
last_viewed = now()
`.catch(e => console.error('Failed to track view:', e));
}
// Guest global filter check for public items (unlisted items requested by direct link/slug bypass guest rating blocks)
if (!session && getGlobalfilter() && (actitem.visibility || 0) === 0) {
const filteredItem = await db`
select 1 from tags_assign where item_id = ${itemid} and (${db.unsafe(getGlobalfilter())}) limit 1
`;
if (filteredItem.length > 0) {
// Guest rating restriction check for public items (unlisted items requested by direct link/slug bypass guest rating blocks)
if (!session && (actitem.visibility || 0) === 0) {
let blocked = false;
if (getGlobalfilter()) {
const filteredItem = await db`
select 1 from tags_assign where item_id = ${itemid} and (${db.unsafe(getGlobalfilter())}) limit 1
`;
if (filteredItem.length > 0) blocked = true;
}
if (!blocked && !cfg.websrv.public_untagged) {
const ratingTag = await db`
select 1 from tags_assign where item_id = ${itemid} and tag_id in (1, 2, ${nsflId}) limit 1
`;
if (ratingTag.length === 0) blocked = true;
}
if (blocked) {
const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall;
return {
success: false,
@@ -1157,12 +1180,13 @@ export default {
const isNsfw = tags.some(t => t.id == 2);
const isSfw = tags.some(t => t.id == 1);
const isTagged = tags.length > 0;
const isUntagged = !isSfw && !isNsfw && !isNsfl;
// Guest rating restriction check for public uploads (visibility === 0)
// Direct links to public unrated/untagged posts are allowed for guests.
if (!session && !isOwnerOrAdmin && (actitem.visibility || 0) === 0) {
let guestBlocked = false;
if (isNsfw && !cfg.websrv.public_nsfw) guestBlocked = true;
else if (isNsfl) guestBlocked = true;
else if (isUntagged && !cfg.websrv.public_untagged) guestBlocked = true;
if (guestBlocked) {
const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall;
@@ -1187,10 +1211,10 @@ export default {
const userMode = Number(mode ?? 0);
if (userMode !== 3) {
let modeBlocked = false;
if (userMode === 0 && (isNsfw || isNsfl)) modeBlocked = true; // SFW mode, item is NSFW or NSFL
if (userMode === 0 && (isNsfw || isNsfl || (!session && isUntagged && !cfg.websrv.public_untagged))) modeBlocked = true; // SFW mode, item is NSFW or NSFL
else if (userMode === 1 && !isNsfw) modeBlocked = true; // NSFW mode, item is not NSFW
else if (userMode === 4 && (!cfg.enable_nsfl || !isNsfl)) modeBlocked = true; // NSFL mode, item is not NSFL
else if (userMode === 2 && isTagged) modeBlocked = true; // Untagged mode, item has tags
else if (userMode === 2 && (isTagged || (!session && !cfg.websrv.public_untagged))) modeBlocked = true; // Untagged mode, item has tags
if (modeBlocked && !isOwnerOrAdmin && actitem.visibility !== 1) {
const hallSlug = hall && typeof hall === 'object' ? hall.slug : hall;
+1 -1
View File
@@ -1016,7 +1016,7 @@ export default (router, tpl) => {
const multiRatingSQL = (ratingsArr && ratingsArr.length > 0) ? lib.getMultiRatingMode(ratingsArr) : null;
// Build mode SQL — replace items.id alias with i.id used in the activity query
const modequery = (multiRatingSQL ?? lib.getMode(mode)).replace(/items\.id/g, 'i.id');
const modequery = f0cklib.computeBaseMode(mode, ratingsArr, req.session).replace(/items\.id/g, 'i.id');
const globalfilterTags = cfg.websrv.public_nsfw ? (cfg.nsfp || []).filter(id => id !== 2) : (cfg.nsfp || []);
const globalfilter = globalfilterTags.length ? globalfilterTags.map(n => `tag_id = ${n}`).join(' or ') : null;
const excludedTags = req.session ? (req.session.excluded_tags || []) : [];