Added a new registration HTML page under data/static/register.html and introduced a static file serving route in routes/static.js. Minor adjustments were made to authRepository.js and userRepository.js to update module imports. This enables serving static assets and provides a registration UI.
190 lines
6.0 KiB
JavaScript
190 lines
6.0 KiB
JavaScript
const bcrypt = require("bcryptjs")
|
|
const database = require("../modules/database")
|
|
const utils = require("../modules/utils")
|
|
const { DefaultError } = require("../errors/errors")
|
|
|
|
async function getUser(identifier, requirePassword = false) {
|
|
try {
|
|
const sql = `SELECT * FROM players WHERE uuid = ? OR email = ? OR username = ?`
|
|
const rows = await database.query(sql, [identifier, identifier, identifier])
|
|
const user = rows[0]
|
|
if (!user) {
|
|
throw new DefaultError(404, "User not found")
|
|
}
|
|
|
|
delete user.email
|
|
if (!requirePassword) {
|
|
delete user.password
|
|
}
|
|
return { code: 200, user }
|
|
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function register(email, username, password) {
|
|
try {
|
|
const sql = `INSERT INTO players (email, username, password, uuid) VALUES (?, ?, ?, ?)`
|
|
const uuid = crypto.randomUUID()
|
|
const hashedPassword = await bcrypt.hash(password, 10)
|
|
const result = await database.query(sql, [email, username, hashedPassword, uuid])
|
|
if (result.affectedRows > 0) {
|
|
return { code: 200, email, username, uuid }
|
|
} else {
|
|
throw new DefaultError(500, "Please contact an administrator.", "InternalServerError")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function insertClientSession(accessToken, clientToken, uuid) {
|
|
try {
|
|
const sql = `INSERT INTO clientSessions (accessToken, clientToken, uuid) VALUES (?, ?, ?)`
|
|
const result = await database.query(sql, [accessToken, clientToken, uuid])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return { code: 204, accessToken, clientToken }
|
|
} else {
|
|
throw new DefaultError(500, "Please contact an administrator.", "InternalServerError")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getPlayerProperties(uuid) {
|
|
try {
|
|
const sql = `SELECT * FROM playersProperties WHERE uuid = ?`
|
|
const properties = await database.query(sql, [uuid])
|
|
|
|
if (properties.length === 0) {
|
|
throw new DefaultError(404, "Properties not found for this user.", "InternalServerError")
|
|
}
|
|
return { code: 200, properties: properties.map(property => { return { name: property.name, value: property.value } }) }
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getClientSession(accessToken, clientToken) {
|
|
try {
|
|
const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
|
|
const rows = await database.query(sql, [accessToken, clientToken])
|
|
|
|
const session = rows[0]
|
|
if (session) {
|
|
return {
|
|
code: 200,
|
|
session: session
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Client session not found")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function validateClientSession(accessToken, clientToken) {
|
|
try {
|
|
const sql = `SELECT * FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
|
|
const rows = await database.query(sql, [accessToken, clientToken])
|
|
|
|
const session = rows[0]
|
|
if (session) {
|
|
return {
|
|
code: 200,
|
|
message: "Client session valid."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Client session not found for this accessToken/clientToken combination.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function validateClientSessionWithoutClientToken(accessToken) {
|
|
try {
|
|
const sql = `SELECT * FROM clientSessions WHERE accessToken = ?`
|
|
const rows = await database.query(sql, [accessToken])
|
|
|
|
const session = rows[0]
|
|
if (session) {
|
|
return {
|
|
code: 200,
|
|
message: "Client session valid."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Client session not found for this accessToken.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function invalidateClientSession(accessToken, clientToken) {
|
|
try {
|
|
const sql = `DELETE FROM clientSessions WHERE accessToken = ? AND clientToken = ?`
|
|
const result = await database.query(sql, [accessToken, clientToken])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "Client session successfully invalidated."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "Client session not found for this accessToken/clientToken combination.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function revokeAccessTokens(uuid) {
|
|
try {
|
|
const sql = `DELETE FROM clientSessions WHERE uuid = ?`
|
|
const result = await database.query(sql, [uuid])
|
|
|
|
if (result.affectedRows > 0) {
|
|
return {
|
|
code: 200,
|
|
message: "Access tokens successfully revoked."
|
|
}
|
|
} else {
|
|
throw new DefaultError(404, "No access token found for this user.")
|
|
}
|
|
} catch (error) {
|
|
return utils.handleDBError(error)
|
|
}
|
|
}
|
|
|
|
async function getUsernamesRules() {
|
|
try {
|
|
const rows = await database.query("SELECT rule, type FROM usernameRules")
|
|
return rows.map(row => {
|
|
if (row.type === 1) {
|
|
return { type: "regex", pattern: new RegExp(row.rule, "i") }
|
|
} else {
|
|
return { type: "literal", value: row.rule.toLowerCase() }
|
|
}
|
|
})
|
|
} catch (err) {
|
|
throw err
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
getUser,
|
|
register,
|
|
getClientSession,
|
|
getUsernamesRules,
|
|
revokeAccessTokens,
|
|
insertClientSession,
|
|
getPlayerProperties,
|
|
validateClientSession,
|
|
invalidateClientSession,
|
|
validateClientSessionWithoutClientToken
|
|
} |