Skip to content

fix(framework): sap-ui-themeRoot block all origins by defaultTheme root disallow default #12035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/2-advanced/01-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ Example:
### themeRoot
<a name="themeRoot"></a>

**Deprecated:** Please use the `theme` setting to pass both the theme and theme root, in the `theme@themeRoot` format instead

Allows you to set a URL, from which the framework will fetch the theme styles (CSS variables).

*Note:* This configuration setting is only applicable to custom themes, created with SAP Theme Designer.
Expand All @@ -283,6 +285,25 @@ Example:
</script>
```

or, the preferred new format:

```html
<script data-ui5-config type="application/json">
{
"theme": "sap_horizon@https://my-example-host.com/"
}
</script>
```

*Important:* You must explicitly allow specific origins for this configuration setting to work:

```html
<head>
<meta name="sap-allowed-theme-origins" content="https://my-example-host.com/,https://my-example-host2.com/">
```

Failing to do so will result in a warning in the console and the theme root will not be set.

## Configuration Script
<a name="script"></a>

Expand Down
4 changes: 2 additions & 2 deletions docs/2-advanced/12-theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ index.html?sap-ui-theme=mytheme@https://my-example-host.com/

In this example, "mytheme" theme will be applied and its resources (CSS variables specific to the theme) will be loaded from https://my-example-host.com/UI5/Base/baseLib/mytheme/css_variables.css.

**Note:** Certain security restrictions will apply before loading the custom theme. Absolute URLs to a different origin than the current page will return the current page as an origin. To allow certain origins, you have to use `<meta name="sap-allowedThemeOrigins" content="https://my-example-host.com/">` tag inside the head of the page.
**Note:** Certain security restrictions will apply before loading the custom theme. Absolute URLs to a different origin than the current page will return the current page as an origin. To allow certain origins, you have to use `<meta name="sap-allowed-theme-origins" content="https://my-example-host.com/">` tag inside the head of the page.

### Using JS API

To load a custom theme via URL, you can also use the available `setThemeRoot` method. The specified theme root will be applied to the currently set theme.

**Note:** Certain security restrictions will apply before loading the custom theme. Absolute URLs to a different origin than the current page will return the current page as an origin. To allow certain origins, you have to use `<meta name="sap-allowedThemeOrigins" content="https://my-example-host.com/">` tag inside the head of the page.
**Note:** Certain security restrictions will apply before loading the custom theme. Absolute URLs to a different origin than the current page will return the current page as an origin. To allow certain origins, you have to use `<meta name="sap-allowed-theme-origins" content="https://my-example-host.com/">` tag inside the head of the page.

```js
import { setThemeRoot } from "@ui5/webcomponents-base/dist/config/ThemeRoot.js";
Expand Down
4 changes: 2 additions & 2 deletions packages/base/cypress/specs/ConfigurationURL.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("Different themeRoot configurations", () => {
cy.window()
.then($el => {
const metaTag = document.createElement("meta");
metaTag.name = "sap-allowedThemeOrigins";
metaTag.name = "sap-allowed-theme-origins";
metaTag.content = "https://example.com";

$el.document.head.append(metaTag);
Expand All @@ -86,7 +86,7 @@ describe("Different themeRoot configurations", () => {
// All allowed theme roots need to be described inside the meta tag.
cy.window()
.then($el => {
const metaTag = $el.document.head.querySelector("[name='sap-allowedThemeOrigins']");
const metaTag = $el.document.head.querySelector("[name='sap-allowed-theme-origins']");

metaTag?.remove();
})
Expand Down
10 changes: 10 additions & 0 deletions packages/base/src/InitialConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ const getTheme = () => {

const getThemeRoot = () => {
initConfiguration();

if (initialConfig.themeRoot === undefined) {
return;
}

if (!validateThemeRoot(initialConfig.themeRoot)) {
console.warn(`The ${initialConfig.themeRoot} is not valid. Check the allowed origins as suggested in the "setThemeRoot" description.`); // eslint-disable-line
return;
}

return initialConfig.themeRoot;
};

Expand Down
4 changes: 3 additions & 1 deletion packages/base/src/config/ThemeRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ const getThemeRoot = (): string | undefined => {
*
* **Note:** Certain security restrictions will apply before fetching the theme assets.
* Absolute URLs to a different origin than the current page will result in using the current page as an origin.
* To allow specific origins, use &lt;meta name="sap-allowedThemeOrigins" content="https://my-example-host.com/"&gt; tag inside the &lt;head&gt; of the page.
*
* **Important:** To use this feature you must explicitly allow specific origins by using &lt;meta name="sap-allowed-theme-origins" content="https://my-example-host.com/"&gt; tag inside the &lt;head&gt; of the page.
* Failing to do so will result in a warning in the console and the theme root will not be set.
*
* @public
* @since 1.14.0
Expand Down
9 changes: 7 additions & 2 deletions packages/base/src/validateThemeRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ const getMetaTagValue = (metaTagName: string) => {
};

const validateThemeOrigin = (origin: string) => {
const allowedOrigins = getMetaTagValue("sap-allowedThemeOrigins");
const allowedOrigins = getMetaTagValue("sap-allowed-theme-origins") ?? getMetaTagValue("sap-allowedThemeOrigins"); // Prioritize the new meta tag name

return allowedOrigins && allowedOrigins.split(",").some(allowedOrigin => {
// If no allowed origins are specified, block.
if (!allowedOrigins) {
return false;
}

return allowedOrigins.split(",").some(allowedOrigin => {
return allowedOrigin === "*" || origin === allowedOrigin.trim();
});
};
Expand Down
2 changes: 1 addition & 1 deletion packages/base/test/pages/Configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<meta name="sap-allowedThemeOrigins" content="https://example.com">
<meta name="sap-allowed-theme-origins" content="https://example.com">

<title>Base package default test page</title>

Expand Down
Loading