Merge cms-upload-userid-capture into dev (capture upload-form user id at init so mid-session token expiry can't discard a composed release)
This commit is contained in:
@@ -129,6 +129,11 @@
|
||||
// Set true once the admin has acknowledged the missing-hero warning, so a second submit proceeds.
|
||||
private bool _heroWarningAcknowledged;
|
||||
|
||||
// Captured once at component initialization on the live interactive circuit, while the token
|
||||
// is known-good, so a mid-session token expiry at submit time cannot discard a long-composed
|
||||
// release. Only assigned when the id parses successfully.
|
||||
private long? _createdByUserId;
|
||||
|
||||
private string _albumName = string.Empty;
|
||||
private string _artist = string.Empty;
|
||||
private string _genre = string.Empty;
|
||||
@@ -156,6 +161,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Capture the user id once at load, while the token is known-good. The CMS host runs with
|
||||
// prerender: false (InteractiveServer), so this is the single init pass — auth state is
|
||||
// fully available. The page is [Authorize]-gated, so the parse should always succeed.
|
||||
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
||||
var userIdValue = authState.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (long.TryParse(userIdValue, out var userId))
|
||||
{
|
||||
_createdByUserId = userId;
|
||||
}
|
||||
}
|
||||
|
||||
// Switching to a single-track medium collapses any multi-track selection to the first row so the
|
||||
// single-track invariant holds before submit. The predicate reads the same MediumRules cardinality
|
||||
// declaration the upload service enforces, so the form and the domain cannot drift.
|
||||
@@ -275,13 +293,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
||||
var userIdValue = authState.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (!long.TryParse(userIdValue, out var createdByUserId))
|
||||
if (_createdByUserId is not long createdByUserId)
|
||||
{
|
||||
// The page is gated by [Authorize] under the Admin role, so a missing or
|
||||
// unparseable id here is a configuration bug, not normal client state.
|
||||
Logger.LogError("Authenticated user has no parseable NameIdentifier claim: {Value}", userIdValue);
|
||||
// _createdByUserId is set at component initialization from the authenticated principal.
|
||||
// A null here means the id was unavailable even at load — a genuine configuration bug,
|
||||
// since the page is [Authorize]-gated.
|
||||
Logger.LogError("User id was not captured at initialization — NameIdentifier claim missing or unparseable.");
|
||||
_errorMessage = "Your session is missing a valid identifier. Please sign in again.";
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user