Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cogstack-cohorter/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ NPM_TOKEN=ghp_your_token_here
# DEFAULT_USER_NAME=Local User
# DEFAULT_USER_EMAIL=
# DEFAULT_USER_ID=local
# DEFAULT_USER_GROUPS= # comma-separated, e.g. "cohorter-users,role:admin"
# DEFAULT_USER_GROUPS=cohorter-users

# ── Other runtime options ─────────────────────────────────────────────────────

Expand Down
10 changes: 0 additions & 10 deletions cogstack-cohorter/WebAPP/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
FROM node:20

ARG VITE_OAUTH2_USERINFO_PATH
ARG VITE_OAUTH2_LOGIN_PATH
ARG VITE_OAUTH2_LOGOUT_PATH

# VITE_* vars must be ENV (not just ARG) for Vite to pick them up at build time.
ENV VITE_OAUTH2_USERINFO_PATH=${VITE_OAUTH2_USERINFO_PATH}
ENV VITE_OAUTH2_LOGIN_PATH=${VITE_OAUTH2_LOGIN_PATH}
ENV VITE_OAUTH2_LOGOUT_PATH=${VITE_OAUTH2_LOGOUT_PATH}

WORKDIR /usr/src/app/client-react
COPY client-react/package*.json ./
RUN --mount=type=secret,id=npm_token,required=true \
Expand Down
33 changes: 33 additions & 0 deletions cogstack-cohorter/WebAPP/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,39 @@ Please make sure to have the six data files ready in the `server/data/` folder b

The recommended way to run the full stack (webapp + NL2DSL + MedCAT + Ollama) is via `docker-compose` from the `cogstack-cohorter/` root — see the root-level README and `.env.example` for details. The `NPM_TOKEN` is passed as a BuildKit secret; set it in the `.env` file before building.

### Environment variables

The webapp is configured entirely through environment variables — no rebuild is required to change settings.

#### Server (Express backend)

| Variable | Default | Description |
|---|-------------------------------------|---|
| `PORT` | `3000` | Port the Express server listens on |
| `NL2DSL_SERVER` | `http://localhost:3002/api/compile` | URL of the NL2DSL service |
| `RANDOM_DATA` | `true` | `true` → generate and serve synthetic demo data; `false` → load real data from `server/data/` |
| `PASSWORD` | `admin_pass` | Password for the admin export panel |
| `DEFAULT_USER_NAME` | `Local User` | Display name shown in the header when no oauth2-proxy is deployed |
| `DEFAULT_USER_EMAIL` | _(empty)_ | Email shown in the user panel when no oauth2-proxy is deployed |
| `DEFAULT_USER_ID` | `local` | Opaque user ID returned by `/oauth2/userinfo` when no oauth2-proxy is deployed |
| `DEFAULT_USER_GROUPS` | `cohorter-users` | Comma-separated groups returned by `/oauth2/userinfo` when no oauth2-proxy is deployed |

#### Frontend runtime config (written to `config.js` at container startup)

At startup `entrypoint.sh` writes `/config.js` into the pre-built static assets folder. `index.html` loads this file before the React bundle, so the values are available as `window.__RUNTIME_CONFIG__` without a rebuild.

These variables are only needed when **oauth2-proxy is deployed in front of the app**. The defaults work correctly for standalone deployments — the Express server handles `/oauth2/userinfo` itself and returns the `DEFAULT_USER_*` values above.

| Variable | Default | Description |
|---|---|---|
| `OAUTH2_USERINFO_PATH` | `/oauth2/userinfo` | Path the `UserSection` component fetches to get the logged-in user's info. With oauth2-proxy this is intercepted by oauth2-proxy before reaching Express. Without oauth2-proxy it hits the Express fallback endpoint. |
| `OAUTH2_LOGIN_PATH` | `/oauth2/sign_in` | Path the header's "Sign in" button links to |
| `OAUTH2_LOGOUT_PATH` | `/oauth2/sign_out?rd=/` | Path the header's "Sign out" button links to |

When deploying with oauth2-proxy, the defaults are correct and no override is needed unless the oauth2-proxy is mounted at a non-standard prefix.

In Kubernetes these are set as env vars on the webapp container (via helm `cogstack-cohorter.webapp.env`) and are picked up automatically on the next pod restart.

### Run using Docker with random data

