feat: sync guard - Blockieren alter Clients beim sync

This commit is contained in:
2026-08-20 23:54:04 +02:00
parent 7b883555bf
commit 59bd8abb45
19 changed files with 369 additions and 26 deletions
+11 -1
View File
@@ -55,6 +55,12 @@ public class EventApplier(LiteDbContext db, byte[] syncKey, HttpClient? http = n
versions?.SetKnownServerSeq(evt.EntityType, evt.EntityId, evt.SequenceNr);
logger?.Info($"Sync: Ereignis angewendet - {evt.EntityType} {evt.Operation} EntityId={evt.EntityId}");
}
catch (SyncProtocolMismatchException)
{
// Anders als ein einzelnes korruptes Ereignis betrifft dies den gesamten Batch. Der
// Pull-Cursor darf nicht vorrücken, solange Client und Server inkompatibel sind.
throw;
}
catch (LiteException ex)
{
// Harte Constraint-Verletzung (z.B. Unique-Index) - dieses eine Ereignis
@@ -86,7 +92,11 @@ public class EventApplier(LiteDbContext db, byte[] syncKey, HttpClient? http = n
foreach (var attachment in entity.Attachments)
{
if (db.Attachments.Exists(attachment.StorageId)) continue;
var resp = await http!.GetAsync($"/api/sync/attachments/{attachment.StorageId}");
using var request = SyncProtocol.CreateRequest(HttpMethod.Get,
$"/api/sync/attachments/{attachment.StorageId}");
using var resp = await http!.SendAsync(request);
if (resp.StatusCode == System.Net.HttpStatusCode.UpgradeRequired)
await SyncProtocol.EnsureCompatibleSuccessAsync(resp);
if (!resp.IsSuccessStatusCode) continue;
var encrypted = await resp.Content.ReadAsByteArrayAsync();
var decrypted = SyncCrypto.Decrypt(encrypted, syncKey);