58 Commits
Author SHA1 Message Date
Linus Rath 6b94f96e83 fix: redirect the bare base path of a sub-path install to the sign-in page #1455 2026-10-31 16:22:58 +01:00
Linus Rath 1a747ac9dd feat: limit the page's CSP to the configured hosts with no third-party traffic #903 2026-10-28 04:30:41 +01:00
Linus Rath d29309ed0d fix: keep plugin embed origins out of the page CSP while plugins are turned off 2026-10-26 15:15:58 +01:00
Linus Rath 121d2d5e31 fix: stop buffering up to 100 MB of every unauthenticated request body before routing 2026-10-26 14:52:04 +01:00
Linus Rath 3036769645 fix: let the allowed frame ancestors saved in the admin dashboard reach the frame-ancestors header 2026-10-26 11:48:38 +01:00
Linus Rath 0f0ebc906b fix: stop trusting the unprefixed sidebar-app frame cookie when COOKIE_SECURE=true (GHSA-cjm9-m826-mh78) 2026-10-26 11:48:38 +01:00
Linus Rath e38e326efb perf: load plugin frames as a plain page instead of a Next app
Every plugin iframe loaded /plugin-sandbox, a force-dynamic Next page.
Each frame then fetched, parsed and hydrated Next's client router on top
of React and the runtime, and the server rendered the page once per
frame, one after another when a dozen plugins started together.
Sandboxed frames have opaque origins, so the browser's code cache never
helps, and they run on the host page's main thread: with 12 plugins
the frames took 2.5-3 s to come up after the app had loaded.

The sandbox routes now return a small HTML page with the UI kit's
stylesheet and the runtime as an ES module, both built ahead of time:

- `scripts/build-plugin-sandbox.mjs` bundles the runtime with esbuild
  and compiles `plugin-kit.css` with the app's Tailwind setup into
  `public/plugin-sandbox-assets/`, with a manifest. Named Tabler imports
  are pointed at the icons' own files, so the full icon set stays in a
  chunk that only loads for an icon name the kit doesn't ship.
- `npm run build`, `npm run dev`, the Dockerfile and the perf-guard
  workflow run it before `next build`.
- `lib/plugin-sandbox/sandbox-document.ts` writes the page; proxy.ts
  still sets the sandbox CSP and the script carries its nonce.
- The assets are served from public/ with CORS and immutable caching.

A frame on an idle page is ready in 255 ms instead of 362 ms, eleven at
once in 1.0 s instead of 2.1 s.
2026-10-25 02:01:47 +01:00
Linus Rath 4f942417c8 fix: show pdf attachment previews in safari #1301 2026-10-20 21:08:01 +02:00
Linus Rath 1fd5d0558c fix: send HSTS on TLS requests and drop the X-Powered-By header 2026-10-19 01:32:27 +02:00
Linus Rath e9b2ef3258 fix: let plugin frames use forms without letting them post anywhere 2026-10-14 06:19:12 +02:00
Linus Rath 9bff740a89 fix: keep plugin network access to the origins in its manifest 2026-10-14 01:27:02 +02:00
Linus Rath 7e1a659c06 fix: open the WOPI editor behind a reverse proxy with split addresses #1130 2026-10-04 22:16:29 +02:00
Linus Rath 3ac6c25c71 fix: keep sibling subdomains from widening the sidebar-app frame-src
The inline sidebar apps hand their origins to the proxy through a
client-written cookie, which the proxy merges into `frame-src`. Any
same-site sibling host could set that cookie too. Over HTTPS the cookie
is now `__Host-bulwark_app_frame_origins`, which only this exact host
can set, and the proxy ignores the unprefixed name there. Plain HTTP
(local development) keeps the old name.
2026-09-26 16:27:03 +02:00
Linus Rath 02703d8b3d fix: stop not-found pages outside the app tree from being framed
Paths the proxy skips (static files, `/_next`, `/api`) got no security
headers at all, so the not-found shell rendered for a missing
`/foo.html`, `/branding/x` or an unknown `/api` route could be framed
by any site. Skipped responses now carry `nosniff` and
`X-Frame-Options: DENY`, and non-API ones `frame-ancestors 'none'`;
API routes keep setting their own CSP.
2026-09-26 16:22:49 +02:00
Linus Rath e7dc992721 fix: never let ALLOWED_FRAME_ANCESTORS frame the admin dashboard or setup 2026-09-26 16:21:02 +02:00
Linus Rath 9b9b4f7ef1 fix: reject cross-origin writes to the JMAP passthrough and other cookie-authed routes (GHSA-9mvj-98f5-9q6g)
The origin gate in the proxy only covered `/api/auth/*`. The JMAP
passthrough, `/api/settings`, `/api/wopi/launch`,
`/api/plugin-approval-status`, `/api/fetch-ical`, `/api/translate`,
`/api/caldav/discover`, `/api/calendar-agenda` and `/api/webdav` all act
with the session cookie and had no origin check. A page on a same-site
sibling origin receives SameSite=Lax cookies, so it could run arbitrary
JMAP as the signed-in user, including sharing mailboxes to a third
account.

