This commit is contained in:
2026-09-13 14:19:37 +02:00
parent 466d3c4f28
commit 7a525494cf
6 changed files with 37 additions and 15 deletions
+24 -4
View File
@@ -765,6 +765,7 @@
* Explicitly log in as anonymous (generates identity if none, establishes session, syncs guest favs) * Explicitly log in as anonymous (generates identity if none, establishes session, syncs guest favs)
*/ */
async loginAsAnonymous() { async loginAsAnonymous() {
if (this._loginInProgress) return;
if (window.f0ckSession && window.f0ckSession.enable_anonymous_access === false) { if (window.f0ckSession && window.f0ckSession.enable_anonymous_access === false) {
return; return;
} }
@@ -780,14 +781,22 @@
return; return;
} }
this._loginInProgress = true;
// Close the login modal immediately for visual feedback
const loginModal = document.getElementById('login-modal');
if (loginModal) loginModal.style.display = 'none';
try { try {
if (!this.pubkey) { if (!this.pubkey) {
await this.generateIdentity(true); await this.generateIdentity();
} else {
await this.ensureSession(true, true);
} }
await this.ensureSession(true, true);
if (!this.isSessionReady) return; if (!this.isSessionReady) {
this._loginInProgress = false;
return;
}
// Sync any guest favorites saved in localStorage to this anon account // Sync any guest favorites saved in localStorage to this anon account
if (window.f0ckGuestFavs && typeof window.f0ckGuestFavs.importToAccount === 'function') { if (window.f0ckGuestFavs && typeof window.f0ckGuestFavs.importToAccount === 'function') {
@@ -800,6 +809,7 @@
// Reload page to reflect authenticated anonymous session across navbar, comments, settings // Reload page to reflect authenticated anonymous session across navbar, comments, settings
window.location.reload(); window.location.reload();
} catch (err) { } catch (err) {
this._loginInProgress = false;
console.error('[ANON_SSH] Login as anonymous failed:', err); console.error('[ANON_SSH] Login as anonymous failed:', err);
alert('Failed to log in as anonymous: ' + (err.message || err)); alert('Failed to log in as anonymous: ' + (err.message || err));
} }
@@ -977,6 +987,16 @@
} }
attachUIListeners() { attachUIListeners() {
// Direct click handler for the modal login-as-anonymous button
const modalAnonBtn = document.getElementById('modal-login-as-anon-btn');
if (modalAnonBtn) {
modalAnonBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
this.loginAsAnonymous();
});
}
// Global click handler for Login as anonymous, Identity modal, & Logout // Global click handler for Login as anonymous, Identity modal, & Logout
document.addEventListener('click', (e) => { document.addEventListener('click', (e) => {
const identityTarget = e.target.closest('#nav-anon-identity-btn'); const identityTarget = e.target.closest('#nav-anon-identity-btn');
+1 -1
View File
@@ -43,7 +43,7 @@
"url_tab_yt": "URL / YouTube", "url_tab_yt": "URL / YouTube",
"url_placeholder": "Paste a URL to download...", "url_placeholder": "Paste a URL to download...",
"url_placeholder_yt": "Paste a URL or YouTube link...", "url_placeholder_yt": "Paste a URL or YouTube link...",
"url_placeholder_shitpost": "Paste multiple URLs here (one per line)...", "url_placeholder_shitpost": "Paste a URL or YouTube link...",
"drop_here": "Drop your file here", "drop_here": "Drop your file here",
"admin_boost": "Admin Boost", "admin_boost": "Admin Boost",
"custom_thumbnail": "Custom Thumbnail", "custom_thumbnail": "Custom Thumbnail",
+7 -2
View File
@@ -13,10 +13,15 @@ const auth = async (req, res, next) => {
}; };
export default (router, tpl) => { export default (router, tpl) => {
router.get(/\/user\/(?<user>[^/]+)\/?$/, async (req, res) => { router.get(/^\/user\/(?<user>[^/]+)\/?$/, async (req, res) => {
// When anonymization is active, user profiles must not be accessible without an authenticated regular session // When anonymization is active, user profiles must not be accessible without an authenticated regular session
// But allow anon users to view their own profile
if (isAnonymizeSession(req.session)) { if (isAnonymizeSession(req.session)) {
return req.session ? res.redirect('/') : res.redirect('/login'); const requestedUser = decodeURIComponent(req.params.user).toLowerCase();
const sessionUser = (req.session?.user || req.session?.login || '').toLowerCase();
if (requestedUser !== sessionUser) {
return req.session ? res.redirect('/') : res.redirect('/login');
}
} }
const user = decodeURIComponent(req.params.user); const user = decodeURIComponent(req.params.user);
const mime = req.cookies.mime !== undefined ? req.cookies.mime : (req.query?.mime || req.url.qs?.mime || null); const mime = req.cookies.mime !== undefined ? req.cookies.mime : (req.query?.mime || req.url.qs?.mime || null);
+2
View File
@@ -1065,7 +1065,9 @@
<button id="chan-open-btn" class="topbar-icon-btn" title="{{ t('scroller.chan_threads') }}" style="display:none"><i class="fa-solid fa-clover"></i></button> <button id="chan-open-btn" class="topbar-icon-btn" title="{{ t('scroller.chan_threads') }}" style="display:none"><i class="fa-solid fa-clover"></i></button>
<button id="chan-gallery-btn" class="topbar-icon-btn" title="{{ t('scroller.thread_gallery') }} (G)" style="display:none"><i class="fa-solid fa-grip"></i></button> <button id="chan-gallery-btn" class="topbar-icon-btn" title="{{ t('scroller.thread_gallery') }} (G)" style="display:none"><i class="fa-solid fa-grip"></i></button>
<button id="settings-open-btn" class="topbar-icon-btn" title="{{ t('scroller.settings') }}"><i class="fa-solid fa-gear"></i></button> <button id="settings-open-btn" class="topbar-icon-btn" title="{{ t('scroller.settings') }}"><i class="fa-solid fa-gear"></i></button>
@if(typeof session !== 'undefined' && session && (!session.is_anon || (enable_anonymous_access && anon_permissions.filter)))
<button id="filter-open-btn" class="topbar-icon-btn" title="{{ t('scroller.filters') }} (F)"><i class="fa-solid fa-sliders"></i></button> <button id="filter-open-btn" class="topbar-icon-btn" title="{{ t('scroller.filters') }} (F)"><i class="fa-solid fa-sliders"></i></button>
@endif
@if(typeof session !== 'undefined' && session) @if(typeof session !== 'undefined' && session)
<div id="scroller-notif-wrap" style="position:relative;"> <div id="scroller-notif-wrap" style="position:relative;">
<button id="scroller-notif-btn" class="topbar-icon-btn" title="Notifications"> <button id="scroller-notif-btn" class="topbar-icon-btn" title="Notifications">
+1 -1
View File
@@ -6,7 +6,7 @@
const _isAnon = typeof session !== 'undefined' && session && (session.is_anon || session.user === 'anonymous' || (typeof session.user === 'string' && session.user.startsWith('anon_'))); const _isAnon = typeof session !== 'undefined' && session && (session.is_anon || session.user === 'anonymous' || (typeof session.user === 'string' && session.user.startsWith('anon_')));
const _isGuest = !_isMember && !_isAnon; const _isGuest = !_isMember && !_isAnon;
const _isAnonUser = !_isMember; const _isAnonUser = !_isMember;
const _canExcludeTags = !_isAnonUser || (typeof anon_permissions !== 'undefined' && anon_permissions && anon_permissions.exclude_tags !== false && anon_permissions.filter !== false); const _canExcludeTags = !_isGuest && (!_isAnonUser || (typeof anon_permissions !== 'undefined' && anon_permissions && anon_permissions.exclude_tags !== false && anon_permissions.filter !== false));
const _allowedModes = _isGuest ? ['sfw'] : ((typeof anon_permissions !== 'undefined' && anon_permissions && anon_permissions.allowed_modes) || ['sfw', 'nsfw', 'untagged', 'all', 'nsfl']); const _allowedModes = _isGuest ? ['sfw'] : ((typeof anon_permissions !== 'undefined' && anon_permissions && anon_permissions.allowed_modes) || ['sfw', 'nsfw', 'untagged', 'all', 'nsfl']);
const _showSfw = true; const _showSfw = true;
const _showNsfw = _isGuest || (!_isAnonUser || _allowedModes.includes('nsfw')); const _showNsfw = _isGuest || (!_isAnonUser || _allowedModes.includes('nsfw'));
+2 -7
View File
@@ -269,12 +269,7 @@
<a href="/random" id="nav-random" title="Random"><i class="fa-solid fa-shuffle"></i></a> <a href="/random" id="nav-random" title="Random"><i class="fa-solid fa-shuffle"></i></a>
@endif @endif
<a href="#" id="nav-search-btn" title="Search"><i class="fa-solid fa-magnifying-glass"></i></a> <a href="#" id="nav-search-btn" title="Search"><i class="fa-solid fa-magnifying-glass"></i></a>
@if(enable_anonymous_access && anon_permissions.filter)
<a href="#" id="nav-filter-btn" title="Filter" style="position: relative; display: inline-flex; align-items: center; justify-content: center; z-index: 1000;">
<i class="fa-solid fa-filter"></i>
<span id="nav-filter-badge" class="filter-badge filter-badge-sfw">SFW</span>
</a>
@endif
</div> </div>
</div> </div>
@@ -290,7 +285,7 @@
<a href="/favs" id="nav-guest-favs-link" class="mobile-only">{{ t('nav.favs') }}</a> <a href="/favs" id="nav-guest-favs-link" class="mobile-only">{{ t('nav.favs') }}</a>
@endif @endif
@if(enable_anonymous_access) @if(enable_anonymous_access)
<a href="#" id="nav-login-anon-btn" @if(session && session.is_anon) style="display:none;" @endif><i class="fa-solid fa-user-secret"></i> Login as anonymous</a>
<a href="#" id="nav-anon-identity-btn" @if(!session || !session.is_anon) style="display:none;" @endif onclick="event.preventDefault(); if(window.f0ckAnonSSH) { window.f0ckAnonSSH.openModal(); } else { const m = document.getElementById('anon-ssh-modal'); if (m) m.style.display='flex'; }"><i class="fa-solid fa-key"></i> Key Management</a> <a href="#" id="nav-anon-identity-btn" @if(!session || !session.is_anon) style="display:none;" @endif onclick="event.preventDefault(); if(window.f0ckAnonSSH) { window.f0ckAnonSSH.openModal(); } else { const m = document.getElementById('anon-ssh-modal'); if (m) m.style.display='flex'; }"><i class="fa-solid fa-key"></i> Key Management</a>
<a href="/settings" id="nav-anon-settings-btn" @if(!session || !session.is_anon) style="display:none;" @endif><i class="fa-solid fa-gear"></i> Settings</a> <a href="/settings" id="nav-anon-settings-btn" @if(!session || !session.is_anon) style="display:none;" @endif><i class="fa-solid fa-gear"></i> Settings</a>
@endif @endif