Skip to content

Commit

Permalink
Merge pull request #506 from Jameskmonger/fix-live-runtime
Browse files Browse the repository at this point in the history
fix: various live runtime fixes
  • Loading branch information
Jameskmonger authored Feb 27, 2023
2 parents 8816e29 + 2e73e6e commit 1cd8391
Show file tree
Hide file tree
Showing 53 changed files with 22,344 additions and 25,914 deletions.
29 changes: 0 additions & 29 deletions .auth0/rules/attach-metadata.js

This file was deleted.

2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ node_modules
npm-debug.log
terraform/
public/
.faundb/
.faunadb/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ apps/**/public/
yarn.lock
*.tfstate
.auth0
.faunadb/
768 changes: 0 additions & 768 deletions .yarn/releases/yarn-3.1.1.cjs

This file was deleted.

873 changes: 873 additions & 0 deletions .yarn/releases/yarn-3.4.1.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.1.1.cjs
yarnPath: .yarn/releases/yarn-3.4.1.cjs
19 changes: 3 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ AUTH0_MANAGEMENT_CLIENT_SECRET=

These will be automatically picked up and used by the build scripts.

### Local app url

Set the environment variable `CREATURE_CHESS_APP_URL` to `http://localhost:8080`

### Auth0 Setup

You will need to set up an Auth0 tenant in order to run Creature Chess locally.
Expand All @@ -65,23 +61,14 @@ See "Environment variables" above for info on how to store them.

There are some steps that you need to take on the Auth0 config for this:

- Set `Allowed Callback URLs` = "http://localhost:8080"
- Set `Allowed Web Origins` = "http://localhost:8080"
- Set `Allowed Callback URLs` = "http://localhost"
- Set `Allowed Web Origins` = "http://localhost"

Then, set the following environment variables

- **domain** as `AUTH0_DOMAIN`
- **client id** as `AUTH0_SPA_CLIENT_ID`

- Add a new Empty Rule to Auth0

This exposes the user's Auth0 metadata.

- Go to your Auth0 Portal
- Find: Auth Pipeline > Rules in the left side navigation.
- Create a new Empty Rule
- Copy and paste the contents of: `.auth0/rules/attach-metadata.js` into this section.

(btw, I am not really happy that we need all this just to test locally, but equally, I don't want to have a "guest mode" locally and not test the auth0 pre-prod. Auth0 sadly doesn't offer a local version. Open to any ideas on it!)

### Setup
Expand All @@ -94,7 +81,7 @@ Run `yarn` in the project root.
$ yarn dockerup
```

The game is then accessible at `http://localhost:8080`.
The game is then accessible at `http://localhost`.

In another console, you will need to run the following command to run the User service locally.

Expand Down
4 changes: 1 addition & 3 deletions apps/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ ADD package.json yarn.lock .yarnrc.yml ./
ADD .yarn/plugins/ ./.yarn/plugins/
ADD .yarn/releases/ ./.yarn/releases/

# TODO we shouldn't have to copy this here.
ADD lambda/user/package.json ./lambda/user/

ADD apps/server-game/package.json ./apps/server-game/
ADD apps/server-info/package.json ./apps/server-info/
ADD apps/web-game/package.json ./apps/web-game/
ADD apps/web-menu/package.json ./apps/web-menu/

Expand Down
183 changes: 183 additions & 0 deletions apps/server-info/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import express from "express";
import { logger as expressWinston } from "express-winston";

import {
authenticate,
convertDatabaseUserToUserModel,
} from "@creature-chess/auth-server";
import {
createDatabaseConnection,
DatabaseConnection,
} from "@creature-chess/data";
import {
AVAILABLE_PROFILE_PICTURES,
validateNicknameFormat,
} from "@creature-chess/models";

import { logger } from "./src/log";
import { getManagementClient } from "./src/util/auth0";
import { sanitize } from "./src/util/sanitize-user";

import Filter = require("bad-words");

const app = express();
const PORT = 3000;

// Define a middleware to parse JSON requests
app.use(express.json());
app.use(expressWinston({ winstonInstance: logger }));

async function getNicknameUpdate(
database: DatabaseConnection,
filter: Filter,
body: { nickname?: string }
): Promise<{ error: string | null; nickname: string | null }> {
const { nickname } = body;

if (!nickname) {
return { error: null, nickname: null };
}

const trimmedNickname = nickname.trim();

const nicknameError = validateNicknameFormat(nickname);

if (nicknameError) {
return { error: nicknameError, nickname: null };
}

if (filter.isProfane(nickname)) {
return { error: "Profanity filter", nickname: null };
}

const isUnique = (await database.user.getByNickname(nickname)) === null;

if (!isUnique) {
return { error: "Nickname already in use", nickname: null };
}

return { error: null, nickname: trimmedNickname };
}

