feat(clickTtHttpPageRoutes, ClickTtView): implement proxy navigation script and enhance URL selection
- Added a new function to inject a navigation script into HTML responses, enabling seamless proxy navigation for links and form submissions. - Updated the ClickTtView component to include new preset URL options for HTTV and TTDE login, improving user experience by providing quick access to common links. - Adjusted form handling logic to support the new preset URLs, ensuring proper URL management during proxy interactions.
This commit is contained in:
@@ -159,6 +159,86 @@ function rewriteFormActionsInHtml(html, proxyBaseUrl, pageBaseUrl, sid) {
|
||||
}
|
||||
}
|
||||
|
||||
function injectProxyNavigationScript(html, proxyBaseUrl, pageBaseUrl, sid) {
|
||||
if (!html || !proxyBaseUrl || !pageBaseUrl) return html;
|
||||
|
||||
const script = `
|
||||
<script>
|
||||
(function () {
|
||||
const PROXY_BASE_URL = ${JSON.stringify(proxyBaseUrl)};
|
||||
const PAGE_BASE_URL = ${JSON.stringify(pageBaseUrl)};
|
||||
const SID = ${JSON.stringify(sid || '')};
|
||||
|
||||
function normalizeUrl(value, base) {
|
||||
if (!value) return null;
|
||||
const trimmed = String(value).trim();
|
||||
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('javascript:')) return null;
|
||||
try {
|
||||
return new URL(trimmed, base || PAGE_BASE_URL).href;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function shouldProxyUrl(value) {
|
||||
return /(^|\\.)click-tt\\.de$|(^|\\.)httv\\.de$/i.test(new URL(value).hostname);
|
||||
}
|
||||
|
||||
function buildProxyUrl(targetUrl) {
|
||||
const separator = PROXY_BASE_URL.includes('?') ? '&' : '?';
|
||||
return PROXY_BASE_URL + separator + 'url=' + encodeURIComponent(targetUrl) + (SID ? '&sid=' + encodeURIComponent(SID) : '');
|
||||
}
|
||||
|
||||
function navigateViaProxy(targetUrl) {
|
||||
if (!targetUrl) return false;
|
||||
if (!shouldProxyUrl(targetUrl)) return false;
|
||||
window.location.assign(buildProxyUrl(targetUrl));
|
||||
return true;
|
||||
}
|
||||
|
||||
function getSubmitTarget(form, submitter) {
|
||||
const action = submitter && submitter.getAttribute && submitter.getAttribute('formaction');
|
||||
if (action) return normalizeUrl(action, PAGE_BASE_URL);
|
||||
return normalizeUrl(form.getAttribute('action') || PAGE_BASE_URL, PAGE_BASE_URL);
|
||||
}
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
const anchor = event.target && event.target.closest ? event.target.closest('a[href]') : null;
|
||||
if (!anchor) return;
|
||||
const targetUrl = normalizeUrl(anchor.getAttribute('href'), PAGE_BASE_URL);
|
||||
if (!targetUrl || !shouldProxyUrl(targetUrl)) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
navigateViaProxy(targetUrl);
|
||||
}, true);
|
||||
|
||||
document.addEventListener('submit', function (event) {
|
||||
const form = event.target;
|
||||
if (!form || !form.tagName || form.tagName.toLowerCase() !== 'form') return;
|
||||
const submitter = event.submitter || null;
|
||||
const targetUrl = getSubmitTarget(form, submitter);
|
||||
if (!targetUrl || !shouldProxyUrl(targetUrl)) return;
|
||||
form.setAttribute('action', buildProxyUrl(targetUrl));
|
||||
}, true);
|
||||
|
||||
const nativeSubmit = HTMLFormElement.prototype.submit;
|
||||
HTMLFormElement.prototype.submit = function patchedSubmit() {
|
||||
const targetUrl = getSubmitTarget(this, null);
|
||||
if (targetUrl && shouldProxyUrl(targetUrl)) {
|
||||
this.setAttribute('action', buildProxyUrl(targetUrl));
|
||||
}
|
||||
return nativeSubmit.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
</script>`;
|
||||
|
||||
if (/<\/body>/i.test(html)) {
|
||||
return html.replace(/<\/body>/i, `${script}</body>`);
|
||||
}
|
||||
|
||||
return html + script;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/clicktt/proxy
|
||||
* Proxy für iframe-Einbettung – liefert HTML direkt (ohne Auth, für iframe src).
|
||||
@@ -248,6 +328,7 @@ router.get('/proxy', async (req, res, next) => {
|
||||
html = rewriteLinksInHtml(html, proxyBase, effectivePageUrl, sid);
|
||||
html = rewriteFormActionsInHtml(html, proxyBase, effectivePageUrl, sid);
|
||||
html = rewriteMetaRefreshInHtml(html, proxyBase, effectivePageUrl, sid);
|
||||
html = injectProxyNavigationScript(html, proxyBase, effectivePageUrl, sid);
|
||||
|
||||
res.set({
|
||||
'Content-Type': 'text/html; charset=utf-8',
|
||||
@@ -344,6 +425,7 @@ router.post('/proxy', async (req, res, next) => {
|
||||
responseBody = rewriteLinksInHtml(responseBody, proxyBase, effectivePageUrl, sid);
|
||||
responseBody = rewriteFormActionsInHtml(responseBody, proxyBase, effectivePageUrl, sid);
|
||||
responseBody = rewriteMetaRefreshInHtml(responseBody, proxyBase, effectivePageUrl, sid);
|
||||
responseBody = injectProxyNavigationScript(responseBody, proxyBase, effectivePageUrl, sid);
|
||||
}
|
||||
|
||||
res.set({
|
||||
|
||||
Reference in New Issue
Block a user