rusackas opened a new pull request, #43667:
URL: https://github.com/apache/superset/pull/43667
### SUMMARY
`@import` in dashboard custom CSS is rejected on save (`validate_css`,
#40640, closed up further in #43666). That leaves no in-product path for a
dashboard that already has `@import`-based CSS (predating the check, or
restored via import before #43666 closed that gap), or for someone who wants to
keep using a remote font stylesheet like Google Fonts, since the two most
common real-world uses of `@import` in dashboard CSS are effectively fonts.
This adds a **Convert @import to inline CSS** action to the dashboard CSS
editor (Properties → Styling), shown whenever the current CSS contains
`@import`, detected with the exact same `@import\b` regex `validate_css` uses
server-side, so the trigger can't drift out of sync with what the backend will
actually reject.
Clicking it:
- Fetches each `@import` target **from the browser**, not the Superset
backend. That's the key design choice: a server-side fetch of an
editor-supplied URL would need the same SSRF hardening applied elsewhere in
this codebase (dataset import, webhook dispatch), a fetch from the editor's own
browser carries none of that risk, and isn't even new exposure, every dashboard
viewer's browser already fetches that same URL today whenever `@import`-based
CSS renders.
- Parses the current CSS and each fetched stylesheet with `postcss` (new
runtime dependency, dynamically imported so it's code-split out of the main
bundle and only downloaded when this action actually runs), and replaces each
`@import` at-rule with the fetched stylesheet's own rules.
- Leaves any `@import` it can't fetch (most commonly a CORS rejection —
`fetch()` is subject to CORS, unlike the browser's native `@import` loading)
untouched in the output, and reports which URL, rather than silently dropping
content.
- Resolves only one level: an `@import` nested inside a fetched stylesheet
is left as-is. There's no security reliance on this resolving everything, only
a UX convenience — a save with a remaining `@import` still fails the existing
backend validation exactly as before.
The action only populates the CSS editor; it never saves on its own, so the
user reviews the result and clicks the normal Save button, same as any other
edit.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — will follow up with a screenshot/gif of the new alert + button once
this is up for review; happy to add on request.
### TESTING INSTRUCTIONS
```bash
npm run test -- \
src/dashboard/util/resolveCssImports.test.ts \
src/dashboard/components/PropertiesModal/sections/StylingSection.test.tsx
```
New coverage:
- `resolveCssImports.test.ts` — detects `@import` case-insensitively; leaves
ordinary CSS untouched (no fetch); replaces a Google-Fonts-style `@import` with
its fetched `@font-face` rules; leaves an `@import` unresolved and reports it
on a fetch failure or a non-CSS response; resolves one `@import` while
reporting another that failed; does **not** recursively resolve an `@import`
nested inside a fetched stylesheet.
- `StylingSection.test.tsx` — the warning/button only appears when the CSS
contains `@import`; clicking it applies the resolved CSS and shows a success
message; an unresolved import is reported and the CSS is left unchanged.
Manually: open a dashboard's Edit properties → Styling tab, paste `@import
url('https://fonts.googleapis.com/css2?family=Inter');` into the CSS field,
confirm the warning + button appear, click it, confirm the `@import` is
replaced with `@font-face` rules pointing at `fonts.gstatic.com`, and that
saving now succeeds.
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [x] Required feature flags:
- [x] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]