fix: capture upload-form user id at init, not submit, so token expiry mid-session can't discard a composed release
This commit is contained in:
@@ -129,6 +129,12 @@
|
|||||||
// Set true once the admin has acknowledged the missing-hero warning, so a second submit proceeds.
|
// Set true once the admin has acknowledged the missing-hero warning, so a second submit proceeds.
|
||||||
private bool _heroWarningAcknowledged;
|
private bool _heroWarningAcknowledged;
|
||||||
|
|
||||||
|
// Captured at component initialization (when 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 — a prerender pass returns an anonymous principal (no JS
|
||||||
|
// interop available), so the field stays null until the live interactive circuit populates it.
|
||||||
|
private long? _createdByUserId;
|
||||||
|
|
||||||
private string _albumName = string.Empty;
|
private string _albumName = string.Empty;
|
||||||
private string _artist = string.Empty;
|
private string _artist = string.Empty;
|
||||||
private string _genre = string.Empty;
|
private string _genre = string.Empty;
|
||||||
@@ -156,6 +162,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
// Capture the user id once at load, while the token is known-good. The page is [Authorize]-gated
|
||||||
|
// so this should always succeed on the live interactive circuit. During static prerender, auth
|
||||||
|
// state is anonymous (no JS interop → no localStorage JWT read), so the parse fails and the
|
||||||
|
// field stays null; the interactive circuit then runs this again and sets the real value.
|
||||||
|
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
|
// 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
|
// 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.
|
// declaration the upload service enforces, so the form and the domain cannot drift.
|
||||||
@@ -275,13 +295,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
if (_createdByUserId is not long createdByUserId)
|
||||||
var userIdValue = authState.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
||||||
if (!long.TryParse(userIdValue, out var createdByUserId))
|
|
||||||
{
|
{
|
||||||
// The page is gated by [Authorize] under the Admin role, so a missing or
|
// _createdByUserId is set at component initialization from the authenticated principal.
|
||||||
// unparseable id here is a configuration bug, not normal client state.
|
// A null here means the id was unavailable even at load — a genuine configuration bug,
|
||||||
Logger.LogError("Authenticated user has no parseable NameIdentifier claim: {Value}", userIdValue);
|
// 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.";
|
_errorMessage = "Your session is missing a valid identifier. Please sign in again.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user