mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-01 00:53:29 +00:00
Client JWT authentication (#723)
## Description: Send JWT to the game server for verification. ## Please complete the following: - [x] I have added screenshots for all UI updates - [ ] 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:
@@ -1,4 +1,5 @@
|
||||
import { Colord } from "colord";
|
||||
import { JWK } from "jose";
|
||||
import { GameConfig, GameID } from "../Schemas";
|
||||
import {
|
||||
Difficulty,
|
||||
@@ -29,7 +30,6 @@ export interface ServerConfig {
|
||||
turnIntervalMs(): number;
|
||||
gameCreationRate(): number;
|
||||
lobbyMaxPlayers(map: GameMapType, mode: GameMode): number;
|
||||
discordRedirectURI(): string;
|
||||
numWorkers(): number;
|
||||
workerIndex(gameID: GameID): number;
|
||||
workerPath(gameID: GameID): string;
|
||||
@@ -49,6 +49,9 @@ export interface ServerConfig {
|
||||
otelUsername(): string;
|
||||
otelPassword(): string;
|
||||
otelEnabled(): boolean;
|
||||
jwtAudience(): string;
|
||||
jwtIssuer(): string;
|
||||
jwkPublicKey(): Promise<JWK>;
|
||||
}
|
||||
|
||||
export interface NukeMagnitude {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { JWK } from "jose";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
Difficulty,
|
||||
Duos,
|
||||
@@ -24,7 +26,35 @@ import { Config, GameEnv, NukeMagnitude, ServerConfig, Theme } from "./Config";
|
||||
import { pastelTheme } from "./PastelTheme";
|
||||
import { pastelThemeDark } from "./PastelThemeDark";
|
||||
|
||||
const JwksSchema = z.object({
|
||||
keys: z
|
||||
.object({
|
||||
alg: z.literal("EdDSA"),
|
||||
crv: z.literal("Ed25519"),
|
||||
kty: z.literal("OKP"),
|
||||
x: z.string(),
|
||||
})
|
||||
.array()
|
||||
.min(1),
|
||||
});
|
||||
|
||||
export abstract class DefaultServerConfig implements ServerConfig {
|
||||
private publicKey: JWK;
|
||||
abstract jwtAudience(): string;
|
||||
jwtIssuer(): string {
|
||||
const audience = this.jwtAudience();
|
||||
return audience === "localhost"
|
||||
? "http://localhost:8787"
|
||||
: `https://api.${audience}`;
|
||||
}
|
||||
async jwkPublicKey(): Promise<JWK> {
|
||||
if (this.publicKey) return this.publicKey;
|
||||
const jwksUrl = this.jwtIssuer() + "/.well-known/jwks.json";
|
||||
const response = await fetch(jwksUrl);
|
||||
const jwks = JwksSchema.parse(await response.json());
|
||||
this.publicKey = jwks.keys[0];
|
||||
return this.publicKey;
|
||||
}
|
||||
otelEnabled(): boolean {
|
||||
return Boolean(
|
||||
this.otelEndpoint() && this.otelUsername() && this.otelPassword(),
|
||||
@@ -70,7 +100,6 @@ export abstract class DefaultServerConfig implements ServerConfig {
|
||||
}
|
||||
abstract numWorkers(): number;
|
||||
abstract env(): GameEnv;
|
||||
abstract discordRedirectURI(): string;
|
||||
turnIntervalMs(): number {
|
||||
return 100;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@ export class DevServerConfig extends DefaultServerConfig {
|
||||
return 1;
|
||||
}
|
||||
|
||||
discordRedirectURI(): string {
|
||||
return "http://localhost:3000/auth/callback";
|
||||
}
|
||||
numWorkers(): number {
|
||||
return 2;
|
||||
}
|
||||
jwtAudience(): string {
|
||||
return "localhost";
|
||||
}
|
||||
gitCommit(): string {
|
||||
return "DEV";
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ export const preprodConfig = new (class extends DefaultServerConfig {
|
||||
env(): GameEnv {
|
||||
return GameEnv.Preprod;
|
||||
}
|
||||
discordRedirectURI(): string {
|
||||
return "https://openfront.dev/auth/callback";
|
||||
}
|
||||
numWorkers(): number {
|
||||
return 3;
|
||||
}
|
||||
jwtAudience(): string {
|
||||
return "openfront.dev";
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -8,7 +8,7 @@ export const prodConfig = new (class extends DefaultServerConfig {
|
||||
env(): GameEnv {
|
||||
return GameEnv.Prod;
|
||||
}
|
||||
discordRedirectURI(): string {
|
||||
return "https://openfront.io/auth/callback";
|
||||
jwtAudience(): string {
|
||||
return "openfront.io";
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user