15a8ab41fd
Adds a third value for the COOKIE_SECURE environment variable that decides the cookie Secure flag per-request based on req.secure. This unblocks a common self-hosted setup where the same PicPeak deployment is reachable over both HTTPS (via reverse proxy) and plain HTTP (e.g. LAN access at http://192.168.x.x:3001). Behavior unset - legacy default: follows NODE_ENV (production=true, dev=false) true - always set Secure (unchanged) false - never set Secure (unchanged) auto - NEW: use req.secure per request. In practice this means Secure on HTTPS requests (when X-Forwarded-Proto: https reaches Express via a trusted proxy) and no Secure flag on plain HTTP requests. The existing trust proxy config (`app.set('trust proxy', 'loopback, linklocal, uniquelocal')` in server.js) means X-Forwarded-Proto is honored when forwarded from local/private-network proxies, which covers Docker network setups and most self-hosted deployments behind NPM, Traefik, or Caddy. auto is strictly opt-in. The default behavior is unchanged, so existing users see no difference. A follow-up release can consider promoting auto to the default after real-world feedback. Also fixed (latent bug, benefits everyone) Cookie clear operations (clearAdminAuthCookie, clearGalleryAuthCookies) previously wrote the same `secure` attribute as the set path. When a cookie was set with Secure=true over HTTPS and the clear request came over HTTP (or vice versa under auto mode), some browsers would reject the Set-Cookie delete header, leaving the cookie in place. Browsers match cookies by (name, domain, path) for deletion and don't care about Secure, so the new buildClearCookieOptions() helper simply omits the secure attribute. Implementation - secureCookie string is replaced by secureCookieMode which can hold true, false, or 'auto'. - New resolveSecureFlag(res) returns the boolean for a specific response, delegating to res.req.secure when in auto mode. - buildCookieBaseOptions and buildCookieOptionsWithExpiry now take res and pass it through. - New buildClearCookieOptions() deliberately omits `secure`. - setAdminAuthCookie / setGalleryAuthCookies / clearAdminAuthCookie / clearGalleryAuthCookies all updated to thread res where needed. Public signatures unchanged — every caller already has res in scope. Testing Verified against a real Express instance inside the backend container with trust proxy configured, covering: - (unset) + NODE_ENV=production -> secure: true (legacy) - (unset) + NODE_ENV=development -> secure: false (legacy) - COOKIE_SECURE=true + req.secure=false -> secure: true (literal wins) - COOKIE_SECURE=false + req.secure=true -> secure: false (literal wins) - COOKIE_SECURE=auto + X-Forwarded-Proto: https -> secure: true - COOKIE_SECURE=auto + plain HTTP -> secure: false - clearCookie always omits the secure attribute Documentation Added a COOKIE_SECURE block to both .env.example files (root for docker-compose, backend/.env.example for native install) explaining the four values, when to use auto, and the two requirements (proxy must forward X-Forwarded-Proto, proxy IP must be in the trust list). Also documented COOKIE_SAMESITE and COOKIE_DOMAIN alongside, which were previously undocumented.