Aman-Mittal opened a new pull request, #361:
URL: https://github.com/apache/fineract-backoffice-ui/pull/361
The UI loaded Inter from `fonts.googleapis.com` via a `<link>` in
`src/index.html`. This removes that dependency and renders in the platform's
own interface font instead.
No dependency is added: `package.json` and `package-lock.json` are
byte-identical to `main`.
## Why
Three problems, in increasing order of how long each went unnoticed.
**The production build depended on a network fetch.** Angular's font
inlining downloads that stylesheet during a production build and inlines the
`@font-face` rules. When the host is unreachable the build does not degrade —
it fails:
```
✘ Inlining of fonts failed. An error has occurred while retrieving
https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap
over the internet.
```
An ASF release has to be buildable from its source package. This one could
not be built without reaching a third-party service.
**The fetched bytes were not pinned.** Every other dependency is locked by
integrity hash in `package-lock.json`. A `css2?family=Inter:wght@…` URL pins
nothing, so two builds of the same commit could embed different bytes with
nothing recording the difference.
**The font never actually loaded in our own container.** `deploy/nginx.conf`
sets `font-src 'self' data:`, so every request the built page made to
`fonts.gstatic.com` was blocked by our own CSP. The deployed UI has always
rendered in the fallback stack — which is why removing Inter changes nothing a
user of the image sees.
## Measured, not assumed
Two Docker images built from `deploy/Dockerfile`, one per revision, driven
in Chrome behind the identical production CSP:
| | `main` | this branch |
| --- | --- | --- |
| Requests to `fonts.gstatic.com` | 35, all blocked | **0** |
| CSP font violations | 35 | **0** |
| Offline production build (`unshare -rn`) | **exit 1** — `Inlining of fonts
failed` | **exit 0** |
## Why not self-host Inter
Self-hosting from a pinned `@fontsource-variable/inter` was implemented and
verified first, and it worked — the offline build passed and the hashed
`.woff2` files served from our own origin, byte-identical (SHA-256) to what
Google served.
It was dropped because Inter is SIL OFL 1.1, which ASF policy classifies as
[**Category B**](https://www.apache.org/legal/resolved.html): admissible in
binary form in a convenience binary when labelled, and *not* admissible in a
source release. `CONTRIBUTING.md` already states the same rule — "New runtime
dependencies must be **Apache Category A** compatible" — and CI enforces it:
`license-checker --onlyAllow
"MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD"` rejects `OFL-1.1` outright.
Satisfiable, but it costs a licence file, a README label, a `.rat-excludes`
entry, a Dockerfile change and an `OFL-1.1` exception in that allow-list — for
a typeface users of the container have never actually seen. For a first release
that is a poor trade. `DOCS/FONTS.md` records the verified route back if a
later release wants Inter.
## The change
- `src/index.html` — removed the stylesheet link and both Google
`preconnect` hints.
- `src/styles.scss` — `system-ui, -apple-system, BlinkMacSystemFont, 'Segoe
UI', Roboto, 'Helvetica Neue', Arial, sans-serif`. `system-ui` leads so Linux
and Android resolve their real UI font rather than falling through to bare
`sans-serif`, as the old stack did.
- `scripts/ga-check.mjs` — new `external-fonts` gate so this cannot silently
return. It scans `src/`, `public/`, `projects/`, `deploy/`, `angular.json`
**and a built `dist/`** — the artifact matters as much as the source, because
the build itself baked the dependency into the output. It matches only
scheme-qualified or protocol-relative references, so prose naming the hosts
does not trip it. Negative-tested by reinserting a `<link>`.
- `DOCS/FONTS.md`, `DOCS/CI_CHECKS.md`, `README.md`, `.rat-excludes`,
`audit/` — documentation, the gate's entry in the checks table, and the audit
this came from.
`NOTICE`, `deploy/nginx.conf` and the `license-checker` allow-list are all
untouched. The CSP is not weakened. No `.woff2` is committed.
## Verification
Online and offline production builds, 952/952 unit tests, `lint`, HTML lint,
`format:check`, `check-license.sh`, Apache RAT (667 approved, 0 unapproved),
`license-checker` against the unchanged allow-list, and the new `ga:check`
gate. `ga:check`'s two other failures (`api-surface`, `adapter-boundary`) are
identical on `main` and untouched here.
One detail worth knowing for future edits: **Angular preserves HTML comments
into the built `index.html`**. An explanatory comment naming the host leaked it
into the artifact, so the comment now deliberately names no external host.
## Related
Verification of this change surfaced two unrelated CSP defects that also
reproduce on `main` — the critical-CSS `onload` and the native-federation
`blob:` module are both blocked by `script-src 'self'`. Filed separately as
#360 rather than mixed in here.
Note there was no pre-existing tracking issue for the font work itself; the
analysis lives in `audit/GOOGLE-FONTS-ASF-AUDIT.md`, added in this PR. Happy to
open one if the convention requires it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]