45 lines
1.8 KiB
C#
45 lines
1.8 KiB
C#
using System.Text.Json;
|
|
using LehrerApp.Sync;
|
|
|
|
namespace LehrerApp.Api;
|
|
|
|
/// <summary>
|
|
/// Stoppt veraltete Sync-Clients vor Authentifizierung und insbesondere vor jedem Store-Zugriff.
|
|
/// Die Prüfung gilt auch für Anhänge, Plain-Sync und Device-Pairing-Snapshots.
|
|
/// </summary>
|
|
public sealed class SyncProtocolVersionMiddleware(RequestDelegate next)
|
|
{
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
if (!IsProtectedSyncPath(context.Request.Path))
|
|
{
|
|
await next(context);
|
|
return;
|
|
}
|
|
|
|
context.Response.Headers[SyncProtocol.VersionHeaderName] = SyncProtocol.CurrentVersion;
|
|
var clientVersion = context.Request.Headers[SyncProtocol.VersionHeaderName].ToString();
|
|
if (string.Equals(clientVersion, SyncProtocol.CurrentVersion, StringComparison.Ordinal))
|
|
{
|
|
await next(context);
|
|
return;
|
|
}
|
|
|
|
context.Response.StatusCode = StatusCodes.Status426UpgradeRequired;
|
|
context.Response.ContentType = "application/problem+json";
|
|
await JsonSerializer.SerializeAsync(context.Response.Body, new
|
|
{
|
|
type = "https://lehrerapp.local/problems/sync-version-mismatch",
|
|
title = "Inkompatible Sync-Version",
|
|
status = StatusCodes.Status426UpgradeRequired,
|
|
detail = $"Der Server erwartet Sync-Version {SyncProtocol.CurrentVersion}.",
|
|
expectedVersion = SyncProtocol.CurrentVersion,
|
|
receivedVersion = string.IsNullOrEmpty(clientVersion) ? null : clientVersion,
|
|
});
|
|
}
|
|
|
|
private static bool IsProtectedSyncPath(PathString path) =>
|
|
path.StartsWithSegments("/api/sync", StringComparison.OrdinalIgnoreCase) ||
|
|
path.StartsWithSegments("/api/snapshot", StringComparison.OrdinalIgnoreCase);
|
|
}
|