diff --git a/apps/server/AliasVault.Admin/Middleware/AntiforgeryTokenMiddleware.cs b/apps/server/AliasVault.Admin/Middleware/AntiforgeryTokenMiddleware.cs index 87616f286..efeb3b0b4 100644 --- a/apps/server/AliasVault.Admin/Middleware/AntiforgeryTokenMiddleware.cs +++ b/apps/server/AliasVault.Admin/Middleware/AntiforgeryTokenMiddleware.cs @@ -73,12 +73,12 @@ public class AntiforgeryTokenMiddleware protector.Unprotect(bytes); } } - catch (CryptographicException ex) + catch (CryptographicException) { - _logger.LogWarning( - "Invalid antiforgery cookie detected (cannot decrypt). Clearing cookies and redirecting. Path: {Path}, Error: {Error}", - context.Request.Path, - ex.Message); + // Expected after server restart with old cookies + _logger.LogDebug( + "Stale antiforgery cookie detected (key not in ring). Clearing cookies and redirecting. Path: {Path}", + context.Request.Path); ClearCookiesAndRedirect(context); return; @@ -86,7 +86,7 @@ public class AntiforgeryTokenMiddleware catch (FormatException) { // Cookie value is not valid base64, clear it - _logger.LogWarning( + _logger.LogDebug( "Invalid antiforgery cookie format detected. Clearing cookies and redirecting. Path: {Path}", context.Request.Path); @@ -95,10 +95,10 @@ public class AntiforgeryTokenMiddleware } catch (Exception ex) { - // Any other exception during decryption, clear cookies + // Unexpected exception during decryption _logger.LogWarning( ex, - "Error validating antiforgery cookie. Clearing cookies and redirecting. Path: {Path}", + "Unexpected error validating antiforgery cookie. Clearing cookies and redirecting. Path: {Path}", context.Request.Path); ClearCookiesAndRedirect(context); diff --git a/apps/server/Databases/AliasServerDb/Configuration/DatabaseConfiguration.cs b/apps/server/Databases/AliasServerDb/Configuration/DatabaseConfiguration.cs index 3ca68d72f..7e1c81e1b 100644 --- a/apps/server/Databases/AliasServerDb/Configuration/DatabaseConfiguration.cs +++ b/apps/server/Databases/AliasServerDb/Configuration/DatabaseConfiguration.cs @@ -92,7 +92,41 @@ public static class DatabaseConfiguration try { - // Check if database is accessible and all migrations are applied + // First check if database is accessible + var canConnect = await context.Database.CanConnectAsync(); + if (!canConnect) + { + logger?.LogInformation( + "Database not yet accessible. Attempt {Attempt}. Waiting {Interval}ms...", + attempt, + checkIntervalMs); + await Task.Delay(checkIntervalMs); + continue; + } + + // Check if migrations history table exists to avoid PostgreSQL logging errors + var connection = context.Database.GetDbConnection(); + await using var command = connection.CreateCommand(); + command.CommandText = "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = '__EFMigrationsHistory')"; + + if (connection.State != System.Data.ConnectionState.Open) + { + await connection.OpenAsync(); + } + + var tableExists = (bool)(await command.ExecuteScalarAsync() ?? false); + + if (!tableExists) + { + logger?.LogInformation( + "Database accessible but migrations not yet started. Attempt {Attempt}. Waiting {Interval}ms...", + attempt, + checkIntervalMs); + await Task.Delay(checkIntervalMs); + continue; + } + + // Now safe to check pending migrations without PostgreSQL logging errors var pendingMigrations = await context.Database.GetPendingMigrationsAsync(); if (!pendingMigrations.Any()) { @@ -109,7 +143,7 @@ public static class DatabaseConfiguration { logger?.LogWarning( ex, - "Database not yet accessible. Attempt {Attempt}. Waiting {Interval}ms before retry...", + "Error checking database status. Attempt {Attempt}. Waiting {Interval}ms before retry...", attempt, checkIntervalMs); }