Skip to content

Commit 926cdcc

Browse files
committed
some code cleanup
1 parent 85bf5a6 commit 926cdcc

File tree

4 files changed

+26
-133
lines changed

4 files changed

+26
-133
lines changed

src/api/kzMaps.js

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,6 @@ const { validatePagination, sanitizeString } = require("../utils/validators");
55
const logger = require("../utils/logger");
66
const { cacheMiddleware, kzKeyGenerator } = require("../utils/cacheMiddleware");
77

8-
/**
9-
* Helper function to get partition hints for kz_records_partitioned
10-
* Partitions: p_old (before 2018), p2018-p2027, pfuture
11-
* @param {string} dateFrom - Optional start date filter
12-
* @param {string} dateTo - Optional end date filter
13-
* @returns {string} Partition hint clause or empty string
14-
*/
15-
const getPartitionHint = (dateFrom, dateTo) => {
16-
const partitions = [];
17-
const currentYear = new Date().getFullYear();
18-
19-
if (!dateFrom && !dateTo) {
20-
// No date filter - scan all partitions (let MySQL optimize)
21-
return "";
22-
}
23-
24-
const fromYear = dateFrom ? new Date(dateFrom).getFullYear() : 2014;
25-
const toYear = dateTo ? new Date(dateTo).getFullYear() : currentYear;
26-
27-
if (fromYear < 2018) {
28-
partitions.push("p_old");
29-
}
30-
31-
for (
32-
let year = Math.max(fromYear, 2018);
33-
year <= Math.min(toYear, 2027);
34-
year++
35-
) {
36-
partitions.push(`p${year}`);
37-
}
38-
39-
if (toYear >= currentYear) {
40-
partitions.push("pfuture");
41-
}
42-
43-
if (partitions.length === 0) return "";
44-
return `PARTITION (${partitions.join(",")})`;
45-
};
46-
47-
/**
48-
* Get default partition hint for queries without date filters
49-
* Uses all partitions for complete data coverage
50-
*/
51-
const getDefaultPartitionHint = () => {
52-
// For aggregate queries across all data, don't use partition hints
53-
// Let MySQL's partition pruning work naturally with map_id filters
54-
return "";
55-
};
56-
578
/**
589
* @swagger
5910
* /kzglobal/maps:

src/api/kzPlayers.js

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,10 @@ const {
77
isValidSteamID,
88
convertToSteamID64,
99
} = require("../utils/validators");
10+
const { getPlayerPartitionHint } = require("../utils/kzHelpers");
1011
const logger = require("../utils/logger");
1112
const { cacheMiddleware, kzKeyGenerator } = require("../utils/cacheMiddleware");
1213

13-
/**
14-
* Helper function to get partition hints for player queries
15-
* Since player records span many years, we need smart partitioning
16-
*/
17-
const getPlayerPartitionHint = (yearFilter) => {
18-
const currentYear = new Date().getFullYear();
19-
const partitions = [];
20-
21-
if (!yearFilter) {
22-
// For general player stats, scan all partitions (no hint - let MySQL optimize)
23-
return "";
24-
}
25-
26-
const year = parseInt(yearFilter, 10);
27-
if (year < 2018) {
28-
partitions.push("p_old");
29-
} else if (year >= 2018 && year <= currentYear + 1) {
30-
partitions.push(`p${year}`);
31-
}
32-
33-
if (year >= currentYear) {
34-
partitions.push("pfuture");
35-
}
36-
37-
return partitions.length > 0 ? `PARTITION (${partitions.join(",")})` : "";
38-
};
39-
4014
/**
4115
* @swagger
4216
* /kzglobal/players:

src/utils/auth.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* - Uses same key extraction methods (Bearer, X-API-Key, query param)
1515
*/
1616

17+
const crypto = require("crypto");
1718
const logger = require("./logger");
1819

1920
// Admin Configuration
@@ -152,18 +153,22 @@ function extractAPIKey(req) {
152153
}
153154