The proxy now gates every `/api/` route except the WOPI file endpoints
the office editor calls server-to-server, and each of these handlers
checks again. The proxy also decides on the decoded path, so an escaped
spelling such as `/api/%61uth/session` no longer skips the gate.
2026-09-26 14:08:44 +02:00
Linus Rath f086d21d84 docs: use framed standard-theme screenshots in the readme 2026-09-22 23:04:27 +02:00
Linus Rath 77ef60caae feat: resolve deep links to the local instance 2026-09-20 19:59:37 +02:00
Linus Rath 9bc54a4ef6 fix: keep security headers on dotted app paths and neutralise cid: blobs (GHSA-xvjh-v9c6-qcvc) 2026-09-17 21:08:37 +02:00
Linus Rath d5c0996519 fix: bind the plugin sandbox to its framing window (GHSA-96cx-gx36-3g79) 2026-09-17 20:31:39 +02:00
Linus Rath e908aee994 fix: reject cross-site requests to /api/auth/* to stop session fixation (GHSA-qvr9-m8cq-7wvg) 2026-09-17 20:01:35 +02:00
Linus Rath ca7fbbe416 feat: WOPI office document editing in Files (Collabora/OnlyOffice/EuroOffice) #425 2026-08-31 23:16:19 +02:00
Linus Rath 1e2409f8b9 fix: keep basePath when normalizing Chinese Accept-Language 2026-08-29 12:35:38 +02:00
Linus Rath 42f736b96d Merge pull request #932 from kchuang1015/feat/zh-tw-locale
feat(i18n): add Traditional Chinese (Taiwan) locale
2026-08-29 12:32:02 +02:00
Linus Rath 4fe5701b3b feat: default sidebar apps for all users #931 2026-08-29 12:31:17 +02:00
Kuan-Chieh Huang f1736b63c9 fix(i18n): preserve locale cookie precedence 2026-08-29 13:04:25 +08:00
Kuan-Chieh Huang 9fab1d1f4a fix(i18n): normalize Chinese proxy locale detection 2026-08-29 11:44:40 +08:00
Linus Rath 67be0446e3 fix: forward every request header from the proxy so Next 16.3's RSC hash check stops 307-looping navigations #919 2026-08-26 19:28:31 +02:00
Linus Rath d9f9ed10cd fix: add embedded custom app origins to CSP frame-src #787 2026-08-16 23:48:58 +02:00
Shuki Vaknin 0d73cb5dfb fix(csp): allow external/data fonts so email webfonts render
The page CSP set font-src 'self', which blocked fonts referenced by
rendered email CSS (brand webfonts loaded over https). Allow https:/data:
for font-src. Email bodies render inside the sandboxed iframe, which keeps
its own stricter blocking-mode font-src for privacy.
2026-07-05 21:28:15 +02:00
Linus Rath 512adab7e3 feat: add privileged same-origin plugin tier + crypto API surface 2026-06-28 16:51:42 +02:00
dealerweb 241544cd08 Fix: correct <html lang> and localize the <head> description per locale
The root (main)/layout renders <html> ABOVE the [locale] segment, so next-intl's
getLocale() returns the default locale there - emitting <html lang="en"> on every
page regardless of UI language (e.g. /de) and a hardcoded English <head>
description. Both are strong "translate this page" triggers in Chrome.

proxy.ts already exposes the nonce to server components via the
x-middleware-request-* mechanism; expose the request pathname the same way as
x-pathname, and have the root layout derive the locale from it (falling back to
getLocale() when the path has no locale segment) for both <html lang> and the
localized meta_description (new key in all 17 locales; the English value is
unchanged).
2026-05-30 13:51:21 +02:00
Linus Rath afe1e5a67c fix: restore blob: in object-src and frame-src CSP for PDF/HTML previews 2026-05-23 15:53:58 +02:00
Linus Rath 628966d3b5 fix: split app into (main)/(sandbox) route groups so plugin iframe hydrates properly 2026-05-20 23:41:49 +02:00
Linus Rath 9f312aa556 feat: sandbox plugins in null-origin iframes with postMessage RPC 2026-05-18 10:50:49 +02:00
Linus Rath c646c87030 fix: standardize punctuation in tooltips and comments across multiple locales and code files 2026-05-14 21:44:24 +02:00
Lucas Gaitzsch 3f444a8912 Feature/protocol handlers
* Added account selection for protocol links when multiple connected accounts are available, including mailto: links
* Added support for handling mailto: links in an already-open PWA/session instead of always opening a new tab
* Added webcal: protocol handling for calendar links
* Added account selection for webcal: links when multiple calendar-capable accounts are connected
* Added an import-or-subscribe choice for detected webcal calendars
* Added protocol handler settings for registering mail and calendar handlers and choosing the open mode
* Added service worker/session coordination for passing protocol requests between browser/PWA contexts
* Added tests and translations for the new protocol handler flows
2026-05-12 20:49:05 +02:00
Linus Rath 876ea370e4 feat: allow file uploads on the wizard branding step 2026-05-09 21:40:39 +02:00
Linus Rath 51745ea03d feat: web setup wizard + admin config/state dir split (#226) 2026-05-09 17:37:41 +02:00
Linus Rath e7be3d1e0c fix: render PDF previews via <object> with blob: in object-src CSP #253 2026-05-06 00:54:46 +02:00
Linus Rath 0b6fdcabfb fix: update connect-src to include http protocol in development mode 2026-04-29 13:55:38 +02:00
Linus RathandCopilot e683c90404 fix: implement inline matcher for Next.js proxy and remove unnecessary config
Co-authored-by: Copilot <copilot@github.com>
2026-04-25 19:25:15 +02:00
Linus Rath cfb4a23c9d fix: remove unnecessary runtime config for Node.js in proxy settings 2026-04-25 18:54:15 +02:00
Linus Rath fe1d4861bb feat: composer-sidebar slot + plugin-declared frame-src origins 2026-04-25 18:40:54 +02:00
Denis Teyssier 37bd490072 fix: added media-src CSP rule for media attachments #209 2026-04-20 14:55:50 +02:00
Linus Rath 440a4e919a Revert "perf: make root HTML cacheable by dropping per-request CSP nonce"
This reverts commit 522bf6a019.
2026-04-18 13:10:42 +02:00
Linus Rath b8f39198e1 fix: allow blob: in frame-src CSP for attachment previews #209 2026-04-18 13:04:25 +02:00
Linus Rath 522bf6a019 perf: make root HTML cacheable by dropping per-request CSP nonce 2026-04-18 13:01:12 +02:00
Linus Rath 8bdadc7ba3 fix: standardize punctuation 2026-04-16 19:07:42 +02:00
shuki c690e8eb76 fix: skip intl middleware for paths already containing a locale prefix
When localePrefix is 'always' (or 'as-needed' with a non-default locale),
paths like /en/settings already have the locale in the URL. Running them
through the next-intl middleware a second time can trigger rewrite loops,
especially when combined with a proxy basePath where the middleware's
detection of the 'current' path conflicts with the rewritten one.

Skip the intl middleware in this case — the path is already in the
canonical locale-prefixed form and no further rewriting is needed.

This makes NEXT_PUBLIC_LOCALE_PREFIX=always reliable for sub-path
deployments.
2026-04-14 18:09:37 +02:00