Files
FOSSBilling/frontend
41d3475eb5 Backport safe fixes from main to 0.8-next (#4318)
* Allow domain transfers through the Email and Custom registrars (#4304)

🐛 Allow domain transfers through the Email and Custom registrars

The Email registrar's transfer check has thrown unconditionally since the
2014 initial release, so any TLD assigned to it could not take transfer
orders even though transferDomain() is implemented. The Custom registrar
returned true without consulting RDAP, so with lookups enabled it accepted
transfers for domains that do not exist.

Both adapters now mirror their own availability check. With RDAP off the
transfer is allowed. With RDAP on, a domain that is not registered is
rejected with a message telling the client it isn't registered and may be
registerable instead, as the Internet.bs adapter does since #2241. When
RDAP cannot answer, the transfer is allowed and the operator verifies it
manually, matching the Custom adapter's existing fallback.

Fixes #4303

Co-authored-by: Kai Randles <kai.randles@streetkidsdirect.org.uk>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Adam Daley <admdly@users.noreply.github.com>
(cherry picked from commit be630a9fcc)

* Guard against missing nameserver list in Namecheap::getDomainDetails (#4285)

(cherry picked from commit 6c44fe9493)

* Restore "Allow quantity selection" toggle to admin product form (#4282)

(cherry picked from commit 8dda64f8e4)

* Exclude Email registrar RDAP-not-enabled error from Sentry (#4281)

(cherry picked from commit 14788de090)

* Fix reCAPTCHA v3 bypass on fast form submit in Antispam module (#4280)

(cherry picked from commit 7ce4e4f06e)

* Exclude expected cache-backend config errors from Sentry reporting (#4275)

* Exclude expected cache-backend config errors from Sentry reporting

Admin::update_cache_settings() eagerly connection-tests a not-yet-saved
redis/memcached config before writing it, so an admin who selects a
driver whose PHP extension isn't installed (or gives a bad
host/port/password) gets that surfaced back as an expected validation
error in the settings form - not a code bug.

These FOSSBilling\Exceptions had no error code, so ErrorPage::getCodeInfo()
defaulted them to 'report' => true and every occurrence got forwarded to
Sentry as noise. Give them a dedicated 'Cache' error-code range (5000-5999,
code 5001) and list it as report:false, mirroring the existing pattern for
'not fully configured' server manager/registrar/payment gateway errors
(2001/3001/4001).

* Keep unexpected \Error instances reportable in CacheFactory

catch (\Throwable) around adapter construction/assertUsable() also caught
\Error (TypeError, ArgumentCountError, ...), which would then get wrapped
into the new code-5001 exception and silently excluded from Sentry even
though an \Error there means a genuine bug in our own code, not an admin
misconfiguration. Narrow the catch to \Exception - the redis/memcached
extensions and Symfony's cache adapters only ever raise \Exception (or a
subclass) for expected connection/configuration failures - so a real
\Error now propagates and gets reported as usual.

(cherry picked from commit e17411cd24)

* fix(product): build serie_nr in promo redemption instead of selecting a missing column (#4279)

* fix(product): build serie_nr in promo redemption instead of selecting a missing column

findInvoiceSummary() selected a `serie_nr` column from the invoice table, but
the invoice table stores `serie` and `nr` separately and `serie_nr` is a
computed value. Viewing a promo's redemption history therefore threw
"Unknown column 'serie_nr'". Select the real columns and build serie_nr the
same way the Invoice module does: the serie followed by the zero-padded number.

Signed-off-by: Devadatta Sahoo <devadattas@gmail.com>

* Address review: normalize invoice nr with ID fallback in promo redemption

Align serie_nr construction with Invoice service: use numeric nr when
possible, falling back to the invoice ID otherwise. Add regression
coverage for formatting and the invoice summary query.

---------

Signed-off-by: Devadatta Sahoo <devadattas@gmail.com>
Co-authored-by: Adam Daley <admdly@users.noreply.github.com>
(cherry picked from commit 3dddfa67d3)

* Fix nginx security bugs in DDEV config (#4270)

- location ~ ^/(index.php|ipn.php|install/index.php|install/install.php)
  had no trailing $, so it prefix-matched instead of requiring an exact
  entry-point filename.
- Both PHP-related regexes had an unescaped leading dot (`.` matches any
  character, not just a literal dot), including the final catch-all
  `.(php)$` deny rule.
- The sensitive-file extension list had `yam` instead of `yaml`/`yml`,
  so those extensions were never actually blocked.
- No protection at all for composer.json/README.md/CHANGELOG.md, unlike
  src/.htaccess, which blocks these explicitly.

Verified against the real file with an isolated nginx+php-fpm harness
before and after: confirmed config.yaml, composer.json, and README.md
were served as static 200s pre-fix and are 403 post-fix, confirmed
routing (front-controller path resolution, query strings, all four
real entry points) is unaffected, and confirmed `nginx -t` passes on
the file as committed.

(cherry picked from commit 409a86786e)

* 🐛 Keep Tabler data-tblr-* rules when purging theme CSS (#4310)

Tabler 1.5 stamps navbar dropdown menus with data-tblr-popper instead of
data-bs-popper. The PurgeCSS safelist only protected data-bs-*, so
production builds dropped the rule that positions top-nav menus below
their toggle and they opened over the header. Dev builds skip PurgeCSS,
which is why it never reproduced locally.

Fixes #4309

Co-authored-by: Kai Randles <kai.randles@streetkidsdirect.org.uk>
Co-authored-by: Adam Daley <admdly@users.noreply.github.com>
(cherry picked from commit 336f06b3b2)

* Fix broken Style Guides link in contributor documentation (#4267)

📝 Fix contributor guide style anchor [ci skip]

Co-authored-by: wangyusheng1985 <wangyusheng1985@users.noreply.github.com>
Co-authored-by: Adam Daley <admdly@users.noreply.github.com>
(cherry picked from commit fb44037af7)

* Backport partial fixes from main: normalize module names (#4299) and handle PDO SQLSTATE codes (#4296)

- Cookieconsent/Embed display names only; theme manifest hunks skipped (0.8-next has no default/ theme yet, still admin_default/huraga).
- ExceptionResponseFactory is_int guard plus prod SQLSTATE test only; DDEV refresh hunks intentionally excluded.
- Refs main commits 3cb15eec7 and 7fb8024c2.

* Update src/modules/Cookieconsent/Controller/Admin.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Signed-off-by: Devadatta Sahoo <devadattas@gmail.com>
Co-authored-by: Kai Randles <77554122+kairandles@users.noreply.github.com>
Co-authored-by: Kai Randles <kai.randles@streetkidsdirect.org.uk>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Dev S <56180+devadattas@users.noreply.github.com>
Co-authored-by: 玉升 <wyshdiy@163.com>
Co-authored-by: wangyusheng1985 <wangyusheng1985@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-09-15 20:02:38 +01:00
..

Frontend and Theme Builds

FOSSBilling builds shared browser assets from frontend/ and theme assets from each theme workspace.

Build Commands

  • npm run build checks frontend source, builds core assets, and builds all themes.
  • npm run build:production runs the same build with NODE_ENV=production.
  • npm run check runs lightweight JavaScript syntax checks and validates theme icon manifests.
  • npm run build-admin_default and npm run build-huraga build a single theme.

Generated assets are written to src/public/assets and src/themes/*/assets/build. These paths are ignored by Git and are copied into release artifacts by the Docker build.

Theme Dependencies

Themes own the UI packages they consume. Shared tooling in frontend/tools can help compile assets, generate sprites, and post-process CSS, but it should not make a theme depend on a specific UI package.

Examples:

  • admin_default owns Tabler, Coloris, Chart.js, Litepicker, Tom Select, Flag Icons, and its Tabler icon package.
  • huraga owns Bootstrap, Tom Select, Flag Icons, and its Tabler icon package.
  • svg-sprite is a root development dependency because the shared sprite helper imports it.

Icons

Theme icon sprites are generated from each theme's icon-manifest.json.

  • Add static SVG icon usage to the relevant theme manifest.
  • Mark icons as "dynamic": true when the icon name is resolved at runtime, such as admin navigation icons from module metadata.
  • Put theme-specific SVG files in the theme's custom-icons directory.
  • Reference generated symbols with inline sprite IDs, for example <use href="#home" />.

Run npm run check-icons before changing icon usage.

CSS

Theme vendor CSS belongs in src/themes/*/assets/css/vendor.css. Theme-specific styles belong in the theme Sass entrypoint.

PurgeCSS runs only for production builds. A PurgeCSS failure fails production builds so release CSS problems are caught early.