diff --git a/.env.example b/.env.example
index 6c181fb..cdf052f 100644
--- a/.env.example
+++ b/.env.example
@@ -4,6 +4,9 @@ FRONTEND_BIND=127.0.0.1:18080
# URL of the backend client configuration endpoint.
VITE_CONFIG_URL=https://hub.example.com/api/client/config/global
+# Public hCaptcha site key for the frontend domain.
+VITE_HCAPTCHA_SITEKEY=replace-with-your-hcaptcha-site-key
+
# Use an empty value when the frontend and its assets use the same origin.
ASSETS_BASE=
diff --git a/Dockerfile b/Dockerfile
index f64aa27..4dbe9ac 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,20 +6,39 @@ WORKDIR /build
ENV ELECTRON_SKIP_BINARY_DOWNLOAD=1
+RUN apt-get update \
+ && apt-get install --yes --no-install-recommends patch \
+ && rm -rf /var/lib/apt/lists/*
+
COPY upstream/HubFrontend/package.json upstream/HubFrontend/package-lock.json upstream/HubFrontend/.npmrc ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY upstream/HubFrontend/ ./
+COPY docker/hcaptcha-sitekey.patch /tmp/hcaptcha-sitekey.patch
+
+RUN if grep -q 'sitekey="1788882d-3695-4807-abac-7d7166ec6325"' src/routes/auth/login.js; then \
+ patch -p1 < /tmp/hcaptcha-sitekey.patch; \
+ elif grep -q 'VITE_HCAPTCHA_SITEKEY' src/routes/auth/login.js; then \
+ echo "Upstream already supports VITE_HCAPTCHA_SITEKEY; skip the deployment patch."; \
+ else \
+ echo "Unsupported upstream hCaptcha configuration." >&2; \
+ exit 1; \
+ fi
ARG ASSETS_BASE=""
ARG VITE_USE_MULTIHUB=false
ARG VITE_MULTIHUB_DISCOVERY=""
ARG VITE_CONFIG_URL
+ARG VITE_HCAPTCHA_SITEKEY
ENV ASSETS_BASE=${ASSETS_BASE} \
VITE_USE_MULTIHUB=${VITE_USE_MULTIHUB} \
VITE_MULTIHUB_DISCOVERY=${VITE_MULTIHUB_DISCOVERY} \
- VITE_CONFIG_URL=${VITE_CONFIG_URL}
+ VITE_CONFIG_URL=${VITE_CONFIG_URL} \
+ VITE_HCAPTCHA_SITEKEY=${VITE_HCAPTCHA_SITEKEY}
+
+RUN test -n "$VITE_HCAPTCHA_SITEKEY" \
+ || (echo "VITE_HCAPTCHA_SITEKEY must be set." >&2; exit 1)
RUN npm run build
diff --git a/README.md b/README.md
index e473f2f..15ea305 100644
--- a/README.md
+++ b/README.md
@@ -27,12 +27,17 @@ backend. The URL usually has this format:
https://hub.example.com/api/client/config/global
```
+Create an hCaptcha site for the public frontend domain. Set its public site key
+as `VITE_HCAPTCHA_SITEKEY`. Set the related secret in the backend
+`config/config.json` file. The site key is included in the frontend files and is
+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"`.
The frontend uses the Vite values during the image build. Rebuild the image after
-you change `.env`.
+you change `.env`, including the hCaptcha site key.
## Start the deployment
diff --git a/compose.yaml b/compose.yaml
index b4d751f..f5615f7 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -10,6 +10,7 @@ services:
VITE_USE_MULTIHUB: ${VITE_USE_MULTIHUB:-false}
VITE_MULTIHUB_DISCOVERY: ${VITE_MULTIHUB_DISCOVERY:-}
VITE_CONFIG_URL: ${VITE_CONFIG_URL:?Set VITE_CONFIG_URL in .env}
+ VITE_HCAPTCHA_SITEKEY: ${VITE_HCAPTCHA_SITEKEY:?Set VITE_HCAPTCHA_SITEKEY in .env}
restart: unless-stopped
ports:
- "${FRONTEND_BIND:-127.0.0.1:18080}:8080"
diff --git a/docker/hcaptcha-sitekey.patch b/docker/hcaptcha-sitekey.patch
new file mode 100644
index 0000000..46f14d5
--- /dev/null
+++ b/docker/hcaptcha-sitekey.patch
@@ -0,0 +1,11 @@
+--- a/src/routes/auth/login.js
++++ b/src/routes/auth/login.js
+@@ -247,7 +247,7 @@
+ {tr("are_you_a_robot")}
+
+
+-
++
+
+
+