mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 02:52:33 -05:00
Durable delivery identified every activity by a card and a list, so a rule's createSwimlane activity, which names neither, and a cross-board move's moveCardBoard activity, which names no list, were written once but delivered the ordinary way: their notifications and webhooks were not replayed after a crash. Durable delivery now takes activities without a list, and without a card. Recipients and webhook senders are checked against the board, plus the card when one is named. A card or list the activity does not name is refused. An assigned-only member never receives a board-level event, since its scope cannot be checked against their assignments. The rule stage has nothing to run for these types, because no trigger exists for them, and it refuses a list-less activity whose type has one. Thanks to xet7 !
23 lines
1.3 KiB
JavaScript
23 lines
1.3 KiB
JavaScript
'use strict';
|
|
const { memberCan } = require('../../models/lib/boardRoleCapabilities');
|
|
const { isAssignedOnlyMember } = require('../../models/lib/boardCardScope');
|
|
const { canonical, sha256 } = require('../../models/lib/changeHistoryIntegrity');
|
|
// A board-level activity (no card): the actor writes the board and is not
|
|
// restricted to their assigned cards.
|
|
function canWriteWebhookBoard({ user, board }) {
|
|
return !!(user && !user.loginDisabled && board && memberCan(board.members, user._id, 'write') &&
|
|
!isAssignedOnlyMember(board, user._id));
|
|
}
|
|
function canWriteWebhookCard({ user, board, card }) {
|
|
return !!(user && !user.loginDisabled && board && card && card.boardId === board._id &&
|
|
memberCan(board.members, user._id, 'write') &&
|
|
(!isAssignedOnlyMember(board, user._id) || (Array.isArray(card.assignees) && card.assignees.includes(user._id))));
|
|
}
|
|
function isCurrentWebhookTarget({ target, integration, activity }) {
|
|
return !!(target && integration && activity && integration.enabled === true &&
|
|
integration._id === target.integrationId && integration.boardId === target.integrationBoardId &&
|
|
[activity.boardId, '_global'].includes(integration.boardId) &&
|
|
sha256(canonical(integration)) === target.integrationHash);
|
|
}
|
|
module.exports = { canWriteWebhookCard, canWriteWebhookBoard, isCurrentWebhookTarget };
|