mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 01:04:35 +00:00
Server role lookup (#954)
## Description: - Validate that user tokens are accepted by the API server, in case of token revoked / remote logout. - Lookup user roles by their token. - Sets the groundwork for validating custom flag codes, patterns, etc. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
committed by
evanpelle
parent
de089291f4
commit
b0b0ebb53e
@@ -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>;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user