Skip to content

Commit

Permalink
Moved all validation to middleware and replaced per-title routes with…
Browse files Browse the repository at this point in the history
… configs
  • Loading branch information
jonbarrow committed Nov 19, 2022
1 parent a258d6d commit 27ef1dd
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 187 deletions.
13 changes: 13 additions & 0 deletions src/middleware/title-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const titles = require('../titles');

function titleCodeMiddleware(request, response, next) {
request.titleCode = request.subdomains.pop();

if (!titles[request.titleCode]) {
return next(`No valid title config set for title code ${request.titleCode}`);
}

next();
}

module.exports = titleCodeMiddleware;
40 changes: 40 additions & 0 deletions src/middleware/validate-multipart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const titles = require('../titles');

function validateMultipartMiddleware(request, response, next) {
const title = titles[request.titleCode];

const multipartValidator = title.multipart_validator;
const validationSchema = title.validation_schema;

multipartValidator(request.copy, response, error => {
if (error) {
return next(error);
}

const resultData = {
...request.copy.body,
};

for (const key in request.copy.files) {
if (Object.hasOwnProperty.call(request.copy.files, key)) {
const field = request.copy.files[key];

for (const file of field) {
resultData[file.fieldname] = file.buffer;
}
}
}

const validationResult = validationSchema.validate(resultData);

if (validationResult.error) {
return next(validationResult.error);
}

request.resultData = validationResult.value;

next();
});
}

module.exports = validateMultipartMiddleware;
3 changes: 3 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
post: require('./post')
};
27 changes: 27 additions & 0 deletions src/routes/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const router = require('express').Router();
const titles = require('../titles');

router.post('/post', async (request, response, next) => {
const title = titles[request.titleCode];

const resultType = title.type;
const ResultTypeModel = title.result_model;

const result = new ResultTypeModel({
type: resultType,
bossUniqueId: request.headers['x-boss-uniqueid'],
bossDigest: request.headers['x-boss-digest'],
resultData: request.resultData
});

try {
await result.save();
} catch (error) {
return next(error);
}


return response.send('success');
});

module.exports = router;
11 changes: 7 additions & 4 deletions src/server.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
const express = require('express');
const morgan = require('morgan');
const routes = require('./routes')
const titleCodeMiddleware = require('./middleware/title-code');
const rawBodyMiddleware = require('./middleware/raw-body');
const validateBOSSDigestMiddleware = require('./middleware/validate-boss-digest');
const copyRequestStreamMiddleware = require('./middleware/copy-request-stream');
const validateMultipartMiddleware = require('./middleware/validate-multipart');
const database = require('./database');
const config = require('../config.json');

const splatoon = require('./titles/splatoon');

const app = express();
const { port } = config.http;

app.use(morgan('dev'));
app.use(titleCodeMiddleware);
app.use(rawBodyMiddleware);
app.use(validateBOSSDigestMiddleware);
app.use(copyRequestStreamMiddleware);
app.use(splatoon);
app.use(validateMultipartMiddleware);
app.use(routes.post);

