Add Discord OAuth2 account linking and login support

Introduces Discord OAuth2 integration for account association and login, including new routes for linking, unlinking, and authenticating via Discord. Adds supporting services, repositories, and schema validation for the OAuth2 flow. Refactors database schema and queries for consistency, and updates dependencies to include required OAuth2 libraries.
This commit is contained in:
2026-01-11 21:03:12 +01:00
parent 5b81f57adb
commit c5b6f6c107
19 changed files with 656 additions and 36 deletions

View File

@@ -45,7 +45,7 @@ async function setupDatabase() {
name VARCHAR(256) NOT NULL,
value VARCHAR(512) NOT NULL,
uuid VARCHAR(36) NOT NULL,
UNIQUE KEY unique_property (uuid, name),
UNIQUE KEY uniqueProperty (uuid, name),
FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE
)
`)
@@ -142,7 +142,7 @@ async function setupDatabase() {
await conn.query(`
CREATE TABLE IF NOT EXISTS banReasons (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
reason_key VARCHAR(512) UNIQUE NOT NULL
reasonKey VARCHAR(512) UNIQUE NOT NULL
)
`)
logger.log(`${"banReasons".bold} table ready`, ["MariaDB", "yellow"])
@@ -347,32 +347,42 @@ async function setupDatabase() {
logger.log(`${"clean_expired_certificates".bold} event ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS api_administrators (
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(`${"api_administrators".bold} table ready`, ["MariaDB", "yellow"])
logger.log(`${"apiAdministrators".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS api_administrators_permissions_list (
permission_key VARCHAR(64) PRIMARY KEY
CREATE TABLE IF NOT EXISTS apiAdministratorsPermissionsList (
permissionKey VARCHAR(64) PRIMARY KEY
)
`)
logger.log(`${"api_administrators_permissions_list".bold} table ready`, ["MariaDB", "yellow"])
logger.log(`${"apiAdministratorsPermissionsList".bold} table ready`, ["MariaDB", "yellow"])
await conn.query(`
CREATE TABLE IF NOT EXISTS api_administrators_permissions (
administrator_id INTEGER NOT NULL,
permission_key VARCHAR(64) NOT NULL,
PRIMARY KEY (administrator_id, permission_key),
FOREIGN KEY (administrator_id) REFERENCES api_administrators(id) ON DELETE CASCADE,
FOREIGN KEY (permission_key) REFERENCES api_administrators_permissions_list(permission_key) ON DELETE CASCADE
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(`${"api_administrators_permissions".bold} table ready`, ["MariaDB", "yellow"])
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"])

View File

@@ -55,7 +55,13 @@ function isTrueFromDotEnv(key) {
return (process.env[key] || "").trim().toLowerCase() === "true"
}
function getUrlParam(url, param) {
const urlParams = new URLSearchParams(url)
return urlParams.get(param)
}
module.exports = {
getUrlParam,
signProfileData,
addDashesToUUID,
isTrueFromDotEnv,