Commit Graph
35 Commits
Author SHA1 Message Date
john-okeefe 9e420b63ad chore(deps): upgrade core dependencies
- pgx/v5: v5.4.3 → v5.8.0
- golang-jwt/jwt/v5: v5.3.0 → v5.3.1
- echo/v4: v4.13.4 → v4.15.1
- google/uuid: v1.4.0 → v1.6.0
- golang.org/x/crypto: v0.46.0 → v0.48.0
- golang.org/x/text: v0.33.0 → v0.34.0

Also updates indirect dependencies including puddle/v2, brotli,
regexp2, and other transitive deps.

Build and tests passing with pgx v5.8.0 (internal/anynil package
removed but not used by our code).
2026-02-22 13:11:06 -05:00
john-okeefe 31e286a14b fix(handlers): check user existence before deletion in DeleteUser
Add explicit check to verify target user exists in database before
attempting deletion. Previously, the handler would return 200 OK when
trying to delete non-existent users.

Changes:
- Add userFound flag to track if target user was found in user list
- Explicitly check pgtype.UUID.Bytes against all users' IDs
- Return 404 Not Found if user doesn't exist (before last admin check)
- Supports both JSON and HTML (HTMX) response formats

This fixes the failing test:
- TestDeleteUserConsolidated/DELETE_/api/auth/profile/:id_-_Delete_non-existent_user

The check uses the existing ListUsers result, so no additional database
query is required. The pgtype.UUID.Bytes comparison ensures exact
16-byte UUID matching.
2026-02-22 12:17:50 -05:00
john-okeefe bb0970dfd0 feat(handlers): implement consolidated user profile endpoints
Implement DeleteUser, ResetUserPassword, and UpdateUserAdmin handlers.
Update collections handler to check soft-deleted users. Update dashboard
service to exclude deleted users from statistics.
2026-02-22 01:57:49 -05:00
john-okeefe fce16b53f7 fix(auth): return JSON for HTMX login failures instead of HTML 2026-02-16 21:08:15 -05:00
john-okeefe 2e1af8d20b feat(auth): extend session duration to 7 days using constants
- Add SessionDuration constant (7 days) and SessionDurationSec computed value
- Update JWT token expiration to use SessionDuration instead of 1 hour
- Update register/login cookie MaxAge to use SessionDurationSec (604800)
- Update register/login API response ExpiresIn to use SessionDurationSec
- Update refresh token endpoint ExpiresIn to use SessionDurationSec
- Remove redundant client-side document.cookie lines from login/register
- Add TODO comment for HTTPS cookie Secure flag

This provides Google-like persistent sessions with a single source of truth
for session duration, eliminating hardcoded values throughout the codebase.
2026-02-16 16:49:43 -05:00
john-okeefe b5156bbe16 feat: add HTTP-only cookie for browser authentication
- Set HTTP-only cookie in login handler for SSR authentication
- Set HTTP-only cookie in registration handler
- Change default redirect from /bookshelf to /dashboard
- Cookie enables browser page navigation without JavaScript
2026-02-15 21:36:42 -05:00
john-okeefe d7ab22c399 fix(auth): add jti claim to JWT tokens for unique token identification 2026-02-14 21:37:29 -05:00
john-okeefe 4488ed5d16 refactor(handlers): remove per-user scan settings handlers
Clean up auth.go after migrating to system-wide settings:
- Remove UpdateScanSettings handler (moved to system_settings.go)
- Remove GetScanSettings handler (moved to system_settings.go)
- Remove UpdateScanSettingsRequest type (now in system_settings.go)

These handlers are now in SystemSettingsHandler with system-wide scope
instead of per-user functionality.
2026-02-09 20:10:18 -05:00
john-okeefe 3d776e762c Check for pgx.ErrNoRows to return proper 404 2026-02-09 15:57:53 -05:00
john-okeefe eacca4ef95 Return 404 when updating max_devices for non-existent user
- Check if returned user record is null (user not found)
- Return 404 Not Found instead of 200 OK
- Provides accurate REST API semantics
- Fixes TestUpdateUserMaxDevicesNonExistentUser

