diff --git a/Common/Phantom.Common.Messages.Web/ToController/LogInMessage.cs b/Common/Phantom.Common.Messages.Web/ToController/LogInMessage.cs
index d3722d1..e03a4ea 100644
--- a/Common/Phantom.Common.Messages.Web/ToController/LogInMessage.cs
+++ b/Common/Phantom.Common.Messages.Web/ToController/LogInMessage.cs
@@ -1,4 +1,5 @@
 using MemoryPack;
+using Phantom.Common.Data;
 using Phantom.Common.Data.Web.Users;
 using Phantom.Utils.Actor;
 
@@ -8,4 +9,4 @@ namespace Phantom.Common.Messages.Web.ToController;
 public sealed partial record LogInMessage(
 	[property: MemoryPackOrder(0)] string Username,
 	[property: MemoryPackOrder(1)] string Password
-) : IMessageToController, ICanReply<LogInSuccess?>;
+) : IMessageToController, ICanReply<Optional<LogInSuccess>>;
diff --git a/Common/Phantom.Common.Messages.Web/WebMessageRegistries.cs b/Common/Phantom.Common.Messages.Web/WebMessageRegistries.cs
index e146230..0a1b9c7 100644
--- a/Common/Phantom.Common.Messages.Web/WebMessageRegistries.cs
+++ b/Common/Phantom.Common.Messages.Web/WebMessageRegistries.cs
@@ -24,7 +24,7 @@ public static class WebMessageRegistries {
 	static WebMessageRegistries() {
 		ToController.Add<RegisterWebMessage>(0);
 		ToController.Add<UnregisterWebMessage>(1);
-		ToController.Add<LogInMessage, LogInSuccess?>(2);
+		ToController.Add<LogInMessage, Optional<LogInSuccess>>(2);
 		ToController.Add<LogOutMessage>(3);
 		ToController.Add<GetAuthenticatedUser, Optional<AuthenticatedUserInfo>>(4);
 		ToController.Add<CreateOrUpdateAdministratorUserMessage, CreateOrUpdateAdministratorUserResult>(5);
diff --git a/Controller/Phantom.Controller.Services/Rpc/WebMessageHandlerActor.cs b/Controller/Phantom.Controller.Services/Rpc/WebMessageHandlerActor.cs
index 091671a..dbb1f9c 100644
--- a/Controller/Phantom.Controller.Services/Rpc/WebMessageHandlerActor.cs
+++ b/Controller/Phantom.Controller.Services/Rpc/WebMessageHandlerActor.cs
@@ -71,7 +71,7 @@ sealed class WebMessageHandlerActor : ReceiveActor<IMessageToController> {
 
 		ReceiveAsync<RegisterWebMessage>(HandleRegisterWeb);
 		Receive<UnregisterWebMessage>(HandleUnregisterWeb);
-		ReceiveAndReplyLater<LogInMessage, LogInSuccess?>(HandleLogIn);
+		ReceiveAndReplyLater<LogInMessage, Optional<LogInSuccess>>(HandleLogIn);
 		Receive<LogOutMessage>(HandleLogOut);
 		ReceiveAndReply<GetAuthenticatedUser, Optional<AuthenticatedUserInfo>>(GetAuthenticatedUser);
 		ReceiveAndReplyLater<CreateOrUpdateAdministratorUserMessage, CreateOrUpdateAdministratorUserResult>(HandleCreateOrUpdateAdministratorUser);
@@ -100,7 +100,7 @@ sealed class WebMessageHandlerActor : ReceiveActor<IMessageToController> {
 		connection.Close();
 	}
 
-	private Task<LogInSuccess?> HandleLogIn(LogInMessage message) {
+	private Task<Optional<LogInSuccess>> HandleLogIn(LogInMessage message) {
 		return userLoginManager.LogIn(message.Username, message.Password);
 	}
 
diff --git a/Controller/Phantom.Controller.Services/Users/Sessions/UserLoginManager.cs b/Controller/Phantom.Controller.Services/Users/Sessions/UserLoginManager.cs
index aa3157a..84f9bb3 100644
--- a/Controller/Phantom.Controller.Services/Users/Sessions/UserLoginManager.cs
+++ b/Controller/Phantom.Controller.Services/Users/Sessions/UserLoginManager.cs
@@ -1,5 +1,6 @@
 using System.Collections.Immutable;
 using System.Security.Cryptography;
+using Phantom.Common.Data;
 using Phantom.Common.Data.Web.Users;
 using Phantom.Controller.Database;
 using Phantom.Controller.Database.Repositories;
@@ -29,7 +30,7 @@ sealed class UserLoginManager {
 		return sessionBuckets[token[0]];
 	}
 
-	public async Task<LogInSuccess?> LogIn(string username, string password) {
+	public async Task<Optional<LogInSuccess>> LogIn(string username, string password) {
 		Guid userGuid;
 		AuthenticatedUserInfo? authenticatedUserInfo;
 		
@@ -38,12 +39,12 @@ sealed class UserLoginManager {
 
 			var user = await userRepository.GetByName(username);
 			if (user == null || !UserPasswords.Verify(password, user.PasswordHash)) {
-				return null;
+				return default;
 			}
 
 			authenticatedUserInfo = await authenticatedUserCache.Update(user, db);
 			if (authenticatedUserInfo == null) {
-				return null;
+				return default;
 			}
 
 			userGuid = user.UserGuid;
diff --git a/Web/Phantom.Web.Services/Authentication/UserLoginManager.cs b/Web/Phantom.Web.Services/Authentication/UserLoginManager.cs
index b92866b..e7474ac 100644
--- a/Web/Phantom.Web.Services/Authentication/UserLoginManager.cs
+++ b/Web/Phantom.Web.Services/Authentication/UserLoginManager.cs
@@ -1,4 +1,5 @@
-using Phantom.Common.Data.Web.Users;
+using Phantom.Common.Data;
+using Phantom.Common.Data.Web.Users;
 using Phantom.Common.Messages.Web.ToController;
 using Phantom.Utils.Logging;
 using Phantom.Web.Services.Rpc;
@@ -22,23 +23,20 @@ public sealed class UserLoginManager {
 	}
 
 	public async Task<bool> LogIn(string username, string password, string? returnUrl = null) {
-		LogInSuccess? success;
+		Optional<LogInSuccess> result;
 		try {
-			success = await controllerConnection.Send<LogInMessage, LogInSuccess?>(new LogInMessage(username, password), TimeSpan.FromSeconds(30));
+			result = await controllerConnection.Send<LogInMessage, Optional<LogInSuccess>>(new LogInMessage(username, password), TimeSpan.FromSeconds(30));
 		} catch (Exception e) {
 			Logger.Error(e, "Could not log in {Username}.", username);
 			return false;
 		}
 
-		if (success == null) {
+		if (result.Value is not var (userInfo, authToken)) {
 			return false;
 		}
 
 		Logger.Information("Successfully logged in {Username}.", username);
 
-		var userInfo = success.UserInfo;
-		var authToken = success.AuthToken;
-		
 		authenticationStateProvider.SetUnloadedSession();
 		await sessionBrowserStorage.Store(userInfo.Guid, authToken);
 		await authenticationStateProvider.GetAuthenticationStateAsync();