diff --git a/src/proxy.ts b/src/proxy.ts index 7655aa0..8dec27e 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -129,6 +129,10 @@ async function reverseProxy(request: Request, siteConfig: NooxySiteConfigFull): // Modify response headers const modifiedResponseHeaders = modifyResponseHeaders(response.headers, hostname, siteConfig); + modifiedResponseHeaders.delete('content-encoding'); + modifiedResponseHeaders.delete('content-length'); + modifiedResponseHeaders.delete('content-digest'); + modifiedResponseHeaders.delete('etag'); return new Response(modifiedData, { status: response.status, diff --git a/src/rewriters/data-rewriter.ts b/src/rewriters/data-rewriter.ts index 521600a..9381737 100644 --- a/src/rewriters/data-rewriter.ts +++ b/src/rewriters/data-rewriter.ts @@ -4,6 +4,8 @@ import { HEAD_JS_STRING } from './custom/generated/_head-js-string'; import { HEAD_CSS_STRING } from './custom/generated/_head-css-string'; import { rewriteMetaTags } from './meta-rewriter'; +const ASSET_PATCH_VERSION = '1'; + function escapeForJS(str: string): string { return str .replace(/\\/g, '\\\\') // Escape backslashes first @@ -16,6 +18,20 @@ function escapeForJS(str: string): string { .replace(/>/g, '\\x3e'); // Escape > for safety } +function removePublicDomainInterstitial(responseData: string): string { + try { + const payload = JSON.parse(responseData) as Record; + if (!Object.prototype.hasOwnProperty.call(payload, 'requireInterstitial')) { + return responseData; + } + + payload.requireInterstitial = undefined; + return JSON.stringify(payload); + } catch (_error) { + return responseData; + } +} + // Helper function to modify response data export function modifyResponseData( responseData: string, @@ -84,12 +100,27 @@ export function modifyResponseData( // // console.log('[DEBUG]', pathname, found); // } + if (pathname === '/api/v3/getPublicPageData' || pathname === '/api/v3/getPublicPageDataForDomain') { + data = removePublicDomainInterstitial(data); + } + // IMPORTANT: This must happen BEFORE script injection to avoid replacing the notionDomain variable const escapedNotionDomain = notionDomain.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const notionDomainPattern = new RegExp(`https?://${escapedNotionDomain}(?=[/?"'>#\\s]|$)`, 'gi'); - if (/^\/_assets\/[^/]*\.js$/.test(pathname)) { - data = data.replace(/window\.location\.href(?=[^=]|={2,})/g, 'window.nooxy.href()'); // Exclude 'window.location.href=' but not 'window.location.href==' + if (/^\/_assets\/.+\.js$/.test(pathname)) { + data = data + .replace(/nooxy=\d+/g, `nooxy=${ASSET_PATCH_VERSION}`) + // Exclude assignments like window.location.href=, but keep reads and comparisons patched. + .replace(/window\.location\.href(?=[^=]|={2,})/g, 'window.nooxy.href()') + .replace( + /baseUrl:[^,;{}]+\.domainBaseUrl,publicDomainName:[^,;{}]+\.publicDomainName/g, + 'baseUrl:new URL(window.nooxy.href()).origin,publicDomainName:void 0', + ) + .replace( + /(\.src=)([a-zA-Z_$][\w$]*)(\),[a-zA-Z_$][\w$]*\[[a-zA-Z_$][\w$]*\]=\[)/g, + `$1$2+($2.indexOf("?")===-1?"?nooxy=${ASSET_PATCH_VERSION}":"&nooxy=${ASSET_PATCH_VERSION}")$3`, + ); } else if (/ and ) // Apply meta tag rewriting first @@ -99,6 +130,10 @@ export function modifyResponseData( data = data.replace(notionDomainPattern, `${protocol}//${targetDomain}`); data = data + .replace(/(]*\bsrc=["'])(\/_assets\/[^"']+\.js)(["'][^>]*>)/gi, (_match, prefix, src, suffix) => { + const separator = src.includes('?') ? '&' : '?'; + return `${prefix}${src}${separator}nooxy=${ASSET_PATCH_VERSION}${suffix}`; + }) .replace( /<\/head>/i, `${googleFontInject}`,