Related: Database query change commit
2026-02-09 15:53:14 -05:00
john-okeefe d9c6be1429 docs: rename DEVELOPMENT.md to development.md and update links
- Rename docs/contributing/DEVELOPMENT.md to development.md (lowercase)
- Update all references from DEVELOPMENT.md to Development.md (titlecase links)
- Update docs/contributing/contributing.md
- Update docs/index.md
2026-02-03 13:54:11 -05:00
john-okeefe 00a083b60b Rename backend code references: Bookmann → Bookhoard
Backend changes:
- Update import paths: bookmann/internal → bookhoard/internal
- Rename struct fields: BookmannUUID → BookhoardUUID
- Update handler function names: mapContentIdToBookmannUUID → mapContentIdToBookhoardUUID
- Update HTTP response headers: X-Bookmann-* → X-Bookhoard-*
- Update service and middleware references
- Update main.go imports and references

This is part 2 of the project rename to Bookhoard.
2026-02-01 16:11:54 -05:00
john-okeefe 6bdf4bfcd4 refactor: remove deprecated ebook folder handlers and restore auth functions
Phase 2: Dead Code Removal

Removed:
- AddEbookFolder handler (deprecated)
- GetEbookFolders handler (deprecated)
- DeleteEbookFolder handler (deprecated)
- AddEbookFolderRequest struct
- DeleteEbookFolderRequest struct
- EbookFolderResponse struct

Fixed:
- Restored Register function (user registration)
- Restored Login function (user authentication)
- Restored GetProfile function
- Restored UpdateProfile function
- Restored UserProfile struct
- Restored UpdateProfileRequest struct

Note: Critical auth functions were accidentally deleted during cleanup
and have been restored to maintain application functionality.
2026-02-01 14:10:57 -05:00
john-okeefe 5039071ea3 Add admin-configurable device cap per user
- Add max_devices column to users table (default: 10)
- Add UpdateUserMaxDevices database query
- Add CountUserDevices database query
- Add UpdateUserMaxDevices handler with validation (1-100 devices)
- Add PUT /api/auth/users/:id/max-devices endpoint (admin only)
- Update UserList struct to include max_devices field
- Validate user ID format and max_devices range
- Return appropriate errors for invalid requests
2026-01-31 13:06:21 -05:00
john-okeefe d440e55f05 Update handlers to work with UUID refresh tokens
- Add parseTokenUUID() helper to convert string to pgtype.UUID
- Update RefreshAccessToken to parse token string to UUID before validation
- Update Logout to parse token string to UUID before revoking
- Update CreateRefreshToken to pass UUID directly to database
- Update auth.go: fix return value order from CreateRefreshToken
- Remove unnecessary comments for cleaner code
2026-01-31 11:44:35 -05:00
john-okeefe 420af7978a fix: critical security vulnerabilities
- Fix type assertion panics in auth.go (9 handlers)
  * GetProfile, UpdateProfile, UpdateTheme, UpdateUsername
  * UpdateEmail, UpdatePassword, DeleteAccount
  * UpdateScanSettings, GetScanSettings, Register admin check
  * Replace c.Get("user_id").(string) with MustGetAuthenticatedUser()

- Fix type assertion panic in library.go
  * GetUserVisibleLibraries now uses MustGetAuthenticatedUser()

- Add path traversal protection to AddLibraryFolder
  * Detect and block ".." in paths
  * Clean paths with filepath.Clean()
  * Verify path is a directory before adding

- Remove debug logging from Login handler
  * Removed all fmt.Printf statements
  * No more plaintext password logging

- Create safe context helper functions
  * internal/handlers/context.go added
  * GetAuthenticatedUser() for safe retrieval
  * MustGetAuthenticatedUser() for post-auth middleware

Security: Critical
Tests: All 62 integration tests pass
Breaking: None - backward compatible
2026-01-30 08:58:43 -05:00
john-okeefe d9ca3d5a65 feat: add /bookshelf route and update redirects
- Add /bookshelf route as default page for logged-in users
- Update login and register handlers to redirect to /bookshelf
- Update homepage to auto-redirect to /bookshelf when logged in
- Preserve /dashboard route for backward compatibility
- Update test redirects to use /bookshelf

Changes:
- main.go: Add /bookshelf protected route
- auth.go: Change login/register redirects from /api/dashboard to /bookshelf (2 locations)
- edge_cases_test.go: Update test redirect to /bookshelf
- Maintains backward compatibility with existing /dashboard route

