12 Commits
Author SHA1 Message Date
Lauri Ojansivu b7589737f5 File docs/Features the way the WeKan menus are.
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 !
2026-10-16 23:45:35 +03:00
Lauri Ojansivu 85a226433c Stream attachment and background uploads and downloads over the REST API.
The attachment REST API carried every file as base64 inside JSON: an upload
gathered the whole body into a string, decoded it and stored it, and a
download read the whole file and encoded it - the file and its base64 copy
in memory at once, up to the API limits. Beside that form, each route now
takes the file itself: an upload whose body is the file (any Content-Type
but JSON, its card or board in the query) streams into storage, and
?raw=1 on a download streams the file out, served as a download that
cannot run in WeKan's origin. Both make the same checks first - one helper
now holds the card upload checks for both forms - and the API limits are
checked against Content-Length before reading and counted as the bytes flow.
api.py uses the raw form for its four attachment and background commands,
streaming from and to disk. The DDP methods stay base64 by their nature;
docs/API/Attachments.md says to use the raw routes for large files.
Removed from TODO Later.

Thanks to markusst1982 and xet7 !
2026-10-09 23:10:43 +03:00
Lauri Ojansivu ad51a03731 Log in by full-page redirect by default with OAuth2/OIDC, Google & co, SAML and CAS.
Every login that chooses between a popup and a redirect opened a popup by
default. Google's sign-in pages, and other identity providers', can send
Cross-Origin-Opener-Policy, which makes Meteor's popup look closed at
once: the login was tried before the provider answered, and the user
was back on the sign-in page with no error. Popups are also blocked in
iframes and on some phones. The full-page redirect has no popup to lose.

- OAUTH2_LOGIN_STYLE (OAuth2/OIDC): redirect unless it says popup, in the
  server, the Admin Panel catalog and the samples.
- OAUTH_PROVIDERS_LOGIN_STYLE (Google, GitHub, Facebook, X, Meteor
  Developer, Weibo, Meetup): redirect by default, in the code, Dockerfile,
  snap, Sandstorm package and samples.
- SAML: both identity-provider profiles log in by redirect;
  SAML_LOGIN_FLOW=popup still chooses the popup, and the client no longer
  falls back to a popup while the configuration loads.
- CAS: redirects unless "popup": true. Its redirect could never finish:
  nothing called Meteor.initCas, which the package now does at startup.
  The sign-in page also passed username and password as loginWithCas's
  options and callback, so its callback never ran, and the CAS redirect
  page echoed the request address into HTML unescaped.

A redirect login's error now reaches the reloaded sign-in page, from
accounts-oauth's page-load hook and the SAML and CAS events, instead of
the page coming back silently.

Verified against a freshly built and prepared bundle with the local
identity-provider suite and no login style set: OIDC, SAML, CAS and all
seven Meteor providers log in by redirect, and each refusal is shown on
the sign-in page (31 of 31 with Chromium). Its LDAP wrong-password case
expected wording that changed in 679a8b3499 and is corrected.

Thanks to xet7 !
2026-10-08 15:18:59 +03:00
Lauri Ojansivu 953d8f7c13 Organize feature guides by menu and document backup alternatives
Add September feature instructions, preserve guide forwarding links, and document backup coverage with descriptive screenshots from #6683.

Thanks to markusst1982 and xet7 !
2026-09-23 18:34:37 +03:00
Lauri Ojansivu c64d3454ac Add REST API for Board Settings / Board View, and OpenAPI blocks for the card settings routes.
GET /api/boards/:boardId/boardViewSettings answers which entries of the
Board View menu a board offers, which one it opens in, separately for a
public and a private board, and the menu order - in the normalised shape the
menu renders with: every view once with both showOnPublic and showOnPrivate
explicit, the two defaults resolved (missing or unknown reads as Swimlanes),
boardViewOrder made whole, and `keys` listing the known views. Board access.

