diff --git a/astro.config.mjs b/astro.config.mjs index 8508e67..fed7cf1 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -139,6 +139,7 @@ export default defineConfig({ { label: 'Design system', link: '/docs/contributing/design-system/' }, { label: 'Translations', link: '/docs/contributing/translations/' }, { label: 'API errors', link: '/docs/contributing/api-errors/' }, + { label: 'Other clients', link: '/docs/contributing/other-clients/' }, { label: 'Releasing', link: '/docs/contributing/releasing/' }, ], }, diff --git a/src/content/docs/docs/contributing/index.md b/src/content/docs/docs/contributing/index.md index 9298bc8..601c137 100644 --- a/src/content/docs/docs/contributing/index.md +++ b/src/content/docs/docs/contributing/index.md @@ -33,24 +33,7 @@ Playwright specs in `e2e/` run against `BASE_URL`, default `http://127.0.0.1:873 ## Pull request checks -CI runs `.github/actions/checks/action.yml`: - -```sh -npm ci -node scripts/changelog-check.js -node scripts/bump-cache-busting.js --check -npm run paths:check -cd api && npm test -cd api && npx c8 check-coverage --lines 92 -cd ui/test && node --test -npm run lint -npm run format:check -npm run typecheck -npm run typecheck:ui -docker build -t stackyard:ci . -``` - -CodeQL and Trivy also run. Both block on a finding. +The checks CI runs are listed in [CONTRIBUTING.md](https://github.com/SandObserver/stackyard/blob/main/CONTRIBUTING.md#before-opening-a-pr). - Do not edit `CHANGELOG.md`. List user-visible changes in the pull request description under **Changelog**, as `- ` lines below a Keep a Changelog heading such as `### Fixed`. Merging adds them to `[Unreleased]`. - Write `?v=1` on new `/css/` and `/js/` imports. The release sets the real hash. diff --git a/src/content/docs/docs/contributing/other-clients.md b/src/content/docs/docs/contributing/other-clients.md new file mode 100644 index 0000000..491180b --- /dev/null +++ b/src/content/docs/docs/contributing/other-clients.md @@ -0,0 +1,49 @@ +--- +title: Build another client +description: How an app or script signs in to Stackyard and reads the dashboard. Unstable, with no compatibility promise. +--- + +The API serves the dashboard and the admin. It has no version and can change in any release. Read the version first, and refuse one you have not tested. + +## Sign in + +1. `GET /api/auth/check`. If `enabled` is `false`, sign-in is off and no cookie is needed. +2. `POST /api/auth/login` with `{"password": "..."}`. +3. Keep the `ds` cookie from the response. Send it on every request. + +While no password is set, Stackyard answers only local addresses and the names in **Allowed Addresses**. Any other `Host` gets a `403`. + +A session ends after 12 hours unused, or 30 days after sign-in. `SESSION_MAX_AGE_DAYS` changes the first. A `401` with `"kind": "auth"` means sign in again. + +## Origin header + +Every `POST`, sign-in included, needs an `Origin` header with the same host as the `Host` header. Without it, the request gets a `403`. + +``` +Origin: http://stackyard.lan:8700 +``` + +## Read the dashboard + +| Request | Returns | +| --- | --- | +| `GET /api/version` | `current`, the installed version. | +| `GET /api/config` | The layout: `items` and `settings`. Stored secrets are removed. | + +`_rev` in the config changes on every save. Poll `/api/config` and redraw when it changes. The dashboard polls every 15 seconds. Do not poll faster. + +## Widgets + +Show a widget by loading its page in a web view: + +``` +/widgets//?id=&size= +``` + +`` is `index.html`, unless the widget's entry in `GET /api/widgets` has `views`. Then it is the `src` of the view that the item's `widgetConfig[viewField]` names, or of `defaultView` when that is unset. + +The page fetches its own data with the session cookie. The data each widget returns is private to its page and changes without notice. + +## Errors + +See [API errors](/docs/contributing/api-errors/).