mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 09:54:16 +00:00
Merge branch 'v27'
This commit is contained in:
@@ -138,8 +138,6 @@ export class MapPlaylist {
|
||||
const ffa1: GameMapType[] = rand.shuffleArray([...maps]);
|
||||
const team1: GameMapType[] = rand.shuffleArray([...maps]);
|
||||
const ffa2: GameMapType[] = rand.shuffleArray([...maps]);
|
||||
const team2: GameMapType[] = rand.shuffleArray([...maps]);
|
||||
const ffa3: GameMapType[] = rand.shuffleArray([...maps]);
|
||||
|
||||
this.mapsPlaylist = [];
|
||||
for (let i = 0; i < maps.length; i++) {
|
||||
@@ -154,14 +152,6 @@ export class MapPlaylist {
|
||||
if (!this.addNextMap(this.mapsPlaylist, ffa2, GameMode.FFA)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.disableTeams) {
|
||||
if (!this.addNextMap(this.mapsPlaylist, team2, GameMode.Team)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!this.addNextMap(this.mapsPlaylist, ffa3, GameMode.FFA)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+19
-9
@@ -337,9 +337,14 @@ export async function startWorker() {
|
||||
|
||||
// Verify token signature
|
||||
const result = await verifyClientToken(clientMsg.token, config);
|
||||
if (result === false) {
|
||||
log.warn("Unauthorized: Invalid token");
|
||||
ws.close(1002, "Unauthorized");
|
||||
if (result.type === "error") {
|
||||
log.warn(`Invalid token: ${result.message}`, {
|
||||
clientID: clientMsg.clientID,
|
||||
});
|
||||
ws.close(
|
||||
1002,
|
||||
`Unauthorized: invalid token for client ${clientMsg.clientID}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const { persistentId, claims } = result;
|
||||
@@ -374,13 +379,18 @@ export async function startWorker() {
|
||||
} else {
|
||||
// Verify token and get player permissions
|
||||
const result = await getUserMe(clientMsg.token, config);
|
||||
if (result === false) {
|
||||
log.warn("Unauthorized: Invalid session");
|
||||
ws.close(1002, "Unauthorized");
|
||||
if (result.type === "error") {
|
||||
log.warn(`Unauthorized: ${result.message}`, {
|
||||
clientID: clientMsg.clientID,
|
||||
});
|
||||
ws.close(
|
||||
1002,
|
||||
`Unauthorized: user me fetch failed for client ${clientMsg.clientID}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
roles = result.player.roles;
|
||||
flares = result.player.flares;
|
||||
roles = result.response.player.roles;
|
||||
flares = result.response.player.flares;
|
||||
|
||||
if (allowedFlares !== undefined) {
|
||||
const allowed =
|
||||
@@ -422,7 +432,7 @@ export async function startWorker() {
|
||||
clientID: clientMsg.clientID,
|
||||
reason: turnstileResult.reason,
|
||||
});
|
||||
ws.close(1002, "Unauthorized");
|
||||
ws.close(1002, "Unauthorized: Turnstile token rejected");
|
||||
return;
|
||||
case "error":
|
||||
// Fail open, allow the client to join.
|
||||
|
||||
+35
-17
@@ -11,17 +11,18 @@ import { PersistentIdSchema } from "../core/Schemas";
|
||||
|
||||
type TokenVerificationResult =
|
||||
| {
|
||||
type: "success";
|
||||
persistentId: string;
|
||||
claims: TokenPayload | null;
|
||||
}
|
||||
| false;
|
||||
| { type: "error"; message: string };
|
||||
|
||||
export async function verifyClientToken(
|
||||
token: string,
|
||||
config: ServerConfig,
|
||||
): Promise<TokenVerificationResult> {
|
||||
if (PersistentIdSchema.safeParse(token).success) {
|
||||
return { persistentId: token, claims: null };
|
||||
return { type: "success", persistentId: token, claims: null };
|
||||
}
|
||||
try {
|
||||
const issuer = config.jwtIssuer();
|
||||
@@ -34,22 +35,33 @@ export async function verifyClientToken(
|
||||
});
|
||||
const result = TokenPayloadSchema.safeParse(payload);
|
||||
if (!result.success) {
|
||||
const error = z.prettifyError(result.error);
|
||||
console.warn("Error parsing token payload", error);
|
||||
return false;
|
||||
return {
|
||||
type: "error",
|
||||
message: z.prettifyError(result.error),
|
||||
};
|
||||
}
|
||||
const claims = result.data;
|
||||
const persistentId = claims.sub;
|
||||
return { persistentId, claims };
|
||||
return { type: "success", persistentId, claims };
|
||||
} catch (e) {
|
||||
return false;
|
||||
const message =
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: typeof e === "string"
|
||||
? e
|
||||
: "An unknown error occurred";
|
||||
|
||||
return { type: "error", message };
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserMe(
|
||||
token: string,
|
||||
config: ServerConfig,
|
||||
): Promise<UserMeResponse | false> {
|
||||
): Promise<
|
||||
| { type: "success"; response: UserMeResponse }
|
||||
| { type: "error"; message: string }
|
||||
> {
|
||||
try {
|
||||
// Get the user object
|
||||
const response = await fetch(config.jwtIssuer() + "/users/@me", {
|
||||
@@ -57,19 +69,25 @@ export async function getUserMe(
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
if (response.status !== 200) return false;
|
||||
if (response.status !== 200) {
|
||||
return {
|
||||
type: "error",
|
||||
message: `Failed to fetch user me: ${response.statusText}`,
|
||||
};
|
||||
}
|
||||
const body = await response.json();
|
||||
const result = UserMeResponseSchema.safeParse(body);
|
||||
if (!result.success) {
|
||||
console.error(
|
||||
"Invalid response",
|
||||
JSON.stringify(body),
|
||||
JSON.stringify(result.error),
|
||||
);
|
||||
return false;
|
||||
return {
|
||||
type: "error",
|
||||
message: `Invalid response: ${z.prettifyError(result.error)}`,
|
||||
};
|
||||
}
|
||||
return result.data;
|
||||
return { type: "success", response: result.data };
|
||||
} catch (e) {
|
||||
return false;
|
||||
return {
|
||||
type: "error",
|
||||
message: `Failed to fetch user me: ${e}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user