gfsd
This commit is contained in:
@@ -63,11 +63,22 @@ export default (router, tpl) => {
|
||||
}
|
||||
|
||||
// Transform for frontend if needed, or send as is
|
||||
const anonymize = !req.session && cfg.main.guest_anonymize;
|
||||
const outComments = anonymize
|
||||
? comments.map(c => ({
|
||||
...c,
|
||||
username: 'anonymous',
|
||||
display_name: null,
|
||||
username_color: null,
|
||||
avatar: null,
|
||||
avatar_file: null
|
||||
}))
|
||||
: comments;
|
||||
return res.reply({
|
||||
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
||||
body: JSON.stringify({
|
||||
success: true,
|
||||
comments,
|
||||
comments: outComments,
|
||||
is_subscribed,
|
||||
is_locked,
|
||||
user_id: req.session ? req.session.id : null,
|
||||
@@ -122,6 +133,9 @@ export default (router, tpl) => {
|
||||
|
||||
// Browse User Comments
|
||||
router.get(/\/user\/(?<user>[^\/]+)\/comments/, async (req, res) => {
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
const user = decodeURIComponent(req.params.user);
|
||||
|
||||
try {
|
||||
@@ -1135,6 +1149,7 @@ export default (router, tpl) => {
|
||||
}
|
||||
}
|
||||
|
||||
const isAnonymized = !req.session && cfg.main.guest_anonymize;
|
||||
const processedComments = comments.map(c => {
|
||||
let ratingLabel = '?';
|
||||
let ratingClass = 'untagged';
|
||||
@@ -1144,9 +1159,6 @@ export default (router, tpl) => {
|
||||
|
||||
const commentContent = (c.content || '').trim();
|
||||
const commentFiles = filesMap.get(c.id) || [];
|
||||
// Compute overflow hint: true if content is likely taller than the 80px clamp.
|
||||
// ~120 chars ≈ 2-3 wrapped lines in the sidebar; any newlines > 2 or file
|
||||
// attachments (images/video) will also push height above the limit.
|
||||
const isLong = commentContent.length > 120
|
||||
|| commentContent.split('\n').length > 2
|
||||
|| commentFiles.length > 0
|
||||
@@ -1154,17 +1166,22 @@ export default (router, tpl) => {
|
||||
|
||||
return {
|
||||
...c,
|
||||
username: isAnonymized ? 'anonymous' : c.username,
|
||||
display_name: isAnonymized ? null : c.display_name,
|
||||
username_color: isAnonymized ? null : c.username_color,
|
||||
avatar: isAnonymized ? null : c.avatar,
|
||||
avatar_file: isAnonymized ? null : c.avatar_file,
|
||||
banner_file: isAnonymized ? null : c.banner_file,
|
||||
content: commentContent,
|
||||
username_color: c.username_color,
|
||||
item_rating_class: ratingClass,
|
||||
item_rating_label: ratingLabel,
|
||||
files: commentFiles,
|
||||
poll: pollMap.get(c.id) || null,
|
||||
is_long: isLong
|
||||
// created_at stays as the raw ISO timestamp so the frontend f0ckTimeAgo can localize it
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
if (req.url.qs?.json === 'true' || req.headers['x-requested-with'] === 'XMLHttpRequest') {
|
||||
return res.reply({
|
||||
headers: {
|
||||
|
||||
@@ -12,6 +12,10 @@ const auth = async (req, res, next) => {
|
||||
|
||||
export default (router, tpl) => {
|
||||
router.get(/\/user\/(?<user>[^/]+)\/?$/, async (req, res) => {
|
||||
// When guest anonymization is active, user profiles must not be accessible without a session
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
const user = decodeURIComponent(req.params.user);
|
||||
const mime = req.cookies.mime !== undefined ? req.cookies.mime : (req.query?.mime || req.url.qs?.mime || null);
|
||||
|
||||
@@ -223,6 +227,11 @@ export default (router, tpl) => {
|
||||
return res.reply({ code: 404, body: tpl.render('error', { message: 'Not found', tmp: null }, req) });
|
||||
}
|
||||
|
||||
// When guest anonymization is active, user gallery pages must require authentication
|
||||
if (cfg.main.guest_anonymize && !req.session && req.params.user && req.params.mode) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
// Auto-persist strict mode from URL to session if it's there
|
||||
if (req.session && (req.query?.strict !== undefined || req.url.qs?.strict !== undefined)) {
|
||||
req.session.strict_mode = (req.query?.strict === '1' || req.url.qs?.strict === '1');
|
||||
@@ -384,6 +393,10 @@ export default (router, tpl) => {
|
||||
// Hall columns for display
|
||||
data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : '';
|
||||
data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : '';
|
||||
// When guest anonymization is active, suppress source URL from the info modal
|
||||
if (cfg.main.guest_anonymize && !req.session && item.src) {
|
||||
item.src = null;
|
||||
}
|
||||
// Precomputed for template engine compatibility (avoids nested { } inside {{ }})
|
||||
data.item_rating_class = item.is_nsfl ? 'is-nsfl' : (item.is_nsfw ? 'is-nsfw' : (item.is_sfw ? 'is-sfw' : 'is-untagged'));
|
||||
data.item_rating_label = item.is_nsfl ? 'NSFL' : (item.is_nsfw ? 'NSFW' : (item.is_sfw ? 'SFW' : '?'));
|
||||
|
||||
@@ -377,9 +377,21 @@ export default (router, tpl) => {
|
||||
const lastItem = items[items.length - 1];
|
||||
const nextCursor = lastItem ? lastItem.id : null;
|
||||
|
||||
const isAnonymized = !req.session && cfg.main.guest_anonymize;
|
||||
const outItems = isAnonymized
|
||||
? items.map(item => ({
|
||||
...item,
|
||||
username: 'anonymous',
|
||||
display_name: 'anonymous',
|
||||
avatar: '/a/default.png',
|
||||
username_color: null,
|
||||
src_host: ''
|
||||
}))
|
||||
: items;
|
||||
|
||||
return res.reply({
|
||||
headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store, no-cache' },
|
||||
body: JSON.stringify({ success: true, items, nextCursor })
|
||||
body: JSON.stringify({ success: true, items: outItems, nextCursor })
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('[SCROLLER] Feed error:', e);
|
||||
|
||||
@@ -43,6 +43,9 @@ export default (router, tpl) => {
|
||||
|
||||
// List halls for a user
|
||||
router.get(/^\/user\/(?<owner>[^/]+)\/halls\/?$/, async (req, res) => {
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
if (cfg.websrv.userhalls_enabled === false) return res.reply({ code: 404, body: tpl.render('error', { message: 'Not found', tmp: null }, req) });
|
||||
const ownerName = decodeURIComponent(req.params.owner);
|
||||
const mode = req.mode ?? 0;
|
||||
@@ -80,6 +83,9 @@ export default (router, tpl) => {
|
||||
|
||||
// Item grid for a user hall
|
||||
router.get(/^\/user\/(?<owner>[^/]+)\/hall\/(?<slug>[^/]+)(?:\/p\/(?<page>\d+))?\/?$/, async (req, res) => {
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
if (cfg.websrv.userhalls_enabled === false) return res.reply({ code: 404, body: tpl.render('error', { message: 'Not found', tmp: null }, req) });
|
||||
const ownerName = decodeURIComponent(req.params.owner);
|
||||
const slug = decodeURIComponent(req.params.slug);
|
||||
@@ -126,6 +132,9 @@ export default (router, tpl) => {
|
||||
|
||||
// Single item within a user hall
|
||||
router.get(/^\/user\/(?<owner>[^/]+)\/hall\/(?<slug>[^/]+)\/(?<itemid>\d+)\/?$/, async (req, res) => {
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
if (cfg.websrv.userhalls_enabled === false) return res.reply({ code: 404, body: tpl.render('error', { message: 'Not found', tmp: null }, req) });
|
||||
const ownerName = decodeURIComponent(req.params.owner);
|
||||
const slug = decodeURIComponent(req.params.slug);
|
||||
@@ -176,6 +185,10 @@ export default (router, tpl) => {
|
||||
data.current_user_hall_slug = (data.tmp && data.tmp.userHall && typeof data.tmp.userHall === 'object') ? data.tmp.userHall.slug : (data.tmp && data.tmp.userHall ? data.tmp.userHall : '');
|
||||
data.current_user_hall_owner = (data.tmp && data.tmp.userHallOwner) ? data.tmp.userHallOwner : '';
|
||||
data.item_has_dimensions = !!(item.width && item.height);
|
||||
// When guest anonymization is active, suppress source URL from the info modal
|
||||
if (cfg.main.guest_anonymize && !req.session && item.src) {
|
||||
item.src = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Precompute hall display
|
||||
|
||||
@@ -158,6 +158,9 @@ export default (router, tpl) => {
|
||||
|
||||
// Main tags page
|
||||
router.get(/^\/user\/(?<user>[^\/]+)\/tags$/, async (req, res) => {
|
||||
if (cfg.main.guest_anonymize && !req.session) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
const userParam = decodeURIComponent(req.params.user);
|
||||
|
||||
const u = await db`
|
||||
|
||||
@@ -1419,6 +1419,7 @@ process.on('uncaughtException', err => {
|
||||
site: cfg.main.url.full,
|
||||
domain: cfg.main.url.domain,
|
||||
hide_comments_from_public: cfg.main.hide_comments_from_public,
|
||||
guest_anonymize: !!cfg.main.guest_anonymize,
|
||||
git_hash: typeof gitHash !== 'undefined' ? gitHash : 'unknown',
|
||||
get motd() { return getMotd(); },
|
||||
get manual_approval() { return getManualApproval(); },
|
||||
@@ -1495,6 +1496,7 @@ process.on('uncaughtException', err => {
|
||||
allow_language_change: cfg.websrv.allow_language_change !== false,
|
||||
enable_xd_score: !!cfg.websrv.enable_xd_score,
|
||||
enable_dynamic_thumbs: !!cfg.websrv.enable_dynamic_thumbs,
|
||||
default_thumb_size: (() => { const v = (cfg.websrv.default_thumb_size || '').toLowerCase(); return ['s', 'm', 'l', 'xl'].includes(v) ? v : 'm'; })(),
|
||||
comment_max_length: cfg.main.comment_max_length ?? null,
|
||||
enable_swf: !!cfg.websrv.enable_swf,
|
||||
enable_archive: !!cfg.websrv.enable_archive,
|
||||
|
||||
Reference in New Issue
Block a user