Derive API path from frontend config URL
This commit is contained in:
@@ -17,6 +17,7 @@ COPY upstream/HubFrontend/ ./
|
||||
COPY docker/hcaptcha-sitekey.patch /tmp/hcaptcha-sitekey.patch
|
||||
COPY docker/remove-analytics.mjs /tmp/remove-analytics.mjs
|
||||
COPY docker/replace-fallback-avatar.mjs /tmp/replace-fallback-avatar.mjs
|
||||
COPY docker/use-config-url-api-path.mjs /tmp/use-config-url-api-path.mjs
|
||||
|
||||
RUN if grep -q 'sitekey="1788882d-3695-4807-abac-7d7166ec6325"' src/routes/auth/login.js; then \
|
||||
patch -p1 < /tmp/hcaptcha-sitekey.patch; \
|
||||
@@ -29,6 +30,7 @@ RUN if grep -q 'sitekey="1788882d-3695-4807-abac-7d7166ec6325"' src/routes/auth/
|
||||
|
||||
RUN node /tmp/remove-analytics.mjs
|
||||
RUN node /tmp/replace-fallback-avatar.mjs
|
||||
RUN node /tmp/use-config-url-api-path.mjs
|
||||
|
||||
ARG ASSETS_BASE=""
|
||||
ARG VITE_USE_MULTIHUB=false
|
||||
@@ -45,6 +47,13 @@ ENV ASSETS_BASE=${ASSETS_BASE} \
|
||||
RUN test -n "$VITE_HCAPTCHA_SITEKEY" \
|
||||
|| (echo "VITE_HCAPTCHA_SITEKEY must be set." >&2; exit 1)
|
||||
|
||||
RUN if [ "$VITE_USE_MULTIHUB" != "true" ]; then \
|
||||
case "$VITE_CONFIG_URL" in \
|
||||
*/client/config/global|*/client/config/global/) ;; \
|
||||
*) echo "VITE_CONFIG_URL must end with /client/config/global." >&2; exit 1 ;; \
|
||||
esac; \
|
||||
fi
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# Electron entry points are not part of the web deployment.
|
||||
|
||||
@@ -40,8 +40,10 @@ as `VITE_HCAPTCHA_SITEKEY`. Set the related secret in the backend
|
||||
not a secret.
|
||||
|
||||
Enable the `client-config` external plugin in the backend configuration. The
|
||||
backend `abbr` value must match the API prefix without its leading slash. For
|
||||
example, use `"abbr": "api"` with `"prefix": "/api"`.
|
||||
single-hub build derives the API base URL from `VITE_CONFIG_URL`. The backend
|
||||
`abbr` can contain the VTC abbreviation and does not have to match the API
|
||||
prefix. This deployment-specific behavior does not apply when
|
||||
`VITE_USE_MULTIHUB` is `true`.
|
||||
|
||||
The frontend uses the Vite values during the image build. Rebuild the image after
|
||||
you change `.env`, including the hCaptcha site key.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
|
||||
const loaderPath = "src/components/loader.js";
|
||||
let source = readFileSync(loaderPath, "utf8");
|
||||
|
||||
const upstreamApiPath = "`${webConfig.api_host}/${webConfig.abbr}`";
|
||||
const deploymentApiPath = "getApiPath(webConfig)";
|
||||
const helperMarker = "function getApiPath(webConfig) {";
|
||||
const insertBefore = "function sleep(ms) {";
|
||||
const occurrences = source.split(upstreamApiPath).length - 1;
|
||||
|
||||
if (occurrences === 3 && !source.includes(helperMarker)) {
|
||||
const helper = `function getApiPath(webConfig) {
|
||||
if (import.meta.env.VITE_USE_MULTIHUB == "true") {
|
||||
return \`${upstreamApiPath.slice(1, -1)}\`;
|
||||
}
|
||||
|
||||
const configUrl = new URL(import.meta.env.VITE_CONFIG_URL);
|
||||
const endpoint = "/client/config/global";
|
||||
const pathname = configUrl.pathname.replace(/\\/+$/, "");
|
||||
if (!pathname.endsWith(endpoint)) {
|
||||
throw new Error("VITE_CONFIG_URL must end with /client/config/global.");
|
||||
}
|
||||
|
||||
configUrl.pathname = pathname.slice(0, -endpoint.length) || "/";
|
||||
configUrl.search = "";
|
||||
configUrl.hash = "";
|
||||
return configUrl.toString().replace(/\\/$/, "");
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
if (!source.includes(insertBefore)) {
|
||||
throw new Error("Cannot locate the API path helper insertion point.");
|
||||
}
|
||||
|
||||
source = source.replace(insertBefore, helper + insertBefore);
|
||||
source = source.replaceAll(upstreamApiPath, deploymentApiPath);
|
||||
console.log("Use VITE_CONFIG_URL as the single-hub API path source.");
|
||||
} else if (occurrences === 0 && !/api_host[^;\n]{0,80}abbr/.test(source)) {
|
||||
console.log("Upstream does not contain the known API path dependency; skip the patch.");
|
||||
} else {
|
||||
throw new Error(`Unsupported upstream API path implementation (${occurrences} known references).`);
|
||||
}
|
||||
|
||||
if (source.includes(upstreamApiPath) && !source.includes("VITE_USE_MULTIHUB")) {
|
||||
throw new Error("The upstream API path dependency remains without a multihub fallback.");
|
||||
}
|
||||
|
||||
writeFileSync(loaderPath, source);
|
||||
Reference in New Issue
Block a user