You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Lower-severity and needs-a-look items from the round 3 audit, grouped so they don't each need their own issue. Happy to split any out.
Backend
Magic-code request enumerates account existence on invite-only instances: an unregistered email returns 403 "invite only" while a registered one returns 200.
Notification MarkRead/Archive/Snooze return 404 for a not-yours row but 500 for a missing id, which leaks which notification UUIDs exist.
RequestEmailChange accepts any not-yet-registered address and emails a confirmation code to it, so an authed user can use the instance SMTP to send codes to arbitrary addresses (spam vector).
Per-IP rate limits collapse to one global bucket behind a reverse proxy (SetTrustedProxies(nil) means ClientIP() is the proxy IP), so users throttle each other on signin/magic-code/forgot-password.
user_recent_visits upsert is a read-then-write with no unique constraint, so concurrent visits to the same entity create duplicate rows.
ProjectService.ListByWorkspace uses context.Background() for one lookup instead of the request ctx (drops cancellation/deadline).
Recent-visit resolver returns an entity's title/identifier without a project-membership check, so a workspace member who holds a secret-project issue/page UUID can read its title back.
UnsplashSearch is the one instance-settings endpoint with no admin gate (any authed user can drive the stored Unsplash key/quota). Likely intended, worth a conscious call.
Favorite folders can be nested / form a parent cycle (only self-parent is blocked).
IssueViewService.Update can't clear a saved view's description back to empty (if description != ""), and RichFilters is never updatable.
Move-to-project leaves the issue with no state (unlike Create/importer, which fall back to the project default state).
Frontend
Epic progress bar stays stale after add/remove issue (optimistic issue mutation doesn't refresh the progress map). Candidate list also capped at 250.
NotificationsPage: fast selection marks a row read on the server while it still shows "New" locally; onMarkAllRead never clears explicitUnreadIds.
Several settings panels (ProjectEstimatesSettings, ModuleLinksSection, WebhooksSettings) re-fetch after a mutation with no cancelled guard (set-state-after-unmount).
StickyNoteCard onUpdate closure can capture a stale persistSticky if props change identity.
IssueAttachmentsPanel always renders size in KB (a 5MB file shows "5120KB").
Lower-severity and needs-a-look items from the round 3 audit, grouped so they don't each need their own issue. Happy to split any out.
Backend
RequestEmailChangeaccepts any not-yet-registered address and emails a confirmation code to it, so an authed user can use the instance SMTP to send codes to arbitrary addresses (spam vector).user_recent_visitsupsert is a read-then-write with no unique constraint, so concurrent visits to the same entity create duplicate rows.ProjectService.ListByWorkspaceusescontext.Background()for one lookup instead of the request ctx (drops cancellation/deadline).UnsplashSearchis the one instance-settings endpoint with no admin gate (any authed user can drive the stored Unsplash key/quota). Likely intended, worth a conscious call.IssueViewService.Updatecan't clear a saved view's description back to empty (if description != ""), andRichFiltersis never updatable.Frontend
onMarkAllReadnever clearsexplicitUnreadIds.onUpdateclosure can capture a stalepersistStickyif props change identity.