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:
@@ -4,7 +4,7 @@ const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function getAdminById(id) {
|
||||
try {
|
||||
const sql = "SELECT id, username, createdAt FROM api_administrators WHERE id = ?"
|
||||
const sql = "SELECT id, username, createdAt FROM apiAdministrators WHERE id = ?"
|
||||
const rows = await database.query(sql, [id])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
@@ -15,7 +15,7 @@ async function getAdminById(id) {
|
||||
|
||||
async function createAdmin(username, hashedPassword) {
|
||||
try {
|
||||
const sql = "INSERT INTO api_administrators (username, password) VALUES (?, ?)"
|
||||
const sql = "INSERT INTO apiAdministrators (username, password) VALUES (?, ?)"
|
||||
const result = await database.query(sql, [username, hashedPassword])
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
@@ -36,7 +36,7 @@ async function hasPermission(adminId, permissionKey) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT COUNT(*) as count
|
||||
FROM api_administrators_permissions
|
||||
FROM apiAdministrators_permissions
|
||||
WHERE administrator_id = ? AND permission_key = ?
|
||||
`
|
||||
const rows = await database.query(sql, [adminId, permissionKey])
|
||||
@@ -49,7 +49,7 @@ async function hasPermission(adminId, permissionKey) {
|
||||
|
||||
async function assignPermission(adminId, permissionKey) {
|
||||
try {
|
||||
const sql = "INSERT INTO api_administrators_permissions (administrator_id, permission_key) VALUES (?, ?)"
|
||||
const sql = "INSERT INTO apiAdministrators_permissions (administrator_id, permission_key) VALUES (?, ?)"
|
||||
const result = await database.query(sql, [adminId, permissionKey])
|
||||
|
||||
return result.affectedRows > 0
|
||||
@@ -62,7 +62,7 @@ async function assignPermission(adminId, permissionKey) {
|
||||
|
||||
async function revokePermission(adminId, permissionKey) {
|
||||
try {
|
||||
const sql = "DELETE FROM api_administrators_permissions WHERE administrator_id = ? AND permission_key = ?"
|
||||
const sql = "DELETE FROM apiAdministrators_permissions WHERE administrator_id = ? AND permission_key = ?"
|
||||
const result = await database.query(sql, [adminId, permissionKey])
|
||||
|
||||
return result.affectedRows > 0
|
||||
@@ -76,7 +76,7 @@ async function getAdminPermissions(adminId) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT permission_key
|
||||
FROM api_administrators_permissions
|
||||
FROM apiAdministrators_permissions
|
||||
WHERE administrator_id = ?
|
||||
`
|
||||
const rows = await database.query(sql, [adminId])
|
||||
@@ -89,7 +89,7 @@ async function getAdminPermissions(adminId) {
|
||||
|
||||
async function updateAdminPassword(adminId, newHashedPassword) {
|
||||
try {
|
||||
const sql = "UPDATE api_administrators SET password = ? WHERE id = ?"
|
||||
const sql = "UPDATE apiAdministrators SET password = ? WHERE id = ?"
|
||||
const result = await database.query(sql, [newHashedPassword, adminId])
|
||||
|
||||
if (result.affectedRows > 0) {
|
||||
@@ -109,7 +109,7 @@ async function updateAdminPassword(adminId, newHashedPassword) {
|
||||
|
||||
async function getAdminByUsername(username) {
|
||||
try {
|
||||
const sql = "SELECT id, username, password, createdAt FROM api_administrators WHERE username = ?"
|
||||
const sql = "SELECT id, username, password, createdAt FROM apiAdministrators WHERE username = ?"
|
||||
const rows = await database.query(sql, [username])
|
||||
|
||||
return rows[0] || null
|
||||
|
||||
55
repositories/oauth2Repository.js
Normal file
55
repositories/oauth2Repository.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const logger = require("../modules/logger")
|
||||
const database = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function createLinkAttempt(OAuth2LinkId, playerUuid) {
|
||||
try {
|
||||
const sql = `
|
||||
INSERT INTO oaauth2LinkAttempts (OAuth2LinkId, playerUuid)
|
||||
VALUES (?, ?)
|
||||
ON DUPLICATE KEY UPDATE playerUuid = VALUES(playerUuid), createdAt = NOW()
|
||||
`
|
||||
const result = await database.query(sql, [OAuth2LinkId, playerUuid])
|
||||
return result.affectedRows > 0
|
||||
} catch (error) {
|
||||
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
|
||||
throw new DefaultError(500, "Internal Server Error", "Database Error")
|
||||
}
|
||||
}
|
||||
|
||||
async function popLinkAttempt(OAuth2LinkId) {
|
||||
try {
|
||||
const selectSql = "SELECT playerUuid FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?"
|
||||
const rows = await database.query(selectSql, [OAuth2LinkId])
|
||||
|
||||
if (rows.length === 0) return null
|
||||
|
||||
const playerUuid = rows[0].playerUuid
|
||||
|
||||
const deleteSql = "DELETE FROM oaauth2LinkAttempts WHERE OAuth2LinkId = ?"
|
||||
await database.query(deleteSql, [OAuth2LinkId])
|
||||
|
||||
return playerUuid
|
||||
} catch (error) {
|
||||
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
|
||||
throw new DefaultError(500, "Internal Server Error", "Database Error")
|
||||
}
|
||||
}
|
||||
|
||||
async function unlinkProviderAccount(provider, playerUuid) {
|
||||
try {
|
||||
const sql = `DELETE FROM playersProperties WHERE name = '${provider}Id' AND uuid = ?`
|
||||
const result = await database.query(sql, [playerUuid])
|
||||
|
||||
return result.affectedRows > 0
|
||||
} catch (error) {
|
||||
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
|
||||
throw new DefaultError(500, "Internal Server Error", "Database Error")
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
popLinkAttempt,
|
||||
createLinkAttempt,
|
||||
unlinkProviderAccount
|
||||
}
|
||||
@@ -90,6 +90,31 @@ async function getPlayerProperty(key, uuid) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getPlayerPropertyByValue(key, value) {
|
||||
try {
|
||||
const sql = `SELECT * FROM playersProperties WHERE name = ? AND value = ?`
|
||||
const rows = await database.query(sql, [key, value])
|
||||
const property = rows[0]
|
||||
|
||||
if (!property) {
|
||||
throw new DefaultError(404, "No property found with this value for the specified key")
|
||||
}
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
property: {
|
||||
name: property.name,
|
||||
value: property.value,
|
||||
uuid: property.uuid
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof DefaultError) throw error
|
||||
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
|
||||
throw new DefaultError(500, "Please contact an administrator.", "InternalServerError")
|
||||
}
|
||||
}
|
||||
|
||||
async function getPlayerSettingsSchema() {
|
||||
const RAW_SCHEMA_CACHE = {
|
||||
privileges: {},
|
||||
@@ -213,11 +238,11 @@ async function banUser(uuid, { reasonKey, reasonMessage, expires = null }) {
|
||||
}
|
||||
|
||||
let reasonId
|
||||
const reasonRows = await database.query("SELECT id FROM banReasons WHERE reason_key = ?", [reasonKey])
|
||||
const reasonRows = await database.query("SELECT id FROM banReasons WHERE reasonKey = ?", [reasonKey])
|
||||
if (reasonRows.length > 0) {
|
||||
reasonId = reasonRows[0].id
|
||||
} else {
|
||||
const insertReason = await database.query("INSERT INTO banReasons (reason_key) VALUES (?)", [reasonKey])
|
||||
const insertReason = await database.query("INSERT INTO banReasons (reasonKey) VALUES (?)", [reasonKey])
|
||||
reasonId = insertReason.insertId
|
||||
}
|
||||
|
||||
@@ -279,7 +304,7 @@ async function getPlayerBans(uuid) {
|
||||
b.banId,
|
||||
b.expires,
|
||||
b.reasonMessage,
|
||||
r.reason_key as reason
|
||||
r.reasonKey as reason
|
||||
FROM bans b
|
||||
JOIN banReasons r ON b.reason = r.id
|
||||
WHERE b.uuid = ?
|
||||
@@ -770,5 +795,6 @@ module.exports = {
|
||||
updatePropertyToPlayer,
|
||||
getPlayerSettingsSchema,
|
||||
updatePlayerPreferences,
|
||||
getPlayerPropertyByValue,
|
||||
deleteExpiredCertificates,
|
||||
}
|
||||
Reference in New Issue
Block a user