Fix login return routes and recovery feedback
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 6m29s

This commit is contained in:
2026-10-31 13:56:01 +05:00
parent 48d4058e06
commit 0d62f08e77
6 changed files with 47 additions and 7 deletions

View File

@@ -158,6 +158,7 @@ export function AccountSettings({
async function recover() {
setSending(true);
setRecoveryError("");
setRecoveryMessage("");
try {
const data = await api<{ message: string }>("auth", {
action: "recover",
@@ -344,12 +345,12 @@ export function AccountSettings({
</button>
{recoveryMessage && (
<p role="status" className="success-message">
{recoveryMessage}
{t(recoveryMessage)}
</p>
)}
{recoveryError && (
<p role="alert" className="error-message">
{recoveryError}
{t(recoveryError)}
</p>
)}
</div>

View File

@@ -145,7 +145,10 @@ export function MapCommunity({
</div>
{!data.viewer && (
<p>
<Link className="button" href="/log-in">
<Link
className="button"
href={`/log-in?next=${encodeURIComponent(`/servers/${datasetId}`)}`}
>
{t("Sign in to react, comment, or report.")}
</Link>
</p>

View File

@@ -338,7 +338,11 @@ export function StartGame({
) : (
<p className="muted">
{t("Log in to create a multiplayer room")}{" "}
<Link href="/log-in?next=/servers">{t("Log in")}</Link>
<Link
href={`/log-in?next=${encodeURIComponent(`/servers/${datasetId}`)}`}
>
{t("Log in")}
</Link>
</p>
)}
<label htmlFor="room-player-limit">

View File

@@ -157,7 +157,14 @@ export function TournamentIndex({
{t(creating ? "Close" : "Create tournament")}
</button>
) : (
<Link href="/log-in" className="button primary">
<Link
href={`/log-in?next=${encodeURIComponent(
initialMapId
? `/tournaments?map=${initialMapId}`
: "/tournaments",
)}`}
className="button primary"
>
{t("Log in to create or join")}
</Link>
)}
@@ -595,7 +602,10 @@ export function TournamentLobby({
{event.status === "scheduled" && (
<div className="tournament-actions">
{!signedIn ? (
<Link className="button primary" href="/log-in">
<Link
className="button primary"
href={`/log-in?next=${encodeURIComponent(`/tournaments/${id}`)}`}
>
{t("Log in to create or join")}
</Link>
) : joined ? (

View File

@@ -77,9 +77,16 @@ export function authDestination(value: string | null | undefined): string {
value === "/dashboard" ||
value === "/servers" ||
value === "/support" ||
value === "/tournaments" ||
value === "/ban/appeal" ||
value === "/dev/api" ||
value === "/admin" ||
value === "/moderation" ||
value === "/auth/reset-password"
)
return value;
if (value && /^\/(?:servers|tournaments)\/[0-9a-f-]{36}$/i.test(value))
return value;
if (value && /^\/dashboard\/[0-9a-f-]{36}$/i.test(value)) return value;
if (value && /^\/support\/[0-9a-f-]{36}$/i.test(value)) return value;
if (value && /^\/tournaments\?map=[0-9a-f-]{36}$/i.test(value)) return value;

View File

@@ -84,7 +84,22 @@ test("authentication redirects accept supported local routes and reject open red
assert.equal(authDestination(next), "/dashboard");
assert.equal(authDestination("/settings"), "/settings");
assert.equal(authDestination("/servers"), "/servers");
const tournamentMap = "/tournaments?map=123e4567-e89b-12d3-a456-426614174000";
const id = "123e4567-e89b-12d3-a456-426614174000";
for (const next of [
"/ban/appeal",
"/dev/api",
"/admin",
"/moderation",
"/tournaments",
`/servers/${id}`,
`/tournaments/${id}`,
])
assert.equal(authDestination(next), next);
assert.equal(
authDestination(`/servers/${id}?next=//evil.example`),
"/dashboard",
);
const tournamentMap = `/tournaments?map=${id}`;
assert.equal(authDestination(tournamentMap), tournamentMap);
assert.equal(
authDestination(`${tournamentMap}&next=//evil.example`),