PUT /api/boards/:boardId/boardViewSettings takes any subset of
boardViewSettings, defaultPublicBoardView, defaultPrivateBoardView and
boardViewOrder, through the same pure modifiers the popup's clicks apply
(showBoardViewModifier, defaultBoardViewModifier, normalizeBoardViewOrder),
now composed by boardViewSettingsRequest() in models/lib/boardViewSettings.js:
a default is always shown on its side, hiding a side's current default is a
400 (set another default first - or in the same request, since defaults are
applied before the show flags), an unknown view key anywhere in the body is a
400 and nothing of that request is written, and the order is normalised so the
menu lists every view exactly once. Board admin (or site admin), the same
check as cardFieldOrder. Both answer boardViewSettingsSnapshot().

The existing GET/PUT /api/boards/:boardId/cardSettings routes get the JSDoc
@operation blocks the OpenAPI generator reads (get_board_card_settings,
update_board_card_settings), so the hand-written copy in
openapi/extra_paths.yml - which now duplicated the operationId - is removed.
public/api/wekan.yml and wekan.html are regenerated with the release
workflow's own commands: 158 operations. docs/API/REST-API.md documents both
endpoints with curl examples, and docs/Features/Board/Board-View-Settings.md
links to them.

tests/restApiNewFeatureRoutes.test.cjs pins the four routes to their method,
path, @operation and auth check, that the PUT writes only the helper's $set,
the snapshot's shape, the request helper's positive cases (setting a default
shows it, one request may move the default and hide the old one, the order is
normalised, the input board is not mutated) and negatives (unknown view key in
the order, the settings or a default; hiding a side's default; malformed
bodies; a partly-invalid body applies nothing), and that the generated and the
committed spec carry the four operations exactly once with the old
edit_board_card_settings gone.

Thanks to xet7 !
2026-09-11 21:18:35 +03:00
Lauri Ojansivu bbcd98d9d8 Add REST API for attachment soft delete and restore, Admin Panel Problems, OAuth login provider and passwordless settings, card field order and pausing a rule.
Every feature of the recent releases that had a UI but no endpoint, on the
same server-side code the UI uses:

- DELETE /api/boards/:boardId/attachments/:attachmentId soft-deletes,
  POST .../attachments/:attachmentId/restore restores, and
  GET /api/boards/:boardId/attachments/deleted lists what is restorable -
  all through the attachments.softDelete / attachments.restore methods the
  card and the card history use, run as the request's user. No hard delete.
- GET /api/admin/problems (the Problems status overview plus the new-problem
  count per stream), GET /api/admin/problems/:stream (one page, with
  limit/skip/search) and POST /api/admin/problems/:stream/acknowledge,
  through the admin-only eventLog* methods the Admin Panel pages call.
- GET /api/admin/oauth-providers, PUT /api/admin/oauth-providers/:providerKey
  and PUT /api/admin/passwordless, through saveOauthProviderSettings,
  savePasswordlessSettings and getOauthProviderConfigSources. A provider's
  secret is reported only as { source, hasValue }, never its value.
- GET/PUT /api/boards/:boardId/cardFieldOrder, normalised with the same
  applyCardFieldOrder() the card renders with.
- PUT /api/boards/:boardId/rules/:ruleId accepts `enabled` to pause and
  resume a rule, and GET reports it.

The OpenAPI generator is fixed on the way: server/models/boards.js has had a
bare `catch {` since v11.67, the esprima parser cannot read that, and a parse
failure was silently skipped - so public/api/wekan.yml has shipped WITHOUT
the whole Boards API since then. It now downlevels `catch {` and
`for await (`, warns when a file cannot be parsed, and no longer emits an
empty sub-schema for a primitive array-element marker such as
`wipLimitGroups.$.listIds.$`, which made the spec unparseable YAML.
public/api/wekan.yml and wekan.html are regenerated with the release
workflow's own commands: 156 operations, up from 122.