This makes the beautiful bookshelf the default landing page
for all authenticated users while keeping the old dashboard accessible.
2026-01-29 15:52:11 -05:00
john-okeefe ce0e448e58 refactor: standardize API response formats for list endpoints
- ListLibraries now returns {"data": []} instead of []
- ListUsers now returns {"data": []} instead of []
- ListMediaItems now returns {"data": []} instead of []

This provides consistent response structure across all list endpoints
and aligns with integration test expectations.
2026-01-29 13:33:08 -05:00
john-okeefe 1e04ef4861 test(security): add comprehensive security tests
- Test password complexity requirements
- Test account lockout mechanism
- Test rate limiting functionality
- Test JWT expiration (1 hour)
- Test refresh token expiration (7 days)
- Test password requirements list
- Verify transaction manager and error handler types
- All tests passing
2026-01-29 09:23:34 -05:00
john-okeefe 124b5748c9 fix: improve authentication validation and security
- Trim whitespace from usernames and validate non-empty
- Normalize role values to lowercase for case-insensitive comparison
- Prevent registration with whitespace-only usernames
- Maintain backward compatibility with existing functionality

Fixes validation gap: Username whitespace handling
2026-01-29 09:23:33 -05:00
john-okeefe d3b728c458 fix: resolve registration database connection error
- Fix database authentication error by exposing actual database error messages
- Update error handling to follow pgx v5 standards with detailed error reporting
- Restore token environment variable management in Register User.bru for subsequent requests
- Enable proper debugging of database connection issues during user registration

The registration API now provides detailed error messages instead of generic 'failed to check existing users'
when database connection or authentication fails, making debugging easier.
2026-01-28 20:57:15 -05:00
john-okeefe 84d846ae6c chore: deprecate user ebook folders endpoints
- Replace with 410 Gone responses directing to libraries
- Maintain API contract for backward compatibility
- Remove old user folder management functionality
- Prepare for complete library system migration

Old folder management now handled through library system
2026-01-28 11:04:18 -05:00
john-okeefe 481adaa71e feat: Implement role-based registration restrictions and reorganize Bruno collection
- Add role-based restrictions to POST /api/auth/register endpoint
- Only admins can create admin accounts if any admin already exists
- First user automatically gets admin role regardless of request
- Regular users can only create user accounts, not admin accounts
- Unauthenticated users can only create first admin, not subsequent admins
- Reorganize Bruno collection into logical subfolders (auth/, admin/, profile/)
- Update documentation to reflect new registration restrictions and security rules

BREAKING CHANGES:
- /api/auth/register now enforces role-based creation restrictions
- Bruno collection reorganized with subfolder structure
2026-01-27 14:15:06 -05:00
john-okeefe 71584c1b55 feat: Enhance admin user management system
- Add admin override capability to DELETE /api/auth/account endpoint
- Move /api/auth/users to admin-only with complete user fields (first_name, last_name, role, theme)
- Consolidate Bruno requests: remove duplicate List Users (Admin), merge Delete Account functionality
- Update all documentation to reflect enhanced capabilities
- Implement pgx 5 standards compliance with proper error handling

BREAKING CHANGES:
- /api/auth/users endpoint now requires admin role (was previously accessible)
- DELETE /api/auth/account accepts optional user_id parameter for admin deletion
2026-01-27 13:36:11 -05:00
john-okeefe 997a7318f8 feat: Implement first-user admin and last-user protection
- First registered user automatically becomes admin regardless of request
- Prevent deletion of the last user account to protect system
- Enhanced role validation and HTMX error handling
- Proper pgx 5 database standards throughout

