Add DDL-based DB init and bootstrap

Add bootstrap entrypoint and migrate DB schema setup to SQL files. Introduces bootstrap.js, many data/ddl/*.sql files, and a new runDDL() in modules/database.js (exports pool and runDDL). Remove legacy modules/databaseGlobals.js. Update repositories and code to use database.pool.query calls. Bump package version and set main to bootstrap.js. Clean up server.js to remove inline DB/cert init (now handled by bootstrap). Overall: refactor DB initialization to run ordered SQL DDL files and centralize startup logic.
This commit is contained in:
2026-09-06 23:52:25 +02:00
parent 93892197ad
commit 87407fe604
40 changed files with 405 additions and 485 deletions
+20
View File
@@ -0,0 +1,20 @@
const certificates = require("./modules/certificatesManager")
const database = require("./modules/database")
const logger = require("./modules/logger")
async function boot() {
try {
await database.runDDL()
certificates.setupKeys()
require("./server")
} catch (error) {
if (error?.fatal) {
logger.error("Fatal error while booting:", ["STARTUP", "cyan"])
logger.error(error?.stack || error?.toString(), ["STARTUP", "cyan"])
process.exit(1)
}
return
}
}
boot()
+8
View File
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS players (
email VARCHAR(255) NULL UNIQUE,
username VARCHAR(16) NOT NULL UNIQUE,
password TEXT NOT NULL,
uuid VARCHAR(36) NOT NULL UNIQUE PRIMARY KEY,
nameChangeAllowed TINYINT(1) DEFAULT 1,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
+7
View File
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS playersProperties (
name VARCHAR(256) NOT NULL,
value VARCHAR(512) NOT NULL,
uuid VARCHAR(36) NOT NULL,
UNIQUE KEY uniqueProperty (uuid, name),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+6
View File
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS clientSessions (
accessToken TEXT NOT NULL,
clientToken VARCHAR(36) NOT NULL,
uuid VARCHAR(36) NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid)
)
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS legacyClientSessions (
sessionId VARCHAR(36) NOT NULL,
uuid VARCHAR(36) NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+8
View File
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS uuidToNameHistory (
uuid VARCHAR(36) NOT NULL,
username VARCHAR(255) NOT NULL,
changedAt DATETIME NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_uuidToNameHistory_uuid ON uuidToNameHistory (uuid);
+9
View File
@@ -0,0 +1,9 @@
DROP TRIGGER IF EXISTS log_new_user_name;
CREATE TRIGGER log_new_user_name
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO uuidToNameHistory (uuid, username, changedAt)
VALUES (NEW.uuid, NEW.username, NULL);
END;
+11
View File
@@ -0,0 +1,11 @@
DROP TRIGGER IF EXISTS log_user_name_change;
CREATE TRIGGER log_user_name_change
AFTER UPDATE ON players
FOR EACH ROW
BEGIN
IF OLD.username != NEW.username THEN
INSERT INTO uuidToNameHistory (uuid, username, changedAt)
VALUES (NEW.uuid, NEW.username, CURRENT_TIMESTAMP);
END IF;
END;
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS blockedServers (
hashedIp VARCHAR(40) NOT NULL PRIMARY KEY,
banner VARCHAR(256) DEFAULT 'CONSOLE',
reason VARCHAR(512) NULL
)
+8
View File
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS playersPrivileges (
uuid VARCHAR(36) PRIMARY KEY,
onlineChat TINYINT(1) DEFAULT 1,
multiplayerServer TINYINT(1) DEFAULT 1,
multiplayerRealms TINYINT(1) DEFAULT 1,
telemetry TINYINT(1) DEFAULT 1,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS playersPreferences (
uuid VARCHAR(36) PRIMARY KEY,
profanityFilter TINYINT(1) DEFAULT 0,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+4
View File
@@ -0,0 +1,4 @@
CREATE TABLE IF NOT EXISTS banReasons (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
reasonKey VARCHAR(512) UNIQUE NOT NULL
)
+11
View File
@@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS bans (
banId VARCHAR(512) PRIMARY KEY NOT NULL,
uuid VARCHAR(36) NOT NULL,
expires BIGINT DEFAULT NULL,
reason INTEGER NOT NULL,
reasonMessage VARCHAR(1024) DEFAULT NULL,
FOREIGN KEY(reason) REFERENCES banReasons(id),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_bans_uuid ON bans (uuid)
@@ -0,0 +1,9 @@
DROP TRIGGER IF EXISTS auto_init_player_settings;
CREATE TRIGGER auto_init_player_settings
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO playersPrivileges (uuid) VALUES (NEW.uuid);
INSERT INTO playersPreferences (uuid) VALUES (NEW.uuid);
END;
+7
View File
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS playersBlockslist (
blockerUuid VARCHAR(36) NOT NULL,
blockedUuid VARCHAR(36) NOT NULL,
PRIMARY KEY (blockerUuid, blockedUuid),
FOREIGN KEY (blockerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (blockedUuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+5
View File
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS usernameRules (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
rule VARCHAR(255) NOT NULL,
type INTEGER DEFAULT 0
)
+8
View File
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS textures (
uuid VARCHAR(36) NOT NULL UNIQUE,
hash VARCHAR(64) PRIMARY KEY NOT NULL,
type VARCHAR(10) NOT NULL,
url VARCHAR(2048) NOT NULL,
alias VARCHAR(64) NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
+12
View File
@@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS playersSkins (
playerUuid VARCHAR(36) NOT NULL,
assetHash VARCHAR(64) NOT NULL,
variant VARCHAR(10) DEFAULT "CLASSIC",
isSelected TINYINT(1) DEFAULT 0,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (playerUuid, assetHash),
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (assetHash) REFERENCES textures(hash)
);
CREATE INDEX IF NOT EXISTS idx_active_skin ON playersSkins (playerUuid, isSelected);
+11
View File
@@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS playersCapes (
playerUuid VARCHAR(36) NOT NULL,
assetHash VARCHAR(64) NOT NULL,
isSelected TINYINT(1) DEFAULT 0,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (playerUuid, assetHash),
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (assetHash) REFERENCES textures(hash) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_active_cape ON playersCapes (playerUuid, assetHash)
+3
View File
@@ -0,0 +1,3 @@
INSERT IGNORE INTO textures (hash, type, url, uuid) VALUES
('df8ed96c557d441a63e7b6a4a911ab84fa453b42fc2ae6b01c3e1b02e138168c', 'SKIN', '/texture/alex.png', UUID()),
('4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d', 'SKIN', '/texture/steve.png', UUID());
@@ -0,0 +1,2 @@
DROP TRIGGER IF EXISTS unique_active_skin;
DROP TRIGGER IF EXISTS unique_active_cape;
@@ -0,0 +1,23 @@
DROP TRIGGER IF EXISTS auto_assign_random_default_skin;
CREATE TRIGGER auto_assign_random_default_skin
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO playersSkins (playerUuid, assetHash, variant, isSelected)
SELECT
NEW.uuid,
hash,
CASE
WHEN hash = '4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d' THEN 'CLASSIC'
ELSE 'SLIM'
END,
1
FROM textures
WHERE hash IN (
'4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d',
'df8ed96c557d441a63e7b6a4a911ab84fa453b42fc2ae6b01c3e1b02e138168c'
)
ORDER BY RAND()
LIMIT 1;
END;
+9
View File
@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS playerCertificates (
uuid VARCHAR(36) PRIMARY KEY,
privateKey TEXT NOT NULL,
publicKey TEXT NOT NULL,
publicKeySignatureV2 TEXT NOT NULL,
expiresAt DATETIME NOT NULL,
refreshedAfter DATETIME NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+7
View File
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS playerProfileActions (
uuid VARCHAR(36) NOT NULL,
action VARCHAR(64) NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (uuid, action),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+8
View File
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS serverSessions (
uuid VARCHAR(36) PRIMARY KEY,
accessToken TEXT NOT NULL,
serverId VARCHAR(255) NOT NULL,
ip VARCHAR(45) NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+1
View File
@@ -0,0 +1 @@
SET GLOBAL event_scheduler = ON;
@@ -0,0 +1,4 @@
CREATE EVENT IF NOT EXISTS clean_expired_certificates
ON SCHEDULE EVERY 1 HOUR
DO
DELETE FROM playerCertificates WHERE expiresAt < NOW();
+6
View File
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS apiAdministrators (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) UNIQUE NOT NULL,
password TEXT NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS apiAdministratorsPermissionsList (
permissionKey VARCHAR(64) PRIMARY KEY
);
INSERT IGNORE INTO apiAdministratorsPermissionsList(permissionKey) VALUES ("RESET_PLAYER_SKIN"), ("GRANT_PLAYER_CAPE"), ("REMOVE_PLAYER_CAPE"), ("CHANGE_PLAYER_USERNAME"), ("CHANGE_PLAYER_PASSWORD"), ("UPLOAD_CAPE"), ("DELETE_CAPES"), ("PLAYER_BAN"), ("PLAYER_BAN_HISTORY"), ("PLAYER_BAN_STATUS"), ("PLAYER_ACTIONS_LIST"), ("PLAYER_UNBAN"), ("REGISTER_USER")
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS apiAdministratorsPermissions (
administratorId INTEGER NOT NULL,
permissionKey VARCHAR(64) NOT NULL,
PRIMARY KEY (administratorId, permissionKey),
FOREIGN KEY (administratorId) REFERENCES apiAdministrators(id) ON DELETE CASCADE,
FOREIGN KEY (permissionkey) REFERENCES apiAdministratorsPermissionsList(permissionKey) ON DELETE CASCADE
)
+6
View File
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS oaauth2LinkAttempts (
OAuth2LinkId VARCHAR(255) NOT NULL,
playerUuid VARCHAR(255) NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE
)
+76 -3
View File
@@ -1,16 +1,89 @@
const mariadb = require("mariadb") const mariadb = require("mariadb")
const logger = require("./logger")
const fs = require("fs/promises")
const path = require("path")
const pool = mariadb.createPool({ const dbConfig = {
host: process.env.DATABASE_HOST, host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER, user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD, password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME, database: process.env.DATABASE_NAME,
connectionLimit: process.env.DATABASE_CONNECTION_LIMIT || 10,
acquireTimeout: 20000, acquireTimeout: 20000,
connectTimeout: 20000, connectTimeout: 20000,
bigIntAsNumber: true, bigIntAsNumber: true,
insertIdAsNumber: true, insertIdAsNumber: true,
decimalAsNumber: true decimalAsNumber: true
}
const pool = mariadb.createPool({
...dbConfig,
connectionLimit: Number(process.env.DATABASE_CONNECTION_LIMIT) || 10
}) })
module.exports = pool async function runDDL() {
let rootConn
let ddlConn
try {
rootConn = await mariadb.createConnection({
host: dbConfig.host,
user: dbConfig.user,
password: dbConfig.password,
connectTimeout: dbConfig.connectTimeout
})
await rootConn.query(
`CREATE DATABASE IF NOT EXISTS \`${dbConfig.database}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`
)
logger.log(`Base de données '${dbConfig.database}' vérifiée.`, ["MariaDB", "yellow"])
await rootConn.end()
rootConn = null
ddlConn = await mariadb.createConnection({
...dbConfig,
multipleStatements: true
})
logger.log("Checking and synchronising the schema...", ["MariaDB", "yellow"])
const ddlDir = path.join(process.cwd(), "data", "ddl")
const files = await fs.readdir(ddlDir)
const sqlFiles = files
.filter(file => file.endsWith(".sql"))
.sort()
for (const file of sqlFiles) {
const filePath = path.join(ddlDir, file)
const sql = await fs.readFile(filePath, "utf-8")
if (sql.trim()) {
logger.log(`Execution of ${file.bold || file}`, ["DDL", "yellow"])
await ddlConn.query(sql)
}
}
logger.log("MariaDB database successfully initialised!", ["MariaDB", "yellow"])
} catch (error) {
if (error?.fatal) {
logger.error("Critical error during DB initialisation: " + error.message, ["MariaDB", "yellow"])
logger.error(error)
throw error
} else {
logger.warn("Minimal error during DB initialisation: " + error.message, ["MariaDB", "yellow"])
}
} finally {
if (rootConn) {
await rootConn.end()
}
if (ddlConn) {
await ddlConn.end()
}
}
}
module.exports = {
pool,
runDDL
}
-387
View File
@@ -1,387 +0,0 @@
const path = require("node:path")
const mariadb = require("mariadb")
const logger = require("./logger")
const crypto = require("node:crypto")
const rootConfig = {
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
connectionLimit: 1,
connectTimeout: 20000
}
async function setupDatabase() {
let conn
try {
conn = await mariadb.createConnection(rootConfig)
await conn.query(`CREATE DATABASE IF NOT EXISTS \`${process.env.DATABASE_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`)
logger.log(`Base de données '${process.env.DB_NAME}' vérifiée.`, ["MariaDB", "yellow"])
await conn.end()
conn = await mariadb.createConnection({
...rootConfig,
database: process.env.DB_NAME,
multipleStatements: true
})
logger.log("Checking and synchronising the schema...", ["MariaDB", "yellow"])
await conn.query(`USE \`${process.env.DATABASE_NAME}\``)
await conn.query(`
CREATE TABLE IF NOT EXISTS players (
email VARCHAR(255) NULL UNIQUE,
username VARCHAR(16) NOT NULL UNIQUE,
password TEXT NOT NULL,
uuid VARCHAR(36) NOT NULL UNIQUE PRIMARY KEY,
nameChangeAllowed TINYINT(1) DEFAULT 1,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
logger.log(`${"players".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersProperties (
name VARCHAR(256) NOT NULL,
value VARCHAR(512) NOT NULL,
uuid VARCHAR(36) NOT NULL,
UNIQUE KEY uniqueProperty (uuid, name),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playersProperties".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS clientSessions (
accessToken TEXT NOT NULL,
clientToken VARCHAR(36) NOT NULL,
uuid VARCHAR(36) NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid)
)
`)
logger.log(`${"clientSessions".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS legacyClientSessions (
sessionId VARCHAR(36) NOT NULL,
uuid VARCHAR(36) NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"legacyClientSessions".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS uuidToNameHistory (
uuid VARCHAR(36) NOT NULL,
username VARCHAR(255) NOT NULL,
changedAt DATETIME NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"uuidToNameHistory".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`CREATE INDEX IF NOT EXISTS idx_uuidToNameHistory_uuid ON uuidToNameHistory (uuid)`)
logger.log(`${"idx_uuidToNameHistory_uuid".bold} index ready`, ["MariaDB", "yellow"])
await conn.query(`DROP TRIGGER IF EXISTS log_new_user_name`)
await conn.query(`
CREATE TRIGGER log_new_user_name
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO uuidToNameHistory (uuid, username, changedAt)
VALUES (NEW.uuid, NEW.username, NULL);
END;
`)
logger.log(`${"log_new_user_name".bold} trigger ready`, ["MariaDB", "yellow"])
await conn.query(`DROP TRIGGER IF EXISTS log_user_name_change`)
await conn.query(`
CREATE TRIGGER log_user_name_change
AFTER UPDATE ON players
FOR EACH ROW
BEGIN
IF OLD.username != NEW.username THEN
INSERT INTO uuidToNameHistory (uuid, username, changedAt)
VALUES (NEW.uuid, NEW.username, CURRENT_TIMESTAMP);
END IF;
END;
`)
logger.log(`${"log_user_name_change".bold} trigger ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS blockedServers (
hashedIp VARCHAR(40) NOT NULL PRIMARY KEY,
banner VARCHAR(256) DEFAULT 'CONSOLE',
reason VARCHAR(512) NULL
)
`)
logger.log(`${"blockedServers".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersPrivileges (
uuid VARCHAR(36) PRIMARY KEY,
onlineChat TINYINT(1) DEFAULT 1,
multiplayerServer TINYINT(1) DEFAULT 1,
multiplayerRealms TINYINT(1) DEFAULT 1,
telemetry TINYINT(1) DEFAULT 1,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playersPrivileges".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersPreferences (
uuid VARCHAR(36) PRIMARY KEY,
profanityFilter TINYINT(1) DEFAULT 0,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playersPreferences".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS banReasons (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
reasonKey VARCHAR(512) UNIQUE NOT NULL
)
`)
logger.log(`${"banReasons".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS bans (
banId VARCHAR(512) PRIMARY KEY NOT NULL,
uuid VARCHAR(36) NOT NULL,
expires BIGINT DEFAULT NULL,
reason INTEGER NOT NULL,
reasonMessage VARCHAR(1024) DEFAULT NULL,
FOREIGN KEY(reason) REFERENCES banReasons(id),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"bans".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`CREATE INDEX IF NOT EXISTS idx_bans_uuid ON bans (uuid)`)
logger.log(`${"idx_bans_uuid".bold} index ready`, ["MariaDB", "yellow"])
await conn.query(`DROP TRIGGER IF EXISTS auto_init_player_settings`)
await conn.query(`
CREATE TRIGGER auto_init_player_settings
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO playersPrivileges (uuid) VALUES (NEW.uuid);
INSERT INTO playersPreferences (uuid) VALUES (NEW.uuid);
END;
`)
logger.log(`${"auto_init_player_settings".bold} trigger ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersBlockslist (
blockerUuid VARCHAR(36) NOT NULL,
blockedUuid VARCHAR(36) NOT NULL,
PRIMARY KEY (blockerUuid, blockedUuid),
FOREIGN KEY (blockerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (blockedUuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playersBlockslist".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS usernameRules (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
rule VARCHAR(255) NOT NULL,
type INTEGER DEFAULT 0
)
`)
logger.log(`${"usernameRules".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS textures (
uuid VARCHAR(36) NOT NULL UNIQUE,
hash VARCHAR(64) PRIMARY KEY NOT NULL,
type VARCHAR(10) NOT NULL,
url VARCHAR(2048) NOT NULL,
alias VARCHAR(64) NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
logger.log(`${"textures".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersSkins (
playerUuid VARCHAR(36) NOT NULL,
assetHash VARCHAR(64) NOT NULL,
variant VARCHAR(10) DEFAULT "CLASSIC",
isSelected TINYINT(1) DEFAULT 0,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (playerUuid, assetHash),
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (assetHash) REFERENCES textures(hash)
)
`)
logger.log(`${"playersSkins".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`CREATE INDEX IF NOT EXISTS idx_active_skin ON playersSkins (playerUuid, isSelected)`)
logger.log(`${"idx_active_skin".bold} index ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playersCapes (
playerUuid VARCHAR(36) NOT NULL,
assetHash VARCHAR(64) NOT NULL,
isSelected TINYINT(1) DEFAULT 0,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (playerUuid, assetHash),
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE,
FOREIGN KEY (assetHash) REFERENCES textures(hash) ON DELETE CASCADE
)
`)
logger.log(`${"playersCapes".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`CREATE INDEX IF NOT EXISTS idx_active_cape ON playersCapes (playerUuid, assetHash)`)
logger.log(`${"idx_active_cape".bold} index ready`, ["MariaDB", "yellow"])
await conn.query(`INSERT IGNORE INTO textures (hash, type, url, uuid) VALUES ('df8ed96c557d441a63e7b6a4a911ab84fa453b42fc2ae6b01c3e1b02e138168c', 'SKIN', '/texture/alex.png', '${crypto.randomUUID()}')`)
await conn.query(`INSERT IGNORE INTO textures (hash, type, url, uuid) VALUES ('4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d', 'SKIN', '/texture/steve.png', '${crypto.randomUUID()}')`)
logger.log(`defaults skins (steve, alex) ready`, ["MariaDB", "yellow"])
await conn.query(`DROP TRIGGER IF EXISTS unique_active_skin`)
await conn.query(`DROP TRIGGER IF EXISTS unique_active_cape`)
await conn.query(`DROP TRIGGER IF EXISTS auto_assign_random_default_skin`)
await conn.query(`
CREATE TRIGGER auto_assign_random_default_skin
AFTER INSERT ON players
FOR EACH ROW
BEGIN
INSERT INTO playersSkins (playerUuid, assetHash, variant, isSelected)
SELECT
NEW.uuid,
hash,
CASE
WHEN hash = '4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d' THEN 'CLASSIC'
ELSE 'SLIM'
END,
1
FROM textures
WHERE hash IN (
'4c7b0468044bfecacc43d00a3a69335a834b73937688292c20d3988cae58248d',
'df8ed96c557d441a63e7b6a4a911ab84fa453b42fc2ae6b01c3e1b02e138168c'
)
ORDER BY RAND()
LIMIT 1;
END;
`)
logger.log(`${"auto_assign_random_default_skin".bold} trigger ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playerCertificates (
uuid VARCHAR(36) PRIMARY KEY,
privateKey TEXT NOT NULL,
publicKey TEXT NOT NULL,
publicKeySignatureV2 TEXT NOT NULL,
expiresAt DATETIME NOT NULL,
refreshedAfter DATETIME NOT NULL,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playerCertificates".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS playerProfileActions (
uuid VARCHAR(36) NOT NULL,
action VARCHAR(64) NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (uuid, action),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"playerProfileActions".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS serverSessions (
uuid VARCHAR(36) PRIMARY KEY,
accessToken TEXT NOT NULL,
serverId VARCHAR(255) NOT NULL,
ip VARCHAR(45) NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"serverSessions".bold} table ready`, ["MariaDB", "yellow"])
try {
await conn.query(`SET GLOBAL event_scheduler = ON;`)
logger.log("MySQL Event Scheduler enabled.", ["MySQL", "yellow"])
await conn.query(`
CREATE EVENT IF NOT EXISTS clean_expired_certificates
ON SCHEDULE EVERY 1 HOUR
DO
DELETE FROM playerCertificates WHERE expiresAt < NOW();
`)
logger.log(`${"clean_expired_certificates".bold} event ready`, ["MySQL", "yellow"])
} catch (e) {
logger.log("Warning: Could not enable Event Scheduler (permission issue?). Skipping event creation.", ["MySQL", "red"])
}
await conn.query(`
CREATE EVENT IF NOT EXISTS clean_expired_certificates
ON SCHEDULE EVERY 1 HOUR
DO
DELETE FROM playerCertificates WHERE expiresAt < NOW();
`)
logger.log(`${"clean_expired_certificates".bold} event ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS apiAdministrators (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) UNIQUE NOT NULL,
password TEXT NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
logger.log(`${"apiAdministrators".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS apiAdministratorsPermissionsList (
permissionKey VARCHAR(64) PRIMARY KEY
)
`)
logger.log(`${"apiAdministratorsPermissionsList".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`INSERT IGNORE INTO apiAdministratorsPermissionsList(permissionKey) VALUES ("RESET_PLAYER_SKIN"), ("GRANT_PLAYER_CAPE"), ("REMOVE_PLAYER_CAPE"), ("CHANGE_PLAYER_USERNAME"), ("CHANGE_PLAYER_PASSWORD"), ("UPLOAD_CAPE"), ("DELETE_CAPES"), ("PLAYER_BAN"), ("PLAYER_BAN_HISTORY"), ("PLAYER_BAN_STATUS"), ("PLAYER_ACTIONS_LIST"), ("PLAYER_UNBAN"), ("REGISTER_USER")`)
logger.log(`${"apiAdministratorsPermissionsList".bold} permissions ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS apiAdministratorsPermissions (
administratorId INTEGER NOT NULL,
permissionKey VARCHAR(64) NOT NULL,
PRIMARY KEY (administratorId, permissionKey),
FOREIGN KEY (administratorId) REFERENCES apiAdministrators(id) ON DELETE CASCADE,
FOREIGN KEY (permissionkey) REFERENCES apiAdministratorsPermissionsList(permissionKey) ON DELETE CASCADE
)
`)
logger.log(`${"apiAdministratorsPermissions".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS oaauth2LinkAttempts (
OAuth2LinkId VARCHAR(255) NOT NULL,
playerUuid VARCHAR(255) NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (playerUuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
logger.log(`${"oaauth2LinkAttempts".bold} table ready`, ["MariaDB", "yellow"])
logger.log("MariaDB database successfully initialised!", ["MariaDB", "yellow"])
} catch (err) {
logger.error("Critical error during DB initialisation: " + err.message, ["MariaDB", "yellow"])
console.error(err)
process.exit(1)
} finally {
if (conn) conn.end()
}
}
module.exports = {
setupDatabase
}
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "yggdrasil", "name": "yggdrasil",
"version": "0.0.1-alpha", "version": "0.0.5-alpha",
"description": "", "description": "",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -13,7 +13,7 @@
"email": "gilleslazure04@gmail.com" "email": "gilleslazure04@gmail.com"
}, },
"type": "commonjs", "type": "commonjs",
"main": "server.js", "main": "bootstrap.js",
"scripts": { "scripts": {
"start:dev": "nodemon .", "start:dev": "nodemon .",
"start": "node .", "start": "node .",
+9 -9
View File
@@ -5,7 +5,7 @@ const { DefaultError } = require("../errors/errors")
async function getAdminById(id) { async function getAdminById(id) {
try { try {
const sql = "SELECT id, username, createdAt FROM apiAdministrators WHERE id = ?" const sql = "SELECT id, username, createdAt FROM apiAdministrators WHERE id = ?"
const rows = await database.query(sql, [id]) const rows = await database.pool.query(sql, [id])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -15,7 +15,7 @@ async function getAdminById(id) {
async function createAdmin(username, hashedPassword) { async function createAdmin(username, hashedPassword) {
try { try {
const sql = "INSERT INTO apiAdministrators (username, password) VALUES (?, ?)" const sql = "INSERT INTO apiAdministrators (username, password) VALUES (?, ?)"
const result = await database.query(sql, [username, hashedPassword]) const result = await database.pool.query(sql, [username, hashedPassword])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, id: result.insertId, username } return { code: 200, id: result.insertId, username }
@@ -37,7 +37,7 @@ async function hasPermission(adminId, permissionKey) {
FROM apiAdministratorsPermissions FROM apiAdministratorsPermissions
WHERE administratorId = ? AND permissionKey = ? WHERE administratorId = ? AND permissionKey = ?
` `
const rows = await database.query(sql, [adminId, permissionKey]) const rows = await database.pool.query(sql, [adminId, permissionKey])
return rows[0].count === 1 return rows[0].count === 1
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -47,7 +47,7 @@ async function hasPermission(adminId, permissionKey) {
async function assignPermission(adminId, permissionKey) { async function assignPermission(adminId, permissionKey) {
try { try {
const sql = "INSERT INTO apiAdministratorsPermissions (administratorId, permissionKey) VALUES (?, ?)" const sql = "INSERT INTO apiAdministratorsPermissions (administratorId, permissionKey) VALUES (?, ?)"
const result = await database.query(sql, [adminId, permissionKey]) const result = await database.pool.query(sql, [adminId, permissionKey])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
@@ -59,7 +59,7 @@ async function assignPermission(adminId, permissionKey) {
async function revokePermission(adminId, permissionKey) { async function revokePermission(adminId, permissionKey) {
try { try {
const sql = "DELETE FROM apiAdministratorsPermissions WHERE administratorId = ? AND permissionKey = ?" const sql = "DELETE FROM apiAdministratorsPermissions WHERE administratorId = ? AND permissionKey = ?"
const result = await database.query(sql, [adminId, permissionKey]) const result = await database.pool.query(sql, [adminId, permissionKey])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
@@ -74,7 +74,7 @@ async function getAdminPermissions(adminId) {
FROM apiAdministratorsPermissions FROM apiAdministratorsPermissions
WHERE administratorId = ? WHERE administratorId = ?
` `
const rows = await database.query(sql, [adminId]) const rows = await database.pool.query(sql, [adminId])
return rows.map(r => r.permissionKey) return rows.map(r => r.permissionKey)
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -84,7 +84,7 @@ async function getAdminPermissions(adminId) {
async function updateAdminPassword(adminId, newHashedPassword) { async function updateAdminPassword(adminId, newHashedPassword) {
try { try {
const sql = "UPDATE apiAdministrators SET password = ? WHERE id = ?" const sql = "UPDATE apiAdministrators SET password = ? WHERE id = ?"
const result = await database.query(sql, [newHashedPassword, adminId]) const result = await database.pool.query(sql, [newHashedPassword, adminId])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
@@ -102,7 +102,7 @@ async function updateAdminPassword(adminId, newHashedPassword) {
async function getAdminByUsername(username) { async function getAdminByUsername(username) {
try { try {
const sql = "SELECT id, username, password, createdAt FROM apiAdministrators WHERE username = ?" const sql = "SELECT id, username, password, createdAt FROM apiAdministrators WHERE username = ?"
const rows = await database.query(sql, [username]) const rows = await database.pool.query(sql, [username])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
@@ -114,7 +114,7 @@ async function addPlayerAction(playerUuid, actionCode) {
try { try {
const cleanUuid = playerUuid.replace(/-/g, "") const cleanUuid = playerUuid.replace(/-/g, "")
const sql = "INSERT IGNORE INTO playerProfileActions (uuid, action) VALUES (?, ?)" const sql = "INSERT IGNORE INTO playerProfileActions (uuid, action) VALUES (?, ?)"
const result = await database.query(sql, [cleanUuid, actionCode]) const result = await database.pool.query(sql, [cleanUuid, actionCode])
return { return {
code: 200, code: 200,
+10 -10
View File
@@ -6,7 +6,7 @@ const { DefaultError } = require("../errors/errors")
async function getUser(identifier, requirePassword = false) { async function getUser(identifier, requirePassword = false) {
try { try {
const sql = `SELECT * FROM players WHERE uuid = ? OR email = ? OR username = ?` const sql = `SELECT * FROM players WHERE uuid = ? OR email = ? OR username = ?`
const rows = await database.query(sql, [identifier, identifier, identifier]) const rows = await database.pool.query(sql, [identifier, identifier, identifier])
const user = rows[0] const user = rows[0]
if (!user) { if (!user) {
throw new DefaultError(404, "User not found") throw new DefaultError(404, "User not found")
@@ -28,7 +28,7 @@ async function register(email, username, password) {
const sql = `INSERT INTO players (email, username, password, uuid) VALUES (?, ?, ?, ?)` const sql = `INSERT INTO players (email, username, password, uuid) VALUES (?, ?, ?, ?)`
const uuid = crypto.randomUUID() const uuid = crypto.randomUUID()
const hashedPassword = await bcrypt.hash(password, 10) const hashedPassword = await bcrypt.hash(password, 10)
const result = await database.query(sql, [email, username, hashedPassword, uuid]) const result = await database.pool.query(sql, [email, username, hashedPassword, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, email, username, uuid } return { code: 200, email, username, uuid }
} else { } else {
@@ -42,7 +42,7 @@ async function register(email, username, password) {
async function insertClientSession(accessToken, clientToken, uuid) { async function insertClientSession(accessToken, clientToken, uuid) {
try { try {
const sql = `INSERT INTO clientSessions (accessToken, clientToken, uuid) VALUES (?, ?, ?)` const sql = `INSERT INTO clientSessions (accessToken, clientToken, uuid) VALUES (?, ?, ?)`
const result = await database.query(sql, [accessToken, clientToken, uuid]) const result = await database.pool.query(sql, [accessToken, clientToken, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 204, accessToken, clientToken } return { code: 204, accessToken, clientToken }
@@ -57,7 +57,7 @@ async function insertClientSession(accessToken, clientToken, uuid) {
async function getPlayerProperties(uuid) { async function getPlayerProperties(uuid) {
try { try {
const sql = `SELECT * FROM playersProperties WHERE uuid = ?` const sql = `SELECT * FROM playersProperties WHERE uuid = ?`
const properties = await database.query(sql, [uuid]) const properties = await database.pool.query(sql, [uuid])
if (properties.length === 0) { if (properties.length === 0) {
throw new DefaultError(404, "Properties not found for this user.", "InternalServerError") throw new DefaultError(404, "Properties not found for this user.", "InternalServerError")
@@ -71,7 +71,7 @@ async function getPlayerProperties(uuid) {
async function getClientSession(accessToken, clientToken) { async function getClientSession(accessToken, clientToken) {
try { try {
const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?` const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
const rows = await database.query(sql, [accessToken, clientToken]) const rows = await database.pool.query(sql, [accessToken, clientToken])
const session = rows[0] const session = rows[0]
if (session) { if (session) {
@@ -90,7 +90,7 @@ async function getClientSession(accessToken, clientToken) {
async function validateClientSession(accessToken, clientToken) { async function validateClientSession(accessToken, clientToken) {
try { try {
const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?` const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
const rows = await database.query(sql, [accessToken, clientToken]) const rows = await database.pool.query(sql, [accessToken, clientToken])
const session = rows[0] const session = rows[0]
if (session) { if (session) {
@@ -109,7 +109,7 @@ async function validateClientSession(accessToken, clientToken) {
async function validateClientSessionWithoutClientToken(accessToken) { async function validateClientSessionWithoutClientToken(accessToken) {
try { try {
const sql = `SELECT * FROM clientSessions WHERE accessToken = ?` const sql = `SELECT * FROM clientSessions WHERE accessToken = ?`
const rows = await database.query(sql, [accessToken]) const rows = await database.pool.query(sql, [accessToken])
const session = rows[0] const session = rows[0]
if (session) { if (session) {
@@ -128,7 +128,7 @@ async function validateClientSessionWithoutClientToken(accessToken) {
async function invalidateClientSession(accessToken, clientToken) { async function invalidateClientSession(accessToken, clientToken) {
try { try {
const sql = `DELETE FROM clientSessions WHERE accessToken = ? AND clientToken = ?` const sql = `DELETE FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
const result = await database.query(sql, [accessToken, clientToken]) const result = await database.pool.query(sql, [accessToken, clientToken])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
@@ -146,7 +146,7 @@ async function invalidateClientSession(accessToken, clientToken) {
async function revokeAccessTokens(uuid) { async function revokeAccessTokens(uuid) {
try { try {
const sql = `DELETE FROM clientSessions WHERE uuid = ?` const sql = `DELETE FROM clientSessions WHERE uuid = ?`
const result = await database.query(sql, [uuid]) const result = await database.pool.query(sql, [uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
@@ -163,7 +163,7 @@ async function revokeAccessTokens(uuid) {
async function getUsernamesRules() { async function getUsernamesRules() {
try { try {
const rows = await database.query("SELECT rule, type FROM usernameRules") const rows = await database.pool.query("SELECT rule, type FROM usernameRules")
return rows.map(row => { return rows.map(row => {
if (row.type === 1) { if (row.type === 1) {
return { type: "regex", pattern: new RegExp(row.rule, "i") } return { type: "regex", pattern: new RegExp(row.rule, "i") }
+4 -4
View File
@@ -8,7 +8,7 @@ async function createLinkAttempt(OAuth2LinkId, playerUuid) {
VALUES (?, ?) VALUES (?, ?)
ON DUPLICATE KEY UPDATE playerUuid = VALUES(playerUuid), createdAt = NOW() ON DUPLICATE KEY UPDATE playerUuid = VALUES(playerUuid), createdAt = NOW()
` `
const result = await database.query(sql, [OAuth2LinkId, playerUuid]) const result = await database.pool.query(sql, [OAuth2LinkId, playerUuid])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -18,14 +18,14 @@ async function createLinkAttempt(OAuth2LinkId, playerUuid) {
async function popLinkAttempt(OAuth2LinkId) { async function popLinkAttempt(OAuth2LinkId) {
try { try {
const selectSql = "SELECT playerUuid FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?" const selectSql = "SELECT playerUuid FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?"
const rows = await database.query(selectSql, [OAuth2LinkId]) const rows = await database.pool.query(selectSql, [OAuth2LinkId])
if (rows.length === 0) return null if (rows.length === 0) return null
const playerUuid = rows[0].playerUuid const playerUuid = rows[0].playerUuid
const deleteSql = "DELETE FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?" const deleteSql = "DELETE FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?"
await database.query(deleteSql, [OAuth2LinkId]) await database.pool.query(deleteSql, [OAuth2LinkId])
return playerUuid return playerUuid
} catch (error) { } catch (error) {
@@ -36,7 +36,7 @@ async function popLinkAttempt(OAuth2LinkId) {
async function unlinkProviderAccount(provider, playerUuid) { async function unlinkProviderAccount(provider, playerUuid) {
try { try {
const sql = `DELETE FROM playersProperties WHERE name = '${provider}Id' AND uuid = ?` const sql = `DELETE FROM playersProperties WHERE name = '${provider}Id' AND uuid = ?`
const result = await database.query(sql, [playerUuid]) const result = await database.pool.query(sql, [playerUuid])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
+9 -9
View File
@@ -4,10 +4,10 @@ const { DefaultError } = require("../errors/errors")
async function insertLegacyClientSessions(sessionId, uuid) { async function insertLegacyClientSessions(sessionId, uuid) {
try { try {
await database.query(`DELETE FROM legacyClientSessions WHERE uuid = ?`, [uuid]) await database.pool.query(`DELETE FROM legacyClientSessions WHERE uuid = ?`, [uuid])
const sql = `INSERT INTO legacyClientSessions (sessionId, uuid) VALUES (?, ?)` const sql = `INSERT INTO legacyClientSessions (sessionId, uuid) VALUES (?, ?)`
const result = await database.query(sql, [sessionId, uuid]) const result = await database.pool.query(sql, [sessionId, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, sessionId, uuid } return { code: 200, sessionId, uuid }
@@ -22,7 +22,7 @@ async function insertLegacyClientSessions(sessionId, uuid) {
async function validateLegacyClientSession(sessionId, uuid) { async function validateLegacyClientSession(sessionId, uuid) {
try { try {
const sql = `SELECT * FROM legacyClientSessions WHERE sessionId = ? AND uuid = ?` const sql = `SELECT * FROM legacyClientSessions WHERE sessionId = ? AND uuid = ?`
const rows = await database.query(sql, [sessionId, uuid]) const rows = await database.pool.query(sql, [sessionId, uuid])
const session = rows[0] const session = rows[0]
if (session) { if (session) {
@@ -44,7 +44,7 @@ async function validateLegacyClientSession(sessionId, uuid) {
async function getBlockedServers() { async function getBlockedServers() {
try { try {
const sql = `SELECT * FROM blockedServers` const sql = `SELECT * FROM blockedServers`
const blockedServers = await database.query(sql) const blockedServers = await database.pool.query(sql)
return { return {
code: 200, code: 200,
@@ -63,7 +63,7 @@ async function getActiveSkin(uuid) {
JOIN textures t ON ps.assetHash = t.hash JOIN textures t ON ps.assetHash = t.hash
WHERE ps.playerUuid = ? AND ps.isSelected = 1 WHERE ps.playerUuid = ? AND ps.isSelected = 1
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
const skin = rows[0] const skin = rows[0]
if (!skin) { if (!skin) {
throw new DefaultError(404, "Not found", "Not found") throw new DefaultError(404, "Not found", "Not found")
@@ -82,7 +82,7 @@ async function getActiveCape(uuid) {
JOIN textures t ON pc.assetHash = t.hash JOIN textures t ON pc.assetHash = t.hash
WHERE pc.playerUuid = ? AND pc.isSelected = 1 WHERE pc.playerUuid = ? AND pc.isSelected = 1
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
const cape = rows[0] const cape = rows[0]
if (!cape) { if (!cape) {
throw new DefaultError(404, "Not found", "Not found") throw new DefaultError(404, "Not found", "Not found")
@@ -97,7 +97,7 @@ async function getProfileActionsList(uuid) {
try { try {
const cleanUuid = uuid.replace(/-/g, "") const cleanUuid = uuid.replace(/-/g, "")
const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?" const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?"
const rows = await database.query(sql, [cleanUuid]) const rows = await database.pool.query(sql, [cleanUuid])
const actions = rows.map(row => row.action) const actions = rows.map(row => row.action)
@@ -118,7 +118,7 @@ async function saveServerSession(uuid, accessToken, serverId, ip) {
ip = VALUES(ip), ip = VALUES(ip),
createdAt = CURRENT_TIMESTAMP createdAt = CURRENT_TIMESTAMP
` `
const result = await database.query(sql, [uuid, accessToken, serverId, ip]) const result = await database.pool.query(sql, [uuid, accessToken, serverId, ip])
return { code: 200, success: result.affectedRows > 0 } return { code: 200, success: result.affectedRows > 0 }
} catch (error) { } catch (error) {
@@ -134,7 +134,7 @@ async function getServerSession(uuid, serverId) {
WHERE uuid = ? AND serverId = ? WHERE uuid = ? AND serverId = ?
AND createdAt > (NOW() - INTERVAL 30 SECOND) AND createdAt > (NOW() - INTERVAL 30 SECOND)
` `
const rows = await database.query(sql, [uuid, serverId]) const rows = await database.pool.query(sql, [uuid, serverId])
const session = rows[0] const session = rows[0]
if (!session) { if (!session) {
+53 -53
View File
@@ -11,7 +11,7 @@ async function getSkins(uuid) {
JOIN textures t ON ps.assetHash = t.hash JOIN textures t ON ps.assetHash = t.hash
WHERE ps.playerUuid = ? WHERE ps.playerUuid = ?
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows return rows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -26,7 +26,7 @@ async function getCapes(uuid) {
JOIN textures t ON pc.assetHash = t.hash JOIN textures t ON pc.assetHash = t.hash
WHERE pc.playerUuid = ? WHERE pc.playerUuid = ?
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows return rows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -40,7 +40,7 @@ async function addPropertyToPlayer(key, value, uuid) {
VALUES (?, ?, ?) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE value = VALUES(value) ON DUPLICATE KEY UPDATE value = VALUES(value)
` `
const result = await database.query(sql, [key, value, uuid]) const result = await database.pool.query(sql, [key, value, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, key, value, uuid } return { code: 200, key, value, uuid }
@@ -55,7 +55,7 @@ async function addPropertyToPlayer(key, value, uuid) {
async function deletePropertyToPlayer(key, uuid) { async function deletePropertyToPlayer(key, uuid) {
try { try {
const sql = `DELETE FROM playersProperties WHERE name = ? AND uuid = ?` const sql = `DELETE FROM playersProperties WHERE name = ? AND uuid = ?`
const result = await database.query(sql, [key, uuid]) const result = await database.pool.query(sql, [key, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, key, uuid } return { code: 200, key, uuid }
@@ -70,7 +70,7 @@ async function deletePropertyToPlayer(key, uuid) {
async function updatePropertyToPlayer(key, value, uuid) { async function updatePropertyToPlayer(key, value, uuid) {
try { try {
const sql = `UPDATE playersProperties SET value = ? WHERE name = ? AND uuid = ?` const sql = `UPDATE playersProperties SET value = ? WHERE name = ? AND uuid = ?`
const result = await database.query(sql, [value, key, uuid]) const result = await database.pool.query(sql, [value, key, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, key, value, uuid } return { code: 200, key, value, uuid }
} else { } else {
@@ -84,7 +84,7 @@ async function updatePropertyToPlayer(key, value, uuid) {
async function getPlayerProperties(uuid) { async function getPlayerProperties(uuid) {
try { try {
const sql = `SELECT * FROM playersProperties WHERE uuid = ?` const sql = `SELECT * FROM playersProperties WHERE uuid = ?`
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
if (rows.length === 0) { if (rows.length === 0) {
throw new DefaultError(404, "Properties not found for this user") throw new DefaultError(404, "Properties not found for this user")
} }
@@ -100,7 +100,7 @@ async function getPlayerProperties(uuid) {
async function getPlayerProperty(key, uuid) { async function getPlayerProperty(key, uuid) {
try { try {
const sql = `SELECT * FROM playersProperties WHERE name = ? AND uuid = ?` const sql = `SELECT * FROM playersProperties WHERE name = ? AND uuid = ?`
const rows = await database.query(sql, [key, uuid]) const rows = await database.pool.query(sql, [key, uuid])
const property = rows[0] const property = rows[0]
if (!property) { if (!property) {
throw new DefaultError(404, "Property not found for this user/key combination") throw new DefaultError(404, "Property not found for this user/key combination")
@@ -114,7 +114,7 @@ async function getPlayerProperty(key, uuid) {
async function getPlayerPropertyByValue(key, value) { async function getPlayerPropertyByValue(key, value) {
try { try {
const sql = `SELECT * FROM playersProperties WHERE name = ? AND value = ?` const sql = `SELECT * FROM playersProperties WHERE name = ? AND value = ?`
const rows = await database.query(sql, [key, value]) const rows = await database.pool.query(sql, [key, value])
const property = rows[0] const property = rows[0]
if (!property) { if (!property) {
@@ -140,8 +140,8 @@ async function getPlayerSettingsSchema() {
preferences: {} preferences: {}
} }
try { try {
const privilegesRows = await database.query("DESCRIBE playersPrivileges") const privilegesRows = await database.pool.query("DESCRIBE playersPrivileges")
const preferencesRows = await database.query("DESCRIBE playersPreferences") const preferencesRows = await database.pool.query("DESCRIBE playersPreferences")
RAW_SCHEMA_CACHE.privileges = privilegesRows.map(c => c.Field).filter(n => n !== "uuid") RAW_SCHEMA_CACHE.privileges = privilegesRows.map(c => c.Field).filter(n => n !== "uuid")
RAW_SCHEMA_CACHE.preferences = preferencesRows.map(c => c.Field).filter(n => n !== "uuid") RAW_SCHEMA_CACHE.preferences = preferencesRows.map(c => c.Field).filter(n => n !== "uuid")
return RAW_SCHEMA_CACHE return RAW_SCHEMA_CACHE
@@ -160,7 +160,7 @@ async function updatePlayerPreferences(uuid, updates) {
const sql = `UPDATE playersPreferences SET ${setClause} WHERE uuid = ?` const sql = `UPDATE playersPreferences SET ${setClause} WHERE uuid = ?`
const values = keys.map(key => updates[key]) const values = keys.map(key => updates[key])
values.push(uuid) values.push(uuid)
const result = await database.query(sql, values) const result = await database.pool.query(sql, values)
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
code: 200, code: 200,
@@ -177,7 +177,7 @@ async function updatePlayerPreferences(uuid, updates) {
async function getPlayerPreferences(uuid) { async function getPlayerPreferences(uuid) {
try { try {
const sql = `SELECT profanityFilter FROM playersPreferences WHERE uuid = ?` const sql = `SELECT profanityFilter FROM playersPreferences WHERE uuid = ?`
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
const data = rows[0] const data = rows[0]
if (data) { if (data) {
@@ -201,7 +201,7 @@ async function getPlayerPrivileges(uuid) {
FROM playersPrivileges FROM playersPrivileges
WHERE uuid = ? WHERE uuid = ?
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
const data = rows[0] const data = rows[0]
if (data) { if (data) {
return { return {
@@ -227,7 +227,7 @@ async function updatePlayerPrivileges(uuid, updates) {
const sql = `UPDATE playersPrivileges SET ${setClause} WHERE uuid = ?` const sql = `UPDATE playersPrivileges SET ${setClause} WHERE uuid = ?`
const values = keys.map(key => updates[key]) const values = keys.map(key => updates[key])
values.push(uuid) values.push(uuid)
const result = await database.query(sql, values) const result = await database.pool.query(sql, values)
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
code: 200, code: 200,
@@ -248,11 +248,11 @@ async function banUser(uuid, { reasonKey, reasonMessage, expires = null }) {
} }
let reasonId let reasonId
const reasonRows = await database.query("SELECT id FROM banReasons WHERE reasonKey = ?", [reasonKey]) const reasonRows = await database.pool.query("SELECT id FROM banReasons WHERE reasonKey = ?", [reasonKey])
if (reasonRows.length > 0) { if (reasonRows.length > 0) {
reasonId = reasonRows[0].id reasonId = reasonRows[0].id
} else { } else {
const insertReason = await database.query("INSERT INTO banReasons (reasonKey) VALUES (?)", [reasonKey]) const insertReason = await database.pool.query("INSERT INTO banReasons (reasonKey) VALUES (?)", [reasonKey])
reasonId = insertReason.insertId reasonId = insertReason.insertId
} }
@@ -261,7 +261,7 @@ async function banUser(uuid, { reasonKey, reasonMessage, expires = null }) {
INSERT INTO bans (banId, uuid, reason, reasonMessage, expires) INSERT INTO bans (banId, uuid, reason, reasonMessage, expires)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
` `
const result = await database.query(insertSql, [banId, uuid, reasonId, reasonMessage || "Banned by operator", expires]) const result = await database.pool.query(insertSql, [banId, uuid, reasonId, reasonMessage || "Banned by operator", expires])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
@@ -288,7 +288,7 @@ async function unbanUser(uuid) {
throw new DefaultError(400, "Missing uuid.") throw new DefaultError(400, "Missing uuid.")
} }
const sql = "DELETE FROM bans WHERE uuid = ?" const sql = "DELETE FROM bans WHERE uuid = ?"
const result = await database.query(sql, [uuid]) const result = await database.pool.query(sql, [uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { return {
code: 200, code: 200,
@@ -317,7 +317,7 @@ async function getPlayerBans(uuid) {
WHERE b.uuid = ? WHERE b.uuid = ?
ORDER BY b.expires ASC ORDER BY b.expires ASC
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
if (rows.length > 0) { if (rows.length > 0) {
return { code: 200, bans: rows } return { code: 200, bans: rows }
@@ -332,7 +332,7 @@ async function getPlayerBans(uuid) {
async function changeUsername(uuid, newName) { async function changeUsername(uuid, newName) {
try { try {
const sql = "UPDATE players SET username = ? WHERE uuid = ?" const sql = "UPDATE players SET username = ? WHERE uuid = ?"
const result = await database.query(sql, [newName, uuid]) const result = await database.pool.query(sql, [newName, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, message: "Username changed successfully" } return { code: 200, message: "Username changed successfully" }
} else { } else {
@@ -353,7 +353,7 @@ async function createTexture(uuid, hash, type, url, alias) {
INSERT INTO textures (uuid, hash, type, url, alias) INSERT INTO textures (uuid, hash, type, url, alias)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
` `
await database.query(sql, [uuid, hash, type, url, alias]) await database.pool.query(sql, [uuid, hash, type, url, alias])
return true return true
} catch (error) { } catch (error) {
if (error.code === 'ER_DUP_ENTRY') { if (error.code === 'ER_DUP_ENTRY') {
@@ -367,7 +367,7 @@ async function createTexture(uuid, hash, type, url, alias) {
async function getTextureByUuid(textureUuid) { async function getTextureByUuid(textureUuid) {
try { try {
const sql = "SELECT hash FROM textures WHERE uuid = ?" const sql = "SELECT hash FROM textures WHERE uuid = ?"
const rows = await database.query(sql, [textureUuid]) const rows = await database.pool.query(sql, [textureUuid])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -377,7 +377,7 @@ async function getTextureByUuid(textureUuid) {
async function getTextureByHash(hash) { async function getTextureByHash(hash) {
try { try {
const sql = "SELECT uuid FROM textures WHERE hash = ?" const sql = "SELECT uuid FROM textures WHERE hash = ?"
const rows = await database.query(sql, [hash]) const rows = await database.pool.query(sql, [hash])
return rows[0] return rows[0]
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -390,13 +390,13 @@ async function resetSkin(uuid, hash, variant) {
INSERT IGNORE INTO playersSkins (playerUuid, assetHash, variant, isSelected) INSERT IGNORE INTO playersSkins (playerUuid, assetHash, variant, isSelected)
VALUES (?, ?, ?, 0) VALUES (?, ?, ?, 0)
` `
await database.query(insertSql, [uuid, hash, variant]) await database.pool.query(insertSql, [uuid, hash, variant])
const updateSql = ` const updateSql = `
UPDATE playersSkins UPDATE playersSkins
SET isSelected = (assetHash = ?) SET isSelected = (assetHash = ?)
WHERE playerUuid = ? WHERE playerUuid = ?
` `
await database.query(updateSql, [hash, uuid]) await database.pool.query(updateSql, [hash, uuid])
return { code: 200 } return { code: 200 }
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -406,7 +406,7 @@ async function resetSkin(uuid, hash, variant) {
async function hideCape(uuid) { async function hideCape(uuid) {
try { try {
const sql = "UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?" const sql = "UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?"
await database.query(sql, [uuid]) await database.pool.query(sql, [uuid])
return { code: 200 } return { code: 200 }
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -415,12 +415,12 @@ async function hideCape(uuid) {
async function showCape(uuid, hash) { async function showCape(uuid, hash) {
try { try {
await database.query( await database.pool.query(
"UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?", "UPDATE playersCapes SET isSelected = 0 WHERE playerUuid = ?",
[uuid] [uuid]
) )
const result = await database.query( const result = await database.pool.query(
"UPDATE playersCapes SET isSelected = 1 WHERE playerUuid = ? AND assetHash = ?", "UPDATE playersCapes SET isSelected = 1 WHERE playerUuid = ? AND assetHash = ?",
[uuid, hash] [uuid, hash]
) )
@@ -436,7 +436,7 @@ async function showCape(uuid, hash) {
async function checkCapeOwnership(uuid, hash) { async function checkCapeOwnership(uuid, hash) {
try { try {
const sql = "SELECT 1 FROM playersCapes WHERE playerUuid = ? AND assetHash = ?" const sql = "SELECT 1 FROM playersCapes WHERE playerUuid = ? AND assetHash = ?"
const rows = await database.query(sql, [uuid, hash]) const rows = await database.pool.query(sql, [uuid, hash])
return rows.length > 0 return rows.length > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -446,7 +446,7 @@ async function checkCapeOwnership(uuid, hash) {
async function getPlayerMeta(uuid) { async function getPlayerMeta(uuid) {
try { try {
const sql = `SELECT createdAt, nameChangeAllowed FROM players WHERE uuid = ?` const sql = `SELECT createdAt, nameChangeAllowed FROM players WHERE uuid = ?`
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows[0] return rows[0]
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -462,7 +462,7 @@ async function getLastNameChange(uuid) {
ORDER BY changedAt DESC ORDER BY changedAt DESC
LIMIT 1 LIMIT 1
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows[0] return rows[0]
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -472,7 +472,7 @@ async function getLastNameChange(uuid) {
async function getPlayerCertificate(uuid) { async function getPlayerCertificate(uuid) {
try { try {
const sql = "SELECT * FROM playerCertificates WHERE uuid = ?" const sql = "SELECT * FROM playerCertificates WHERE uuid = ?"
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows[0] return rows[0]
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -486,7 +486,7 @@ async function savePlayerCertificate(uuid, privateKey, publicKey, signatureV2, e
(uuid, privateKey, publicKey, publicKeySignatureV2, expiresAt, refreshedAfter) (uuid, privateKey, publicKey, publicKeySignatureV2, expiresAt, refreshedAfter)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
` `
const result = await database.query(sql, [uuid, privateKey, publicKey, signatureV2, expiresAt, refreshedAfter]) const result = await database.pool.query(sql, [uuid, privateKey, publicKey, signatureV2, expiresAt, refreshedAfter])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -496,7 +496,7 @@ async function savePlayerCertificate(uuid, privateKey, publicKey, signatureV2, e
async function deleteExpiredCertificates(isoDate) { async function deleteExpiredCertificates(isoDate) {
try { try {
const sql = "DELETE FROM playerCertificates WHERE expiresAt < ?" const sql = "DELETE FROM playerCertificates WHERE expiresAt < ?"
const result = await database.query(sql, [isoDate]) const result = await database.pool.query(sql, [isoDate])
return result.affectedRows return result.affectedRows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -507,7 +507,7 @@ async function addProfileAction(uuid, actionCode) {
try { try {
const cleanUuid = uuid.replace(/-/g, "") const cleanUuid = uuid.replace(/-/g, "")
const sql = "INSERT IGNORE INTO playerProfileActions (uuid, action) VALUES (?, ?)" const sql = "INSERT IGNORE INTO playerProfileActions (uuid, action) VALUES (?, ?)"
const result = await database.query(sql, [cleanUuid, actionCode]) const result = await database.pool.query(sql, [cleanUuid, actionCode])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -518,7 +518,7 @@ async function removeProfileAction(uuid, actionCode) {
try { try {
const cleanUuid = uuid.replace(/-/g, "") const cleanUuid = uuid.replace(/-/g, "")
const sql = "DELETE FROM playerProfileActions WHERE uuid = ? AND action = ?" const sql = "DELETE FROM playerProfileActions WHERE uuid = ? AND action = ?"
const result = await database.query(sql, [cleanUuid, actionCode]) const result = await database.pool.query(sql, [cleanUuid, actionCode])
return result.affectedRows return result.affectedRows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -529,7 +529,7 @@ async function getPlayerActions(uuid) {
try { try {
const cleanUuid = uuid.replace(/-/g, "") const cleanUuid = uuid.replace(/-/g, "")
const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?" const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?"
const rows = await database.query(sql, [cleanUuid]) const rows = await database.pool.query(sql, [cleanUuid])
return rows.map(r => r.action) return rows.map(r => r.action)
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -540,7 +540,7 @@ async function clearAllPlayerActions(uuid) {
try { try {
const cleanUuid = uuid.replace(/-/g, "") const cleanUuid = uuid.replace(/-/g, "")
const sql = "DELETE FROM playerProfileActions WHERE uuid = ?" const sql = "DELETE FROM playerProfileActions WHERE uuid = ?"
const result = await database.query(sql, [cleanUuid]) const result = await database.pool.query(sql, [cleanUuid])
return result.affectedRows return result.affectedRows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -550,7 +550,7 @@ async function clearAllPlayerActions(uuid) {
async function blockPlayer(blockerUuid, blockedUuid) { async function blockPlayer(blockerUuid, blockedUuid) {
try { try {
const sql = `INSERT IGNORE INTO playersBlockslist (blockerUuid, blockedUuid) VALUES (?, ?)` const sql = `INSERT IGNORE INTO playersBlockslist (blockerUuid, blockedUuid) VALUES (?, ?)`
const result = await database.query(sql, [blockerUuid, blockedUuid]) const result = await database.pool.query(sql, [blockerUuid, blockedUuid])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -560,7 +560,7 @@ async function blockPlayer(blockerUuid, blockedUuid) {
async function unblockPlayer(blockerUuid, blockedUuid) { async function unblockPlayer(blockerUuid, blockedUuid) {
try { try {
const sql = `DELETE FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ?` const sql = `DELETE FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ?`
const result = await database.query(sql, [blockerUuid, blockedUuid]) const result = await database.pool.query(sql, [blockerUuid, blockedUuid])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -570,7 +570,7 @@ async function unblockPlayer(blockerUuid, blockedUuid) {
async function getBlockedUuids(blockerUuid) { async function getBlockedUuids(blockerUuid) {
try { try {
const sql = `SELECT blockedUuid FROM playersBlockslist WHERE blockerUuid = ?` const sql = `SELECT blockedUuid FROM playersBlockslist WHERE blockerUuid = ?`
const rows = await database.query(sql, [blockerUuid]) const rows = await database.pool.query(sql, [blockerUuid])
return rows.map(r => r.blockedUuid) return rows.map(r => r.blockedUuid)
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -580,7 +580,7 @@ async function getBlockedUuids(blockerUuid) {
async function isBlocked(blockerUuid, targetUuid) { async function isBlocked(blockerUuid, targetUuid) {
try { try {
const sql = `SELECT 1 FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ? LIMIT 1` const sql = `SELECT 1 FROM playersBlockslist WHERE blockerUuid = ? AND blockedUuid = ? LIMIT 1`
const rows = await database.query(sql, [blockerUuid, targetUuid]) const rows = await database.pool.query(sql, [blockerUuid, targetUuid])
return rows.length > 0 return rows.length > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -595,7 +595,7 @@ async function getUsersByNames(usernames) {
const placeholders = uniqueNames.map(() => "?").join(", ") const placeholders = uniqueNames.map(() => "?").join(", ")
const sql = `SELECT uuid, username FROM players WHERE username IN (${placeholders})` const sql = `SELECT uuid, username FROM players WHERE username IN (${placeholders})`
const rows = await database.query(sql, uniqueNames) const rows = await database.pool.query(sql, uniqueNames)
return rows return rows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -605,7 +605,7 @@ async function getUsersByNames(usernames) {
async function getUuidAndUsername(username) { async function getUuidAndUsername(username) {
try { try {
const sql = "SELECT uuid, username FROM players WHERE username = ?" const sql = "SELECT uuid, username FROM players WHERE username = ?"
const rows = await database.query(sql, [username]) const rows = await database.pool.query(sql, [username])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
@@ -616,7 +616,7 @@ async function getUuidAndUsername(username) {
async function getProfileByUsername(username) { async function getProfileByUsername(username) {
try { try {
const sql = "SELECT uuid, username FROM players WHERE username = ?" const sql = "SELECT uuid, username FROM players WHERE username = ?"
const rows = await database.query(sql, [username]) const rows = await database.pool.query(sql, [username])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -633,7 +633,7 @@ async function getProfileByHistory(username, isoDate) {
ORDER BY changedAt DESC ORDER BY changedAt DESC
LIMIT 1 LIMIT 1
` `
const rows = await database.query(sql, [username, isoDate]) const rows = await database.pool.query(sql, [username, isoDate])
return rows[0] || null return rows[0] || null
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -648,7 +648,7 @@ async function getNameHistory(uuid) {
WHERE uuid = ? WHERE uuid = ?
ORDER BY changedAt ASC ORDER BY changedAt ASC
` `
const rows = await database.query(sql, [uuid]) const rows = await database.pool.query(sql, [uuid])
return rows return rows
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
@@ -658,14 +658,14 @@ async function getNameHistory(uuid) {
async function setSkin(uuid, hash, variant) { async function setSkin(uuid, hash, variant) {
try { try {
const resetSql = `UPDATE playersSkins SET isSelected = 0 WHERE playerUuid = ?` const resetSql = `UPDATE playersSkins SET isSelected = 0 WHERE playerUuid = ?`
await database.query(resetSql, [uuid]) await database.pool.query(resetSql, [uuid])
const upsertSql = ` const upsertSql = `
INSERT INTO playersSkins (playerUuid, assetHash, variant, isSelected) INSERT INTO playersSkins (playerUuid, assetHash, variant, isSelected)
VALUES (?, ?, ?, 1) VALUES (?, ?, ?, 1)
ON DUPLICATE KEY UPDATE isSelected = 1, variant = VALUES(variant) ON DUPLICATE KEY UPDATE isSelected = 1, variant = VALUES(variant)
` `
await database.query(upsertSql, [uuid, hash, variant.toUpperCase()]) await database.pool.query(upsertSql, [uuid, hash, variant.toUpperCase()])
return true return true
} catch (error) { } catch (error) {
@@ -676,7 +676,7 @@ async function setSkin(uuid, hash, variant) {
async function updatePassword(uuid, hashedPassword) { async function updatePassword(uuid, hashedPassword) {
try { try {
const sql = "UPDATE players SET password = ? WHERE uuid = ?" const sql = "UPDATE players SET password = ? WHERE uuid = ?"
const result = await database.query(sql, [hashedPassword, uuid]) const result = await database.pool.query(sql, [hashedPassword, uuid])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, message: "Password updated successfully" } return { code: 200, message: "Password updated successfully" }
@@ -694,7 +694,7 @@ async function addCapeToPlayer(uuid, hash) {
INSERT INTO playersCapes (playerUuid, assetHash, isSelected) INSERT INTO playersCapes (playerUuid, assetHash, isSelected)
VALUES (?, ?, 0) VALUES (?, ?, 0)
` `
const result = await database.query(sql, [uuid, hash]) const result = await database.pool.query(sql, [uuid, hash])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, message: "Cape granted to the player." } return { code: 200, message: "Cape granted to the player." }
@@ -711,7 +711,7 @@ async function addCapeToPlayer(uuid, hash) {
async function removeCapeFromPlayer(uuid, hash) { async function removeCapeFromPlayer(uuid, hash) {
try { try {
const sql = "DELETE FROM playersCapes WHERE playerUuid = ? AND assetHash = ?" const sql = "DELETE FROM playersCapes WHERE playerUuid = ? AND assetHash = ?"
const result = await database.query(sql, [uuid, hash]) const result = await database.pool.query(sql, [uuid, hash])
if (result.affectedRows > 0) { if (result.affectedRows > 0) {
return { code: 200, message: "Cape removed from player." } return { code: 200, message: "Cape removed from player." }
@@ -726,7 +726,7 @@ async function removeCapeFromPlayer(uuid, hash) {
async function deleteTexture(hash) { async function deleteTexture(hash) {
try { try {
const sql = "DELETE FROM textures WHERE hash = ?" const sql = "DELETE FROM textures WHERE hash = ?"
const result = await database.query(sql, [hash]) const result = await database.pool.query(sql, [hash])
return result.affectedRows > 0 return result.affectedRows > 0
} catch (error) { } catch (error) {
return utils.handleDBError(error) return utils.handleDBError(error)
-6
View File
@@ -3,22 +3,16 @@ const hpp = require("hpp")
const app = express() const app = express()
const cors = require("cors") const cors = require("cors")
const path = require("node:path") const path = require("node:path")
const utils = require("./modules/utils")
const logger = require("./modules/logger") const logger = require("./modules/logger")
const helmet = require("helmet") const helmet = require("helmet")
const loader = require("./modules/loader") const loader = require("./modules/loader")
const DefaultError = require("./errors/DefaultError")
const path2regex = require("path-to-regexp") const path2regex = require("path-to-regexp")
const databaseGlobals = require("./modules/databaseGlobals")
const certificates = require("./modules/certificatesManager")
const { ValidationError } = require("./errors/errors") const { ValidationError } = require("./errors/errors")
const routes = loader.getRecursiveFiles(path.join(__dirname, "routes")) const routes = loader.getRecursiveFiles(path.join(__dirname, "routes"))
const schemas = loader.getRecursiveFiles(path.join(__dirname, "schemas")) const schemas = loader.getRecursiveFiles(path.join(__dirname, "schemas"))
const schemaRegistry = {} const schemaRegistry = {}
databaseGlobals.setupDatabase()
certificates.setupKeys()
app.use(hpp()) app.use(hpp())
app.use(helmet({ app.use(helmet({