async function getPictureUpdate(body: {
picture?: string;
}): Promise<{ error: string | null; picture: number | null }> {
const { picture } = body;

if (!picture) {
return { error: null, picture: null };
}

const pictureId = parseInt(picture, 10);

if (isNaN(pictureId)) {
return { error: "Invalid picture id", picture: null };
}

if (!Object.keys(AVAILABLE_PROFILE_PICTURES).includes(picture.toString())) {
return { error: "Picture id supplied is not useable", picture: null };
}

return { error: null, picture: pictureId };
}

async function startServer() {
const authClient = getManagementClient();
const filter = new Filter();

const database = await createDatabaseConnection(logger);

app.get("/user/current", async (req, res) => {
const { authorization } = req.headers;

if (!authorization) {
logger.info("No authorization header found");

return res.status(401).json({
message: "Not authorized",
});
}

const user = await authenticate(
authClient,
database,
authorization as string
);

res.status(200).json(sanitize(user));
});

app.patch("/user/current", async (req, res) => {
const { authorization } = req.headers;

if (!authorization) {
logger.info("No authorization header found");

return res.status(401).json({
message: "Not authorized",
});
}

const user = await authenticate(
authClient,
database,
authorization as string
);

if (!user) {
logger.info("No user found");

return res.status(401).json({
message: "Not authorized",
});
}

if (user.registered) {
console.log(`Registered user ${user.id} tried to patch`);

return res.status(403).json({
message: "Forbidden",
});
}

const nicknameUpdate = await getNicknameUpdate(database, filter, req.body);

if (nicknameUpdate.error) {
return res.status(400).json({
message: nicknameUpdate.error,
});
}

const pictureUpdate = await getPictureUpdate(req.body);

if (pictureUpdate.error) {
return res.status(400).json({
message: pictureUpdate.error,
});
}

const updatedUser = await database.user.setProfileInfo(
user.id,
nicknameUpdate.nickname,
pictureUpdate.picture
);

if (!updatedUser) {
return res.status(500).json({
message: "An error occurred while updating the user",
});
}

res.status(200).json(sanitize(convertDatabaseUserToUserModel(updatedUser)));
});

// Start the server
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
}

startServer().catch((e) => {
logger.error("An error occurred while starting the server", e);
process.exit(1);
});
34 changes: 34 additions & 0 deletions apps/server-info/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"private": true,
"name": "@creature-chess/server-info",
"version": "0.0.1",
"description": "HTTP info server",
"keywords": [],
"author": "James Monger <[email protected]>",
"license": "ISC",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Jameskmonger/creature-chess.git"
},
"bugs": {
"url": "https://github.com/Jameskmonger/creature-chess/issues"
},
"homepage": "https://github.com/Jameskmonger/creature-chess#readme",
"scripts": {
"build": "yarn run -T tsc -p ./tsconfig.json",
"test": "yarn run -T jest --passWithNoTests"
},
"dependencies": {
"@creature-chess/auth-server": "workspace:*",
"@creature-chess/data": "workspace:*",
"@creature-chess/models": "workspace:*",
"@types/bad-words": "^3.0.1",
"bad-words": "^3.0.4",
"express": "^4.17.2",
"express-winston": "^4.2.0",
"winston": "^3.3.3"
}
}
23 changes: 23 additions & 0 deletions apps/server-info/src/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import winston = require("winston");

const createWinstonLogger = () => {
const devMode = false;

const newLogger = winston.createLogger({
format: devMode
? winston.format.combine(
winston.format.errors({ stack: true }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.prettyPrint()
)
: undefined,
});

newLogger.add(new winston.transports.Console());
newLogger.info("Sending Winston logs to console");

return newLogger;
};

export const logger = createWinstonLogger();
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions apps/server-info/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./lib",
"importHelpers": true
},
"include": ["./src/**/*", "index.ts"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function ReadyUpButton() {
}

dispatch(PlayerActions.readyUpPlayerAction());
}, []);
}, [canReadyUp]);

if (!canReadyUp) {
// To keep the Sell button in the same place
Expand Down
Loading

0 comments on commit 1cd8391

Please sign in to comment.