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
A principal review of the codebase covering performance bottlenecks, architectural drift / duplication, and security vulnerabilities. This is an Avalonia desktop + Android app using raw SQLite and an embedded Kestrel/SignalR sync host.
P0 — Critical
Sync SQLite rewrite on every mutation — IncidentRepository.Save() does DELETE-all then INSERT-all across 15 tables synchronously on the UI thread (src/LageBuch.Persistence/IncidentRepository.cs:13, src/LageBuch.AppLogic/LocalIncidentSession.cs:256). Make async and/or diff-based.
No TLS on sync channel — Kestrel host listens on plain HTTP, IPAddress.Any, port 5859 (src/LageBuch.Sync.Hosting/IncidentHost.cs:50, src/LageBuch.App/Services/IncidentHostController.cs:45). PIN + all incident data travel unencrypted.
4-digit PIN with no rate limiting — 10,000 combinations, no backoff/lockout (IncidentHost.cs:60, IncidentHostController.cs:41). Brute-forceable.
P1 — High
File upload sync on UI thread — IncidentFileStore.SaveBytes + Save sync, called from LocalIncidentSession.AddFileAsync which returns Task.CompletedTask while doing sync work (IncidentFileStore.cs:29, LocalIncidentSession.cs:187).
Full byte arrays in memory for sync file transfer — 25 MB file → base64 in JSON, all in memory, no streaming (src/LageBuch.Sync/RemoteIncidentSession.cs:221).
PdfAttachmentMerger holds all PDFs in memory as byte[] then temp-files them (src/LageBuch.Documents/PdfAttachmentMerger.cs:17). Use Stream-based merging.
MIME type mapping duplicated 3× with inconsistent defaults — ContentTypeFor (upper, octet-stream) vs MimeTypeOf (lower, */*) (FilesViewModel.cs:157, AndroidFileDialogService.cs:176). Extract shared helper.
Missing CancellationToken on async methods — only RemoteIncidentSession.ConnectAsync/SendAsync take tokens.
Self-asserted client identity — operator name rides on every SyncCommand, no server-side verification beyond PIN (SessionOperator.cs, SyncCommand.cs). Document as design decision.
P2 — Medium
LocalIncidentSession / RemoteIncidentSession lockstep — ~25 parallel delegation methods, no generation/shared base (LocalIncidentSession.cs:120, RemoteIncidentSession.cs:153).
DispatcherTimerTicker._subscribers not thread-safe — unsynchronized List<Action> (DispatcherTimerTicker.cs).
Unbounded file cache on remote client — no eviction/size limit (RemoteIncidentSession.cs:239).
JsonRecentFilesStore / JsonLastSaveFolderStore read disk every call — no cache (JsonRecentFilesStore.cs, JsonLastSaveFolderStore.cs).
SystemAlarmService preloads all WAVs, never cleans temp files (SystemAlarmService.cs:35,93).
File.ReadAllBytes before size check — OOM risk on oversized files (FilesViewModel.cs:112).
IncidentWorkspaceViewModel.BuildChildren full rebuild (IncidentWorkspaceViewModel.cs:218).
P3 — Low
Explicit .DisableCors() on sync endpoints for defense-in-depth (IncidentHost.cs).
MemoryStream.ToArray() extra copy (SystemAlarmMerger.cs:117).
Architecture / Security / Performance Audit — Prioritized Findings
A principal review of the codebase covering performance bottlenecks, architectural drift / duplication, and security vulnerabilities. This is an Avalonia desktop + Android app using raw SQLite and an embedded Kestrel/SignalR sync host.
P0 — Critical
IncidentRepository.Save()does DELETE-all then INSERT-all across 15 tables synchronously on the UI thread (src/LageBuch.Persistence/IncidentRepository.cs:13,src/LageBuch.AppLogic/LocalIncidentSession.cs:256). Make async and/or diff-based.IPAddress.Any, port 5859 (src/LageBuch.Sync.Hosting/IncidentHost.cs:50,src/LageBuch.App/Services/IncidentHostController.cs:45). PIN + all incident data travel unencrypted.IncidentHost.cs:60,IncidentHostController.cs:41). Brute-forceable.P1 — High
IncidentFileStore.SaveBytes+Savesync, called fromLocalIncidentSession.AddFileAsyncwhich returnsTask.CompletedTaskwhile doing sync work (IncidentFileStore.cs:29,LocalIncidentSession.cs:187).src/LageBuch.Sync/RemoteIncidentSession.cs:221).PdfAttachmentMergerholds all PDFs in memory as byte[] then temp-files them (src/LageBuch.Documents/PdfAttachmentMerger.cs:17). Use Stream-based merging.ContentTypeFor(upper,octet-stream) vsMimeTypeOf(lower,*/*) (FilesViewModel.cs:157,AndroidFileDialogService.cs:176). Extract shared helper.LinksViewModel.cs:42,AboutViewModel.cs:53, both platformIFileDialogService(StorageProviderFileDialogService.cs:130,AndroidFileDialogService.cs:165).CancellationTokenon async methods — onlyRemoteIncidentSession.ConnectAsync/SendAsynctake tokens.SyncCommand, no server-side verification beyond PIN (SessionOperator.cs,SyncCommand.cs). Document as design decision.P2 — Medium
LocalIncidentSession/RemoteIncidentSessionlockstep — ~25 parallel delegation methods, no generation/shared base (LocalIncidentSession.cs:120,RemoteIncidentSession.cs:153).DispatcherTimerTicker._subscribersnot thread-safe — unsynchronizedList<Action>(DispatcherTimerTicker.cs).RemoteIncidentSession.cs:239).JsonRecentFilesStore/JsonLastSaveFolderStoreread disk every call — no cache (JsonRecentFilesStore.cs,JsonLastSaveFolderStore.cs).SystemAlarmServicepreloads all WAVs, never cleans temp files (SystemAlarmService.cs:35,93).File.ReadAllBytesbefore size check — OOM risk on oversized files (FilesViewModel.cs:112).IncidentWorkspaceViewModel.BuildChildrenfull rebuild (IncidentWorkspaceViewModel.cs:218).P3 — Low
.DisableCors()on sync endpoints for defense-in-depth (IncidentHost.cs).MemoryStream.ToArray()extra copy (SystemAlarmMerger.cs:117).Positives (no action)
file://,javascript:,ftp://.