3 Commits
Author SHA1 Message Date
Lauri Ojansivu f735eba194 Rules: assignee actions, an optional title, and remove-all members that removes them.
#4294 asked for four things. Several triggers and actions, rule variables,
renaming in place and rule import/export were built earlier; two parts were
still missing.

- "I want the assignee to be the creator of the card by default": rules had
  member actions only. Add and Remove assignee actions take a username, a
  {creator}/{assignees}/{members} token, the user who triggered the rule, or
  "*" for every assignee, and write card.assignees. They are durable through
  Sync like the member actions, with the joinAssignee/unjoinAssignee
  activities the assignees hook writes.
- "give a Rule a default name": Add Rule with an empty title showed an
  error, and rules.createRule stored the literal "Rule". The title is now
  optional; the rule is named after its trigger and action ("When ...,
  then ..."), and the rules list renames it in place.

Fixing this found that "Remove all members from the card" iterated the
card's assignees while removing from its members: an earlier fix believed
assignMember wrote assignees, but both definitions in models/cards.js write
members. It removed only members who were also assignees. Remove-all now
iterates card.members, in the ordinary and the durable path, and the guards
that pinned the wrong collection now read models/cards.js to decide.

New text is added in English, pending Transifex.

Thanks to xeruf and xet7 !

Fixes #4294.
2026-10-08 11:31:12 +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