fix eslint errors

This commit is contained in:
2023-08-09 15:49:53 +02:00
parent 0aafd390a7
commit 7470d8174f
8 changed files with 561 additions and 659 deletions
+11 -9
View File
@@ -1,17 +1,19 @@
module.exports = { module.exports = {
env: { env: {
browser: true, browser: true,
es2021: true es2021: true,
}, },
extends: 'standard-with-typescript', extends: "standard-with-typescript",
overrides: [], overrides: [],
parserOptions: { parserOptions: {
ecmaVersion: 'latest', ecmaVersion: "latest",
sourceType: 'module', sourceType: "module",
project: ['./tsconfig.json'] project: ["./tsconfig.json"],
}, },
rules: { rules: {
'@typescript-eslint/strict-boolean-expressions': 0, "@typescript-eslint/strict-boolean-expressions": 0,
'@typescript-eslint/explicit-function-return-type': 'off' "@typescript-eslint/explicit-function-return-type": "off",
} },
} plugins: ["jest"],
"jest/globals": true,
};
+2 -1
View File
@@ -6,5 +6,6 @@
"eslint.format.enable": true, "eslint.format.enable": true,
"[typescript]": { "[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint" "editor.defaultFormatter": "dbaeumer.vscode-eslint"
} },
"typescript.tsdk": "node_modules\\typescript\\lib"
} }
+306 -410
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -3,6 +3,7 @@
"@types/ws": "^8.5.4", "@types/ws": "^8.5.4",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
"eslint-plugin-jest": "^27.2.3",
"express": "^4.18.2", "express": "^4.18.2",
"express-basic-auth": "^1.2.1", "express-basic-auth": "^1.2.1",
"express-validator": "^6.15.0", "express-validator": "^6.15.0",
+1 -1
View File
@@ -43,7 +43,7 @@ router.get('/hosts', (_req, res) => {
void (async () => { void (async () => {
const result = await getHostList() const result = await getHostList()
const data: Record<number, string> = {} const data: Record<number, string> = {}
result.forEach((e) => (data[Number(e.id)] = e.name)) result.forEach((e) => (data[Number(e.host_id)] = e.host_name))
const dataString = JSON.stringify(data) const dataString = JSON.stringify(data)
const buffer = Buffer.from(dataString) const buffer = Buffer.from(dataString)
+170 -161
View File
@@ -1,47 +1,58 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Router } from 'express' import { Router } from 'express'
import { body, header } from 'express-validator' import { body, header } from 'express-validator'
import { CreateKillRecord, CheckServerToken } from '../db/db' import { /* CreateKillRecord, */ CheckServerToken } from '../db/db'
import { validateErrors } from '../common' import { validateErrors } from '../common'
const router = Router() const router = Router()
//auth middleware // auth middleware
router.post( router.post(
'/*', '/*',
header('authorization') header('authorization')
.exists({ checkFalsy: true }) .exists({ checkFalsy: true })
.withMessage('Missing Authorization Header') .withMessage('Missing Authorization Header')
.bail() .bail()
.custom(e => e.split(' ')[0].toLowerCase() == 'bearer') .custom((e) => e.split(' ')[0].toLowerCase() === 'bearer')
.withMessage('Authorization Token is not Bearer'), .withMessage('Authorization Token is not Bearer'),
validateErrors, validateErrors,
async (req, res, next) => { (req, res, next) => {
if (!req) return res.sendStatus(500) void (async () => {
if (!req.headers.authorization) { if (!req) return res.sendStatus(500)
console.error("no authorization header") if (!req.headers.authorization) {
return res.sendStatus(403) console.error('no authorization header')
} return res.sendStatus(403)
const query = await CheckServerToken(req.headers.authorization.split(' ')[1]) }
if (!query || !query.id) { const query = await CheckServerToken(
console.error("incorrect token : " + req.headers.authorization.split(' ')[1] + " for " + req.body.servername + " with IP " + (req.headers['x-forwarded-for']?.toString() || req.headers.authorization.split(' ')[1]
req.socket.remoteAddress?.toString() || )
'')) if (!query?.host_id) {
return res.sendStatus(403) console.error(
} `incorrect token : ${
next() req.headers.authorization.split(' ')[1]
} with IP ${
req.headers['x-forwarded-for']?.toString() ??
req.socket.remoteAddress?.toString() ??
''
}`
)
return res.sendStatus(403)
}
next()
})()
} }
) )
//Route to check auth // Route to check auth
router.post('/', (req, res) => { router.post('/', (req, res) => {
res.sendStatus(200) res.sendStatus(200)
}) })
const serversCount: { [id: string]: number } = {} // const serversCount: Record<string, number> = {}
const serversTimeout: { [id: string]: NodeJS.Timeout } = {} // const serversTimeout: Record<string, NodeJS.Timeout> = {}
//same rate limiting code as register. max 10 kills per server every 1 sec. should be enough. // same rate limiting code as register. max 10 kills per server every 1 sec. should be enough.
/*router.post('/kill', (req, res, next) => { /* router.post('/kill', (req, res, next) => {
let host = Number(req.query.serverId) let host = Number(req.query.serverId)
if (serversCount[serverId] > 2) { if (serversCount[serverId] > 2) {
return res.status(429).json({ return res.status(429).json({
@@ -55,7 +66,7 @@ const serversTimeout: { [id: string]: NodeJS.Timeout } = {}
serversCount[serverId] = 0 serversCount[serverId] = 0
}, 1000) }, 1000)
next() next()
})*/ }) */
router.post( router.post(
'/kill', '/kill',
@@ -134,149 +145,147 @@ router.post(
.isString() .isString()
.isLength({ max: 50 }) .isLength({ max: 50 })
.isAscii(), .isAscii(),
body('servername',).isString() body('servername').isString().isLength({ max: 100 }).isAscii(),
.isLength({ max: 100 })
.isAscii(),
body(['distance', 'game_time'], 'must be postitive floats').isFloat({ body(['distance', 'game_time'], 'must be postitive floats').isFloat({
min: 0 min: 0
}), }),
body(['cause_of_death', 'victim_id'], 'mandatory').exists().notEmpty(), body(['cause_of_death', 'victim_id'], 'mandatory').exists().notEmpty(),
//do we need this ? // do we need this ?
//body('servername').customSanitizer(e => e.replace(/[^a-z0-9]/gi, '')), // body('servername').customSanitizer(e => e.replace(/[^a-z0-9]/gi, '')),
validateErrors, validateErrors,
async (req, res) => { (req, res) => {
// Do we check the same thing twice ????? void (async () => {
if (!req.headers.authorization) return res.sendStatus(403) // Do we check the same thing twice ?????
const headers = req.headers.authorization.split(' ') if (!req.headers.authorization) return res.sendStatus(403)
if (headers[0].toLowerCase() != "bearer") return res.status(403).send("authorization must be token bearer") const headers = req.headers.authorization.split(' ')
const query = (await CheckServerToken(headers[1])) if (headers[0].toLowerCase() !== 'bearer') { return res.status(403).send('authorization must be token bearer') }
if (!query) return res.sendStatus(403) const query = await CheckServerToken(headers[1])
const host = query.id if (!query) return res.sendStatus(403)
const { // const host = query.id
servername, // const {
killstat_version, // servername,
match_id, // match_id,
game_mode, // game_mode,
map, // map,
game_time, // game_time,
player_count, // player_count,
attacker_name, // attacker_name,
attacker_id, // attacker_id,
attacker_current_weapon, // attacker_current_weapon,
attacker_current_weapon_mods, // attacker_current_weapon_mods,
attacker_weapon_1, // attacker_weapon_1,
attacker_weapon_1_mods, // attacker_weapon_1_mods,
attacker_weapon_2, // attacker_weapon_2,
attacker_weapon_2_mods, // attacker_weapon_2_mods,
attacker_weapon_3, // attacker_weapon_3,
attacker_weapon_3_mods, // attacker_weapon_3_mods,
attacker_offhand_weapon_1, // attacker_offhand_weapon_1,
attacker_offhand_weapon_1_mods, // attacker_offhand_weapon_1_mods,
attacker_offhand_weapon_2, // attacker_offhand_weapon_2,
attacker_offhand_weapon_2_mods, // attacker_offhand_weapon_2_mods,
victim_name, // victim_name,
victim_id, // victim_id,
victim_current_weapon, // victim_current_weapon,
victim_current_weapon_mods, // victim_current_weapon_mods,
victim_weapon_1, // victim_weapon_1,
victim_weapon_1_mods, // victim_weapon_1_mods,
victim_weapon_2, // victim_weapon_2,
victim_weapon_2_mods, // victim_weapon_2_mods,
victim_weapon_3, // victim_weapon_3,
victim_weapon_3_mods, // victim_weapon_3_mods,
victim_offhand_weapon_1, // victim_offhand_weapon_1,
victim_offhand_weapon_1_mods, // victim_offhand_weapon_1_mods,
victim_offhand_weapon_2, // victim_offhand_weapon_2,
victim_offhand_weapon_2_mods, // victim_offhand_weapon_2_mods,
cause_of_death, // cause_of_death,
distance // distance
} = req.body // } = req.body
CreateKillRecord({ // CreateKillRecord({
killstat_version, // servername,
servername, // host,
host, // match_id,
match_id, // game_mode,
game_mode, // map,
map, // game_time,
game_time, // player_count,
player_count, // attacker_name,
attacker_name, // attacker_id,
attacker_id, // attacker_current_weapon,
attacker_current_weapon, // attacker_current_weapon_mods,
attacker_current_weapon_mods, // attacker_weapon_1,
attacker_weapon_1, // attacker_weapon_1_mods,
attacker_weapon_1_mods, // attacker_weapon_2,
attacker_weapon_2, // attacker_weapon_2_mods,
attacker_weapon_2_mods, // attacker_weapon_3,
attacker_weapon_3, // attacker_weapon_3_mods,
attacker_weapon_3_mods, // attacker_offhand_weapon_1,
attacker_offhand_weapon_1, // attacker_offhand_weapon_1_mods,
attacker_offhand_weapon_1_mods, // attacker_offhand_weapon_2,
attacker_offhand_weapon_2, // attacker_offhand_weapon_2_mods,
attacker_offhand_weapon_2_mods, // victim_name,
victim_name, // victim_id,
victim_id, // victim_current_weapon,
victim_current_weapon, // victim_current_weapon_mods,
victim_current_weapon_mods, // victim_weapon_1,
victim_weapon_1, // victim_weapon_1_mods,
victim_weapon_1_mods, // victim_weapon_2,
victim_weapon_2, // victim_weapon_2_mods,
victim_weapon_2_mods, // victim_weapon_3,
victim_weapon_3, // victim_weapon_3_mods,
victim_weapon_3_mods, // victim_offhand_weapon_1,
victim_offhand_weapon_1, // victim_offhand_weapon_1_mods,
victim_offhand_weapon_1_mods, // victim_offhand_weapon_2,
victim_offhand_weapon_2, // victim_offhand_weapon_2_mods,
victim_offhand_weapon_2_mods, // cause_of_death,
cause_of_death, // distance
distance // })
}) // .then((e) => {
.then((e) => { // res.sendStatus(201)
res.sendStatus(201) // console.log(
console.log( // `[${new Date().toLocaleString()}] Kill submitted for server ${servername}, ${attacker_name} killed ${victim_name}`
`[${new Date().toLocaleString()}] Kill submitted for server ${servername}, ${attacker_name} killed ${victim_name}` // )
) // })
}) // .catch((e) => {
.catch((e) => { // res.sendStatus(500)
res.sendStatus(500) // console.error({
console.error({ // killstat_version,
killstat_version, // servername,
servername, // host,
host, // match_id,
match_id, // game_mode,
game_mode, // map,
map, // game_time,
game_time, // player_count,
player_count, // attacker_name,
attacker_name, // attacker_id,
attacker_id, // attacker_current_weapon,
attacker_current_weapon, // attacker_current_weapon_mods,
attacker_current_weapon_mods, // attacker_weapon_1,
attacker_weapon_1, // attacker_weapon_1_mods,
attacker_weapon_1_mods, // attacker_weapon_2,
attacker_weapon_2, // attacker_weapon_2_mods,
attacker_weapon_2_mods, // attacker_weapon_3,
attacker_weapon_3, // attacker_weapon_3_mods,
attacker_weapon_3_mods, // attacker_offhand_weapon_1,
attacker_offhand_weapon_1, // attacker_offhand_weapon_2,
attacker_offhand_weapon_2, // victim_name,
victim_name, // victim_id,
victim_id, // victim_current_weapon,
victim_current_weapon, // victim_current_weapon_mods,
victim_current_weapon_mods, // victim_weapon_1,
victim_weapon_1, // victim_weapon_1_mods,
victim_weapon_1_mods, // victim_weapon_2,
victim_weapon_2, // victim_weapon_2_mods,
victim_weapon_2_mods, // victim_weapon_3,
victim_weapon_3, // victim_weapon_3_mods,
victim_weapon_3_mods, // victim_offhand_weapon_1,
victim_offhand_weapon_1, // victim_offhand_weapon_2,
victim_offhand_weapon_2, // cause_of_death,
cause_of_death, // distance
distance // })
}) // console.error(e)
console.error(e) // })
}) })()
} }
) )
export default router export default router
+3 -3
View File
@@ -1,9 +1,9 @@
import * as dotenv from 'dotenv' import * as dotenv from 'dotenv'
dotenv.config()
import express from 'express' import express from 'express'
import cors from 'cors' import cors from 'cors'
import db, { dbReady } from './db/db' import { dbReady } from './db/db'
import server from './server/server' import server from './server/server'
dotenv.config()
const app = express() const app = express()
const port = 3001 const port = 3001
@@ -18,7 +18,7 @@ app.get('/', (req, res) => {
app.use('/', server) app.use('/', server)
export default new Promise((resolve, reject) => { export default new Promise((resolve, reject) => {
dbReady().then((e) => { void dbReady().then((e) => {
const listenServer = app.listen(port, '0.0.0.0', () => { const listenServer = app.listen(port, '0.0.0.0', () => {
console.log(`Tone server api listening on port ${port}`) console.log(`Tone server api listening on port ${port}`)
resolve(listenServer) resolve(listenServer)
+67 -74
View File
@@ -1,85 +1,78 @@
import * as dotenv from 'dotenv' import * as dotenv from 'dotenv'
dotenv.config()
import { Client } from 'pg' import { Client } from 'pg'
import { WebSocket, WebSocketServer } from 'ws' import { type WebSocket, WebSocketServer } from 'ws'
import { KillTable } from './db/model' import { type KillTable } from './db/model'
dotenv.config()
const port = 3002 const port = 3002
const wss = new WebSocketServer({ port }) const wss = new WebSocketServer({ port })
export const pgClient = new Client({ export const pgClient = new Client({
host: process.env.POSTGRES_HOST, host: process.env.POSTGRES_HOST,
database: process.env.POSTGRES_DATABASE, database: process.env.POSTGRES_DATABASE,
user: process.env.POSTGRES_USER, user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD password: process.env.POSTGRES_PASSWORD
}) })
wss.on('connection', function connection(ws: WebSocket & { isAlive: boolean }, req) { wss.on('connection', function connection (ws: WebSocket & { isAlive: boolean }, req) {
const ip = const ip = req?.headers['x-forwarded-for']?.toString().split(',')[0].trim() ??
req?.headers['x-forwarded-for']?.toString().split(',')[0].trim() || req.socket.remoteAddress ?? 'ip_unknown'
req.socket.remoteAddress console.log(`${new Date().toLocaleString()},${ip},connect,${wss.clients.size}`)
console.log( ws.onclose = function () {
new Date().toLocaleString() + ',' + ip + ',connect,' + wss.clients.size console.log(`${new Date().toLocaleString()},${ip},connect,${wss.clients.size}`)
) }
ws.onclose = function () { ws.onmessage = function (msg) {
const ip = if (msg.data === 'pong') {
req?.headers['x-forwarded-for']?.toString().split(',')[0].trim() || ws.isAlive = true
req.socket.remoteAddress return
console.log( }
new Date().toLocaleString() + ',' + ip + ',close,' + wss.clients.size if (msg.data === 'ping') {
ws.send('pong')
}
}
ws.send('ping')
})
const interval = setInterval(function ping () {
wss.clients.forEach(function each (ws) {
if (!(ws as WebSocket & { isAlive: boolean }).isAlive) { ws.terminate(); return }
(ws as WebSocket & { isAlive: boolean }).isAlive = false
ws.send('ping')
})
}, 30000)
wss.on('close', function close () {
clearInterval(interval)
})
export default async () => {
await pgClient.connect()
await pgClient.query('LISTEN new_kill')
pgClient.on('notification', (data) => {
if (!data.payload) return
const payload = JSON.parse(data.payload) as KillTable
wss.clients.forEach(function (client) {
if (client.readyState === client.OPEN) {
client.send(
JSON.stringify({
match_id: payload.match_id,
attacker_id: payload.attacker_id
// attacker_name: payload.attacker_name,
// cause_of_death: payload.cause_of_death,
// victim_id: payload.victim_id,
// victim_name: payload.victim_name,
// attacker_current_weapon: payload.attacker_current_weapon,
// victim_current_weapon: payload.victim_current_weapon,
// distance: payload.distance,
// game_mode: payload.game_mode,
// servername: payload.servername,
// map: payload.map,
// host: payload.host
})
) )
} }
ws.onmessage = function (msg) {
if (msg.data === "pong") {
return ws.isAlive = true
}
if (msg.data === "ping") {
return ws.send("pong")
}
}
ws.send("ping");
})
const interval = setInterval(function ping() {
wss.clients.forEach(function each(ws) {
if ((ws as WebSocket & { isAlive: boolean }).isAlive === false) return ws.terminate();
(ws as WebSocket & { isAlive: boolean }).isAlive = false;
ws.send("ping");
});
}, 30000);
wss.on('close', function close() {
clearInterval(interval);
});
export default new Promise(async (resolve, reject) => {
await pgClient.connect()
await pgClient.query('LISTEN new_kill')
pgClient.on('notification', (data) => {
if (!data.payload) return
const payload = JSON.parse(data.payload) as KillTable
wss.clients.forEach(function (client) {
if (client.readyState === client.OPEN) {
client.send(
JSON.stringify({
match_id: payload.match_id,
attacker_id: payload.attacker_id,
attacker_name: payload.attacker_name,
cause_of_death: payload.cause_of_death,
victim_id: payload.victim_id,
victim_name: payload.victim_name,
attacker_current_weapon: payload.attacker_current_weapon,
victim_current_weapon: payload.victim_current_weapon,
distance: payload.distance,
game_mode: payload.game_mode,
servername: payload.servername,
map: payload.map,
host: payload.host
})
)
}
})
}) })
}) })
}