auth: link Steam to UDID-keyed viewer on first authenticated request
After /tool/signup, the client has a viewer_id but no Steam social row. The first authenticated request (typically /check/game_start) carries the Steam ticket; if the SteamId lookup misses but the UDID resolves to a viewer, attach the Steam social now. Subsequent requests hit the fast SteamId path. Closes the CheckController.GameStart TODO that was blocking fresh-client boot. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -30,10 +30,6 @@ public class CheckController : SVSimController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: spec lists this as anonymous (identity from SHORT_UDID), but the base controller's
|
|
||||||
// [Authorize] still applies. For now requires a Steam-linked viewer; new-user bootstrap (where
|
|
||||||
// the server creates a viewer + returns rewrite_viewer_id) is deferred until the boot flow is
|
|
||||||
// exercised end-to-end with a real client.
|
|
||||||
[HttpPost("game_start")]
|
[HttpPost("game_start")]
|
||||||
public async Task<GameStartResponse> GameStart(GameStartRequest request)
|
public async Task<GameStartResponse> GameStart(GameStartRequest request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -97,13 +97,33 @@ public class SteamSessionAuthenticationHandler : AuthenticationHandler<SteamAuth
|
|||||||
|
|
||||||
if (viewer is null)
|
if (viewer is null)
|
||||||
{
|
{
|
||||||
// Most common dev-loop cause: DB was re-bootstrapped and this Steam account hasn't
|
// Find-or-link: first authenticated request after /tool/signup. The client signed up
|
||||||
// been re-linked yet. Log loudly with the steam_id so it's obvious what to add back.
|
// anonymously and has no Steam social row yet; if the UDID resolves to a viewer, attach
|
||||||
Logger.LogWarning(
|
// Steam to it now so subsequent requests hit the fast SteamId path. The SteamId unique
|
||||||
"Auth: no viewer linked to steamId={SteamId} on {Path}. " +
|
// index on SocialAccountConnection is the dedup backstop for concurrent first-touch.
|
||||||
"Likely you re-bootstrapped the DB without re-linking this Steam account.",
|
Guid? udid = Context.GetUdid();
|
||||||
requestJson.SteamId, path);
|
if (udid is Guid u && u != Guid.Empty)
|
||||||
return AuthenticateResult.Fail("User not found.");
|
{
|
||||||
|
viewer = await _viewerRepository.GetViewerByUdid(u);
|
||||||
|
if (viewer is not null)
|
||||||
|
{
|
||||||
|
await _viewerRepository.LinkSteamToViewer(viewer.Id, requestJson.SteamId);
|
||||||
|
// Re-read with socials so transition_account_data downstream sees the new link.
|
||||||
|
viewer = await _viewerRepository.GetViewerWithSocials(viewer.Id) ?? viewer;
|
||||||
|
Logger.LogInformation(
|
||||||
|
"Auth: linked steamId={SteamId} to UDID-keyed viewer_id={ViewerId} on {Path} (first-Steam-touch).",
|
||||||
|
requestJson.SteamId, viewer.Id, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewer is null)
|
||||||
|
{
|
||||||
|
Logger.LogWarning(
|
||||||
|
"Auth: no viewer linked to steamId={SteamId} on {Path}, and no UDID-keyed viewer to link to. " +
|
||||||
|
"Client must call /tool/signup before authenticated endpoints.",
|
||||||
|
requestJson.SteamId, path);
|
||||||
|
return AuthenticateResult.Fail("User not found.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add viewer to context
|
// Add viewer to context
|
||||||
|
|||||||
Reference in New Issue
Block a user