diff --git a/Server/Endpoints/AuthEndpoints.cs b/Server/Endpoints/AuthEndpoints.cs index 2a1efa4..63ac4ff 100644 --- a/Server/Endpoints/AuthEndpoints.cs +++ b/Server/Endpoints/AuthEndpoints.cs @@ -18,7 +18,7 @@ public static class AuthEndpoints { var group = routes.MapGroup("/api/auth"); - group.MapPost("/register", async (RegisterRequest req, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, IConfiguration configuration, HttpClient httpClient) => + group.MapPost("/register", async (RegisterRequest req, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, IConfiguration configuration, HttpClient httpClient, IServiceProvider serviceProvider) => { if (string.IsNullOrWhiteSpace(req.Username) || string.IsNullOrWhiteSpace(req.Password) || string.IsNullOrWhiteSpace(req.EncryptedKey)) { @@ -45,9 +45,11 @@ public static class AuthEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); - await SyncEndpoints.BroadcastUserChangeAsync(user.Username, scopeDb, peerCache, rsaKeyManager, configuration, httpClient); + var scopeRsa = scope.ServiceProvider.GetRequiredService(); + var scopeConfig = scope.ServiceProvider.GetRequiredService(); + await SyncEndpoints.BroadcastUserChangeAsync(user.Username, scopeDb, peerCache, scopeRsa, scopeConfig, httpClient); } catch (Exception ex) { @@ -58,7 +60,7 @@ public static class AuthEndpoints return Results.Ok(new { message = "Registration successful." }); }); - group.MapPost("/change-password", async (ChangePasswordRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, RsaKeyManager rsaKeyManager, IConfiguration configuration, HttpClient httpClient) => + group.MapPost("/change-password", async (ChangePasswordRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, RsaKeyManager rsaKeyManager, IConfiguration configuration, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -88,9 +90,11 @@ public static class AuthEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); - await SyncEndpoints.BroadcastUserChangeAsync(user.Username, scopeDb, peerCache, rsaKeyManager, configuration, httpClient); + var scopeRsa = scope.ServiceProvider.GetRequiredService(); + var scopeConfig = scope.ServiceProvider.GetRequiredService(); + await SyncEndpoints.BroadcastUserChangeAsync(user.Username, scopeDb, peerCache, scopeRsa, scopeConfig, httpClient); } catch (Exception ex) { diff --git a/Server/Endpoints/NodeEndpoints.cs b/Server/Endpoints/NodeEndpoints.cs index 7daf8c5..1c2fdd3 100644 --- a/Server/Endpoints/NodeEndpoints.cs +++ b/Server/Endpoints/NodeEndpoints.cs @@ -131,7 +131,7 @@ public static class NodeEndpoints }); // POST create new node (folder/note) - group.MapPost("/", async (CreateNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapPost("/", async (CreateNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -188,7 +188,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); @@ -206,7 +206,7 @@ public static class NodeEndpoints }); // PUT update node (rename/edit content) - group.MapPut("/{uuid}", async (string uuid, UpdateNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapPut("/{uuid}", async (string uuid, UpdateNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -266,7 +266,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); @@ -282,7 +282,7 @@ public static class NodeEndpoints }); // DELETE a node (soft delete) - group.MapDelete("/{uuid}", async (string uuid, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapDelete("/{uuid}", async (string uuid, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -306,7 +306,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); @@ -338,7 +338,7 @@ public static class NodeEndpoints }); // PUT update ACL entries - group.MapPut("/{uuid}/acl", async (string uuid, List aclReqs, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapPut("/{uuid}/acl", async (string uuid, List aclReqs, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -435,7 +435,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); @@ -451,7 +451,7 @@ public static class NodeEndpoints }); // POST Share a Node (generates k0 encrypted by k1 and saves in PendingShare) - group.MapPost("/share", async (ShareNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapPost("/share", async (ShareNodeRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -522,7 +522,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); @@ -538,7 +538,7 @@ public static class NodeEndpoints }); // POST Accept a Share (decrypts E_k1(k0) using k1 and re-encrypts using recipient's masterKey) - group.MapPost("/accept-share", async (AcceptShareRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient) => + group.MapPost("/accept-share", async (AcceptShareRequest req, HttpContext context, ServerDbContext db, CertificateManager certManager, PeerCache peerCache, HttpClient httpClient, IServiceProvider serviceProvider) => { var username = AuthHelper.GetAuthenticatedUser(context, certManager); if (string.IsNullOrEmpty(username)) return Results.Unauthorized(); @@ -609,7 +609,7 @@ public static class NodeEndpoints { try { - using var scope = context.RequestServices.CreateScope(); + using var scope = serviceProvider.CreateScope(); var scopeDb = scope.ServiceProvider.GetRequiredService(); var rsaKeyManager = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); diff --git a/Server/Endpoints/SyncEndpoints.cs b/Server/Endpoints/SyncEndpoints.cs index a80f898..ebef7d9 100644 --- a/Server/Endpoints/SyncEndpoints.cs +++ b/Server/Endpoints/SyncEndpoints.cs @@ -211,7 +211,7 @@ public static class SyncEndpoints }); // 5. Receive broadcast of changes (broadcasts single node updates) - routes.MapPost("/api/sync/broadcast", async (SyncPushItem item, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, HttpClient httpClient) => + routes.MapPost("/api/sync/broadcast", async (SyncPushItem item, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, HttpClient httpClient, IServiceProvider serviceProvider) => { if (!AuthHelper.IsServerTokenValid(context, peerCache)) { @@ -273,13 +273,21 @@ public static class SyncEndpoints { await db.SaveChangesAsync(); - // Relay broadcast to all peers (upstream + downstream) with loop prevention! if (!string.IsNullOrEmpty(broadcastId)) { _ = Task.Run(async () => { - var configuration = context.RequestServices.GetRequiredService(); - await BroadcastNodeChangeAsync(item.Node.Uuid, db, peerCache, rsaKeyManager, configuration, httpClient, broadcastId); + try + { + using var scope = serviceProvider.CreateScope(); + var backgroundDb = scope.ServiceProvider.GetRequiredService(); + var backgroundConfig = scope.ServiceProvider.GetRequiredService(); + await BroadcastNodeChangeAsync(item.Node.Uuid, backgroundDb, peerCache, rsaKeyManager, backgroundConfig, httpClient, broadcastId); + } + catch (Exception ex) + { + Console.WriteLine($"Error during background BroadcastNodeChangeAsync: {ex.Message}"); + } }); } } @@ -288,7 +296,7 @@ public static class SyncEndpoints }); // Receive broadcast of user registration or password updates - routes.MapPost("/api/sync/broadcast-user", async (UserBroadcastPayload payload, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, HttpClient httpClient) => + routes.MapPost("/api/sync/broadcast-user", async (UserBroadcastPayload payload, HttpContext context, ServerDbContext db, PeerCache peerCache, RsaKeyManager rsaKeyManager, HttpClient httpClient, IServiceProvider serviceProvider) => { if (!AuthHelper.IsServerTokenValid(context, peerCache)) { @@ -326,13 +334,21 @@ public static class SyncEndpoints { await db.SaveChangesAsync(); - // Relay the user broadcast to other peers if (!string.IsNullOrEmpty(broadcastId)) { _ = Task.Run(async () => { - var configuration = context.RequestServices.GetRequiredService(); - await BroadcastUserChangeAsync(payload.User.Username, db, peerCache, rsaKeyManager, configuration, httpClient, broadcastId); + try + { + using var scope = serviceProvider.CreateScope(); + var backgroundDb = scope.ServiceProvider.GetRequiredService(); + var backgroundConfig = scope.ServiceProvider.GetRequiredService(); + await BroadcastUserChangeAsync(payload.User.Username, backgroundDb, peerCache, rsaKeyManager, backgroundConfig, httpClient, broadcastId); + } + catch (Exception ex) + { + Console.WriteLine($"Error during background BroadcastUserChangeAsync: {ex.Message}"); + } }); } }