From 124d1ffa98415dbc04efec7ef2ee68489add159b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 15:59:36 +0000 Subject: [PATCH 1/4] Initial plan From 276a3e24d129b901d6682f65f3ae49a6002a838b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 16:11:46 +0000 Subject: [PATCH 2/4] fix(edit-ema): use page host for scanner URL on traditional pages Agent-Logs-Url: https://github.com/dotCMS/core/sessions/558b48f9-b52e-4808-b825-472ef0d53dc6 --- .../dot-ema-shell.component.spec.ts | 8 ++++ .../dot-ema-shell/dot-ema-shell.component.ts | 5 ++- .../edit-ema/portlet/src/lib/utils/index.ts | 16 +++++++- .../portlet/src/lib/utils/utils.spec.ts | 37 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts index d08e2a52073c..ca7f26895eaa 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.spec.ts @@ -1251,6 +1251,14 @@ describe('DotEmaShellComponent', () => { expect(currentUrl).toMatch(/^\//); }); + + it('should use page hostname when clientHost is not present', () => { + const seoParams = spectator.component['$seoParams'](); + + expect(seoParams.requestHostName).toBe( + `${window.location.protocol}//${MOCK_RESPONSE_HEADLESS.site.hostname}` + ); + }); }); describe('$errorDisplay computed property', () => { diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts index 0099305c7305..9bd258719b97 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/dot-ema-shell/dot-ema-shell.component.ts @@ -164,7 +164,10 @@ export class DotEmaShellComponent implements OnInit, OnDestroy { protected readonly $seoParams = computed(() => { const url = sanitizeURL(this.uveStore.pageAsset()?.page?.pageURI); const currentUrl = url.startsWith('/') ? url : '/' + url; - const requestHostName = getRequestHostName(this.uveStore.pageParams()); + const requestHostName = getRequestHostName( + this.uveStore.pageParams(), + this.uveStore.pageAsset()?.site?.hostname + ); return { siteId: this.uveStore.pageAsset()?.site?.identifier, diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts index 836bb87a0dc0..804e2d6e75e4 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts @@ -794,8 +794,20 @@ export const mapContainerStructureToArrayOfContainers = (containers: DotCMSPageA * @param {DotPageApiParams} params * @return {*} {string} */ -export const getRequestHostName = (params: DotPageApiParams) => { - return params?.clientHost || window.location.origin; +export const getRequestHostName = (params: DotPageApiParams, pageHostname?: string) => { + if (params?.clientHost) { + return params.clientHost; + } + + if (pageHostname) { + try { + return new URL(pageHostname).origin; + } catch { + return `${window.location.protocol}//${pageHostname}`; + } + } + + return window.location.origin; }; /** diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts index 77bf274f8ce8..9ac241d1853b 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts @@ -26,6 +26,7 @@ import { createFullURL, getDragItemData, createReorderMenuURL, + getRequestHostName, getOrientation, normalizeQueryParams, convertUTCToLocalTime, @@ -1295,6 +1296,42 @@ describe('utils functions', () => { }); }); + describe('getRequestHostName', () => { + it('should return clientHost when it is provided', () => { + expect( + getRequestHostName({ + url: 'test', + language_id: '1', + [PERSONA_KEY]: DEFAULT_PERSONA.keyTag, + clientHost: 'https://headless.example.com' + }) + ).toBe('https://headless.example.com'); + }); + + it('should build the host from page hostname when clientHost is missing', () => { + expect( + getRequestHostName( + { + url: 'test', + language_id: '1', + [PERSONA_KEY]: DEFAULT_PERSONA.keyTag + }, + 'siteb.example.com' + ) + ).toBe(`${window.location.protocol}//siteb.example.com`); + }); + + it('should fallback to window origin when neither clientHost nor page hostname is provided', () => { + expect( + getRequestHostName({ + url: 'test', + language_id: '1', + [PERSONA_KEY]: DEFAULT_PERSONA.keyTag + }) + ).toBe(window.location.origin); + }); + }); + describe('getDragItemData', () => { it('should return correct data for content-type', () => { const dataset = { From d6287cb583eec57ceadc2943313d9ea07376a82e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 16:15:03 +0000 Subject: [PATCH 3/4] test(edit-ema): cover scanner host precedence and URL parsing Agent-Logs-Url: https://github.com/dotCMS/core/sessions/558b48f9-b52e-4808-b825-472ef0d53dc6 --- .../portlet/src/lib/utils/utils.spec.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts index 9ac241d1853b..e326061a2b93 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/utils.spec.ts @@ -1321,6 +1321,33 @@ describe('utils functions', () => { ).toBe(`${window.location.protocol}//siteb.example.com`); }); + it('should extract origin when page hostname is a full URL', () => { + expect( + getRequestHostName( + { + url: 'test', + language_id: '1', + [PERSONA_KEY]: DEFAULT_PERSONA.keyTag + }, + 'https://siteb.example.com/path' + ) + ).toBe('https://siteb.example.com'); + }); + + it('should prioritize clientHost over page hostname', () => { + expect( + getRequestHostName( + { + url: 'test', + language_id: '1', + [PERSONA_KEY]: DEFAULT_PERSONA.keyTag, + clientHost: 'https://headless.example.com' + }, + 'siteb.example.com' + ) + ).toBe('https://headless.example.com'); + }); + it('should fallback to window origin when neither clientHost nor page hostname is provided', () => { expect( getRequestHostName({ From f9aab830915b52a66c150106c70bad05c731f6f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 16:20:03 +0000 Subject: [PATCH 4/4] chore(edit-ema): document hostname fallback in scanner host resolver Agent-Logs-Url: https://github.com/dotCMS/core/sessions/558b48f9-b52e-4808-b825-472ef0d53dc6 --- core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts index 804e2d6e75e4..aa7c50f14935 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/utils/index.ts @@ -803,6 +803,7 @@ export const getRequestHostName = (params: DotPageApiParams, pageHostname?: stri try { return new URL(pageHostname).origin; } catch { + // Hostname can be provided without scheme (e.g. "siteb.example.com") return `${window.location.protocol}//${pageHostname}`; } }