From fdd46852f2492ab34384892a273e93c3b0fdad99 Mon Sep 17 00:00:00 2001 From: Alex <25013571+alexhb1@users.noreply.github.com> Date: Fri, 20 Feb 2026 18:07:43 +0000 Subject: [PATCH] Add new docs (#633) --- docs/oidc.md | 39 +++++++++++++++ docs/users-and-requests.md | 98 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 docs/oidc.md create mode 100644 docs/users-and-requests.md diff --git a/docs/oidc.md b/docs/oidc.md new file mode 100644 index 0000000..169622b --- /dev/null +++ b/docs/oidc.md @@ -0,0 +1,39 @@ +# OpenID Connect (OIDC) Authentication + +## Callback URL + +``` +https:///api/auth/oidc/callback +``` + +With a subpath (`URL_BASE=/shelfmark/`): + +``` +https:///shelfmark/api/auth/oidc/callback +``` + +The callback URL is constructed from the incoming request, so your reverse proxy must forward `X-Forwarded-Proto` and `X-Forwarded-Host` correctly. PKCE (S256) is used automatically. + +## Settings + +Configure in **Settings → Security → Authentication Method → OIDC**. + +| Setting | Description | Default | +|---------|-------------|---------| +| Discovery URL | `/.well-known/openid-configuration` endpoint | — | +| Client ID | OAuth2 client ID | — | +| Client Secret | OAuth2 client secret | — | +| Scopes | Scopes to request. The group claim is added automatically when admin group authorization is enabled | `openid email profile` | +| Group Claim Name | Claim containing user groups | `groups` | +| Admin Group Name | Group granted admin access. Leave empty for database-only roles | — | +| Use Admin Group for Authorization | Toggle group-based admin detection | `true` | +| Auto-Provision Users | Create accounts on first login | `true` | +| Login Button Label | Custom text for the sign-in button | — | + +Use **Test Connection** to verify discovery and client configuration before attempting login. + +## Troubleshooting + +- **Issuer validation failed** — The issuer in the token doesn't match the discovery document. Check your provider's external URL / issuer configuration. +- **Callback URL mismatch** — Reverse proxy isn't forwarding `X-Forwarded-Proto` or `X-Forwarded-Host`, so the constructed callback URL doesn't match what's registered in the provider. +- **Account not found** — Auto-provision is disabled and the user hasn't been pre-created by an admin. diff --git a/docs/users-and-requests.md b/docs/users-and-requests.md new file mode 100644 index 0000000..79c81e4 --- /dev/null +++ b/docs/users-and-requests.md @@ -0,0 +1,98 @@ +# Users & Requests + +Configure in **Settings → Users & Requests**. + +## Authentication Methods + +Shelfmark supports four authentication methods, configured in **Settings → Security**. + +### Local + +You create user accounts directly in Shelfmark with a username and password. At least one local admin account must exist before this mode can be enabled. + +### Proxy Authentication + +Your reverse proxy handles authentication and passes the username to Shelfmark via a header (e.g. `Remote-User`). Accounts are created automatically on first sign-in. If a local user with the same username already exists, the proxy identity will be linked to that account rather than creating a duplicate. Admin status can optionally be derived from a groups header. + +### OIDC (OpenID Connect) + +Users sign in through your identity provider. Accounts are created automatically on first login (unless auto-provisioning is disabled, in which case you need to pre-create them). If a local user with a matching verified email already exists, the OIDC identity will be linked to that account on first sign-in. Admin status can optionally be derived from a group claim. + +A local admin account is required as a fallback. See [OIDC](oidc.md) for provider setup. + +### Calibre-Web Database + +User accounts are synced from your Calibre-Web `app.db`. If a local user with a matching email already exists, the CWA identity will be linked to that account. Roles are kept in sync with CWA. Users removed from CWA are cleaned up on the next sync. + +Requires mounting your Calibre-Web `app.db` to `/auth/app.db`. + +## Per-User Settings + +Admins can configure per-user settings by editing a user in the user management panel. Non-admin users can also edit their own settings through **My Account** (accessible from the user menu). Admins control which sections are visible in My Account via the **Visible Self-Settings Sections** option. + +There are three categories of per-user settings: + +### Delivery Preferences + +Override where a user's downloads are sent. Options depend on the global output mode configuration: + +- **Output mode** — Folder, Email (SMTP), or BookLore (API) +- **Destination** — A custom folder path for this user's ebook downloads +- **Audiobook destination** — A custom folder path for audiobook downloads +- **BookLore library/path** — Per-user BookLore target (when using BookLore output mode) +- **Email recipient** — Per-user email address (when using Email output mode) + +### Notifications + +Users can configure personal notification routes, separate from the global notification settings. Each route targets a URL (e.g. an Apprise-compatible endpoint) and can be scoped to specific event types or all events. + +### Request Policy (admin-only) + +Admins can override the default ebook/audiobook modes and request rules for individual users. See [Per-User Overrides](#per-user-overrides) below. + +--- + +## Requests + +The request system controls whether users can download directly or need admin approval first. + +### Policy Modes + +Each content type (ebook, audiobook) has a default mode that sets the baseline: + +| Mode | Behaviour | +|------|-----------| +| **Download** | Users download directly, no approval needed | +| **Request Release** | Users pick a specific release, then submit it for admin approval | +| **Request Book** | Users request the book itself — an admin picks the release and fulfils it | +| **Blocked** | No downloads or requests allowed | + +### Settings + +| Setting | Description | Default | +|---------|-------------|---------| +| Enable Requests | Master toggle. When off, everyone downloads directly | Off | +| Default Ebook Mode | Baseline mode for all ebook sources | Download | +| Default Audiobook Mode | Baseline mode for all audiobook sources | Download | +| Request Rules | Per-source overrides (see below) | None | +| Max Pending Requests Per User | Open request limit per user | 20 | +| Allow Notes on Requests | Let users attach a note when submitting | On | + +### Request Rules + +The rules matrix lets you override the mode for specific source + content type combinations. Rules can only be **equal to or more restrictive** than the content-type default — they cannot grant more access than the baseline. + +For example, if the default ebook mode is "Download", a rule can restrict a specific source to "Request Release" or "Blocked", but not the other way around. If no rule matches, the content-type default applies. + +### Per-User Overrides + +Admins can override the default ebook/audiobook modes and request rules for individual users. Per-user rules are overlaid on the global rules, not replacing them. + +### Request Lifecycle + +1. User submits a request (book or release level, depending on the resolved policy mode) +2. Request appears in the admin request queue as **pending** +3. Admin either **fulfils** (queues a download) or **rejects** the request +4. For fulfilled requests, delivery state is tracked through the download pipeline +5. If delivery fails, an admin can reopen the request to try a different release +6. Users can cancel their own pending requests