154155
/**
155-
* Validate admin API key
156+
* Validate admin API key (ADMIN_API_KEY)
156157
* Uses timing-safe comparison to prevent timing attacks
158+
* @param {string} providedKey - The key to validate
159+
* @returns {boolean} True if key matches ADMIN_API_KEY
157160
*/
158-
function validateAPIKey(providedKey) {
161+
function validateAdminKey(providedKey) {
159162
return validateKeyAgainst(providedKey, ADMIN_API_KEY);
160163
}
161164

162165
/**
163-
* Validate general API key (for rate limit bypass)
166+
* Validate general API key (API_KEY - for rate limit bypass)
164167
* Uses timing-safe comparison to prevent timing attacks
168+
* @param {string} providedKey - The key to validate
169+
* @returns {boolean} True if key matches API_KEY
165170
*/
166-
function validateApiKey(providedKey) {
171+
function validateGeneralApiKey(providedKey) {
167172
return validateKeyAgainst(providedKey, API_KEY);
168173
}
169174

@@ -199,7 +204,7 @@ function shouldSkipRateLimit(req) {
199204
const apiKey = extractAPIKey(req);
200205

201206
// Check API key (either general API_KEY or ADMIN_API_KEY)
202-
if (apiKey && (validateApiKey(apiKey) || validateAPIKey(apiKey))) {
207+
if (apiKey && (validateGeneralApiKey(apiKey) || validateAdminKey(apiKey))) {
203208
logger.debug(`Rate limit bypass: Valid API key from ${clientIP}`);
204209
req.apiAuth = { method: "api_key", ip: clientIP };
205210
return true;
@@ -230,7 +235,7 @@ function apiKeyMiddleware(req, res, next) {
230235
const clientIP = getClientIP(req);
231236
const apiKey = extractAPIKey(req);
232237

233-
if (apiKey && (validateApiKey(apiKey) || validateAPIKey(apiKey))) {
238+
if (apiKey && (validateGeneralApiKey(apiKey) || validateAdminKey(apiKey))) {
234239
req.apiAuth = { method: "api_key", ip: clientIP };
235240
} else if (isApiWhitelisted(clientIP)) {
236241
req.apiAuth = { method: "ip_whitelist", ip: clientIP };
@@ -255,7 +260,7 @@ function adminAuth(req, res, next) {
255260

256261
// Method 1: API Key authentication
257262
if (apiKey) {
258-
if (validateAPIKey(apiKey)) {
263+
if (validateAdminKey(apiKey)) {
259264
logger.debug(`Admin auth: API key accepted from ${clientIP}`);
260265
req.adminAuth = { method: "api_key", ip: clientIP };
261266
return next();
@@ -318,7 +323,7 @@ function optionalAdminAuth(req, res, next) {
318323

319324
req.isAdmin = false;
320325

321-
if (apiKey && validateAPIKey(apiKey)) {
326+
if (apiKey && validateAdminKey(apiKey)) {
322327
req.isAdmin = true;
323328
req.adminAuth = { method: "api_key", ip: clientIP };
324329
} else if (isWhitelisted(clientIP)) {
@@ -335,9 +340,10 @@ function optionalAdminAuth(req, res, next) {
335340
/**
336341
* Generate a secure random API key
337342
* Can be used to generate keys for .env file
343+
* @param {number} length - Length of key in bytes (default: 32, produces 64 hex chars)
344+
* @returns {string} Random hex string
338345
*/
339346
function generateAPIKey(length = 32) {
340-
const crypto = require("crypto");
341347
return crypto.randomBytes(length).toString("hex");
342348
}
343349

src/utils/kzHelpers.js

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
* used across kzLocal, kzLocalCS2, kzRecords, kzPlayers, kzMaps, etc.
66
*/
77

8+
// Import shared utilities from validators to avoid duplication
9+
const {
10+
STEAM_BASE_ID,
11+
steamid32To64,
12+
steamid64To32,
13+
validateSortField,
14+
validateSortOrder,
15+
} = require("./validators");
16+
817
// ==================== CONSTANTS ====================
918

1019
/**
@@ -75,31 +84,6 @@ const SCROLL_EFF_TYPES = {
7584
4: "timing_samples",
7685
};
7786

78-
// ==================== STEAMID CONVERSION ====================
79-
80-
/**
81-
* Steam base ID constant (used in all SteamID conversions)
82-
*/
83-
const STEAM_BASE_ID = BigInt("76561197960265728");
84-
85-
/**
86-
* Convert SteamID32 (account ID) to SteamID64
87-
* @param {number|string} steamid32 - SteamID32 (account ID)
88-
* @returns {string} SteamID64
89-
*/
90-
function steamid32To64(steamid32) {
91-
return (STEAM_BASE_ID + BigInt(steamid32)).toString();
92-
}
93-
94-
/**
95-
* Convert SteamID64 to SteamID32 (account ID)
96-
* @param {string} steamid64 - SteamID64
97-
* @returns {number} SteamID32
98-
*/
99-
function steamid64To32(steamid64) {
100-
return Number(BigInt(steamid64) - STEAM_BASE_ID);
101-
}
102-
10387
// ==================== FORMAT FUNCTIONS ====================
10488

10589
/**
@@ -152,29 +136,7 @@ function formatAirtime(airtime, tickrate = 64) {
152136
}
153137

154138
// ==================== QUERY HELPERS ====================
155-
156-
/**
157-
* Validate and get sort field from allowed fields
158-
* @param {string} sort - Requested sort field
159-
* @param {string[]} validFields - Array of valid field names
160-
* @param {string} defaultField - Default field if invalid
161-
* @returns {string} Valid sort field
162-
*/
163-
function validateSortField(sort, validFields, defaultField) {
164-
return validFields.includes(sort) ? sort : defaultField;
165-
}
166-
167-
/**
168-
* Validate and get sort order (ASC/DESC)
169-
* @param {string} order - Requested order ('asc' or 'desc')
170-
* @param {string} defaultOrder - Default order if not specified ('DESC')
171-
* @returns {string} 'ASC' or 'DESC'
172-
*/
173-
function validateSortOrder(order, defaultOrder = "DESC") {
174-
if (order === "asc") return "ASC";
175-
if (order === "desc") return "DESC";
176-
return defaultOrder;
177-
}
139+
// Note: validateSortField and validateSortOrder are imported from validators.js
178140

179141
/**
180142
* Generate partition hint for yearly partitioned tables

0 commit comments

Comments
 (0)