Try to add url_prefix support
parent
8acb112e4e
commit
b1de476116
|
@ -5,6 +5,7 @@ import {
|
|||
unregisterServiceWorkers,
|
||||
} from "../sw_util.ts";
|
||||
import { encodePageURI } from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||
import { urlPrefix, toRealUrl } from "../../lib/url_hack.ts";
|
||||
|
||||
const defaultFetchTimeout = 30000; // 30 seconds
|
||||
|
||||
|
@ -38,7 +39,8 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
|||
try {
|
||||
options.signal = AbortSignal.timeout(fetchTimeout);
|
||||
options.redirect = "manual";
|
||||
const result = await fetch(url, options);
|
||||
|
||||
const result = await fetch(toRealUrl(url), options);
|
||||
if (result.status === 503) {
|
||||
throw new Error("Offline");
|
||||
}
|
||||
|
@ -67,7 +69,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
|||
"Received an authentication redirect, redirecting to URL: " +
|
||||
redirectHeader,
|
||||
);
|
||||
location.href = redirectHeader;
|
||||
location.href = redirectHeader.startsWith(urlPrefix) ? redirectHeader : toRealUrl(redirectHeader);
|
||||
throw new Error("Redirected");
|
||||
} else {
|
||||
console.error("Got a redirect status but no location header", result);
|
||||
|
@ -82,7 +84,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
|||
result.url,
|
||||
);
|
||||
alert("You are not authenticated, redirecting to: " + redirectHeader);
|
||||
location.href = redirectHeader;
|
||||
location.href = redirectHeader.startsWith(urlPrefix) ? redirectHeader : toRealUrl(redirectHeader);
|
||||
throw new Error("Not authenticated");
|
||||
} else {
|
||||
// If not, let's reload
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { ControllerMessage, WorkerMessage } from "../protocol.ts";
|
|||
import type { Plug } from "../plug.ts";
|
||||
import { AssetBundle, type AssetJson } from "../../asset_bundle/bundle.ts";
|
||||
import type { Sandbox } from "./sandbox.ts";
|
||||
import { toRealUrl } from "../../url_hack.ts";
|
||||
|
||||
/**
|
||||
* Represents a "safe" execution environment for plug code
|
||||
|
@ -36,7 +37,7 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
|
|||
console.warn("Double init of sandbox, ignoring");
|
||||
return Promise.resolve();
|
||||
}
|
||||
this.worker = new Worker(this.workerUrl, {
|
||||
this.worker = new Worker(toRealUrl(this.workerUrl), {
|
||||
...this.workerOptions,
|
||||
type: "module",
|
||||
});
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
export const urlPrefix = Deno.env.get('SB_URL_PREFIX') ?? (globalThis.silverBulletConfig ? globalThis.silverBulletConfig.urlPrefix : null) ?? '';
|
||||
|
||||
export const toRealUrl = <T extends (string | URL)>(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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
export const toInternalUrl = (url : string) => {
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
var parsedUrl = new URL(url);
|
||||
if (parsedUrl.pathname.startsWith(urlPrefix)) {
|
||||
parsedUrl.pathname = parsedUrl.pathname.substr(urlPrefix.length);
|
||||
return parsedUrl.href;
|
||||
}
|
||||
else {
|
||||
return url;
|
||||
}
|
||||
} else if (url.startsWith(urlPrefix)) {
|
||||
return url.substr(urlPrefix.length);
|
||||
}
|
||||
else {
|
||||
console.log("Don't know how to deal with relative path: ", url);
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
|
@ -20,6 +20,7 @@ import {
|
|||
parsePageRef,
|
||||
} from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||
import { base64Encode } from "$lib/crypto.ts";
|
||||
import { urlPrefix, toRealUrl } from "$lib/url_hack.ts";
|
||||
|
||||
const authenticationExpirySeconds = 60 * 60 * 24 * 7; // 1 week
|
||||
|
||||
|
@ -102,6 +103,9 @@ export class HttpServer {
|
|||
.replace(
|
||||
"{{SPACE_PATH}}",
|
||||
spaceServer.pagesPath.replaceAll("\\", "\\\\"),
|
||||
).replaceAll(
|
||||
"{{URL_PREFIX}}",
|
||||
urlPrefix
|
||||
)
|
||||
.replace(
|
||||
"{{DESCRIPTION}}",
|
||||
|
@ -283,7 +287,7 @@ export class HttpServer {
|
|||
if (req.method === "GET") {
|
||||
if (assetName === "service_worker.js") {
|
||||
c.header("Cache-Control", "no-cache");
|
||||
const textData = new TextDecoder().decode(data);
|
||||
const textData = new TextDecoder().decode(data as Uint8Array);
|
||||
// console.log(
|
||||
// "Swapping out config hash in service worker",
|
||||
// );
|
||||
|
@ -298,6 +302,12 @@ export class HttpServer {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (assetName.endsWith(".css")) {
|
||||
const textData = new TextDecoder().decode(data as Uint8Array);
|
||||
data = textData.replaceAll(
|
||||
"{{URL_PREFIX}}",
|
||||
urlPrefix);
|
||||
}
|
||||
return Promise.resolve(c.body(data));
|
||||
} // else e.g. HEAD, OPTIONS, don't send body
|
||||
} catch {
|
||||
|
@ -320,11 +330,15 @@ export class HttpServer {
|
|||
const url = new URL(c.req.url);
|
||||
deleteCookie(c, authCookieName(url.host));
|
||||
|
||||
return c.redirect("/.auth");
|
||||
return c.redirect(toRealUrl("/.auth"));
|
||||
});
|
||||
|
||||
this.app.get("/.auth", (c) => {
|
||||
const html = this.clientAssetBundle.readTextFileSync(".client/auth.html");
|
||||
const html = this.clientAssetBundle.readTextFileSync(".client/auth.html")
|
||||
.replaceAll(
|
||||
"{{URL_PREFIX}}",
|
||||
urlPrefix
|
||||
);
|
||||
|
||||
return c.html(html);
|
||||
}).post(
|
||||
|
@ -336,7 +350,7 @@ export class HttpServer {
|
|||
!username || typeof username !== "string" ||
|
||||
!password || typeof password !== "string"
|
||||
) {
|
||||
return c.redirect("/.auth?error=0");
|
||||
return c.redirect(toRealUrl("/.auth?error=0"));
|
||||
}
|
||||
|
||||
return { username, password };
|
||||
|
@ -367,14 +381,16 @@ export class HttpServer {
|
|||
});
|
||||
const values = await c.req.parseBody();
|
||||
const from = values["from"];
|
||||
return c.redirect(typeof from === "string" ? from : "/");
|
||||
const result = toRealUrl(typeof from === "string" ? from : "/");
|
||||
console.log(result);
|
||||
return c.redirect(result);
|
||||
} else {
|
||||
console.error("Authentication failed, redirecting to auth page.");
|
||||
return c.redirect("/.auth?error=1", 401);
|
||||
return c.redirect(toRealUrl("/.auth?error=1"), 401);
|
||||
}
|
||||
},
|
||||
).all((c) => {
|
||||
return c.redirect("/.auth");
|
||||
return c.redirect(toRealUrl("/.auth"));
|
||||
});
|
||||
|
||||
// Check auth
|
||||
|
@ -389,9 +405,9 @@ export class HttpServer {
|
|||
const redirectToAuth = () => {
|
||||
// Try filtering api paths
|
||||
if (req.path.startsWith("/.") || req.path.endsWith(".md")) {
|
||||
return c.redirect("/.auth", 401);
|
||||
return c.redirect(toRealUrl("/.auth"), 401);
|
||||
} else {
|
||||
return c.redirect(`/.auth?from=${req.path}`, 401);
|
||||
return c.redirect(toRealUrl(`/.auth?from=${req.path}`), 401);
|
||||
}
|
||||
};
|
||||
if (!excludedPaths.includes(url.pathname)) {
|
||||
|
@ -462,7 +478,7 @@ export class HttpServer {
|
|||
} else {
|
||||
// Otherwise, redirect to the UI
|
||||
// The reason to do this is to handle authentication systems like Authelia nicely
|
||||
return c.redirect("/");
|
||||
return c.redirect(toRealUrl("/"));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -541,7 +557,7 @@ export class HttpServer {
|
|||
console.warn(
|
||||
"Request was without X-Sync-Mode nor a CORS request, redirecting to page",
|
||||
);
|
||||
return c.redirect(`/${name.slice(0, -mdExt.length)}`);
|
||||
return c.redirect(toRealUrl(`/${name.slice(0, -mdExt.length)}`));
|
||||
}
|
||||
if (name.startsWith(".")) {
|
||||
// Don't expose hidden files
|
||||
|
|
|
@ -69,11 +69,11 @@
|
|||
<body>
|
||||
<header>
|
||||
<h1>
|
||||
Login to <img src="/.client/logo.png" style="height: 1ch" />
|
||||
Login to <img src="{{URL_PREFIX}}/.client/logo.png" style="height: 1ch" />
|
||||
SilverBullet
|
||||
</h1>
|
||||
</header>
|
||||
<form action="/.auth" method="POST" id="login">
|
||||
<form action="{{URL_PREFIX}}/.auth" method="POST" id="login">
|
||||
<div class="error-message"></div>
|
||||
<div>
|
||||
<input
|
||||
|
|
|
@ -88,6 +88,7 @@ declare global {
|
|||
syncOnly: boolean;
|
||||
readOnly: boolean;
|
||||
enableSpaceScript: boolean;
|
||||
urlPrefix : string;
|
||||
};
|
||||
// deno-lint-ignore no-var
|
||||
var client: Client;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<base href="/" />
|
||||
<link rel="apple-touch-icon" href="/.client/logo.png" />
|
||||
<base href="{{URL_PREFIX}}/" />
|
||||
<link rel="apple-touch-icon" href="{{URL_PREFIX}}/.client/logo.png" />
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#e1e1e1"
|
||||
|
@ -21,7 +21,7 @@
|
|||
<meta name="referrer" content="no-referrer" />
|
||||
|
||||
<title>{{TITLE}}</title>
|
||||
<meta property="og:image" content="/.client/logo.png" />
|
||||
<meta property="og:image" content="{{URL_PREFIX}}/.client/logo.png" />
|
||||
<meta property="og:description" content="{{DESCRIPTION}}" />
|
||||
|
||||
<script>
|
||||
|
@ -55,6 +55,7 @@
|
|||
syncOnly: "{{SYNC_ONLY}}" === "true",
|
||||
enableSpaceScript: "{{ENABLE_SPACE_SCRIPT}}" === "true",
|
||||
readOnly: "{{READ_ONLY}}" === "true",
|
||||
urlPrefix: "{{URL_PREFIX}}",
|
||||
};
|
||||
// But in case these variables aren't replaced by the server, fall back sync only mode
|
||||
if (window.silverBulletConfig.spaceFolderPath.includes("{{")) {
|
||||
|
@ -63,14 +64,15 @@
|
|||
syncOnly: true,
|
||||
readOnly: false,
|
||||
enableSpaceScripts: false,
|
||||
urlPrefix: "",
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<link rel="stylesheet" href="/.client/main.css" />
|
||||
<link rel="stylesheet" href="{{URL_PREFIX}}/.client/main.css" />
|
||||
<style id="custom-styles"></style>
|
||||
<script type="module" src="/.client/client.js"></script>
|
||||
<link rel="manifest" href="/.client/manifest.json" />
|
||||
<link rel="icon" type="image/x-icon" href="/.client/favicon.png" />
|
||||
<script type="module" src="{{URL_PREFIX}}/.client/client.js"></script>
|
||||
<link rel="manifest" href="{{URL_PREFIX}}/.client/manifest.json" />
|
||||
<link rel="icon" type="image/x-icon" href="{{URL_PREFIX}}/.client/favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -7,6 +7,7 @@ import type { Client } from "./client.ts";
|
|||
import { cleanPageRef } from "@silverbulletmd/silverbullet/lib/resolve";
|
||||
import { renderTheTemplate } from "$common/syscalls/template.ts";
|
||||
import { safeRun } from "../lib/async.ts";
|
||||
import { toRealUrl, toInternalUrl } from "../lib/url_hack.ts";
|
||||
|
||||
export type PageState = PageRef & {
|
||||
scrollTop?: number;
|
||||
|
@ -61,18 +62,18 @@ export class PathPageNavigator {
|
|||
globalThis.history.replaceState(
|
||||
cleanState,
|
||||
"",
|
||||
`/${encodePageURI(currentState.page)}`,
|
||||
toRealUrl(`/${encodePageURI(currentState.page)}`),
|
||||
);
|
||||
globalThis.history.pushState(
|
||||
pageRef,
|
||||
"",
|
||||
`/${encodePageURI(pageRef.page)}`,
|
||||
toRealUrl(`/${encodePageURI(pageRef.page)}`),
|
||||
);
|
||||
} else {
|
||||
globalThis.history.replaceState(
|
||||
pageRef,
|
||||
"",
|
||||
`/${encodePageURI(pageRef.page)}`,
|
||||
toRealUrl(`/${encodePageURI(pageRef.page)}`),
|
||||
);
|
||||
}
|
||||
globalThis.dispatchEvent(
|
||||
|
@ -148,7 +149,7 @@ export class PathPageNavigator {
|
|||
|
||||
export function parsePageRefFromURI(): PageRef {
|
||||
const pageRef = parsePageRef(decodeURIComponent(
|
||||
location.pathname.substring(1),
|
||||
toInternalUrl(location.pathname).substring(1),
|
||||
));
|
||||
|
||||
if (location.hash) {
|
||||
|
|
|
@ -5,28 +5,28 @@
|
|||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("/.client/iAWriterMonoS-Regular.woff2");
|
||||
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Regular.woff2");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("/.client/iAWriterMonoS-Bold.woff2");
|
||||
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Bold.woff2");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("/.client/iAWriterMonoS-Italic.woff2");
|
||||
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Italic.woff2");
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "iA-Mono";
|
||||
src: url("/.client/iAWriterMonoS-BoldItalic.woff2");
|
||||
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-BoldItalic.woff2");
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import type { UploadFile } from "../../plug-api/types.ts";
|
|||
import type { PageRef } from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||
import { openSearchPanel } from "@codemirror/search";
|
||||
import { diffAndPrepareChanges } from "../cm_util.ts";
|
||||
import { toRealUrl, toInternalUrl } from "../../lib/url_hack.ts";
|
||||
|
||||
export function editorSyscalls(client: Client): SysCallMapping {
|
||||
const syscalls: SysCallMapping = {
|
||||
|
@ -75,17 +76,17 @@ export function editorSyscalls(client: Client): SysCallMapping {
|
|||
},
|
||||
"editor.openUrl": (_ctx, url: string, existingWindow = false) => {
|
||||
if (!existingWindow) {
|
||||
const win = globalThis.open(url, "_blank");
|
||||
const win = globalThis.open(toRealUrl(url), "_blank");
|
||||
if (win) {
|
||||
win.focus();
|
||||
}
|
||||
} else {
|
||||
location.href = url;
|
||||
location.href = toRealUrl(url);
|
||||
}
|
||||
},
|
||||
"editor.newWindow": () => {
|
||||
globalThis.open(
|
||||
location.href,
|
||||
toInternalUrl(location.href),
|
||||
"rnd" + Math.random(),
|
||||
`width=${globalThis.innerWidth},heigh=${globalThis.innerHeight}`,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue