diff --git a/Dockerfile b/Dockerfile index 7f8e4e9e..8d5c7867 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,6 @@ COPY .npmrc /app/package.json COPY astro.config.ts /app/astro.config.ts COPY package.json /app/package.json COPY package-lock.json /app/package-lock.json -COPY tailwind.config.cjs /app/tailwind.config.cjs COPY tsconfig.json /app/tsconfig.json RUN \ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 0d3e8663..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -pytest -markdown -gitpython \ No newline at end of file diff --git a/src/content/docs/docs/administration/api.md b/src/content/docs/docs/administration/api.md index f74171e7..cb7130cd 100644 --- a/src/content/docs/docs/administration/api.md +++ b/src/content/docs/docs/administration/api.md @@ -16,3 +16,33 @@ Note that for all request, **'Accept: application/json' is mandatory** and that As of version 4.8.1, the api documentation is moved directly inside your own Lychee instance. It is accessible at the url `https://yourLycheeInstance.org/docs/api`. It is also possible to see it on our demo website: [https://demo.lycheeorg.dev/docs/api](https://demo.lycheeorg.dev/docs/api) + +## Authentication and CSRF + +Lychee protects all stateful (cookie/session based) requests with Laravel's standard CSRF protection. This is what your browser uses automatically when you are logged in and is required for `POST`, `PUT`, `PATCH` and `DELETE` requests coming from a session. + +When you script against the API (e.g. with `curl`, Python, or any external tool) you generally do not have a browser session or the associated CSRF cookie/header, so plain session-based requests will be rejected with a `419` error. + +To avoid dealing with CSRF for such use cases, Lychee lets you authenticate with a personal **API token** instead. Any request that carries a valid `Authorization: Bearer ` header is treated as token-authenticated and skips CSRF verification entirely, regardless of the HTTP verb used. + +### Generating a token + +1. Log in to your Lychee instance and open **Settings → Profile**. +2. In the **API Token** section, click **Create token** (or **Reset token** if one already exists). +3. Copy the token immediately — for security reasons it is only ever shown once and cannot be retrieved again later. +4. You can revoke the token at any time from the same dialog with **Disable token**. Resetting the token also invalidates the previous one. + +### Using the token + +Send the token as a Bearer token in the `Authorization` header of your requests: + +```bash +curl -X POST 'https://yourLycheeInstance.org/api/v2/Albums' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' +``` + +:::caution +An API token grants full access to your account. Treat it like a password: never commit it to source control and revoke it immediately if you suspect it has leaked. +::: diff --git a/src/content/docs/docs/getting-started/configuration.md b/src/content/docs/docs/getting-started/configuration.md index a410068f..498b7c85 100644 --- a/src/content/docs/docs/getting-started/configuration.md +++ b/src/content/docs/docs/getting-started/configuration.md @@ -165,13 +165,15 @@ To migrate from Lychee v3 you *must* use the same MySQL/MariaDB server as v3. ### Mailer options -Supported mailers are `smtp`, `ses`, `mailgun`, `postmark` or `sendmail`, which you can set using `MAIL_DRIVER`. +Mail is required if you want to use the [`new_photos_notification`](/docs/getting-started/settings/#new_photos_notification) setting, which emails users a weekly digest when new photos are added to albums shared with them. + +Supported mailers are `smtp`, `ses`, `mailgun`, `postmark` or `sendmail`, which you can set using `MAIL_DRIVER`. There is also a `log` driver (see [Testing your configuration](#testing-your-configuration) below). #### General options | Option | Description | |---------------------|----------------| -| `MAIL_DRIVER` | Mailer type | +| `MAIL_DRIVER` | Mailer type: `smtp`, `ses`, `mailgun`, `postmark`, `sendmail` or `log` | | `MAIL_FROM_ADDRESS` | "From" address | | `MAIL_FROM_NAME` | "From" name (defaults to `APP_NAME`) | | `MAIL_EHLO_DOMAIN` | Local domain announced in the SMTP `EHLO`/`HELO` command. Advanced, rarely needed. | @@ -182,10 +184,12 @@ Supported mailers are `smtp`, `ses`, `mailgun`, `postmark` or `sendmail`, which |-------------------|----------------------------------------------| | `MAIL_HOST` | Host of SMTP server | | `MAIL_PORT` | Port of SMTP server (default 587) | -| `MAIL_ENCRYPTION` | Encryption for SMTP server (default `tls`) | +| `MAIL_ENCRYPTION` | Encryption for SMTP server: `tls` (STARTTLS, default), `ssl` (implicit TLS, typically used with port 465), or left empty for no encryption | | `MAIL_USERNAME` | Username of SMTP server | | `MAIL_PASSWORD` | Password of SMTP server | +Most providers (Gmail, Outlook/Office 365, your ISP...) publish the exact `MAIL_HOST`, `MAIL_PORT` and `MAIL_ENCRYPTION` values to use for SMTP on their support pages — search for "\ SMTP settings". + #### SES SES can be configured using AWS settings. See [AWS configuration](#aws). @@ -210,6 +214,20 @@ SES can be configured using AWS settings. See [AWS configuration](#aws). |---------------------|-------------------------------------------------|-----------------------------------| | `MAIL_SENDMAIL_PATH` | Path (and arguments) to the local `sendmail` binary | `/usr/sbin/sendmail -bs -i` | +#### Testing your configuration + +Set `MAIL_DRIVER=log` to write outgoing emails to `storage/logs/laravel.log` instead of actually sending them. This lets you confirm that Lychee is attempting to send mail (and inspect its contents) without needing a fully working SMTP setup or risking spamming real users while you experiment with the other `MAIL_` options. + +Once configured, you can trigger the notification job manually to test end-to-end instead of waiting for its weekly schedule: + +```bash +php artisan lychee:photos_added_notification +``` + +:::note +Notification emails are only sent by [Laravel's task scheduler](https://laravel.com/docs/scheduling#running-the-scheduler), which itself must be invoked once a minute by a system `cron` job (or systemd timer) pointing at `php artisan schedule:run`. See the [FAQ](/docs/faq/general/) for an example. Without this, `new_photos_notification` will never trigger on its own even if mail sending itself works. +::: + ### Cache options Lychee can use various services as cache driver to store temporary data. The driver is set using `CACHE_DRIVER` and supports: `apc`, `array`, `file`, `memcached`, `redis` or `dynamodb`. diff --git a/src/content/docs/docs/getting-started/contributions.md b/src/content/docs/docs/getting-started/contributions.md index b1d65cce..a547d89e 100644 --- a/src/content/docs/docs/getting-started/contributions.md +++ b/src/content/docs/docs/getting-started/contributions.md @@ -20,13 +20,54 @@ Lychee's GitHub issue trackers are not intended to provide Lychee help or suppor Lychee uses a rolling release system, **we do not backport fixes to previously released versions**. Those are the versions in which we accept vulnerability reports. -| Version | Supported | -|----------------|-----------| -| master | ✔ | -| latest release | ✔ | -| < 7.0 | ✕ | +| Version | Supported | +|------------------|-----------| +| master | ✔ | +| latest release | ✔ | +| < latest release | ✕ | +| < 7.0 | ✕ | -If you discover a security vulnerability within Lychee, please contact us directly on [Discord][2]. All security vulnerabilities will be promptly addressed. +### Reporting a Vulnerability + +If you discover a security vulnerability within Lychee, please contact us directly on [Discord][2] or open a draft advisory [here][5]. All security vulnerabilities will be promptly addressed. + +:::tip +In order to help us triage your report, we encourage you to provide us with a Proof of Concept (PoC) demonstrating the vulnerability. This will help us understand the issue and prioritize it accordingly. You can use our [demo environment](https://demo.lycheeorg.dev) to test your PoC (non-destructively). For destructive testing, please use your own environment and provide us with a clear explanation of the steps to reproduce the issue. +::: + +Please **do not report** security **vulnerabilities which are direct output of your own tools**. Make sure to verify the issue manually and provide a clear explanation of the vulnerability, including steps to reproduce it. We are starting to see a lot of reports which are generated by automated AI scanners and contain hallucinations or do not consider parts of the codebase. + +:::caution +For each low quality report that is closed, you gain 1 strike: ⚾ **3 strikes (⚾⚾⚾) and you will be blocked from this repository.** +::: + +### Well known false positives + +We have seen a few reports mentioning issues which we consider part of the intended design of Lychee. + +#### About the api/v2/Diagnostics endpoint + +If you are thinking about reporting an issue regarding the `api/v2/Diagnostics` endpoint, please note that **it is intentionally public and does not require authentication**. The responses from this endpoint do not contain any sensitive information or secrets and have been anonymized. + +Its main goal is to allow users to easily diagnose issues with their Lychee installation even if they can't log in. + +#### About `fopen` and DNS Rebinding + +We do **not** accept vulnerability reports related to DNS rebinding attacks on `fopen` when `USE_FOPEN_FOR_URL_IMPORTS` is enabled. + +We know that this setting switches URL-based imports from `curl` to PHP's native `fopen`. Unlike `curl`, `fopen` performs its own DNS resolution with no built-in mechanism to detect or prevent DNS rebinding — there is no supported way to mitigate this at the application level while still using `fopen`. + +Deliberately enabling `USE_FOPEN_FOR_URL_IMPORTS` and then expecting the system to be immune to DNS rebinding is not a valid threat model. **Putting the system into a known-vulnerable configuration and then reporting the resulting exposure is not considered a security vulnerability in Lychee.** + +#### Path traversal on Import From Server + +We do not consider this a vulnerability because the import from server feature is only available to admin users. The path traversal issue is mitigated by the fact that only trusted users can access this functionality. + +Furthermore, in the case where there are multiple admins, the owner of the Lychee installation can even disable this functionality completely by adding the following to the `.env`: + +```ini +DISABLE_IMPORT_FROM_SERVER=true +``` ## Core Development Discussion @@ -203,3 +244,4 @@ In summary: [2]: https://discord.gg/JMPvuRQcTf [3]: https://github.com/LycheeOrg/Lychee/discussions [4]: https://github.com/LycheeOrg/Lychee/pulls +[5]: https://github.com/LycheeOrg/Lychee/security/advisories/new diff --git a/src/content/docs/docs/getting-started/docker.md b/src/content/docs/docs/getting-started/docker.md index a11a64fc..4d1826fb 100644 --- a/src/content/docs/docs/getting-started/docker.md +++ b/src/content/docs/docs/getting-started/docker.md @@ -31,7 +31,13 @@ The following tags are available: ### Docker Compose (Recommended) -The recommended way to deploy Lychee is with Docker Compose. Use the official template as a starting point: +The recommended way to deploy Lychee is with Docker Compose. + +:::tip +Not sure which options you need? Use the [**Docker Compose Wizard**](/wizard/) to generate a ready-to-run `docker-compose.yaml` and `.env` tailored to your setup (database, workers, reverse proxy, OAuth, and more) — right in your browser, no install required. +::: + +Alternatively, use the official template as a starting point and edit it by hand: [https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml](https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml) diff --git a/src/content/docs/docs/getting-started/installation.md b/src/content/docs/docs/getting-started/installation.md index f55f7eee..e775bb70 100644 --- a/src/content/docs/docs/getting-started/installation.md +++ b/src/content/docs/docs/getting-started/installation.md @@ -21,7 +21,7 @@ Lychee is now running at [http://localhost:8000](http://localhost:8000). On first visit, you will be prompted to create an admin account. :::tip -For a more complete setup with custom volumes, environment variables, and worker services, see the [Docker documentation](/docs/getting-started/docker/). +For a more complete setup with custom volumes, environment variables, and worker services, use the [Docker Compose Wizard](/wizard/) to generate a tailored `docker-compose.yaml` and `.env`, or see the [Docker documentation](/docs/getting-started/docker/). ::: ## What's Included @@ -44,7 +44,7 @@ For production deployments, you should: - Set a proper `APP_URL` and `APP_KEY` — see [Configuration](/docs/getting-started/configuration/) - Put Lychee behind a reverse proxy with TLS (nginx, Traefik, or Caddy) -- Use the [full Docker Compose template](https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml) with workers for better performance +- Use the [Docker Compose Wizard](/wizard/) or the [full Docker Compose template](https://github.com/LycheeOrg/Lychee/blob/master/docker-compose.yaml) with workers for better performance ## Alternative: Manual Installation diff --git a/src/content/docs/docs/getting-started/settings.md b/src/content/docs/docs/getting-started/settings.md index fe752014..d9fbda1b 100644 --- a/src/content/docs/docs/getting-started/settings.md +++ b/src/content/docs/docs/getting-started/settings.md @@ -75,6 +75,8 @@ _(boolean; default: `0`)_ Expert Send notifications when new photos are uploaded. +Requires mail to be configured (see [Mailer options](/docs/getting-started/configuration/#mailer-options)) and Laravel's scheduler to be running via `cron` or a systemd timer, otherwise the weekly notification job never fires. + --- ## Lychee SE