// * 404 error handler
app.use((request, response) => {
Expand All @@ -35,7 +38,7 @@ app.use((error, request, response, next) => {
console.log(error);
// * 5XX means a server error, but this would be a 4XX client error
// * (wrong body or hash provided)
// * Real server sends this, however, so leave as is
// * The real server sends 500 for all errors, however, so leave as is
return response.status(500).send('error');
});

Expand Down
3 changes: 3 additions & 0 deletions src/titles/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
'wup-agmj': require('./splatoon')
};
132 changes: 132 additions & 0 deletions src/titles/splatoon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
const multer = require('.multer');
const { joi } = require('../util');
const { SplatfestResult } = require('../models/splatfest_result');

module.exports = {
type: 'splatfest',
result_model: SplatfestResult,
validation_schema: joi.object({
ServerEnv: joi.string(),
PId: joi.numberstring(),
MiiName: joi.string(),
Model: joi.numberstring(),
Skin: joi.numberstring(),
EyeColor: joi.numberstring(),
Weapon: joi.numberstring(),
SumPaint: joi.numberstring(),
Gear_Shoes: joi.numberstring(),
Gear_Shoes_Skill0: joi.numberstring(),
Gear_Shoes_Skill1: joi.numberstring(),
Gear_Shoes_Skill2: joi.numberstring(),
Gear_Clothes: joi.numberstring(),
Gear_Clothes_Skill0: joi.numberstring(),
Gear_Clothes_Skill1: joi.numberstring(),
Gear_Clothes_Skill2: joi.numberstring(),
Gear_Head: joi.numberstring(),
Gear_Head_Skill0: joi.numberstring(),
Gear_Head_Skill1: joi.numberstring(),
Gear_Head_Skill2: joi.numberstring(),
Rank: joi.numberstring(),
Udemae: joi.numberstring(),
RegularKillSum: joi.numberstring(),
WinSum: joi.numberstring(),
LoseSum: joi.numberstring(),
TodaysCondition: joi.numberstring(),
Region: joi.string(),
Area: joi.numberstring(),
FesID: joi.numberstring(),
FesState: joi.numberstring(),
FesTeam: joi.numberstring(),
FesGrade: joi.numberstring(),
FesPoint: joi.numberstring(),
FesPower: joi.numberstring(),
BestFesPower: joi.numberstring(),
Money: joi.numberstring(),
Shell: joi.numberstring(),
TotalBonusShell: joi.numberstring(),
MatchingTime: joi.numberstring(),
IsRematch: joi.numberstring(),
SaveDataCorrupted: joi.numberstring(),
DisconnectedPId: joi.numberstring(),
DisconnectedMemHash: joi.numberstring(),
SessionID: joi.numberstring(),
StartNetworkTime: joi.numberstring(),
GameMode: joi.numberstring(),
Rule: joi.numberstring(),
Stage: joi.numberstring(),
Team: joi.numberstring(),
IsWinGame: joi.numberstring(),
Kill: joi.numberstring(),
Death: joi.numberstring(),
Paint: joi.numberstring(),
IsNetworkBurst: joi.numberstring(),
BottleneckPlayerNum: joi.numberstring(),
MaxSilenceFrame: joi.numberstring(),
MemoryHash: joi.numberstring(),
Paint_Alpha: joi.numberstring(),
Paint_Bravo: joi.numberstring(),
FaceImg: joi.binary()
}).options({ presence: 'required' }).required(),
multipart_validator: multer().fields([
{ name: 'ServerEnv' },
{ name: 'PId' },
{ name: 'MiiName' },
{ name: 'Model' },
{ name: 'Skin' },
{ name: 'EyeColor' },
{ name: 'Weapon' },
{ name: 'SumPaint' },
{ name: 'Gear_Shoes' },
{ name: 'Gear_Shoes_Skill0' },
{ name: 'Gear_Shoes_Skill1' },
{ name: 'Gear_Shoes_Skill2' },
{ name: 'Gear_Clothes' },
{ name: 'Gear_Clothes_Skill0' },
{ name: 'Gear_Clothes_Skill1' },
{ name: 'Gear_Clothes_Skill2' },
{ name: 'Gear_Head' },
{ name: 'Gear_Head_Skill0' },
{ name: 'Gear_Head_Skill1' },
{ name: 'Gear_Head_Skill2' },
{ name: 'Rank' },
{ name: 'Udemae' },
{ name: 'RegularKillSum' },
{ name: 'WinSum' },
{ name: 'LoseSum' },
{ name: 'TodaysCondition' },
{ name: 'Region' },
{ name: 'Area' },
{ name: 'FesID' },
{ name: 'FesState' },
{ name: 'FesTeam' },
{ name: 'FesGrade' },
{ name: 'FesPoint' },
{ name: 'FesPower' },
{ name: 'BestFesPower' },
{ name: 'Money' },
{ name: 'Shell' },
{ name: 'TotalBonusShell' },
{ name: 'MatchingTime' },
{ name: 'IsRematch' },
{ name: 'SaveDataCorrupted' },
{ name: 'DisconnectedPId' },
{ name: 'DisconnectedMemHash' },
{ name: 'SessionID' },
{ name: 'StartNetworkTime' },
{ name: 'GameMode' },
{ name: 'Rule' },
{ name: 'Stage' },
{ name: 'Team' },
{ name: 'IsWinGame' },
{ name: 'Kill' },
{ name: 'Death' },
{ name: 'Paint' },
{ name: 'IsNetworkBurst' },
{ name: 'BottleneckPlayerNum' },
{ name: 'MaxSilenceFrame' },
{ name: 'MemoryHash' },
{ name: 'Paint_Alpha' },
{ name: 'Paint_Bravo' },
{ name: 'FaceImg' }
])
};
20 changes: 0 additions & 20 deletions src/titles/splatoon/index.js

This file was deleted.

Loading

0 comments on commit 27ef1dd

Please sign in to comment.