mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-21 15:36:50 -05:00
Enable truly custom fonts in themes while maintaining zero runtime network
requests. Theme authors can include font files in their GitHub repos, and
fonts are automatically downloaded and embedded as data: URIs at install
time — the same approach used for theme CSS itself.
Security model:
- @font-face blocks only allow data: URIs (no http/https/relative URLs)
- Font MIME types are validated (font/woff2, font/ttf, etc.)
- Individual font files capped at 2MB, total at 10MB
- @font-face properties are allowlisted (font-family, src, font-weight,
font-style, font-display, font-stretch, unicode-range only)
- Font-family names from @font-face are available in --font-* variables
- No runtime network requests — all fonts stored locally after install
Key additions:
- extractFontFaceBlocks(): parse @font-face from theme CSS
- validateFontFaceBlock(): validate properties and data: URIs
- splitDeclarations(): semicolon-aware parser that respects data: URIs
- embedThemeFonts(): fetch font files from GitHub, convert to data: URIs
- ThemeInstaller calls embedThemeFonts() during catalog theme installation
- 30+ new test cases for @font-face validation and security edge cases
Example theme CSS with custom fonts:
@font-face {
font-family: 'My Font';
src: url('./MyFont.woff2') format('woff2');
}
:root { --font-body: 'My Font', sans-serif; }
https://claude.ai/code/session_01D4ASLpcBCvWF1nzPLz9Tw5