fix: hardening pass — permissions, socket reconnect, canvas setup, arrangements

- Fix 403 on save for public collection viewers (return role in GET board response)
- Add read-only status indicator (StatusBar + StatusIndicator)
- Fix beforeunload save to use fetch+keepalive with auth header
- Socket reconnect now rejoins board room automatically
- Canvas setup uses polling instead of brittle 200ms timer
- Fix double user:left on disconnect (use disconnecting event, snapshot rooms)
- Thread + comment creation wrapped in db.transaction
- Prevent owner downgrade via addCollectionMember (check existing member)
- Bound redirect depth in downloadImage to 5
- Arrangement operations anchor to bounding box top-left (no drift)
- Distribute H/V also anchor to top-left
- Fix annotations fetch to use axios api instance (401 interceptor)
- Replace require() with static import in shortcut-definitions
This commit is contained in:
Hiren Kangad
2026-03-11 08:08:21 +05:30
parent fc2d9df741
commit 6518ed6763
13 changed files with 141 additions and 84 deletions
+4 -7
View File
@@ -5,6 +5,7 @@ const {
getThreadsByBoard,
getThread,
createThread,
createThreadWithComment,
updateThreadStatus,
deleteThread,
getCommentsByBoard,
@@ -82,19 +83,15 @@ router.post('/:boardId/threads', (req, res) => {
const commentId = uuidv4();
const userId = req.user.id;
const thread = createThread({
id: threadId,
const { thread, comment } = createThreadWithComment({
threadId,
boardId: req.params.boardId,
objectId: object_id,
anchorType: anchor_type || 'object',
pinX: pin_x,
pinY: pin_y,
createdBy: userId,
});
const comment = createComment({
id: commentId,
threadId,
commentId,
userId,
authorName: resolveAuthorName(req.user),
authorColor: null,