mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 11:02:33 -05:00
A feature's guide now sits under the menu it is used from, read from the templates rather than from where somebody once put it: Header-Bar, All-Boards, Pages, Board-Header (search and every Board View), Board-Sidebar (Board Settings, Filter, Members, Labels, Archive), Rules, Swimlanes, Lists, Cards, Member-Settings, Admin-Panel and Login-Page. Topics used from several menus (editor, history, theme, translations, email, troubleshooting) are in General. - Each area has a README mapping its menu entries to their guides and to the template or server module that implements them. Board-Header/README.md lists all 40 Board View entries with the template boardBody.jade renders; five views (Table, Calendar Mode, Time, Timeline, Map) have no guide of their own yet and say so. - Board-View.md listed 25 views while BOARD_VIEWS has 40; it now lists all of them with their English labels. - Pages keep their file names. Where a released changelog links an old path, a "# Moved" page stays there and points to the new one; test-menu.sh skips folders holding only those. - Undo was filed under Login; it is General/Undo now. - Every link in docs, code comments, scripts and tests follows the move; docsLinksResolve checks them all. Tests that read a doc follow it to its new place. boardViewSettings now fails when Board-View.md or Board-Header/README.md differs from BOARD_VIEWS, or names a template boardBody.jade does not render. Thanks to xet7 !
92 lines
4.8 KiB
Markdown
92 lines
4.8 KiB
Markdown
# Admin Panel → Problems → API
|
|
|
|
**Which REST API endpoints are used, by whom, and how often.**
|
|
Address: `/admin/problems/api`
|
|
|
|
Every other pane under Problems answers *what went wrong*. This one answers
|
|
*what is being done*: `POST /api/boards` called 34 times by alice last month,
|
|
812 times yesterday by nobody with an account. Without it the only record of API
|
|
use is whatever the reverse proxy happens to keep, and most instances keep none.
|
|
|
|
The REST API is off unless `WITH_API=true`, so on an instance that never turned
|
|
it on this pane is empty — which is itself the answer.
|
|
|
|
## The table
|
|
|
|
| Username | API | Calls | First called | Last called | IPv4 | IPv6 |
|
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
| alice | `POST /api/boards` | 34 | 2026-02-02 09:14:03 | 2026-05-05 17:22:51 | 100.100.100.100 | |
|
|
| alice | `GET /api/boards/:boardId` | 210 | 2026-02-02 09:14:07 | 2026-05-05 17:22:55 | 100.100.100.100 | |
|
|
| | `POST /api/users` | 812 | 2026-05-04 23:01:12 | 2026-05-05 02:44:39 | | 2001:db8::1 |
|
|
|
|
- **Username** — the account that made the call, as it was named at the time.
|
|
Empty for an unauthenticated call, which is not a gap: it is the row for
|
|
*somebody with no account*, and the addresses beside it are what identify
|
|
them. The third line above is what a registration sweep looks like.
|
|
- **API** — the route **pattern**, not the path that was requested.
|
|
- **Calls**, **First called**, **Last called** — how many, and the window they
|
|
fall in. A count without a window says nothing: 34 calls in a day and 34 in a
|
|
year are different instances.
|
|
- **IPv4** / **IPv6** — where the most recent call came from, in two columns
|
|
rather than one, because an instance reached over IPv6 and one reached over
|
|
IPv4 are different situations and a single column that sometimes holds one and
|
|
sometimes the other cannot be scanned. Resolved with the same spoofing-safe
|
|
rule as the login throttle: `X-Forwarded-For` is trusted only as far as
|
|
`HTTP_FORWARDED_COUNT` says to trust it.
|
|
|
|
Sorted by **Calls**, busiest first — a usage report's question is *what is used
|
|
most*, where a problem report's is *what happened last*. The search box matches
|
|
the endpoint, the username and the address.
|
|
|
|
## Two decisions worth knowing about
|
|
|
|
**The name is the route pattern.** `/api/boards/:boardId/lists` is one endpoint;
|
|
`/api/boards/abc123/lists` and ten thousand of its siblings are that one
|
|
endpoint being used. Recording the concrete path would put a row per board in
|
|
the database — the same one-row-per-event cost the rest of this page exists to
|
|
remove. A request that matched **no route at all** is counted under a single
|
|
`(no route)` name rather than under the path it invented, because a 404 sweep is
|
|
an attacker walking a wordlist and a row per guess would let them fill the
|
|
collection.
|
|
|
|
**One row per account and endpoint — the actor is part of the identity here.**
|
|
That is the one deliberate exception to the rule every other stream follows
|
|
(*the actor is never part of a problem's identity*, see
|
|
[Design.md](Design.md)). For every other stream the question is *what is
|
|
happening* and including the caller would multiply the rows; here *who called
|
|
what* **is** the report, and the cardinality is bounded by real accounts times
|
|
real endpoints rather than by whoever is sending. The account is stored by its
|
|
**id**, so renaming an account does not split its history into two rows.
|
|
|
|
## What it costs
|
|
|
|
Nothing per request. Ordinary API traffic is not rare the way a guard firing is
|
|
rare, so calls are counted **in memory** and folded into their rows on a timer —
|
|
a thousand requests become one write instead of a thousand. Up to a few seconds
|
|
of counts are lost if the process stops between flushes, which is acceptable
|
|
here and would not be anywhere else on this page: this report decides nothing,
|
|
and nothing is protected by it.
|
|
|
|
The number of tracked (account, endpoint) pairs is capped. Past the cap the rest
|
|
are counted together rather than dropped, so *"and 12,000 calls to something
|
|
else"* still appears — that being the signal that something unusual is going on.
|
|
|
|
## Where it is implemented
|
|
|
|
| | |
|
|
| --- | --- |
|
|
| `models/lib/apiUsage.js` | the naming and the accumulator — no Meteor, so it is tested as arithmetic |
|
|
| `server/lib/apiUsageLog.js` | the middleware and the flush |
|
|
| `server/apiMiddleware.js` | where it is installed, in front of every route |
|
|
| `models/lib/eventLogSummary.js` | the `api` / `apiUserId` identity fields |
|
|
| `tests/apiUsageReport.test.cjs` | the guards |
|
|
|
|
Counting hooks the middleware chain rather than the routes, so **a route cannot
|
|
be added without being counted** — there is nothing per route to forget.
|
|
|
|
## See also
|
|
|
|
- [README.md](README.md) — every pane of this page
|
|
- [Design.md](Design.md) — why Problems records summaries and not events
|
|
- [../../Page/Table.md](../../General/Table.md) — the shared table this pane draws with
|