Skip to content

Commit

Permalink
Merge pull request #512 from Jameskmonger/auth-rework
Browse files Browse the repository at this point in the history
Auth rework
  • Loading branch information
Jameskmonger authored Aug 26, 2023
2 parents 9a6ef4c + e1b1ca7 commit efb7af0
Show file tree
Hide file tree
Showing 72 changed files with 897 additions and 416 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ Copy `.env.example` to `.env` in the root of the repo.

These will be automatically picked up and used by the game.

### Auth0 Setup
### Auth0 Setup (optional)

You will need to set up an Auth0 tenant in order to run Creature Chess locally.
You can optionally configure Auth0 to manage users and authentication.

See "Environment variables" above for info on how to store them.
You will need to set up an Auth0 tenant and store some environment variables.

- Set up a [machine to machine app](https://auth0.com/docs/applications/set-up-an-application/register-machine-to-machine-applications)

Expand Down
9 changes: 6 additions & 3 deletions apps/server-game/src/external/auth0.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { AUTH0_ENABLED } from "@creature-chess/auth-web/auth0/config";
import { ManagementClient } from "auth0";

import { UserAppMetadata } from "@creature-chess/auth-server";
export const createManagementClient = (): ManagementClient => {
if (!AUTH0_ENABLED) {
return null as any;
}

export const createManagementClient = (): ManagementClient<UserAppMetadata> => {
const {
AUTH0_DOMAIN,
AUTH0_MACHINE_TO_MACHINE_CLIENT_ID,
Expand All @@ -17,7 +20,7 @@ export const createManagementClient = (): ManagementClient<UserAppMetadata> => {
throw Error("No Auth0 configuration found");
}

const client = new ManagementClient<UserAppMetadata>({
const client = new ManagementClient({
domain: AUTH0_DOMAIN,
clientId: AUTH0_MACHINE_TO_MACHINE_CLIENT_ID,
clientSecret: AUTH0_MANAGEMENT_CLIENT_SECRET,
Expand Down
12 changes: 9 additions & 3 deletions apps/server-game/src/external/bots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import { LobbyPlayer } from "@creature-chess/models";
export const getBots = async (database: DatabaseConnection, count: number) => {
const output: { player: LobbyPlayer; personality: BotPersonality }[] = [];

const bots = await database.bot.getLeastPlayedBots(count);
for (const { id, nickname, ambition, composure, vision } of bots!) {
const bots = await database.prisma.bots.findMany({
take: count,
orderBy: {
games_played: "asc",
},
});

for (const { id, nickname, ambition, composure, vision } of bots) {
// get a random picture from one to 20 - temporary
const picture = Math.floor(Math.random() * 20) + 1;

const player = {
id: (id + 1) * -1,
id: "bot-" + id,
name: `[BOT] ${nickname}`,
profile: {
title: null,
Expand Down
4 changes: 2 additions & 2 deletions apps/server-game/src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ export class Game {
this.gamemode.start(entities);
}

public canJoinGame(playerId: number) {
const existing = this.gamemode.getPlayerById(playerId.toString());
public canJoinGame(playerId: string) {
const existing = this.gamemode.getPlayerById(playerId);

if (!existing) {
return false;
Expand Down
41 changes: 39 additions & 2 deletions apps/server-game/src/handshake/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,49 @@ export const onHandshakeSuccess = (

logger.info("Listening for successful handshakes - inner A");

handshakeListener(deps, async (socket, { idToken }) => {
handshakeListener(deps, async (socket, request) => {
try {
logger.info("Authenticating new handshake", {
meta: { socketId: socket.id },
});

const user = await authenticate(authClient, database, idToken);
if (request.type === "guest") {
const guest = await database.prisma.guests.findFirst({
where: {
token: request.data.accessToken,
expires_at: {
gte: new Date(),
},
}
});

if (!guest) {
failHandshake(socket, { error: { type: "authentication" } });
return;
}

logger.info(`[socket ${socket.id}] Handshake successful for guest`);

successHandshake(socket);

const guestSocket = socket as AuthenticatedSocket;

guestSocket.data = {
type: "guest",
id: guest.id,
nickname: `Guest ${guest.id}`,
profile: {
picture: 1,
title: null
}
};

onReceive(guestSocket);

return;
}

const user = await authenticate(authClient, database, request.data.accessToken);

if (!user.registered) {
failHandshake(socket, { error: { type: "not_registered" } });
Expand All @@ -42,6 +78,7 @@ export const onHandshakeSuccess = (
const authenticatedSocket = socket as AuthenticatedSocket;

authenticatedSocket.data = {
type: "player",
id: user.id,
nickname: user.nickname,
profile: user.profile,
Expand Down
4 changes: 3 additions & 1 deletion apps/server-game/src/handshake/listener.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Socket } from "socket.io";

import { HandshakeRequest } from "@creature-chess/networking/handshake";

import { logger } from "../log";
import { HandshakeListenerDependencies, HandshakeRequest } from "./types";
import { HandshakeListenerDependencies } from "./types";

/**
* Attaches to the socket server and raises incoming handshake requests.
Expand Down
5 changes: 1 addition & 4 deletions apps/server-game/src/handshake/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { ManagementClient } from "auth0";
import { Server } from "socket.io";

import { UserAppMetadata } from "@creature-chess/auth-server";
import { DatabaseConnection } from "@creature-chess/data";

export type HandshakeListenerDependencies = {
io: Server;
authClient: ManagementClient<UserAppMetadata>;
authClient: ManagementClient;
database: DatabaseConnection;
};

export type HandshakeRequest = { idToken: string };
22 changes: 16 additions & 6 deletions apps/server-game/src/lobby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class Lobby {
return this.options.maxPlayers - this.members.length;
}

public isInLobby(playerId: number) {
public isInLobby(playerId: string) {
return this.members.some((m) => m.player.id === playerId);
}

Expand All @@ -50,12 +50,20 @@ export class Lobby {
const existing = this.members.find((m) => m.player.id === socket.data.id);
if (existing) {
existing.socket?.disconnect(true);

existing.socket = socket;
existing.registry = registry;
} else {
const defaultProfile: PlayerProfile = {
picture: 1,
title: null
};

const newMember = {
player: {
id: socket.data.id,
name: socket.data.nickname!,
profile: socket.data.profile!,
profile: socket.data.profile ?? defaultProfile,
},
socket,
registry,
Expand All @@ -65,11 +73,13 @@ export class Lobby {
this.notifyOthers(newMember);
}

this.sendConnected(registry);
setTimeout(() => {
this.sendConnected(registry);

if (this.members.length === this.options.maxPlayers) {
this.start();
}
if (this.members.length === this.options.maxPlayers) {
this.start();
}
}, 500);
}

private start = () => {
Expand Down
6 changes: 4 additions & 2 deletions apps/server-game/src/player/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Parameters = {
getPlayers: () => PlayerListPlayer[];
};

export const playerNetworking = function* (
export const playerNetworking = function*(
socket: Socket,
{ getRoundInfo, getPlayers }: Parameters
) {
Expand All @@ -38,7 +38,7 @@ export const playerNetworking = function* (

yield* setPacketRegistries(registries);

const teardown = function* () {
const teardown = function*() {
socket!.removeAllListeners();
socket!.disconnect();

Expand All @@ -47,6 +47,8 @@ export const playerNetworking = function* (

yield put(PlayerCommands.setSpectatingIdCommand(null));

yield delay(500);

registries.outgoing.send("gameConnected", {
game: getRoundInfo(),
players: getPlayers(),
Expand Down
15 changes: 13 additions & 2 deletions apps/server-game/src/player/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@ import { DefaultEventsMap } from "socket.io/dist/typed-events";

import { PlayerProfile } from "@creature-chess/models";

type AuthenticatedSocketData = {
id: number;
type GuestSocketData = {
type: "guest";
id: string;
nickname: string;
profile: PlayerProfile;
};

type PlayerSocketData = {
type: "player";
id: string;
nickname: string | null;
profile: PlayerProfile | null;
};

type AuthenticatedSocketData = GuestSocketData | PlayerSocketData;

export type AuthenticatedSocket = Socket<
DefaultEventsMap,
DefaultEventsMap,
Expand Down
Loading

0 comments on commit efb7af0

Please sign in to comment.