Support verification via clicking link from e-mail

This commit is contained in:
Bartłomiej Dach 2024-01-24 21:33:34 +01:00
parent 62a0c236bc
commit e3eb7a8b42
No known key found for this signature in database
5 changed files with 57 additions and 1 deletions

View File

@ -11,8 +11,10 @@ using System.Net.Http;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ExceptionExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
@ -76,6 +78,11 @@ namespace osu.Game.Online.API
private readonly Logger log;
private string webSocketEndpointUrl;
[CanBeNull]
private OsuClientWebSocket webSocket;
public APIAccess(OsuGameBase game, OsuConfigManager config, EndpointConfiguration endpointConfiguration, string versionHash)
{
this.game = game;
@ -84,6 +91,7 @@ namespace osu.Game.Online.API
APIEndpointUrl = endpointConfiguration.APIEndpointUrl;
WebsiteRootUrl = endpointConfiguration.WebsiteRootUrl;
webSocketEndpointUrl = endpointConfiguration.NotificationsWebSocketEndpointUrl;
authentication = new OAuth(endpointConfiguration.APIClientID, endpointConfiguration.APIClientSecret, APIEndpointUrl);
log = Logger.GetLogger(LoggingTarget.Network);
@ -267,7 +275,10 @@ namespace osu.Game.Online.API
setLocalUser(me);
state.Value = me.SessionVerified ? APIState.Online : APIState.RequiresSecondFactorAuth;
if (me.SessionVerified)
state.Value = APIState.Online;
else
setUpSecondFactorAuthentication();
failureCount = 0;
};
@ -350,6 +361,42 @@ namespace osu.Game.Online.API
this.password = password;
}
private void setUpSecondFactorAuthentication()
{
if (state.Value == APIState.RequiresSecondFactorAuth)
return;
state.Value = APIState.RequiresSecondFactorAuth;
try
{
webSocket?.DisposeAsync().AsTask().WaitSafely();
var newSocket = new OsuClientWebSocket(this, webSocketEndpointUrl);
newSocket.MessageReceived += async msg =>
{
if (msg.Event == @"verified")
{
state.Value = APIState.Online;
await newSocket.DisposeAsync().ConfigureAwait(false);
if (webSocket == newSocket)
webSocket = null;
}
};
newSocket.Closed += ex =>
{
Logger.Error(ex, "Connection with account verification endpoint closed unexpectedly. Please supply account verification code manually.", LoggingTarget.Network);
return Task.CompletedTask;
};
webSocket = newSocket;
webSocket.ConnectAsync(cancellationToken.Token).WaitSafely();
}
catch (Exception ex)
{
Logger.Error(ex, "Failed to set up connection with account verification endpoint. Please supply account verification code manually.", LoggingTarget.Network);
}
}
public void AuthenticateSecondFactor(string code)
{
Debug.Assert(State.Value == APIState.RequiresSecondFactorAuth);
@ -579,6 +626,7 @@ namespace osu.Game.Online.API
flushQueue();
cancellationToken.Cancel();
webSocket?.DisposeAsync().AsTask().WaitSafely();
}
}

View File

@ -13,6 +13,7 @@ namespace osu.Game.Online
SpectatorEndpointUrl = $@"{APIEndpointUrl}/signalr/spectator";
MultiplayerEndpointUrl = $@"{APIEndpointUrl}/signalr/multiplayer";
MetadataEndpointUrl = $@"{APIEndpointUrl}/signalr/metadata";
NotificationsWebSocketEndpointUrl = "wss://dev.ppy.sh/home/notifications/feed";
}
}
}

View File

@ -44,5 +44,10 @@ namespace osu.Game.Online
/// The endpoint for the SignalR metadata server.
/// </summary>
public string MetadataEndpointUrl { get; set; }
/// <summary>
/// The endpoint for the notifications websocket.
/// </summary>
public string NotificationsWebSocketEndpointUrl { get; set; }
}
}

View File

@ -14,6 +14,7 @@ namespace osu.Game.Online
SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator";
MultiplayerEndpointUrl = "https://spectator.ppy.sh/multiplayer";
MetadataEndpointUrl = "https://spectator.ppy.sh/metadata";
NotificationsWebSocketEndpointUrl = "wss://notify.ppy.sh";
}
}
}

View File

@ -13,6 +13,7 @@ namespace osu.Game.Online
SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator";
MultiplayerEndpointUrl = "https://spectator.ppy.sh/multiplayer";
MetadataEndpointUrl = "https://spectator.ppy.sh/metadata";
NotificationsWebSocketEndpointUrl = "wss://notify.ppy.sh";
}
}
}