Set `RANDOM_DATA=true` in your `.env` file (or leave it unset — it defaults to `true`), then from the `cogstack-cohorter/` root:
Expand Down
1 change: 1 addition & 0 deletions cogstack-cohorter/WebAPP/client-react/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<body class="overflow-x-hidden">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="/config.js" onerror="window.__RUNTIME_CONFIG__={}"></script>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
8 changes: 4 additions & 4 deletions cogstack-cohorter/WebAPP/client-react/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { LoadQueryDialog } from './LoadQueryDialog';
// Fixed header height
const HEADER_HEIGHT = 80;

// OAuth2 proxy paths — configurable at build time via .env
const USERINFO_PATH = import.meta.env.VITE_OAUTH2_USERINFO_PATH ?? '/oauth2/userinfo';
const LOGIN_PATH = import.meta.env.VITE_OAUTH2_LOGIN_PATH ?? '/oauth2/sign_in';
const LOGOUT_PATH = import.meta.env.VITE_OAUTH2_LOGOUT_PATH ?? '/oauth2/sign_out?rd=/';
const runtimeConfig = (typeof window !== 'undefined' && window.__RUNTIME_CONFIG__) || {};
const USERINFO_PATH = runtimeConfig.OAUTH2_USERINFO_PATH || '/oauth2/userinfo';
const LOGIN_PATH = runtimeConfig.OAUTH2_LOGIN_PATH || '/oauth2/sign_in';
const LOGOUT_PATH = runtimeConfig.OAUTH2_LOGOUT_PATH || '/oauth2/sign_out?rd=/';

function App() {
const rootRef = useRef(null);
Expand Down
19 changes: 19 additions & 0 deletions cogstack-cohorter/WebAPP/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,24 @@ if [ "${RANDOM_DATA}" = "true" ] && \
node --max-old-space-size=32768 /usr/src/app/server/gen_random_data.js
fi

# ── Inject runtime config for the React app ──────────────────────────────────
# Writes config.js into the pre-built dist folder so Express serves it
# as /config.js.
# Override any of these via OAUTH2_* env vars.
#
# Values are sanitised before being embedded in the JS string literal:
# backslashes are escaped first, then double-quotes, preventing a
# malformed env var from injecting arbitrary JavaScript.
_js_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }

CONFIG_JS=/usr/src/app/client-react/dist/config.js
{
printf 'window.__RUNTIME_CONFIG__ = {\n'
printf ' OAUTH2_USERINFO_PATH: "%s",\n' "$(_js_escape "${OAUTH2_USERINFO_PATH:-/oauth2/userinfo}")"
printf ' OAUTH2_LOGIN_PATH: "%s",\n' "$(_js_escape "${OAUTH2_LOGIN_PATH:-/oauth2/sign_in}")"
printf ' OAUTH2_LOGOUT_PATH: "%s",\n' "$(_js_escape "${OAUTH2_LOGOUT_PATH:-/oauth2/sign_out?rd=/}")"
printf '};\n'
} > "$CONFIG_JS"

# ── Start the server ──────────────────────────────────────────────────────────
exec node --max-old-space-size=32768 server.js
8 changes: 2 additions & 6 deletions cogstack-cohorter/WebAPP/server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,13 +675,9 @@ app.post('/compare_query', (req, res) => {
//
// During development (or when OAuth2 is not yet deployed) this returns a
// configurable default user so the Header/UserSection renders correctly
// without any real authentication. Override the defaults via env vars:
// DEFAULT_USER_NAME — displayed username (default: "Local User")
// DEFAULT_USER_EMAIL — user email (default: "")
// DEFAULT_USER_ID — opaque user id (default: "local")
// DEFAULT_USER_GROUPS — comma-separated groups (default: "")
// without any real authentication.
app.get("/oauth2/userinfo", (req, res) => {
const groups = process.env.DEFAULT_USER_GROUPS
const groups = process.env.DEFAULT_USER_GROUPS || 'cohorter-users'
? process.env.DEFAULT_USER_GROUPS.split(',').map(g => g.trim()).filter(Boolean)
: [];
res.status(200).json({
Expand Down
2 changes: 1 addition & 1 deletion cogstack-cohorter/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ services:
DEFAULT_USER_EMAIL: "${DEFAULT_USER_EMAIL:-}"
DEFAULT_USER_ID: "${DEFAULT_USER_ID:-local}"
# Comma-separated list, e.g. "cohorter-users,role:admin"
DEFAULT_USER_GROUPS: "${DEFAULT_USER_GROUPS:-}"
DEFAULT_USER_GROUPS: "${DEFAULT_USER_GROUPS:-cohorter-users}"
volumes:
# Mount your data directory here. It should contain either:
# - snomed_terms_data.tar.gz (will be auto-extracted on startup), or
Expand Down
Loading