Server role lookup

This commit is contained in:
Scott Anderson
2025-05-30 03:11:00 -04:00
committed by Aotumuri
parent 534c6d5524
commit f86ce84e65
4 changed files with 51 additions and 7 deletions
-4
View File
@@ -28,10 +28,6 @@ export const TokenPayloadSchema = z.object({
iss: z.string(),
aud: z.string(),
exp: z.number(),
rol: z
.string()
.optional()
.transform((val) => (val ?? "").split(",")),
});
export type TokenPayload = z.infer<typeof TokenPayloadSchema>;
+1
View File
@@ -12,6 +12,7 @@ export class Client {
public readonly clientID: ClientID,
public readonly persistentID: string,
public readonly claims: TokenPayload | null,
public readonly roles: string[] | null,
public readonly ip: string,
public readonly username: string,
public readonly ws: WebSocket,
+16 -2
View File
@@ -19,7 +19,7 @@ import { archive, readGameRecord } from "./Archive";
import { Client } from "./Client";
import { GameManager } from "./GameManager";
import { gatekeeper, LimiterType } from "./Gatekeeper";
import { verifyClientToken } from "./jwt";
import { getUserMe, verifyClientToken } from "./jwt";
import { logger } from "./Logger";
import { initWorkerMetrics } from "./WorkerMetrics";
@@ -316,11 +316,25 @@ export function startWorker() {
config,
);
const roles: string[] | null = null;
// Check user roles
if (claims !== null) {
const result = await getUserMe(clientMsg.token, config);
if (result === false) {
log.warn("Token is not valid", claims);
return;
}
}
// TODO: Validate client settings based on roles
// Create client and add to game
const client = new Client(
clientMsg.clientID,
persistentId,
claims ?? null,
claims,
roles,
ip,
clientMsg.username,
ws,
+34 -1
View File
@@ -1,5 +1,10 @@
import { jwtVerify } from "jose";
import { TokenPayload, TokenPayloadSchema } from "../core/ApiSchemas";
import {
TokenPayload,
TokenPayloadSchema,
UserMeResponse,
UserMeResponseSchema,
} from "../core/ApiSchemas";
import { ServerConfig } from "../core/configuration/Config";
type TokenVerificationResult = {
@@ -27,3 +32,31 @@ export async function verifyClientToken(
const persistentId = claims.sub;
return { persistentId, claims };
}
export async function getUserMe(
token: string,
config: ServerConfig,
): Promise<UserMeResponse | false> {
try {
// Get the user object
const response = await fetch(config.jwtIssuer() + "/users/@me", {
headers: {
authorization: `Bearer ${token}`,
},
});
if (response.status !== 200) return false;
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 result.data;
} catch (e) {
return false;
}
}