mirror of
https://github.com/wekan/wekan.git
synced 2026-01-17 23:15:28 +01:00
Fix New Board Permissions: NormalAssignedOnly, CommentAssignedOnly, ReadOnly, ReadAssignedOnly. Part 1.
Thanks to nazim-oss and xet7 ! Related #6060
This commit is contained in:
parent
2f59e42024
commit
eabb6a239d
25 changed files with 562 additions and 291 deletions
|
|
@ -20,6 +20,17 @@ allowIsBoardMemberNoComments = function(userId, board) {
|
|||
return board && board.hasMember(userId) && !board.hasNoComments(userId);
|
||||
};
|
||||
|
||||
// Check if user has write access to board (can create/edit cards and lists)
|
||||
allowIsBoardMemberWithWriteAccess = function(userId, board) {
|
||||
return board && board.members && board.members.some(e => e.userId === userId && e.isActive && !e.isNoComments && !e.isCommentOnly && !e.isWorker && !e.isReadOnly && !e.isReadAssignedOnly);
|
||||
};
|
||||
|
||||
// Check if user has write access via a card's board
|
||||
allowIsBoardMemberWithWriteAccessByCard = function(userId, card) {
|
||||
const board = card && card.board && card.board();
|
||||
return allowIsBoardMemberWithWriteAccess(userId, board);
|
||||
};
|
||||
|
||||
allowIsBoardMemberByCard = function(userId, card) {
|
||||
const board = card.board();
|
||||
return board && board.hasMember(userId);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,28 @@ Meteor.publish('activities', function(kind, id, limit, showActivities) {
|
|||
return this.ready();
|
||||
}
|
||||
|
||||
// Check user permissions - only BoardAdmin can view activities
|
||||
if (this.userId) {
|
||||
const user = ReactiveCache.getUser(this.userId);
|
||||
const board = ReactiveCache.getBoard(id);
|
||||
|
||||
if (user && board) {
|
||||
// Find user membership in board
|
||||
const membership = board.members.find(m => m.userId === this.userId);
|
||||
|
||||
// Only BoardAdmin can view activities
|
||||
if (!membership || !membership.isAdmin) {
|
||||
return this.ready();
|
||||
}
|
||||
} else {
|
||||
// If board or user not found, deny
|
||||
return this.ready();
|
||||
}
|
||||
} else {
|
||||
// If not logged in, deny
|
||||
return this.ready();
|
||||
}
|
||||
|
||||
// Get linkedBoard
|
||||
let linkedElmtId = [id];
|
||||
if (kind == 'board') {
|
||||
|
|
|
|||
|
|
@ -296,14 +296,23 @@ Meteor.publishRelations('board', function(boardId, isArchived) {
|
|||
const linkedBoardCards = this.join(Cards);
|
||||
linkedBoardCards.selector = _ids => ({ boardId: _ids });
|
||||
|
||||
// Build card selector based on user's permissions
|
||||
const cardSelector = {
|
||||
boardId: { $in: [boardId, board.subtasksDefaultBoardId] },
|
||||
archived: isArchived,
|
||||
};
|
||||
|
||||
// Check if current user has assigned-only permissions
|
||||
if (thisUserId && board.members) {
|
||||
const member = _.findWhere(board.members, { userId: thisUserId, isActive: true });
|
||||
if (member && (member.isNormalAssignedOnly || member.isCommentAssignedOnly || member.isReadAssignedOnly)) {
|
||||
// User with assigned-only permissions should only see cards assigned to them
|
||||
cardSelector.assignees = { $in: [thisUserId] };
|
||||
}
|
||||
}
|
||||
|
||||
this.cursor(
|
||||
ReactiveCache.getCards({
|
||||
boardId: { $in: [boardId, board.subtasksDefaultBoardId] },
|
||||
archived: isArchived,
|
||||
},
|
||||
{},
|
||||
true,
|
||||
),
|
||||
ReactiveCache.getCards(cardSelector, {}, true),
|
||||
function(cardId, card) {
|
||||
if (card.type === 'cardType-linkedCard') {
|
||||
const impCardId = card.linkedId;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,24 @@ import Team from "../../models/team";
|
|||
|
||||
Meteor.publish('card', cardId => {
|
||||
check(cardId, String);
|
||||
|
||||
const userId = Meteor.userId();
|
||||
const card = ReactiveCache.getCard({ _id: cardId });
|
||||
|
||||
// If user has assigned-only permissions, check if they're assigned to this card
|
||||
if (userId && card && card.boardId) {
|
||||
const board = ReactiveCache.getBoard({ _id: card.boardId });
|
||||
if (board && board.members) {
|
||||
const member = _.findWhere(board.members, { userId: userId, isActive: true });
|
||||
if (member && (member.isNormalAssignedOnly || member.isCommentAssignedOnly || member.isReadAssignedOnly)) {
|
||||
// User with assigned-only permissions can only view cards assigned to them
|
||||
if (!card.assignees || !card.assignees.includes(userId)) {
|
||||
return []; // Don't publish if user is not assigned
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ret = ReactiveCache.getCards(
|
||||
{ _id: cardId },
|
||||
{},
|
||||
|
|
@ -88,6 +106,24 @@ Meteor.publish('card', cardId => {
|
|||
*/
|
||||
Meteor.publishRelations('popupCardData', function(cardId) {
|
||||
check(cardId, String);
|
||||
|
||||
const userId = this.userId;
|
||||
const card = ReactiveCache.getCard({ _id: cardId });
|
||||
|
||||
// If user has assigned-only permissions, check if they're assigned to this card
|
||||
if (userId && card && card.boardId) {
|
||||
const board = ReactiveCache.getBoard({ _id: card.boardId });
|
||||
if (board && board.members) {
|
||||
const member = _.findWhere(board.members, { userId: userId, isActive: true });
|
||||
if (member && (member.isNormalAssignedOnly || member.isCommentAssignedOnly || member.isReadAssignedOnly)) {
|
||||
// User with assigned-only permissions can only view cards assigned to them
|
||||
if (!card.assignees || !card.assignees.includes(userId)) {
|
||||
return this.ready(); // Don't publish if user is not assigned
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.cursor(
|
||||
ReactiveCache.getCards(
|
||||
{ _id: cardId },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue