Fix 2FA verification via link not working correctly

Closes https://github.com/ppy/osu/issues/26835.

I must have not re-tested this correctly after all the refactors...

Basically the issue is that the websocket connection would only come
online when the API state changed to full `Online`. In particular
the connector would not attempt to connect when the API state was
`RequiresSecondFactorAuth`, giving the link-based flow no chance to
actually work.

The change in `WebSocketNotificationsClientConnector` is relevant in
that queueing requests does nothing before the API state changes to full
`Online`. It also cleans up things a bit code-wise so... win?

And yes, this means that the _other_ `PersistentEndpointClientConnector`
implementations (i.e. SignalR connectors) will also come online earlier
after this. Based on previous discussions
(https://github.com/ppy/osu/pull/25480#discussion_r1395566545) I think
this is fine, but if it is _not_ fine, then it can be fixed by exposing
a virtual that lets a connector to decide when to come alive, I guess.
This commit is contained in:
Bartłomiej Dach 2024-01-30 21:40:23 +01:00
parent 6931af664e
commit 4126dcbe28
No known key found for this signature in database
2 changed files with 6 additions and 8 deletions

View File

@ -29,14 +29,11 @@ public WebSocketNotificationsClientConnector(IAPIProvider api)
protected override async Task<PersistentEndpointClient> BuildConnectionAsync(CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<string>();
var req = new GetNotificationsRequest();
req.Success += bundle => tcs.SetResult(bundle.Endpoint);
req.Failure += ex => tcs.SetException(ex);
api.Queue(req);
string endpoint = await tcs.Task.ConfigureAwait(false);
// must use `PerformAsync()`, since we may not be fully online yet
// (see `APIState.RequiresSecondFactorAuth` - in this state queued requests will not execute).
await api.PerformAsync(req).ConfigureAwait(false);
string endpoint = req.Response!.Endpoint;
ClientWebSocket socket = new ClientWebSocket();
socket.Options.SetRequestHeader(@"Authorization", @$"Bearer {api.AccessToken}");

View File

@ -69,6 +69,7 @@ private async Task connectIfPossible()
break;
case APIState.Online:
case APIState.RequiresSecondFactorAuth:
await connect().ConfigureAwait(true);
break;
}
@ -83,7 +84,7 @@ private async Task connect()
try
{
while (apiState.Value == APIState.Online)
while (apiState.Value == APIState.RequiresSecondFactorAuth || apiState.Value == APIState.Online)
{
// ensure any previous connection was disposed.
// this will also create a new cancellation token source.