tests/restApiNewFeatureRoutes.test.cjs pins every new route to its method,
path, @operation block and authentication check, that the OAuth endpoints
never mention a secret outside the input whitelist, the generator's two
fixes, that the generated and the committed spec carry the Boards API and the
new operations, and - as the negative sweep - that no route in models/ or
server/models/ lacks an authentication check.

Thanks to xet7 !
2026-09-11 21:18:35 +03:00
Lauri Ojansivu 25d33cec36 Fix #2345 #2674 #574: rules card title filter, rules REST API, api docs;
Sandstorm username races.

- #2345: the Card Title Filter is now SAVED by every board trigger
  builder (a trigger doc missing the field could never satisfy the
  matcher's $in - those rules fired for nothing), SHOWN in the rule
  details, and ENFORCED for archive/restore triggers by resolving the
  title from the card when the activity lacks it; legacy field-less
  triggers keep matching; the filter popup prefills its current value.
- #2674: rules created via POST/PUT /api/boards/:boardId/rules never
  fired - missing matching fields are now normalized to '*' wildcards
  and trigger/action types validated; the addMember/removeMember rule
  actions no longer crash on unresolvable usernames or member-less
  cards and their writes are awaited. New docs/API/Rules.md (endpoints,
  matching fields, wildcard semantics, the exact two-rule
  add-on-move-to/remove-on-move-from workflow), linked from REST-API.md;
  api.py help now lists the rule commands with the same example.
- #574: Sandstorm unique-username generation probes case-insensitively
  (anchored, regex-escaped) and retries the next number when a
  concurrent insert wins the unique-index race, instead of aborting the
  login hook with E11000.

Tests: tests/rulesCardTitleFilter.test.cjs (12),
tests/rulesApiTriggerNormalize.test.cjs (19),
tests/sandstormUsername.test.cjs (11) - positive and negative cases.

Thanks to InfoSec812, sfahrenholz, mitar and xet7.
2026-07-17 03:36:50 +03:00
Lauri OjansivuandClaude Opus 4.8 7b66884ba3 docs: fix bare wiki-style links to relative paths of existing docs pages
Many docs still used flat GitHub-wiki page-name links like [Backup](Backup),
[OAuth2](OAuth2) or [FAQ](FAQ) that only resolved on the old wiki; in the docs/
hierarchy they were broken. Rewrite them to correct relative paths of the
existing pages (e.g. ](Backup) -> ](Backup.md), ](OAuth2) -> ](../Login/OAuth2.md),
](Sandstorm) -> ](../Platforms/FOSS/Sandstorm/Sandstorm.md)).

Mapping: page name -> docs/<...>/<Name>.md by filename, with explicit handling
for renamed pages (Caddy/Nginx-Webserver-Config, Wekan-Markdown, the Sandstorm
grain export page, Uberspace) and the REST-API-<X> family -> docs/API/<X>.md.
Ambiguous names resolved by preferring a same-directory file or the primary page.
Anchors and markdown titles preserved. 280 links across the docs tree.

Out of scope (left as-is): source-code references (models/*.js etc.) and
[Link](url) placeholders, which are not docs pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:03:27 +03:00
Lauri OjansivuandClaude Opus 4.8 84678d3492 Docs: document board-domains & GlobalAdmin REST APIs, big-board export, and template drag-to-share / propagate-members (#5850).
Add REST endpoints for board domain sharing and global-admin settings, document
exporting large boards without base64 attachments, and document template
drag-to-share drop-target gating plus Propagate Members To Boards behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:37:44 +03:00
Lauri Ojansivu f6d8befb56 Moved website to separate repo. Moved docs2 back to docs.
Thanks to xet7 !
2026-04-28 11:59:16 +03:00
Lauri Ojansivu 1c0d8e9964 Moved docs to docs2, and wekan.fi to docs, to be able publish with GitHub Pages.
Thanks to xet7 !
2026-04-16 14:36:10 +03:00
Lauri Ojansivu ce89ff4833 Reorganized Docs. In Progress. 2024-06-27 11:08:43 +03:00