From 06350c1834a89772d675e5d9c81203de1812f2eb Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sun, 23 Aug 2026 17:56:25 +0100 Subject: [PATCH 1/5] Allow scripts for esbuild and fsevents --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 0bfb85f..c0b7741 100644 --- a/package.json +++ b/package.json @@ -25,5 +25,9 @@ "@markdoc/markdoc": "^0.5.7", "astro": "^7.0.0", "sharp": "^0.35.0" + }, + "allowScripts": { + "esbuild": true, + "fsevents": true } } From 09c02ff8a96e48a339377f84c17af0482cdd6315 Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sun, 23 Aug 2026 17:57:44 +0100 Subject: [PATCH 2/5] Update dependencies --- package-lock.json | 163 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 139 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index deddad1..c4b76d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -484,6 +484,37 @@ "win32" ] }, + "node_modules/@astrojs/markdown-satteri/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@astrojs/markdown-satteri/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@astrojs/markdown-satteri/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@astrojs/markdown-satteri/node_modules/satteri": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/satteri/-/satteri-0.10.5.tgz", @@ -799,6 +830,37 @@ "node": ">=14.0.0" } }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@bruits/satteri-win32-arm64-msvc": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@bruits/satteri-win32-arm64-msvc/-/satteri-win32-arm64-msvc-0.9.5.tgz", @@ -937,20 +999,21 @@ "license": "MIT" }, "node_modules/@emnapi/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", - "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", + "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.2", + "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", "license": "MIT", "optional": true, "dependencies": { @@ -958,11 +1021,12 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -3948,9 +4012,9 @@ } }, "node_modules/fast-uri": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", - "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", "dev": true, "funding": [ { @@ -8032,6 +8096,13 @@ "vscode-uri": "^3.1.0" } }, + "node_modules/vscode-css-languageservice/node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, "node_modules/vscode-html-languageservice": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.6.2.tgz", @@ -8063,9 +8134,9 @@ } }, "node_modules/vscode-jsonrpc": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.1.tgz", + "integrity": "sha512-rfuA6T75H6m5EkbhtEPzre9pT0HPcDI2MMy4+nPFIBks5J8JBAUHD4tRYSgaBOijIEC7SRkC1kKyXTLqbmh9jw==", "dev": true, "license": "MIT", "engines": { @@ -8086,14 +8157,14 @@ } }, "node_modules/vscode-languageserver-protocol": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.2.tgz", + "integrity": "sha512-XRyDbT0Pp3sSNti3JmxVEUMySWCSi1hhM+/KUlCy1hV1zmrqpM1OwO12EAki8blhmLuIMpaJrYbo0OzGVfK2Qg==", "dev": true, "license": "MIT", "dependencies": { - "vscode-jsonrpc": "8.2.0", - "vscode-languageserver-types": "3.17.5" + "vscode-jsonrpc": "9.0.1", + "vscode-languageserver-types": "3.18.0" } }, "node_modules/vscode-languageserver-textdocument": { @@ -8104,6 +8175,34 @@ "license": "MIT" }, "node_modules/vscode-languageserver-types": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.0.tgz", + "integrity": "sha512-8TsGPNMIMiiBdkORgRSvLjuiEIiAFtO+KssmYWxQ+uSVvlf7RjK8YKCOjPzZ+YA04jXEV7+7LvkSmHkhpNS99g==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver/node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver/node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver/node_modules/vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", @@ -8200,9 +8299,9 @@ } }, "node_modules/yaml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", - "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "devOptional": true, "license": "ISC", "bin": { @@ -8246,6 +8345,22 @@ "dev": true, "license": "MIT" }, + "node_modules/yaml-language-server/node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", From ca3aa388fc940ceefc42f7227b57db46262b6f4f Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sun, 23 Aug 2026 18:01:09 +0100 Subject: [PATCH 3/5] Update homepage banner for 0.8.6 --- src/content/docs/index.mdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/index.mdoc b/src/content/docs/index.mdoc index 2f4a5ad..91a160b 100644 --- a/src/content/docs/index.mdoc +++ b/src/content/docs/index.mdoc @@ -4,9 +4,9 @@ description: Learn what FOSSBilling is, where to start, and how to get involved tableOfContents: false banner: content: | - 0.8.5 is here! Check out the - release notes - and the 0.7 → 0.8 upgrade guide for details. + 0.8.6 is here! Check out the + release notes + and 0.7 → 0.8 upgrade guide for details. --- FOSSBilling (*FOSS*: Free and Open Source Software) is a billing and client management solution for hosting providers and digital service businesses. From 8eb25ca3f13824b27e59239201b6d8f88a94fa6a Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sun, 23 Aug 2026 18:20:05 +0100 Subject: [PATCH 4/5] Document 0.8.6 cookie and security changes --- .../docs/extensions-and-development/api.mdoc | 4 +-- .../guides/creating-a-theme.mdoc | 2 +- .../javascript.mdoc | 6 ++-- .../docs/maintenance/Updating/0-7-to-0-8.mdoc | 29 +++++++++++++++++-- src/content/docs/maintenance/changelog.mdoc | 11 +++++++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/content/docs/extensions-and-development/api.mdoc b/src/content/docs/extensions-and-development/api.mdoc index 4aeab1e..0aa7176 100644 --- a/src/content/docs/extensions-and-development/api.mdoc +++ b/src/content/docs/extensions-and-development/api.mdoc @@ -52,7 +52,7 @@ For browser calls, FOSSBilling accepts the token in any of these places: - `CSRFToken` in form data or query parameters - `X-CSRF-Token` request header -The token must match the `csrf_token` cookie or the session token. The bundled [JavaScript API wrapper](/extensions-and-development/javascript/) reads the cookie and adds the token automatically. +The token must match the `fossbilling_csrf` cookie or the session token. The bundled [JavaScript API wrapper](/extensions-and-development/javascript/) reads the cookie and adds the token automatically. Use Twig helpers for theme and module templates. This way, you don't need to manually attach CSRF tokens to the requests: @@ -66,7 +66,7 @@ Use Twig helpers for theme and module templates. This way, you don't need to man For raw `fetch()` requests, send the token yourself: ```javascript -const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || ''; +const token = document.cookie.match(/fossbilling_csrf=([^;]*)/)?.[1] || ''; fetch('/api/client/profile/update', { method: 'POST', diff --git a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc index 1f0231c..7f95118 100644 --- a/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc +++ b/src/content/docs/extensions-and-development/guides/creating-a-theme.mdoc @@ -77,7 +77,7 @@ For links that trigger API actions: ``` -Session-authenticated `client` and `admin` browser API calls require CSRF protection. The [JavaScript API wrapper](/extensions-and-development/javascript/) reads the `csrf_token` cookie and sends the token automatically. +Session-authenticated `client` and `admin` browser API calls require CSRF protection. The [JavaScript API wrapper](/extensions-and-development/javascript/) reads the `fossbilling_csrf` cookie and sends the token automatically. Use `role: 'guest'` for public actions such as login, signup, and password reset: diff --git a/src/content/docs/extensions-and-development/javascript.mdoc b/src/content/docs/extensions-and-development/javascript.mdoc index 833ecc0..792e3ad 100644 --- a/src/content/docs/extensions-and-development/javascript.mdoc +++ b/src/content/docs/extensions-and-development/javascript.mdoc @@ -37,7 +37,7 @@ document.addEventListener('DOMContentLoaded', function() { ## CSRF Tokens -FOSSBilling uses a double-submit style token for browser API calls. Browser-rendered Twig pages expose `CSRFToken` and set a `csrf_token` cookie. +FOSSBilling uses a double-submit style token for browser API calls. Browser-rendered Twig pages expose `CSRFToken` and set a `fossbilling_csrf` cookie. | Call type | CSRF requirement | |-----------|------------------| @@ -45,7 +45,7 @@ FOSSBilling uses a double-submit style token for browser API calls. Browser-rend | `client` or `admin` API calls with the browser session | Required. | | External `client` or `admin` API calls using an API key | Not required. | -The JavaScript wrapper reads the `csrf_token` cookie and sends it automatically where applicable. You don't need to manually attach the token to form data when using the wrapper. +The JavaScript wrapper reads the `fossbilling_csrf` cookie and sends it automatically where applicable. You don't need to manually attach the token to form data when using the wrapper. ## Making Requests @@ -219,7 +219,7 @@ Use manual `fetch()` only when the wrapper does not fit. For session-authenticat ```javascript function getCsrfToken() { - const match = document.cookie.match(/csrf_token=([^;]*)/); + const match = document.cookie.match(/fossbilling_csrf=([^;]*)/); return match ? decodeURIComponent(match[1]) : ''; } diff --git a/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc index 490e8b8..c047213 100644 --- a/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc +++ b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc @@ -180,10 +180,10 @@ The `DebugBar_renderHead()` Twig function has been renamed to `debug_bar_render_ ### CSRF Meta Tag Removed -The `` tag has been removed from bundled themes. CSRF tokens are now sent via cookie (`csrf_token`) and handled automatically by the JavaScript API wrapper. If your custom theme relies on the meta tag, switch to reading the cookie: +The `` tag has been removed from bundled themes. CSRF tokens are now sent via cookie (`fossbilling_csrf` since 0.8.6, `csrf_token` before) and handled automatically by the JavaScript API wrapper. If your custom theme relies on the meta tag, switch to reading the cookie: ```javascript -const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || ''; +const token = document.cookie.match(/fossbilling_csrf=([^;]*)/)?.[1] || ''; ``` Build output is written to theme/public asset directories such as `src/public/assets`, not to a tracked `frontend/build` directory. @@ -516,6 +516,31 @@ Custom modules or themes that check permissions directly via `$staff->hasPermiss Existing staff group assignments are migrated automatically, with legacy non-admin staff from the old default group assigned to the **Migrated staff** group. For untouched legacy groups, `manage_settings` is backfilled on selected core modules where access was already granted to preserve prior behavior. After updating, review staff group assignments and permissions in the admin panel. Use the `has_permission` Twig function for template checks; in PHP, use the staff service's group-aware methods instead of reading the `permissions` field directly. +## Cookie Standardization & Security Hardening (0.8.6) + +### Breaking: Cookie Names + +{% aside type="caution" %} +FOSSBilling cookies now use standardized `fossbilling_*` names. Existing sessions and CSRF, locale, and timezone cookies are migrated transparently, but custom themes or scripts that read the legacy cookie names (`csrf_token`, `BBLANG`, `fb_locale`, `fb_timezone`) directly will need updating. +{% /aside %} + +The patcher migrates existing cookies automatically. Update any custom code that reads cookies directly: + +```javascript +// Before (0.8.5 and earlier) +const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || ''; + +// After (0.8.6) +const token = document.cookie.match(/fossbilling_csrf=([^;]*)/)?.[1] || ''; +``` + +The bundled JavaScript API wrapper (`js/api.js`) already handles the new name, so themes using `API.*` or `fb_api_form`/`fb_api_link` require no change. The old names are no longer set after the upgrade. + +### Security + +- **CSV exports** (clients, invoices, orders) now strip secret columns and require both `view` and `export` permissions. Staff with only `export` will no longer see full records - review group permissions if exports appear empty. +- **Extension permissions:** `manage_extensions` is now enforced for inactive modules. Staff without that permission can no longer open their configuration pages. + ## Deprecations & Removals (Summary) | Component | Status | Notes | diff --git a/src/content/docs/maintenance/changelog.mdoc b/src/content/docs/maintenance/changelog.mdoc index 2bf6830..dbc8ea3 100644 --- a/src/content/docs/maintenance/changelog.mdoc +++ b/src/content/docs/maintenance/changelog.mdoc @@ -18,6 +18,17 @@ FOSSBilling publishes release notes and tagged versions on GitHub. Use the links For the latest changes, start with the [most recent release](https://github.com/FOSSBilling/FOSSBilling/releases/latest). +### Version 0.8.6 + +| Area | Summary | +|------|---------| +| **Breaking: Cookies** | Cookie names standardized to `fossbilling_*` (`csrf_token` → `fossbilling_csrf`, `BBLANG`/`fb_locale`/`fb_timezone` etc.). Migrated transparently, but custom themes or scripts reading legacy names directly must update. | +| **Security** | CSV exports hardened against secret columns and now require `view` + `export` permissions; cart config injection via downloadable products blocked; `manage_extensions` enforced for inactive modules; update archives verified via SHA-256 before extraction; hosting plan listings scoped to enabled products with order values cross-checked. | +| **New Features** | Currency format patterns and fraction digits with per-currency manual rate overrides; promo redemption history and duplicate action; `Enable Add Funds` toggle for client top-ups; global Bcc for outgoing mail; ticket priority in email previews; failed invoice-item tracking with attempt counter and Failed Items page; opt-in cron to prune stale never-paid `pending_setup` orders; TLD periods can be restricted to an explicit list; order details show discount and post-discount amount; Update page surfaces preview build. | +| **Bug Fixes** | PayPal IPN backslash stripping; Namecheap expiration dates; Plesk hosting-plan assignment and invalid webspace `set`; DirectAdmin package value reset; WHM reseller ACL; domain expiry sync not refreshing and sync marker advancing on failure; hosting orders stuck in `pending_setup` with duplicate `createacct`; checkout rolling back entire cart on partial failure; promo setup-fee waiver on non-applicable products; duplicate balance credits; race conditions: invoice-number collisions, credit double-spend, stock oversell, and Stripe webhook double-processing serialized; Stripe non-integer amount validation; cron client emails failing without admin session; session regeneration grace period hardcoded to zero and stale admin identity on client login; password reset confirmation and signup country selector timeout; new-order form crash for products missing period prices; one-time product checkout, TLD handler, and undefined `addons` variable; Cookie Consent crash when unconfigured; currency table missing columns and incomplete custom fields; client group not persisting and group-0 search errors; core-update login lockout and file-swap race; exception handler on non-integer codes; mass mailer preview, order button settings, and Service Management tab fatals; gateway highlight and dark border; inconsistent overdue invoice cleanup now routed through normal deletion. | + +[View the full 0.8.6 release notes](https://github.com/FOSSBilling/FOSSBilling/releases/tag/0.8.6) for the complete list of changes. + ### Version 0.8.5 | Area | Summary | From 56431a8acea277a0ebb70ee74a510a76a195760a Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sun, 23 Aug 2026 18:32:55 +0100 Subject: [PATCH 5/5] Update src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc index c047213..9767ca3 100644 --- a/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc +++ b/src/content/docs/maintenance/Updating/0-7-to-0-8.mdoc @@ -524,7 +524,7 @@ Existing staff group assignments are migrated automatically, with legacy non-adm FOSSBilling cookies now use standardized `fossbilling_*` names. Existing sessions and CSRF, locale, and timezone cookies are migrated transparently, but custom themes or scripts that read the legacy cookie names (`csrf_token`, `BBLANG`, `fb_locale`, `fb_timezone`) directly will need updating. {% /aside %} -The patcher migrates existing cookies automatically. Update any custom code that reads cookies directly: +FOSSBilling migrates existing cookies automatically during browser requests. Update any custom code that reads cookies directly: ```javascript // Before (0.8.5 and earlier)