diff --git a/core-web/apps/dotcms-ui/src/assets/seo/page-tools.json b/core-web/apps/dotcms-ui/src/assets/seo/page-tools.json index 33ec10494d94..cb809628fb00 100644 --- a/core-web/apps/dotcms-ui/src/assets/seo/page-tools.json +++ b/core-web/apps/dotcms-ui/src/assets/seo/page-tools.json @@ -12,7 +12,7 @@ "title": "Mozilla Observatory", "description": "The Mozilla Observatory has helped hundreds of thousands of websites by teaching developers, system administrators, and security professionals how to configure their sites safely and securely. ", "tags": ["Security", "Best Practices"], - "runnableLink": "https://developer.mozilla.org/en-US/observatory/analyze?host={requestHostName}" + "runnableLink": "https://developer.mozilla.org/en-US/observatory/analyze?host={domainName}" }, { "icon": "assets/seo/security-headers.png", diff --git a/core-web/libs/portlets/edit-ema/ui/src/lib/dot-page-tools-seo/dot-page-tools-seo.component.spec.ts b/core-web/libs/portlets/edit-ema/ui/src/lib/dot-page-tools-seo/dot-page-tools-seo.component.spec.ts index 726540501555..f086ecab478d 100644 --- a/core-web/libs/portlets/edit-ema/ui/src/lib/dot-page-tools-seo/dot-page-tools-seo.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/ui/src/lib/dot-page-tools-seo/dot-page-tools-seo.component.spec.ts @@ -43,7 +43,7 @@ describe('DotPageToolsSeoComponent', () => { beforeEach(() => { pageToolUrlParamsTest = { currentUrl: '/blogTest', - requestHostName: 'localhost', + requestHostName: 'http://localhost', siteId: '123', languageId: 1 }; diff --git a/core-web/libs/utils-testing/src/lib/dot-page-tools.mock.ts b/core-web/libs/utils-testing/src/lib/dot-page-tools.mock.ts index b595d8a2a60c..e7b5b5519017 100644 --- a/core-web/libs/utils-testing/src/lib/dot-page-tools.mock.ts +++ b/core-web/libs/utils-testing/src/lib/dot-page-tools.mock.ts @@ -9,7 +9,7 @@ export const mockPageTools: DotPageTools = { 'The WAVE® evaluation suite helps educate authors on how to make their web content more accessible to individuals with disabilities. WAVE can identify many accessibility and Web Content Accessibility Guideline (WCAG) errors, but also facilitates human evaluation of web content.', tags: ['Accessibility', 'WCAG'], runnableLink: - 'https://wave.webaim.org/report#/localhost/blogTest?host_id=123?language_id=1' + 'https://wave.webaim.org/report#/http://localhost/blogTest?host_id=123?language_id=1' }, { icon: 'assets/seo/mozilla.png', @@ -17,7 +17,7 @@ export const mockPageTools: DotPageTools = { description: 'The Mozilla Observatory has helped hundreds of thousands of websites by teaching developers, system administrators, and security professionals how to configure their sites safely and securely. ', tags: ['Security', 'Best Practices'], - runnableLink: 'https://observatory.mozilla.org/analyze/localhost' + runnableLink: 'https://developer.mozilla.org/en-US/observatory/analyze?host=localhost' }, { icon: 'assets/seo/security-headers.png', @@ -26,7 +26,7 @@ export const mockPageTools: DotPageTools = { 'This tool is designed to help you better deploy and understand modern security features that are available for your website. It will provide a simple to understand grading system for how well your site follows best practices, as well as suggestions for how to make improvement.', tags: ['Securty', 'Best Practices'], runnableLink: - 'https://securityheaders.com/?q=localhost/blogTest&host_id=123&language_id=1&followRedirects=on' + 'https://securityheaders.com/?q=http://localhost/blogTest&host_id=123&language_id=1&followRedirects=on' } ] }; diff --git a/core-web/libs/utils/src/lib/dot-utils.spec.ts b/core-web/libs/utils/src/lib/dot-utils.spec.ts index 0f7163ffd650..2fb5b6f1d1e9 100644 --- a/core-web/libs/utils/src/lib/dot-utils.spec.ts +++ b/core-web/libs/utils/src/lib/dot-utils.spec.ts @@ -130,13 +130,13 @@ describe('Dot Utils', () => { 'https://wave.webaim.org/report#/{requestHostName}{currentUrl}{urlSearchParams}'; const params: DotPageToolUrlParams = { currentUrl: '', - requestHostName: 'my-site', + requestHostName: 'https://my-site.com', siteId: '', languageId: 1 }; expect(getRunnableLink(url, params)).toEqual( - 'https://wave.webaim.org/report#/my-site?language_id=1' + 'https://wave.webaim.org/report#/https://my-site.com?language_id=1' ); }); @@ -145,28 +145,27 @@ describe('Dot Utils', () => { 'https://wave.webaim.org/report#/{requestHostName}{currentUrl}{urlSearchParams}'; const params: DotPageToolUrlParams = { currentUrl: '/current-page', - requestHostName: 'my-site', + requestHostName: 'https://my-site.com', siteId: '50a79decd9e21702cb2f52fc4935a52b', languageId: 1 }; expect(getRunnableLink(url, params)).toEqual( - 'https://wave.webaim.org/report#/my-site/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1' + 'https://wave.webaim.org/report#/https://my-site.com/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1' ); }); it('should replace {requestHostName} and append query parameters in Mozilla Observatory URL', () => { - const url = - 'https://developer.mozilla.org/en-US/observatory/analyze?host={requestHostName}'; + const url = 'https://developer.mozilla.org/en-US/observatory/analyze?host={domainName}'; const params: DotPageToolUrlParams = { currentUrl: '', - requestHostName: 'my-site', + requestHostName: 'http://my-site.com:80', siteId: '50a79decd9e21702cb2f52fc4935a52b', languageId: 1 }; expect(getRunnableLink(url, params)).toEqual( - 'https://developer.mozilla.org/en-US/observatory/analyze?host=my-site' + 'https://developer.mozilla.org/en-US/observatory/analyze?host=my-site.com' ); }); @@ -175,13 +174,13 @@ describe('Dot Utils', () => { 'https://securityheaders.com/?q={requestHostName}{currentUrl}{urlSearchParams}&followRedirects=on'; const params: DotPageToolUrlParams = { currentUrl: '/current-page', - requestHostName: 'my-site', + requestHostName: 'https://my-site.com', siteId: '50a79decd9e21702cb2f52fc4935a52b', languageId: 1 }; expect(getRunnableLink(url, params)).toEqual( - 'https://securityheaders.com/?q=my-site/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1&followRedirects=on' + 'https://securityheaders.com/?q=https://my-site.com/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1&followRedirects=on' ); }); @@ -200,12 +199,14 @@ describe('Dot Utils', () => { const url = 'https://example.com/{requestHostName}/page'; const params: DotPageToolUrlParams = { currentUrl: '', - requestHostName: 'my-site', + requestHostName: 'https://my-site.com', siteId: '', languageId: 1 }; - expect(getRunnableLink(url, params)).toEqual('https://example.com/my-site/page'); + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/https://my-site.com/page' + ); }); it('should replace {currentUrl} with the actual currentUrl', () => { @@ -238,13 +239,13 @@ describe('Dot Utils', () => { const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}'; const params: DotPageToolUrlParams = { currentUrl: '/current-page', - requestHostName: 'my-site', + requestHostName: 'https://my-site.com', siteId: '123', languageId: 456 }; expect(getRunnableLink(url, params)).toEqual( - 'https://example.com/my-site/current-page?host_id=123&language_id=456' + 'https://example.com/https://my-site.com/current-page?host_id=123&language_id=456' ); }); @@ -295,5 +296,75 @@ describe('Dot Utils', () => { expect(getRunnableLink(url, params)).toEqual('https://example.com/'); }); + + it('should and respect https protocol and port in requestHostName', () => { + const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}'; + const params: DotPageToolUrlParams = { + currentUrl: '/current-page', + requestHostName: 'https://my-site.com:4200', + siteId: '123', + languageId: 456 + }; + + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/https://my-site.com:4200/current-page?host_id=123&language_id=456' + ); + }); + + it('should and respect http protocol and port in requestHostName', () => { + const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}'; + const params: DotPageToolUrlParams = { + currentUrl: '/current-page', + requestHostName: 'http://my-site.com:4200', + siteId: '123', + languageId: 456 + }; + + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/http://my-site.com:4200/current-page?host_id=123&language_id=456' + ); + }); + + it('should remove port and protocol in domainName', () => { + const url = 'https://example.com/{domainName}{currentUrl}{urlSearchParams}'; + const params: DotPageToolUrlParams = { + currentUrl: '/current-page', + requestHostName: 'https://my-site.com:4200', + siteId: '123', + languageId: 456 + }; + + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/my-site.com/current-page?host_id=123&language_id=456' + ); + }); + + it('should remove port in requestHostName given https protocol and 443 port ', () => { + const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}'; + const params: DotPageToolUrlParams = { + currentUrl: '/current-page', + requestHostName: 'https://my-site.com:443', + siteId: '123', + languageId: 456 + }; + + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/https://my-site.com/current-page?host_id=123&language_id=456' + ); + }); + + it('should remove port in requestHostName given http protocol and 80 port ', () => { + const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}'; + const params: DotPageToolUrlParams = { + currentUrl: '/current-page', + requestHostName: 'http://my-site.com:80', + siteId: '123', + languageId: 456 + }; + + expect(getRunnableLink(url, params)).toEqual( + 'https://example.com/http://my-site.com/current-page?host_id=123&language_id=456' + ); + }); }); }); diff --git a/core-web/libs/utils/src/lib/dot-utils.ts b/core-web/libs/utils/src/lib/dot-utils.ts index 27918942f6f1..1db28810f97d 100644 --- a/core-web/libs/utils/src/lib/dot-utils.ts +++ b/core-web/libs/utils/src/lib/dot-utils.ts @@ -70,8 +70,10 @@ export function getRunnableLink(url: string, currentPageUrlParams: DotPageToolUr if (languageId) pageParams.append('language_id', String(languageId)); // Replace placeholders in the base URL with actual values and append query parameters if they exist + const requestHostUrl = requestHostName ? new URL(requestHostName) : null; const finalUrl = url - .replace(/{requestHostName}/g, requestHostName ?? '') + .replace(/{requestHostName}/g, requestHostUrl ? requestHostUrl.origin : '') + .replace(/{domainName}/g, requestHostUrl ? requestHostUrl.hostname : '') .replace(/{currentUrl}/g, currentUrl ?? '') .replace(/{urlSearchParams}/g, pageParams.toString() ? `?${pageParams.toString()}` : '');