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 !
20 lines
1.3 KiB
JavaScript
20 lines
1.3 KiB
JavaScript
'use strict';
|
|
const { isAssignedOnlyMember } = require('../../models/lib/boardCardScope');
|
|
const { boardNotificationRecipients } = require('../../models/lib/boardNotificationRecipients');
|
|
// A card or list the activity names must be there and agree with it; a
|
|
// board-level activity names neither (2026-10-03). An assigned-only member
|
|
// receives only what concerns a card assigned to them - never a board-level
|
|
// event, whose scope cannot be checked against their assignments.
|
|
function canReceiveStoredNotification({ user, board, card, list, activity }) {
|
|
if (typeof user?._id !== 'string' || !user._id || user.loginDisabled || !activity || !board ||
|
|
board._id !== activity.boardId) return false;
|
|
if (activity.cardId ? (!card || card._id !== activity.cardId || card.boardId !== board._id) : card) return false;
|
|
if (activity.listId ? (!list || list._id !== activity.listId || list.boardId !== board._id ||
|
|
(card && card.listId !== activity.listId)) : list) return false;
|
|
if (isAssignedOnlyMember(board, user._id) &&
|
|
(!card || !Array.isArray(card.assignees) || !card.assignees.includes(user._id))) return false;
|
|
return boardNotificationRecipients([user._id], board.members, board.watchers,
|
|
[...(list?.watchers || []), ...(card?.watchers || [])]).includes(user._id);
|
|
}
|
|
module.exports = { canReceiveStoredNotification };
|