* fix(security): guard connection tests, close sign-up and scope SSO providers
Fixes the four privately reported issues GHSA-9m33-xfrc-5jxw,
GHSA-6m23-28hh-gjh2, GHSA-2hpx-83vg-gm45 and GHSA-5pp8-r7f5-6q8p.
- The Gitea and GitHub test-connection routes require a signed-in user.
They were the only non-public API routes without a guard and made a
server side request to any URL in the body.
- Email sign-up is refused server side once an account exists unless
AUTH_ALLOW_SIGNUP=true. Only the signup page redirected before; the
endpoint accepted new accounts from anyone reaching the instance.
- SSO providers are scoped to their owner for list, update and delete,
and the client secret is never returned. An empty secret on update
keeps the stored one, and the form says so.
- HttpError messages carry the status only; the upstream body stays on
the response field for logs and never reaches API clients.
- A narrow outbound guard for user supplied URLs (connection tests, OIDC
discovery, ntfy, Gotify, Apprise, webhook): link local and cloud
metadata addresses are refused, host names are resolved and checked,
and redirects are not followed. Private networks stay allowed since
mirroring to a LAN Gitea is the normal deployment.
* fix(security): pin plain http requests to the checked address
The guard resolved a host name and checked its addresses, but fetch resolved
the name a second time, so a name that changes its answer between the two
lookups could still reach a link local address. Plain http requests now go
to the address the check saw, with the original name in the Host header.
https keeps the name: the certificate is validated against it and the
metadata services speak no TLS.
The login page always opened on the Email tab, so people who sign in with
SSO had to switch every time.
Two things decide the tab now. AUTH_DEFAULT_METHOD sets the instance
default (email or sso, anything else falls back to email) and is served to
the login page by the new public GET /api/auth/methods, which also reports
which methods are available. On top of that the browser remembers the
method last used, stored in localStorage on a successful email login and
when an SSO sign-in starts.
The tab is resolved once the available methods are known: the remembered
method if it is still available, else the server default if available,
else email, else sso. The tabs are controlled now so a manual switch still
sticks.
useAuthMethods calls the new endpoint instead of the two SSO endpoints.
/api/sso/providers/public is unchanged for anyone else using it.
* fix: improve reverse proxy support for subdomain deployments (#63)
- Add X-Accel-Buffering: no header to SSE endpoint to prevent Nginx
from buffering the event stream
- Auto-detect trusted origin from Host/X-Forwarded-* request headers
so the app works behind a proxy without manual env var configuration
- Add prominent reverse proxy documentation to advanced docs page
explaining BETTER_AUTH_URL, PUBLIC_BETTER_AUTH_URL, and
BETTER_AUTH_TRUSTED_ORIGINS are mandatory for proxy deployments
- Add reverse proxy env var comments and entries to both
docker-compose.yml and docker-compose.alt.yml
- Add dedicated reverse proxy configuration section to .env.example
* fix: address review findings for reverse proxy origin detection
- Fix x-forwarded-proto multi-value handling: take first value only
and validate it is "http" or "https" before using
- Update comment to accurately describe auto-detection scope: helps
with per-request CSRF checks but not callback URL validation
- Restore startup logging of static trusted origins for debugging
* fix: handle multi-value x-forwarded-host in chained proxy setups
x-forwarded-host can be comma-separated (e.g. "proxy1.example.com,
proxy2.example.com") in chained proxy setups. Take only the first
value, matching the same handling already applied to x-forwarded-proto.
* test: add unit tests for reverse proxy origin detection
Extract resolveTrustedOrigins into a testable exported function and
add 11 tests covering:
- Default localhost origins
- BETTER_AUTH_URL and BETTER_AUTH_TRUSTED_ORIGINS env vars
- Invalid URL handling
- Auto-detection from x-forwarded-host + x-forwarded-proto
- Multi-value header handling (chained proxy setups)
- Invalid proto rejection (only http/https allowed)
- Deduplication
- Fallback to host header when x-forwarded-host absent
- Prevent Automation UI from overriding schedule:
- mapDbScheduleToUi now parses intervals robustly (cron/duration/seconds) via parseInterval
- mapUiScheduleToDb merges with existing config and stores interval as seconds (no lossy cron conversion)
- /api/config passes existing scheduleConfig to preserve ENV-sourced values
- schedule-sync endpoint uses parseInterval for nextRun calculation
- Add AUTO_MIRROR_REPOS support and scheduled auto-mirror phase:
- scheduleConfig schema includes autoImport and autoMirror
- env-config-loader reads AUTO_MIRROR_REPOS and carries through to DB
- scheduler auto-mirrors imported/pending/failed repos when autoMirror is enabled before regular sync
- docker-compose and ENV docs updated with AUTO_MIRROR_REPOS
- Tests pass and build succeeds
- Added support for 60+ environment variables covering all configuration options
- Created detailed documentation in docs/ENVIRONMENT_VARIABLES.md with tables
- Fixed missing skipStarredIssues field in GitHub config
- Updated docker-compose files to reference environment variable documentation
- Updated README to link to the new environment variables documentation
- Environment variables now populate UI configuration automatically on Docker startup
- Preserves manual UI changes when environment variables are not set
- Includes support for mirror metadata, scheduling, cleanup, and authentication options
Fixes#69🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add support for custom CA certificates in Docker setup
- Two mounting options: individual certs or system CA bundle
- Automatic detection and configuration via NODE_EXTRA_CA_CERTS
- Enhanced documentation with setup guide in certs/README.md
- Added ca-certificates package to Alpine base image
- Updated docker-compose with clear volume mount examples
- Bump version to 2.21.0