diff --git a/lib/url_hack.ts b/lib/url_hack.ts index bed28e27..38051cba 100644 --- a/lib/url_hack.ts +++ b/lib/url_hack.ts @@ -1,48 +1,82 @@ -export const urlPrefix: string = Deno.env.get("SB_URL_PREFIX") ?? - (globalThis.silverBulletConfig - ? globalThis.silverBulletConfig.urlPrefix - : null) ?? - ""; - -export const toRealUrl = (url: T): T => { - if (typeof url === "string") { - const stringUrl = url as string; - if (stringUrl.startsWith("http://") || stringUrl.startsWith("https://")) { - const parsedUrl = new URL(stringUrl); - parsedUrl.pathname = urlPrefix + parsedUrl.pathname; - //console.log("Converted ", url, parsedUrl.href) - return String(parsedUrl.href) as T; - } else { - if (!stringUrl.startsWith("/")) { - console.log("Don't know how to deal with relative path: ", url); - } - //console.log("Converted ", url, urlPrefix + stringUrl) - return (urlPrefix + stringUrl) as T; +const getUrlPrefix = () : string => { + const prefix : string = Deno.env.get("SB_URL_PREFIX") ?? + (globalThis.silverBulletConfig ? + globalThis.silverBulletConfig.urlPrefix + : null) ?? ''; + if (prefix === '') { + return ''; } - } else if (url.protocol === "http:" || url.protocol === "https:") { - const parsedUrl = new URL(url as URL); - parsedUrl.pathname = urlPrefix + parsedUrl.pathname; - //console.log("Converted ", url, parsedUrl) - return parsedUrl as T; - } else { - return url; - } + + let result = prefix; + if (!prefix.startsWith('/')) { + result = '/' + result; + } + if (prefix.endsWith('/')) { + result = result.replace(/\/*$/, ''); + } + + return result; }; -export const toInternalUrl = (url: string) => { - if (url.startsWith("http://") || url.startsWith("https://")) { +export const urlPrefix: string = getUrlPrefix(); + +const toRealUrlObject = (url : URL) : URL => { const parsedUrl = new URL(url); - if (parsedUrl.pathname.startsWith(urlPrefix)) { - parsedUrl.pathname = parsedUrl.pathname.substr(urlPrefix.length); - return parsedUrl.href; + if (typeof location !== 'undefined' && parsedUrl.origin == location.origin) { + if (parsedUrl.pathname.startsWith(urlPrefix)) { + //console.trace("Path starts with prefix already: ", url); + } + + parsedUrl.pathname = urlPrefix + parsedUrl.pathname; + //console.trace("Converted full URL ", url, parsedUrl.href) + return parsedUrl; } else { - console.log("Don't know how to deal with non-prefix: ", url); - return url; + //console.trace("Don't know how to deal with cross origin path: ", url); + return url; + } +} + +export const toRealUrl = (url : T) : T => { + if (typeof url === 'string') { + const stringUrl = url as string; + if (stringUrl.startsWith('http://') || stringUrl.startsWith('https://')) { + return toRealUrlObject(new URL(stringUrl)).href as T; + } + else if (!stringUrl.startsWith('/')) { + //console.trace("Don't know how to deal with relative path: ", url); + return url; + } else { + if (url.startsWith(urlPrefix)) { + //console.trace("Path starts with prefix already: ", url); + } + //console.trace("Converted absolute path ", url, urlPrefix + stringUrl) + return (urlPrefix + stringUrl) as T; + } + } + else if (url.protocol === 'http:' || url.protocol === 'https:') { + return toRealUrlObject(url) as T; + } + else { + return url; + } +}; + +export const toInternalUrl = (url : string) => { + if (url.startsWith('http://') || url.startsWith('https://')) { + const parsedUrl = new URL(url); + if (parsedUrl.pathname.startsWith(urlPrefix)) { + parsedUrl.pathname = parsedUrl.pathname.substr(urlPrefix.length); + return parsedUrl.href; + } + else { + //console.trace("Don't know how to deal with non-prefix: ", url); + return url; + } + } else if (url.startsWith(urlPrefix)) { + return url.substr(urlPrefix.length); + } + else { + //console.trace("Don't know how to deal with non-prefix: ", url); + return url; } - } else if (url.startsWith(urlPrefix)) { - return url.substr(urlPrefix.length); - } else { - console.log("Don't know how to deal with non-prefix: ", url); - return url; - } }; diff --git a/server/http_server.ts b/server/http_server.ts index 46cbbe98..e0cdbf8a 100644 --- a/server/http_server.ts +++ b/server/http_server.ts @@ -404,13 +404,14 @@ export class HttpServer { return next(); } const url = new URL(toInternalUrl(req.url)); + const path = toInternalUrl(req.path); const host = url.host; const redirectToAuth = () => { // Try filtering api paths - if (req.path.startsWith("/.") || req.path.endsWith(".md")) { + if (path.startsWith("/.") || path.endsWith(".md")) { return c.redirect(toRealUrl("/.auth"), 401); } else { - return c.redirect(toRealUrl(`/.auth?from=${req.path}`), 401); + return c.redirect(toRealUrl(`/.auth?from=${path}`), 401); } }; if (!excludedPaths.includes(url.pathname)) { diff --git a/web/boot.ts b/web/boot.ts index 16718b10..f5b48386 100644 --- a/web/boot.ts +++ b/web/boot.ts @@ -1,5 +1,6 @@ import { safeRun } from "../lib/async.ts"; import { Client } from "./client.ts"; +import { toRealUrl } from "../lib/url_hack.ts"; const syncMode = globalThis.silverBulletConfig.syncOnly || !!localStorage.getItem("syncMode"); @@ -26,7 +27,7 @@ safeRun(async () => { if (navigator.serviceWorker) { navigator.serviceWorker - .register(new URL("/service_worker.js", location.href), { + .register(new URL(toRealUrl("/service_worker.js"), location.href), { type: "module", }) .then(() => {