Security improvements:
- Auto-admin for first user ensures system always has administrator
- Last-user protection prevents system from having zero users
- Role validation ensures only 'user' or 'admin' roles accepted
2026-01-26 21:18:08 -05:00
john-okeefe f5bfac996d feat: Implement role-based authentication and authorization
- Add AdminMiddleware for protecting sensitive operations
- Update JWT generation to include user role and details
- Modify login/registration to use enhanced JWT claims
- Update main.go to set admin-protected routes
- Add user role to JWT context for downstream handlers
2026-01-26 16:55:32 -05:00
john-okeefe 6b4e5f0198 Improve error handling in auth handlers
- Add specific pgx.ErrNoRows checks in GetProfile
- Better error handling in UpdatePassword and GetScanSettings
- Return appropriate HTTP status codes for different error types
- Improve error message consistency
2026-01-26 11:31:22 -05:00
john-okeefe 08e80ae84b refactor: reorganize project structure and update configurations
- Move migrations/ to database/schema/ for clarity on database schema definitions
- Move sqlc.yaml to internal/database/ to group with database code
- Move static/ to cmd/server/static/ to co-locate with server
- Update all configuration files and documentation
- Follow Go project conventions for better organization
2026-01-24 23:40:31 -05:00
john-okeefe 382a2369c5 Fix auth handler: remove duplicate validation, fix first_name/last_name type handling 2026-01-23 21:27:10 -05:00
john-okeefe 5f5870b95d Migrate to templ: Convert all HTML templates to type-safe templ components
- Add templ dependency for type-safe HTML rendering
- Convert index.html, login.html, register.html, dashboard.html, admin.html, admin_profile.html, admin_library.html to .templ files
- Generate Go code with templ generate for compile-time safety
- Update server routes to use templ components with proper rendering
- Refactor JavaScript in dashboard to avoid backtick parsing conflicts
- Delete old HTML template files
- Clean up project by removing unnecessary files and binaries
2026-01-23 16:33:08 -05:00
john-okeefe fcc9b0f0b3 fix: resolve user registration error by fixing database queries
- Update CreateUser query to explicitly select only existing columns
- Update all user SELECT queries to explicitly select columns to avoid scan_frequency_minutes column issues
- Add GetUserForLogin query that includes password_hash for authentication
- Update login handler to use GetUserForLogin instead of GetUserByEmailOrUsername
- This prevents errors when migration hasn't been applied yet, allowing user registration to work
2026-01-23 11:06:56 -05:00
john-okeefe 11621462f2 feat: create admin dashboard with user preferences and library settings
- Add admin dashboard at /admin route consolidating all user settings
- Move user preferences (username, email, password, theme) from separate page
- Add ebook library preferences section with folder management
- Add scan settings (frequency and auto-scan toggle) with database persistence
- Create database migration for scan_frequency_minutes and auto_scan_enabled columns
- Add API endpoints for scan settings management:
  - PUT /api/library/scan-settings - Update scan preferences
  - GET /api/library/scan-settings - Get current scan settings
- Update dashboard navigation to link to admin dashboard
- Remove old preferences.html template (functionality moved to admin)
- Create Bruno API testing files for library endpoints
- Add real-time folder loading and management in admin interface
- Implement scan settings persistence and retrieval from database
2026-01-23 09:38:40 -05:00
john-okeefe 2dba1d6eb9 feat: add user preferences dashboard
- Add /preferences route and preferences.html template for user settings
- Implement username, email, password, and theme update functionality
- Add account deletion feature with confirmation
- Add navigation link to preferences from dashboard
- Create API endpoints:
  - PUT /api/user/username - Update username
  - PUT /api/user/email - Update email address
  - PUT /api/user/password - Change password with verification
  - DELETE /api/user/account - Delete user account
- Add database queries for user updates and account deletion
- Create Bruno API testing files for all user preference endpoints
- Add proper validation, error handling, and security checks
2026-01-23 09:30:15 -05:00
john-okeefe c3769fe7f1 refactor: rename project back from shelf to bookmann
- Change Go module name back from 'shelf' to 'bookmann'
- Update all import paths back to 'bookmann' module
- Update README.md project name back to 'Bookmann'
- Update docker-compose.yml container names back to 'bookmann' and 'bookmann_db'
- Regenerate database code with restored module imports
2026-01-23 09:08:59 -05:00
john-okeefe 4318f8624b refactor: restructure project from bookmann to shelf
- Rename project from 'bookmann' to 'shelf'
- Move all backend/ contents to root level (flatten structure)
- Update Go module name from 'bookmann' to 'shelf'
- Update all import paths to use new 'shelf' module
- Update Dockerfile to work without backend/ subdirectory
- Update docker-compose.yml to use new structure and rename containers
- Update .gitignore for new file paths
- Update README.md with new project name and structure
- Regenerate database code with new module imports
2026-01-23 09:08:04 -05:00