-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v1.2.0 #102
Conversation
…ser profiles. (#99) * Delete message after filtering prohibited content. * Fix spacing in network log messages. * Make usernames more presentable in logs. * Remove deleted channel field from being mentioned twice. * Fixed issue where filter errors after response is sent. * Changed from HEX to Colour * Add /poll command. * Add page descriptions to headers. * Added keywords and SEO option to configuration. * Add documentation badges for list and editors. * Push mobile view changes for session views. * Resolved mobile styling issues with dashboard views. * Added a staffChannel config option and a /staffhelp command * Resolve issues with cookie banner not showing on /register * Made urgent change to hasPermission, allowing non-logged in users to view admin panel. * Reformat all project files using Prettier. (#90) * Commit not found. * Prettify all JS and JSON files. * Resolve issue with logout crashing. * Separate redirect route into own file, add config option for kb and added issue tracker route. * Change node engine to support node 18. (#92) * Implementation of a Ranks/donation page. (#91) * Commence work on /ranks page and Tebex integration. * Transitioning back to JSON file, using catagory and packages * Finish rank page implementation. * Update perks. * Implement a call to action button style instead and make mobile friendly. * Made the server name look to site config for /ranks * Change rank page descriptor. * Commit start of rego process. * Add more routes * Implement 2fa interactive form element. * Install packages for email integration * Implement email template draft and smtp credentials. * Commence more work on controller and tests for emails. * Working on pathing. * Fix pathing on email template. * Add email header and footer and fix up routes. * Add a rough template draft of registration * Change registration gateway to discord, commence working on Minecraft link. * Add user verification via /verify * Remove all old rego code and mentions to passwords, remove email views and partials. * Add token code expiry and draft a expiry cron task. * Refactor getUser() into UserGetter * Push user verification service. * Commence drafting profiles and finalising login gateway * Add coming soon alerts on profile features. * Commit more profile work and db profile changes. * Applied permissions to profile. * Add example.env and config files. * Added Minecraft login and chat audits, also added website login. * Added discord voice and message audit events. * Filled in fields for audit to complete feature development. * Start work on profile editor. * Start implementing social connections into editor. * Finalise design for profile editor. * Implemented all of the base work for API routes and controllers. * Start on profile/display in editor and fix issue with Gravatar. * Finalise Social Connections in display and editor. * Fix permission node of everyone able to see dashboard, and open new tab for social connections. * Audit: If no data, then display no data instead of invalid date * Added profile stats for total logins and playtime. * Add latest session with online and offline indicators. * Add support for verification server in /server * Resolved issues with Server types displaying all instead of their type. * Create dbupgrade.sql Convert prior SCHEMA to the new schema. Use this script to upgrade from an already existing database. If creating a new database use the dbinit.sql * Commence port to new schema. * Fix result type return in user api and added 17 global images. * Make unregistered failure link back to rego page. * Set audit to skip for discord voice and chat if discord is not linked. * Resolved issues with user api creation. * Resolve issues with messages attempting to send to channels. * Require the webhook package. * Rollback to d70b343 * Changes to user route and troubleshooting discord login. * Remove redirect returns. * Add troubleshooting to callback. * Push further troubleshooting. * Add troubleshooting to isRegistered * Add additional check and troubleshooting * Commit * Add a build command. * Fix Discord oAuth (#98) * Wrap in string for ID and secret. * Add logging to callback. * Add more logging. * Add more testing * got here marker. * move marker. * Move marker * update marker * marker 4, reveal session * Add permission data log * Fix issues with loading profile editor. * On profile updates, redirect to profile. * Add steam social and profanity filter to interests. * Add ability for linked accounts to not trigger linking codes. * Push profile command. * Add ranks api to fetch by rank and user. * Add debug for user permissions --------- Co-authored-by: Aron Brown <webmaster@birdwingfx.com> Co-authored-by: Ben Robson <ben@reliableit.net.au>
…le command. (#100) * Start rank perms scope on user implementation * Fix getUserPermissions to scope in rank permission nodes. * Remove the zanderdev prefix from permissions lookup. * Replace with amended getUserLastSession() to stop profiles from crashing. * Refactor to stop nulls from crashing the API * Removed all Craftatar discord side features due to traffic amplification attacks.
success: true, | ||
data: results, | ||
return new Promise((resolve, reject) => { | ||
db.query(dbQuery, function (error, results, fields) { |
Check failure
Code scanning / CodeQL
Database query built from user-controlled sources High
user-provided value
This query string depends on a
user-provided value
app.post(baseEndpoint + "/verify", async function (req, res) { | ||
const username = required(req.body, "username"); | ||
const uuid = required(req.body, "uuid"); | ||
|
||
const userData = new UserGetter(); | ||
const user = await userData.byUUID(uuid); | ||
|
||
if (!user) { | ||
return res.send({ | ||
success: false, | ||
message: `User ${username} does not exist in player base, please join the Network and try again.`, | ||
}); | ||
} else { | ||
if (user.discordId) { | ||
return res.send({ | ||
success: false, | ||
message: `You are already registered and linked, you cannot do this again.`, | ||
}); | ||
} | ||
|
||
try { | ||
const linkCode = await generateVerifyCode(); | ||
const now = new Date(); | ||
const codeExpiry = new Date(now.getTime() + 5 * 60000); | ||
|
||
db.query( | ||
`INSERT INTO userVerifyLink (uuid, username, linkCode, codeExpiry) VALUES (?, ?, ?, ?)`, | ||
[uuid, username, linkCode, codeExpiry], | ||
function (error, results, fields) { | ||
if (error) { | ||
return res.send({ | ||
success: false, | ||
message: `There was an error in setting your code, try again in 5 minutes.`, | ||
}); | ||
} | ||
|
||
return res.send({ | ||
success: true, | ||
message: `Here is your code: ${linkCode}\nGo back to the registration form and put this in.\nThis code will expire in 5 minutes.`, | ||
}); | ||
} | ||
); | ||
} catch (error) { | ||
return res.send({ | ||
success: false, | ||
message: `${error}`, | ||
}); | ||
} | ||
} | ||
|
||
return res; | ||
}); |
Check failure
Code scanning / CodeQL
Missing rate limiting High
authorization
This route handler performs
a database access
|
||
async function getRankPermissions(allRanks) { | ||
return new Promise((resolve) => { | ||
db.query( | ||
`SELECT DISTINCT permission FROM rankPermissions WHERE FIND_IN_SET(rankSlug, ?)`, | ||
[allRanks.join()], | ||
async function (err, results) { | ||
if (err) { | ||
throw err; | ||
} | ||
|
||
let rankPermissions = results.map((a) => a.permission); | ||
resolve(rankPermissions); | ||
} | ||
); | ||
}); | ||
} | ||
if (!userResponse.ok) { | ||
const errorText = `Failed to fetch user data: ${userResponse.status} ${userResponse.statusText}`; | ||
console.error(errorText); | ||
throw new Error(errorText); | ||
} | ||
|
||
async function getUserPermissions(userData) { | ||
return new Promise((resolve) => { | ||
//Get permissions assigned directly to user | ||
db.query( | ||
`SELECT DISTINCT permission FROM userPermissions WHERE userId = ?`, | ||
[userData.userId], | ||
async function (err, results) { | ||
if (err) { | ||
throw err; | ||
} | ||
|
||
let userPermissions = results.map((a) => a.permission); | ||
resolve(userPermissions); | ||
} | ||
); | ||
}); | ||
} | ||
const userData = await userResponse.json(); | ||
// Check if user is registered in your system | ||
const userGetData = new UserGetter(); | ||
const userIsRegistered = await userGetData.isRegistered(userData.id); | ||
|
||
if (!userIsRegistered) { | ||
// Set a cookie for unregistered user | ||
res.cookie("discordId", userData.id, { | ||
path: "/", | ||
httpOnly: true, | ||
maxAge: 10000, // Expires in 10 seconds | ||
}); | ||
|
||
async function getPermissions(userData) { | ||
//Get directly assigned User Ranks | ||
userData.userRanks = await getUserRanks(userData); | ||
//get all the ranks including children | ||
let allRanks = await getUserRanks( | ||
userData, | ||
userData.userRanks.map((a) => a.rankSlug) | ||
); | ||
//get permissions assigned to all the ranks | ||
let rankPermissions = await getRankPermissions(allRanks); | ||
//Get permissions assigned directly to user | ||
let userPermissions = await getUserPermissions(userData); | ||
//Combine into 1 permissions array | ||
let permissions = rankPermissions.concat(userPermissions); | ||
//Using a set of the array removes duplicates and prevents infinite loops | ||
userData.permissions = [...new Set(permissions)]; | ||
return userData; | ||
console.log("User is unregistered, redirecting to /unregistered"); | ||
return res.redirect(`/unregistered`); | ||
} else { | ||
// User is registered, proceed with session setup | ||
const userLoginData = await userGetData.byDiscordId(userData.id); | ||
const userPermissionData = await getUserPermissions(userLoginData); | ||
|
||
req.session.authenticated = true; | ||
req.session.user = { | ||
userId: userLoginData.userId, | ||
username: userLoginData.username, | ||
profilePicture: await getProfilePicture(userLoginData.username), | ||
discordID: userLoginData.discordId, | ||
uuid: userLoginData.uuid, | ||
ranks: userPermissionData.userRanks, | ||
permissions: userPermissionData, | ||
}; | ||
|
||
console.log(`User Permissions`); | ||
console.log(userPermissionData); | ||
|
||
// Update user profile for auditing | ||
await updateAudit_lastWebsiteLogin(new Date(), userLoginData.username); | ||
return res.redirect(`${process.env.siteAddress}/`); | ||
} | ||
} catch (error) { | ||
console.error("Error:", error); | ||
return res.status(500).send("Internal Server Error"); | ||
} | ||
}); |
Check failure
Code scanning / CodeQL
Missing rate limiting High
No description provided.