gsdf
This commit is contained in:
@@ -757,10 +757,11 @@ class CommentSystem {
|
||||
// Render skeleton (Result: Layout visible immediately)
|
||||
// Skip when preserveScroll=true (tab re-focus refresh): the user already sees comments,
|
||||
// so wiping the DOM causes the browser to lose the #c anchor element and auto-scroll to top.
|
||||
// Only render skeleton for logged-in users to avoid flashing "Login to comment" before comments/permissions load.
|
||||
if (!scrollToId && !preserveScroll && this.user) {
|
||||
this.render([], this.user, initialIsSubscribed);
|
||||
this.restoreState(state);
|
||||
if (!scrollToId && !preserveScroll) {
|
||||
if (this.user || !this.container.querySelector('.login-placeholder, .comment-input, .lock-notice')) {
|
||||
this.render([], this.user, initialIsSubscribed);
|
||||
this.restoreState(state);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 || []) : [];
|
||||
|
||||
@@ -1463,6 +1463,8 @@ process.on('uncaughtException', err => {
|
||||
default_font: cfg.websrv.default_font || "",
|
||||
site_description: cfg.websrv.description || "The webs dumpster",
|
||||
enable_nsfl: !!cfg.enable_nsfl,
|
||||
public_nsfw: !!cfg.websrv.public_nsfw,
|
||||
public_untagged: !!cfg.websrv.public_untagged,
|
||||
onara: !!(cfg.onara !== undefined ? cfg.onara : cfg.websrv?.onara),
|
||||
is_onara_item: false,
|
||||
enable_private_uploads: cfg.enable_private_uploads !== false,
|
||||
|
||||
@@ -227,10 +227,14 @@
|
||||
@if(session) data-user="{{ session.user }}" @endif
|
||||
@if(session && (session.admin || session.is_moderator)) data-is-admin="true" @endif
|
||||
@if(item.is_comments_locked) data-is-locked="true" @endif>
|
||||
@if(session && !item.is_comments_locked)
|
||||
@if(item.is_comments_locked && !is_mod_or_admin)
|
||||
<div class="lock-notice">🔒 Comments are disabled on this thread.</div>
|
||||
@elseif(session)
|
||||
<div class="comment-input main-input">
|
||||
<textarea disabled></textarea>
|
||||
</div>
|
||||
@else
|
||||
<div class="login-placeholder"><a href="/login" class="login-trigger-btn">Login</a> to comment</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -19,10 +19,14 @@
|
||||
@if(session) data-user="{{ session.user }}" @endif
|
||||
@if(session && is_mod_or_admin) data-is-admin="true" @endif
|
||||
@if(item.is_comments_locked) data-is-locked="true" @endif>
|
||||
@if(session && !item.is_comments_locked)
|
||||
@if(item.is_comments_locked && !is_mod_or_admin)
|
||||
<div class="lock-notice">🔒 Comments are disabled on this thread.</div>
|
||||
@elseif(session)
|
||||
<div class="comment-input main-input">
|
||||
<textarea disabled></textarea>
|
||||
</div>
|
||||
@else
|
||||
<div class="login-placeholder"><a href="/login" class="login-trigger-btn">Login</a> to comment</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
@endif
|
||||
@if(private_society && !session)
|
||||
<script>
|
||||
window.f0ckSession = { logged_in: false, onara: @if(onara) true @else false @endif, enable_item_slugs: @if(enable_item_slugs) true @else false @endif, hide_comments_from_public: @if(hide_comments_from_public) true @else false @endif, enable_xd_score: @if(enable_xd_score) true @else false @endif, default_theme: "{{ default_theme }}", show_content_warning: @if(show_content_warning) true @else false @endif, use_new_layout: @if(default_layout === 'legacy')false @else true @endif, comment_display_mode: {{ comment_display_mode }}, comment_max_length: {{ comment_max_length !== null && comment_max_length !== undefined ? comment_max_length : 'null' }}, development: @if(development) true @else false @endif, allow_comment_deletion: @if(allow_comment_deletion) true @else false @endif, hide_sidebar_default: @if(hide_sidebar_default) true @else false @endif };
|
||||
window.f0ckSession = { logged_in: false, onara: @if(onara) true @else false @endif, enable_item_slugs: @if(enable_item_slugs) true @else false @endif, hide_comments_from_public: @if(hide_comments_from_public) true @else false @endif, enable_xd_score: @if(enable_xd_score) true @else false @endif, default_theme: "{{ default_theme }}", show_content_warning: @if(show_content_warning) true @else false @endif, use_new_layout: @if(default_layout === 'legacy')false @else true @endif, comment_display_mode: {{ comment_display_mode }}, comment_max_length: {{ comment_max_length !== null && comment_max_length !== undefined ? comment_max_length : 'null' }}, development: @if(development) true @else false @endif, allow_comment_deletion: @if(allow_comment_deletion) true @else false @endif, hide_sidebar_default: @if(hide_sidebar_default) true @else false @endif, public_untagged: @if(public_untagged) true @else false @endif, public_nsfw: @if(public_nsfw) true @else false @endif };
|
||||
window.f0ckDebug = window.f0ckSession.development ? console.log.bind(console) : () => {};
|
||||
(() => {
|
||||
const loginModal = document.getElementById('login-modal');
|
||||
@@ -378,6 +378,8 @@
|
||||
<script>
|
||||
window.f0ckSession = {
|
||||
onara: @if(onara) true @else false @endif,
|
||||
public_untagged: @if(public_untagged) true @else false @endif,
|
||||
public_nsfw: @if(public_nsfw) true @else false @endif,
|
||||
enable_item_slugs: @if(enable_item_slugs) true @else false @endif,
|
||||
strict_mode: @if(session && session.strict_mode) true @else false @endif,
|
||||
logged_in: @if(session) true @else false @endif,
|
||||
|
||||
Reference in New Issue
Block a user