diff --git a/maubot/management/frontend/src/api.js b/maubot/management/frontend/src/api.js index dc4bbc0..1f720e0 100644 --- a/maubot/management/frontend/src/api.js +++ b/maubot/management/frontend/src/api.js @@ -14,7 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -export const BASE_PATH = "/_matrix/maubot/v1" +let BASE_PATH = "/_matrix/maubot/v1" + +export function setBasePath(basePath) { + BASE_PATH = basePath +} function getHeaders(contentType = "application/json") { return { @@ -241,8 +245,7 @@ export async function doClientAuth(server, type, username, password) { } export default { - BASE_PATH, - login, ping, getFeatures, remoteGetFeatures, + login, ping, setBasePath, getFeatures, remoteGetFeatures, openLogSocket, debugOpenFile, debugOpenFileEnabled, updateDebugOpenFileEnabled, getInstances, getInstance, putInstance, deleteInstance, diff --git a/maubot/management/frontend/src/pages/Main.js b/maubot/management/frontend/src/pages/Main.js index 33660d9..a2162a4 100644 --- a/maubot/management/frontend/src/pages/Main.js +++ b/maubot/management/frontend/src/pages/Main.js @@ -31,6 +31,7 @@ class Main extends Component { } async componentWillMount() { + await this.getBasePath() if (localStorage.accessToken) { await this.ping() } else { @@ -39,6 +40,20 @@ class Main extends Component { this.setState({ pinged: true }) } + async getBasePath() { + try { + const resp = await fetch(process.env.PUBLIC_URL + "/paths.json", { + headers: { "Content-Type": "application/json" } + }) + const apiPathJson = await resp.json() + const apiPath = apiPathJson.api_path + api.setBasePath(`${apiPath}`) + } catch (err) { + console.error("Failed to get API path:", err) + } + } + + async ping() { try { const username = await api.ping() diff --git a/maubot/server.py b/maubot/server.py index fa84e9d..efb0a13 100644 --- a/maubot/server.py +++ b/maubot/server.py @@ -16,6 +16,8 @@ from typing import Tuple, Dict import logging import asyncio +import json +from yarl import URL from aiohttp import web, hdrs from aiohttp.abc import AbstractAccessLogger @@ -129,6 +131,21 @@ class MaubotServer: self.app.router.add_get(f"{ui_base}/{file}", lambda _: web.Response(body=data, content_type=mime)) + # also set up a resource path for the public url path prefix config + # cut the prefix path from public_url + public_url = self.config["server.public_url"] + base_path = self.config["server.base_path"] + public_url_path = "" + if public_url: + public_url_path = URL(public_url).path.rstrip("/") + + # assemble with base_path + api_path = f"{public_url_path}{base_path}" + + path_prefix_response_body = json.dumps({"api_path": api_path.rstrip("/")}) + self.app.router.add_get(f"{ui_base}/paths.json", lambda _: web.Response(body=path_prefix_response_body, + content_type="application/json")) + def add_route(self, method: Method, path: PathBuilder, handler) -> None: self.app.router.add_route(method.value, str(path), handler)