diff --git a/README.md b/README.md index aa06e5fa..2d45e041 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ # BookLore > The legacy repo (`https://ghcr.io/adityachandelgit/booklore-app`) will remain available for existing images but will not receive further updates. -BookLore is a self-hosted web app for organizing and managing your personal book collection. It provides an intuitive interface to browse, read, and track your progress across PDFs and eBooks. With robust metadata management, multi-user support, and a sleek, modern UI, BookLore makes it easy to build and explore your personal library. +BookLore is a self-hosted web app for organizing and managing your personal book collection. It provides an intuitive interface to browse, read, and track your progress across PDFs and eBooks. With robust metadata management, multi-user support, and a sleek, modern UI, BookLore makes it easy to +build and explore your personal library. ![BookLore Demo](assets/demo.gif) @@ -51,7 +52,8 @@ ## 🌐 Live Demo: Explore BookLore in Action Evaluate BookLore’s features and user experience in a live environment: -**Demo Access:** +**Demo Access:** + - 🌐 **URL:** [demo.booklore.dev](https://demo.booklore.dev) - πŸ‘€ **Username:** `booklore` - πŸ”‘ **Password:** `9HC20PGGfitvWaZ1` @@ -63,7 +65,6 @@ ## 🌐 Live Demo: Explore BookLore in Action ## πŸš€ Getting Started with BookLore - Kick off your BookLore journey with our official documentation and helpful video guides. πŸ“˜ [BookLore Documentation: Getting Started](https://booklore-app.github.io/booklore-docs/docs/getting-started/) @@ -84,6 +85,7 @@ ### 1️⃣ Install Docker & Docker Compose Ensure you have [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed. **Image Repositories:** + - Docker Hub: `https://hub.docker.com/r/booklore/booklore` - GitHub Container Registry: `https://ghcr.io/booklore-app/booklore` @@ -104,21 +106,20 @@ ### 2️⃣ Create docker-compose.yml # image: ghcr.io/booklore-app/booklore:latest container_name: booklore environment: - - USER_ID=0 # Modify this if the volume's ownership is not root - - GROUP_ID=0 # Modify this if the volume's ownership is not root + - USER_ID=0 + - GROUP_ID=0 - TZ=Etc/UTC - - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore # Only modify this if you're familiar with JDBC and your database setup + - DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore - DATABASE_USERNAME=booklore # Must match MYSQL_USER defined in the mariadb container - - DATABASE_PASSWORD=your_secure_password # Use a strong password; must match MYSQL_PASSWORD defined in the mariadb container + - DATABASE_PASSWORD=your_secure_password - BOOKLORE_PORT=6060 # Port BookLore listens on inside the container; must match container port below - - SWAGGER_ENABLED=false # Enable or disable Swagger UI (API docs). Set to 'true' to allow access; 'false' to block access (recommended for production). depends_on: mariadb: condition: service_healthy ports: - "6060:6060" # HostPort:ContainerPort β†’ Keep both numbers the same, and also ensure the container port matches BOOKLORE_PORT, no exceptions. - # All three (host port, container port, BOOKLORE_PORT) must be identical for BookLore to function properly. - # Example: To expose on host port 7070, set BOOKLORE_PORT=7070 and use "7070:7070". + # All three (host port, container port, BOOKLORE_PORT) must be identical for BookLore to function properly. + # Example: To expose on host port 7070, set BOOKLORE_PORT=7070 and use "7070:7070". volumes: - /your/local/path/to/booklore/data:/app/data # Application data (settings, metadata, cache, etc.). Persist this folder to retain your library state across container restarts. - /your/local/path/to/booklore/books:/books # Primary book library folder. Mount your collection here so BookLore can access and organize your books. @@ -140,11 +141,12 @@ ### 2️⃣ Create docker-compose.yml - /your/local/path/to/mariadb/config:/config restart: unless-stopped healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] + test: [ "CMD", "mariadb-admin", "ping", "-h", "localhost" ] interval: 5s timeout: 5s retries: 10 ``` + Note: You can find the latest BookLore image tag `BOOKLORE_IMAGE_TAG` (e.g. v.0.x.x) from the Releases section: πŸ“¦ [Latest Image Tag – GitHub Releases](https://github.com/adityachandelgit/BookLore/releases) @@ -161,9 +163,38 @@ ### 4️⃣ Access BookLore Once the containers are up, access BookLore in your browser at: ```ini -http://localhost:6060 +http : //localhost:6060 ``` -## πŸ“₯ Bookdrop Folder: Auto-Import Files (New) + +## βš™οΈ Supported Environment Variables + +### BookLore Container + +| Key | Default Value | Description | +|----------------------|----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `USER_ID` | `0` | User ID for file ownership within the container. Set this to match your host user's UID if running as non-root (e.g., `1000`). Use `id -u` on Linux to find your UID. | +| `GROUP_ID` | `0` | Group ID for file ownership within the container. Set this to match your host user's GID if running as non-root (e.g., `1000`). Use `id -g` on Linux to find your GID. | +| `TZ` | `Etc/UTC` | Timezone for the application. Controls timestamps in logs and UI. Use standard timezone identifiers (e.g., `America/New_York`, `Europe/London`, `Asia/Tokyo`). See [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | +| `DATABASE_URL` | `jdbc:mariadb://mariadb:3306/booklore` | JDBC connection string for MariaDB/MySQL database. Format: `jdbc:mariadb://hostname:port/database_name`. Only modify if using a custom database host, port, or external database server. | +| `DATABASE_USERNAME` | `booklore` | Username for database authentication. Must match `MYSQL_USER` in your MariaDB container configuration. | +| `DATABASE_PASSWORD` | - | Password for database authentication. **Required**. Use a strong, unique password. Must match `MYSQL_PASSWORD` in your MariaDB container configuration. Store securely and never commit to version control. | +| `BOOKLORE_PORT` | `6060` | Internal port BookLore listens on. **Critical**: This must match both the host and container ports in your port mapping (e.g., `6060:6060`). Changing this requires updating all three values. Example: For port `7070`, use `BOOKLORE_PORT=7070` and `7070:7070`. | +| `SWAGGER_ENABLED` | `false` | Controls access to Swagger UI for API documentation and testing. Set to `true` to enable at `/swagger-ui.html` (useful for development/testing). Keep `false` in production for security. | +| `FORCE_DISABLE_OIDC` | `false` | Forces local username/password authentication only. Set to `true` to completely disable OIDC/OAuth2 providers (Authentik, Pocket ID, etc.). Useful for troubleshooting authentication issues or temporarily bypassing external identity providers. | + +### MariaDB Container + +| Key | Default Value | Description | +|-----------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `PUID` | `1000` | Process User ID for the LinuxServer.io MariaDB container. Set this to match your host user's UID for proper file permissions. Use `id -u` on Linux to find your UID. | +| `PGID` | `1000` | Process Group ID for the LinuxServer.io MariaDB container. Set this to match your host user's GID for proper file permissions. Use `id -g` on Linux to find your GID. | +| `TZ` | `Etc/UTC` | Timezone for the MariaDB container. Should match the BookLore container's timezone for consistency in timestamps. | +| `MYSQL_ROOT_PASSWORD` | - | Root password for the MariaDB database. **Required**. Use a strong, unique password different from `MYSQL_PASSWORD`. This provides administrative access to the database server. Never expose or commit to VCS. | +| `MYSQL_DATABASE` | `booklore` | Name of the database to create on first run. This database will be used by BookLore to store all application data. Should not be changed after initial setup. | +| `MYSQL_USER` | `booklore` | Username for the application database user. Must match `DATABASE_USERNAME` in the BookLore container configuration. This user will have full access to the `MYSQL_DATABASE`. | +| `MYSQL_PASSWORD` | - | Password for the application database user. **Required**. Use a strong, unique password. Must match `DATABASE_PASSWORD` in the BookLore container configuration. Store securely and never commit to VCS. | + +## πŸ“₯ Bookdrop Folder: Auto-Import Files BookLore now supports a **Bookdrop folder**, a special directory where you can drop your book files (`.pdf`, `.epub`, `.cbz`, etc.), and BookLore will automatically detect, process, and prepare them for import. This makes it easy to bulk add new books without manually uploading each one. @@ -190,7 +221,6 @@ ### βš™οΈ Configuration (Docker Setup) ## πŸ”‘ OIDC/OAuth2 Authentication (Authentik, Pocket ID, etc.) - BookLore supports optional OIDC/OAuth2 authentication for secure access. This feature allows you to integrate external authentication providers for a seamless login experience. While the integration has been tested with **Authentik** and **Pocket ID**, it should work with other OIDC providers like **Authelia** as well. The setup allows you to use either JWT-based local authentication or external providers, giving users the flexibility to choose their preferred method. @@ -202,9 +232,11 @@ ## πŸ”‘ OIDC/OAuth2 Authentication (Authentik, Pocket ID, etc.) ## πŸ›‘οΈ Forward Auth with Reverse Proxy -BookLore also supports **Forward Auth** (also known as Remote Auth) for authentication through reverse proxies like **Traefik**, **Nginx**, or **Caddy**. Forward Auth works by having your reverse proxy handle authentication and pass user information via HTTP headers to BookLore. This can be set up with providers like **Authelia** and **Authentik**. +BookLore also supports **Forward Auth** (also known as Remote Auth) for authentication through reverse proxies like **Traefik**, **Nginx**, or **Caddy**. Forward Auth works by having your reverse proxy handle authentication and pass user information via HTTP headers to BookLore. This can be set up +with providers like **Authelia** and **Authentik**. For detailed setup instructions and configuration examples: + - πŸ“˜ [Complete Forward Auth Setup Guide](docs/forward-auth-with-proxy.md) ## 🀝 Community & Support diff --git a/booklore-api/src/main/java/com/adityachandel/booklore/config/AppProperties.java b/booklore-api/src/main/java/com/adityachandel/booklore/config/AppProperties.java index c59acd55..0d075aac 100644 --- a/booklore-api/src/main/java/com/adityachandel/booklore/config/AppProperties.java +++ b/booklore-api/src/main/java/com/adityachandel/booklore/config/AppProperties.java @@ -15,6 +15,7 @@ public class AppProperties { private String version; private RemoteAuth remoteAuth; private Swagger swagger = new Swagger(); + private Boolean forceDisableOidc = false; @Getter @Setter diff --git a/booklore-api/src/main/java/com/adityachandel/booklore/service/appsettings/AppSettingService.java b/booklore-api/src/main/java/com/adityachandel/booklore/service/appsettings/AppSettingService.java index ac36b2e3..91cb8971 100644 --- a/booklore-api/src/main/java/com/adityachandel/booklore/service/appsettings/AppSettingService.java +++ b/booklore-api/src/main/java/com/adityachandel/booklore/service/appsettings/AppSettingService.java @@ -98,13 +98,17 @@ public class AppSettingService { builder.uploadPattern(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.UPLOAD_FILE_PATTERN, "{authors}/<{series}/><{seriesIndex}. >{title}< - {authors}>< ({year})>")); builder.similarBookRecommendation(Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.SIMILAR_BOOK_RECOMMENDATION, "true"))); builder.opdsServerEnabled(Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.OPDS_SERVER_ENABLED, "false"))); - builder.oidcEnabled(Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.OIDC_ENABLED, "false"))); builder.cbxCacheSizeInMb(Integer.parseInt(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.CBX_CACHE_SIZE_IN_MB, "5120"))); builder.pdfCacheSizeInMb(Integer.parseInt(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.PDF_CACHE_SIZE_IN_MB, "5120"))); builder.maxFileUploadSizeInMb(Integer.parseInt(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.MAX_FILE_UPLOAD_SIZE_IN_MB, "100"))); builder.bookDeletionEnabled(Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.BOOK_DELETION_ENABLED, "false"))); builder.metadataDownloadOnBookdrop(Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.METADATA_DOWNLOAD_ON_BOOKDROP, "true"))); + boolean settingEnabled = Boolean.parseBoolean(settingPersistenceHelper.getOrCreateSetting(AppSettingKey.OIDC_ENABLED, "false")); + Boolean forceDisable = appProperties.getForceDisableOidc(); + boolean finalEnabled = settingEnabled && (forceDisable == null || !forceDisable); + builder.oidcEnabled(finalEnabled); + return builder.build(); } } \ No newline at end of file diff --git a/booklore-api/src/main/resources/application.yaml b/booklore-api/src/main/resources/application.yaml index 5ffcf6a7..4d0e52c6 100644 --- a/booklore-api/src/main/resources/application.yaml +++ b/booklore-api/src/main/resources/application.yaml @@ -12,6 +12,7 @@ app: header-email: ${REMOTE_AUTH_HEADER_EMAIL:Remote-Email} header-groups: ${REMOTE_AUTH_HEADER_GROUPS:Remote-Groups} admin-group: ${REMOTE_AUTH_ADMIN_GROUP} + force-disable-oidc: ${FORCE_DISABLE_OIDC:false} server: forward-headers-strategy: native diff --git a/example-docker/docker-compose.yml b/example-docker/docker-compose.yml index a4ca77d9..9af1ce3a 100644 --- a/example-docker/docker-compose.yml +++ b/example-docker/docker-compose.yml @@ -14,6 +14,7 @@ services: - DATABASE_PASSWORD=your_secure_password # Use a strong password; must match MYSQL_PASSWORD defined in the mariadb container - BOOKLORE_PORT=6060 # Port BookLore listens on inside the container; must match container port below - SWAGGER_ENABLED=false # Enable or disable Swagger UI (API docs). Set to 'true' to allow access; 'false' to block access (recommended for production). + - FORCE_DISABLE_OIDC=false # Set to 'true' to force-disable OIDC and allow internal login, regardless of UI config depends_on: mariadb: condition: service_healthy