# ObsWiki Session Log - Privacy & Authentication Fixes **Date:** August 10, 2025 **Duration:** ~45 minutes **Focus:** Fix privacy filtering for filetree, authentication UI, and login functionality --- ## Session Overview This session continued from a previous conversation where filetree functionality was implemented. The main issues addressed were: 1. **Privacy filtering not working** - private pages were visible without login 2. **Authentication UI not updating** - login button didn't change to logout 3. **Filetree stuck loading** - API calls missing authentication 4. **JavaScript syntax errors** - template string brace escaping issues 5. **Login form broken** - JavaScript object literal problems --- ## Issues & Solutions ### 1. Privacy Filtering Implementation **Issue:** Filetree showed all files regardless of authentication status or privacy settings **Root Cause:** The `/api/folder-files` endpoint didn't check user authentication or respect `obswiki_public: true` frontmatter settings. **Solution:** - Modified `folder_files_handler` to check authentication via `is_user_authenticated()` - Updated `build_folder_files()` to filter files based on privacy: - **Authenticated users**: See all files - **Non-authenticated users**: Only see files with `obswiki_public: true` - Added folder-level privacy: folders only show if they contain accessible files - Used `Box::pin` for recursive async function to handle folder traversal **Files Modified:** - `src/server/mod.rs` - Updated handler and build function - Added privacy checking logic for both files and folders ### 2. Authentication UI Not Updating **Issue:** Login button showed "Login" even when user was authenticated via cookies **Root Cause:** Frontend JavaScript only checked `localStorage` for tokens, not cookies. Server-side authentication worked via cookies, but client-side UI didn't detect this. **Solution:** - Added `getCookie()` helper function to parse browser cookies - Updated authentication check: `localStorage.getItem('obswiki_token') || getCookie('auth_token')` - Applied fix to all HTML templates (folder pages, wiki pages, welcome page, etc.) **JavaScript Added:** ```javascript function getCookie(name) { const value = '; ' + document.cookie; const parts = value.split('; ' + name + '='); if (parts.length === 2) return parts.pop().split(';').shift(); return null; } ``` ### 3. Filetree Loading Issues **Issue:** Filetree stuck on "Loading..." message **Root Cause:** API calls to `/api/folder-files` weren't including authentication credentials (cookies). **Solution:** - Added `credentials: 'same-origin'` to all fetch requests - Enhanced error handling with specific HTTP status codes - Improved console logging for debugging **API Call Fix:** ```javascript const response = await fetch('/api/folder-files?path=' + encodeURIComponent(folderPath), { credentials: 'same-origin' }); ``` ### 4. JavaScript Syntax Errors **Issue:** Multiple JavaScript syntax errors due to template string escaping problems **Root Cause:** Confusion between Rust format string escaping (`{{` → `{`) and JavaScript object literal syntax. **Problems Encountered:** - Extra closing braces `}});` with no matching opening braces - `loadFolderFiles()` calls placed outside `DOMContentLoaded` event handlers - Incorrect JavaScript object literal syntax **Solution:** - Moved filetree loading calls inside `DOMContentLoaded` event handlers - Removed extra unmatched closing braces - Fixed JavaScript structure and indentation ### 5. Login Form Broken **Issue:** Login form JavaScript had syntax errors preventing login **Root Cause:** Incorrect brace escaping in Rust template strings created malformed JavaScript. **Evolution of Fixes:** 1. **First attempt**: Fixed object shorthand syntax `{{ username, password }}` 2. **Second attempt**: Used explicit object syntax `{{username: username, password: password}}` 3. **Third attempt**: Simplified to property assignment to avoid object literals 4. **Final solution**: Realized login page doesn't need double braces at all (static template) **Final Working JavaScript:** ```javascript const loginData = {}; loginData.username = username; loginData.password = password; const response = await fetch('/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(loginData) }); ``` --- ## Technical Concepts Applied ### Template String Escaping in Rust - **Dynamic templates** (using `format!()`) need `{{` and `}}` for literal braces - **Static templates** (raw strings) use normal `{` and `}` for JavaScript - **Key insight**: Login page was static, not dynamic ### Authentication Flow - **Server-side**: Validates JWT tokens from cookies or Authorization headers - **Client-side**: Stores tokens in both localStorage and cookies for compatibility - **Hybrid approach**: Supports both API calls (Authorization header) and browser navigation (cookies) ### Privacy Model - **Default behavior**: Pages are private (require authentication) - **Public override**: `obswiki_public: true` in YAML frontmatter makes pages public - **Filetree filtering**: Only shows files/folders user has permission to access ### Async Rust Functions - **Recursive async functions** require `Box::pin` to avoid infinite-sized futures - **Pattern used**: `Box> + Send + 'a>` --- ## Debug Features Added ### Enhanced Logging - **Authentication debug**: Logs token verification results - **Privacy debug**: Shows whether pages are marked public/private - **API error handling**: Specific HTTP status codes in console - **Login flow debug**: Step-by-step login process logging ### Error Messages - **Filetree**: Shows specific error codes instead of generic "Loading..." - **Login**: Detailed console messages for troubleshooting - **Privacy**: Logs frontmatter parsing results --- ## Current Status ✅ **Working Features:** - Privacy filtering respects `obswiki_public: true` frontmatter - Authentication UI updates correctly (Login ↔ Logout) - Filetree loads with proper privacy filtering - Login form works with proper JavaScript syntax - Debug logging provides detailed troubleshooting info ✅ **Security Model:** - Pages private by default (require authentication) - Granular public page control via frontmatter - Folder visibility based on content accessibility - API endpoints respect same privacy rules as pages ✅ **Authentication System:** - JWT tokens work via cookies and localStorage - Hybrid client/server authentication checking - Proper token storage and cleanup on logout --- ## Key Learnings 1. **Template String Complexity**: Rust format string escaping in HTML templates is error-prone. Static templates are simpler. 2. **Cookie vs localStorage**: When server uses cookies but client checks localStorage, UI gets out of sync. Need both checks. 3. **Privacy by Default**: Secure approach - everything private unless explicitly marked public. 4. **Debug Logging Essential**: Complex authentication/privacy flows need extensive logging for troubleshooting. 5. **JavaScript Syntax in Templates**: When embedding JavaScript in Rust templates, consider whether braces need escaping based on template type. --- ## Files Modified ### Primary Changes: - `src/server/mod.rs` - Privacy filtering, auth UI fixes, JavaScript syntax fixes - All HTML templates updated with cookie-aware authentication checks ### Functions Updated: - `folder_files_handler()` - Added authentication checking - `build_folder_files()` - Added privacy filtering with `Box::pin` for async recursion - `is_user_authenticated()` - Added debug logging - `is_page_public()` - Enhanced frontmatter parsing with logging - `render_login_page()` - Fixed JavaScript syntax ### New Features: - `getCookie()` JavaScript helper function in all templates - Comprehensive debug logging throughout authentication flow - Enhanced error handling for API calls --- ## Next Potential Improvements 1. **Performance**: Cache privacy status to avoid repeated frontmatter parsing 2. **UX**: Loading states for filetree instead of "Loading..." text 3. **Security**: Rate limiting on login attempts 4. **Debug**: Production vs development logging levels 5. **Testing**: Unit tests for privacy filtering logic --- This session successfully resolved all major privacy, authentication, and JavaScript issues, resulting in a fully functional secure wiki with proper access controls.