docs: sign-in is SSO-only, speech is a roster, the app is PedsHub Scribe
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
This commit is contained in:
parent
8c6126b112
commit
444fa44444
6 changed files with 47 additions and 10 deletions
|
|
@ -165,7 +165,7 @@ Primary references:
|
|||
- `docs/configuration.md` — environment variables and live `app_settings`.
|
||||
- `docs/database.md` — every table, its columns, and what is encrypted.
|
||||
- `docs/migrations.md` — how schema changes are made and applied.
|
||||
- `docs/authentication.md` — auth, OIDC, sign-in codes, invites, rate limits.
|
||||
- `docs/authentication.md` — SSO-only sign-in, OIDC, sessions, rate limits.
|
||||
- `docs/ai-providers.md` — provider selection, prompts, injection hardening.
|
||||
- `docs/clinical-assistant.md` — MCP-backed assistant behavior and safety rules.
|
||||
- `docs/retrieval-tuning.md` — how much corpus each feature retrieves, and what it costs.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# API Reference
|
||||
|
||||
Working endpoint reference for the main PedAI flows. It covers the clinical, auth, user data, and admin surfaces most commonly used by the frontend, but the source of truth is still `server.js` plus `src/routes/*.js`. Unless noted otherwise, authenticated endpoints require a valid web cookie or `Authorization: Bearer <token>` header.
|
||||
Working endpoint reference for the main PedsHub Scribe flows. It covers the clinical, auth, user data, and admin surfaces most commonly used by the frontend, but the source of truth is still `server.js` plus `src/routes/*.js`. Unless noted otherwise, authenticated endpoints require a valid web cookie or `Authorization: Bearer <token>` header.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
# Authentication & security
|
||||
|
||||
## Sign-in is SSO-only
|
||||
|
||||
The front door is `sso.pedshub.com` (Authentik, `/home/danvics/docker/authentik-pedshub`).
|
||||
`oidc.enabled` and `oidc.disable_local_auth` are both `true`, so `/api/auth/login`,
|
||||
`/register`, `/forgot-password`, `/reset-password`, `/change-password` and the 2FA
|
||||
routes answer 403 (`requireLocalAuth`). The OIDC client is `src/routes/oidc.js`:
|
||||
signed state cookie, PKCE, nonce, `email_verified` required before an existing
|
||||
local account is linked, `sub` mismatch refused, session row written before the
|
||||
cookie is set. New accounts are created at the SSO from an invitation link
|
||||
(`invite.py` there); an SSO account whose email matches a local one signs into
|
||||
that account. The sections below describe the local machinery that remains
|
||||
behind the switch.
|
||||
|
||||
## Password hashing
|
||||
|
||||
- Primary: **argon2id**, memory cost 19 MiB, time cost 2, parallelism 1
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ keys):
|
|||
| Variable | Purpose |
|
||||
|---|---|
|
||||
| `LITELLM_TTS_MODEL`, `LITELLM_TTS_VOICE` | LiteLLM-routed TTS model and default voice. |
|
||||
| `LITELLM_TTS_VOICES` | Comma-separated LiteLLM-compatible voices exposed in voice search and user preferences. |
|
||||
| `LITELLM_TTS_VOICES` | The voices of `LITELLM_TTS_MODEL` only; other models use the built-in table in `src/utils/ttsProvider.js`. The roster itself is `tts.roster` in `app_settings`. |
|
||||
|
||||
### Embeddings
|
||||
|
||||
|
|
@ -80,7 +80,6 @@ keys):
|
|||
| `METRICS_TOKEN` | Lets `/metrics` be scraped from off-host with `Authorization: Bearer <token>`. Without it, any request carrying `X-Forwarded-For` gets a 404, so only same-host scrapes succeed. |
|
||||
| `API_RATE_LIMIT_MAX` | General request ceiling per IP per minute (default 200). |
|
||||
| `LOGIN_RATE_LIMIT_MAX` | Sign-in attempts per IP per 15 min (default 10). Raised in the e2e stack so multi-worker Playwright runs do not trip it. |
|
||||
| `LOGIN_CODE_RATE_LIMIT_MAX` | Emailed sign-in codes per IP per hour (default 5). Lower than the sign-in limit because each request sends mail to somebody else's address. See `docs/authentication.md`. |
|
||||
|
||||
### Integrations
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,26 @@ Browser-native Web Speech is only an explicit opt-in preview path. It is not the
|
|||
|
||||
Browser Whisper and browser-local model workers are removed. Do not expect a pre-download model button, public Whisper worker, or bundled Xenova model path.
|
||||
|
||||
## Signing in
|
||||
|
||||
Sign-in is **SSO-only**: the sign-in screen has one button, "Sign in with
|
||||
PedsHub", which goes to `sso.pedshub.com` (Authentik). There a person types
|
||||
their email and the code that is sent to it — no password. New people are
|
||||
invited with a sign-up link (`authentik-pedshub/invite.py` on the host mints
|
||||
one); they enter a name and email, confirm with a code, and land in the
|
||||
`pedshub-members` group, which is what both PedsHub apps admit. The same
|
||||
account signs into the quiz app at `pedshub.com`. Local password sign-in,
|
||||
registration, reset and the app's own emailed codes are switched off
|
||||
(`oidc.disable_local_auth`); a local account with the same email is the same
|
||||
account.
|
||||
|
||||
## Text To Speech
|
||||
|
||||
The voice preview button calls LiteLLM TTS and plays the returned audio in the browser. If preview is silent, check that a LiteLLM voice is selected, the gateway is configured, the user is authenticated, and browser autoplay has not blocked playback.
|
||||
Read Aloud uses a **roster** of speech models (Admin → Models → Speech): each
|
||||
model brings the voices it accepts, and the default is a model-and-voice pair.
|
||||
Users choose any voice of any roster model under Settings and preview it. If a
|
||||
preview is silent, check that a default pair is set, the gateway is configured,
|
||||
and browser autoplay has not blocked playback.
|
||||
|
||||
## Nextcloud WebDAV
|
||||
|
||||
|
|
@ -100,7 +117,7 @@ Admins can manage users, roles, registration, security settings, model defaults,
|
|||
| Clinical Assistant | Active | Grounded answers over MCP retrieval, with citations and source cards. |
|
||||
| My Resources | Active | Personal teaching decks and documents, rendered by python-pptx / python-docx. |
|
||||
| Deck vision review | Optional | Off by default; one pass, admin-configurable model. |
|
||||
| Passwordless sign-in codes | Active | Emailed 6-digit code; password sign-in always stays available. |
|
||||
| Sign-in | SSO-only | `sso.pedshub.com`: email → code. Invitation links create accounts. |
|
||||
| Personal notes | Active | Including dictation, with trash and restore. |
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
|||
|
|
@ -59,11 +59,19 @@ Browser-native Web Speech can show interim text when the user explicitly enables
|
|||
|
||||
`POST /api/text-to-speech` returns audio from LiteLLM `/audio/speech`. The `X-TTS-Provider` response header identifies the LiteLLM model used. Requests are limited to 5000 characters.
|
||||
|
||||
| Provider | Notes |
|
||||
|---|---|
|
||||
| LiteLLM | Uses `LITELLM_TTS_MODEL` and `LITELLM_TTS_VOICE`. |
|
||||
Speech models sit on a roster (`tts.roster`, Admin → Models → Speech), and the
|
||||
default is a pair — `tts.model` and `tts.voice`, set together through
|
||||
`PUT /api/admin/config/tts/default`, which refuses a voice the model does not
|
||||
accept. `LITELLM_TTS_MODEL` / `LITELLM_TTS_VOICE` are the fallback when no
|
||||
default has been chosen.
|
||||
|
||||
The admin/user voice pickers read available LiteLLM-compatible voices from `LITELLM_TTS_VOICES`.
|
||||
Which voices a model accepts is a property of the model, not the gateway
|
||||
(`/model/info` carries no voice field), so the table lives in
|
||||
`src/utils/ttsProvider.js` (`MODEL_VOICES`, keyed by family: Kokoro, Orpheus
|
||||
English/Arabic, Fish). `LITELLM_TTS_VOICES` names the voices of
|
||||
`LITELLM_TTS_MODEL` only. A user's choice is stored as `model|voice`, so Read
|
||||
Aloud sends each voice to the model that accepts it; `chooseTTS` is the one
|
||||
place that decision is made.
|
||||
|
||||
## Recording
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue