Fix crash rendering public boards as guest (null user isBoardAdmin) (#3897)

Viewing a public board as a guest (no logged-in user) threw
"Cannot read property 'isBoardAdmin' of null" from template helpers that called
ReactiveCache.getCurrentUser().isBoardAdmin() (and .isWorker()). The exception
aborted the Tracker afterFlush computation mid-render, so longer lists never
finished loading for guests.

A null/guest user is never a board admin or worker, so use optional chaining
(getCurrentUser()?.isBoardAdmin()) which yields a falsy value instead of throwing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lauri OjansivuandClaude Opus 4.8 committed 2026-06-21 21:36:04 +03:00
1 parent 931339ec5c
commit fc0fe0b613
9 files changed
+16 -16

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ Template.archivedBoards.onCreated(function () {
Template.archivedBoards.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
archivedBoards() {
+1 -1
View File
@@ -290,7 +290,7 @@ Template.attachmentGallery.helpers({
return filesCursor.each();
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
fileSize(size) {
const ret = filesize(size);
+1 -1
View File
@@ -1402,7 +1402,7 @@ Template.cardDetailsActionsPopup.helpers({
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
showListOnMinicard() {
+3 -3
View File
@@ -78,7 +78,7 @@ Template.subtasks.onCreated(function () {
Template.subtasks.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
toggleDeleteDialog() {
return Template.instance().toggleDeleteDialog;
@@ -115,7 +115,7 @@ Template.subtaskItemDetail.events({
Template.subtaskActionsPopup.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
});
@@ -155,6 +155,6 @@ Template.editSubtaskItemForm.helpers({
return ReactiveCache.getUser(this.userId);
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
});
+3 -3
View File
@@ -20,12 +20,12 @@ Template.listHeader.helpers({
(!list.getWipLimit('enabled') ||
list.getWipLimit('soft') ||
!Template.instance().reachedWipLimit()) &&
!ReactiveCache.getCurrentUser().isWorker()
!ReactiveCache.getCurrentUser()?.isWorker()
);
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
starred() {
@@ -218,7 +218,7 @@ Template.listHeader.events({
Template.listActionPopup.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
isWipLimitEnabled() {
+4 -4
View File
@@ -294,7 +294,7 @@ Template.memberPopup.helpers({
return ReactiveCache.getUser(this.userId);
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
memberType() {
const type = ReactiveCache.getUser(this.userId).isBoardAdmin() ? 'admin' : 'normal';
@@ -433,7 +433,7 @@ Template.boardMenuPopup.onCreated(function() {
Template.boardMenuPopup.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
withApi() {
return Template.instance().apiEnabled.get();
@@ -547,7 +547,7 @@ Template.membersWidget.helpers({
}
},
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
AtLeastOneOrgWasCreated(){
let orgs = ReactiveCache.getOrgs({}, {sort: { createdAt: -1 }});
@@ -919,7 +919,7 @@ Template.labelsWidget.events({
Template.labelsWidget.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
});
+1 -1
View File
@@ -215,7 +215,7 @@ function mapSelection(kind, _id) {
Template.multiselectionSidebar.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
isCommentOnly() {
return ReactiveCache.getCurrentUser().isCommentOnly();
@@ -41,7 +41,7 @@ Template.swimlaneHeader.events({
Template.swimlaneFixedHeader.helpers({
isBoardAdmin() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
collapseSwimlane() {
const swimlane = Template.currentData();
+1 -1
View File
@@ -635,7 +635,7 @@ function initializeSwimlaneResize(tpl, retryCount = 0) {
Template.swimlane.helpers({
canSeeAddList() {
return ReactiveCache.getCurrentUser().isBoardAdmin();
return ReactiveCache.getCurrentUser()?.isBoardAdmin();
},
lists() {
const swimlane = this;