Skip to content

Commit

Permalink
v1.2.0 (#102)
Browse files Browse the repository at this point in the history
* Implement Discord-based registration with Minecraft backed auth and user 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>

* Added rank permissions context into login sessions and clean up profile 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.

* Add ` in profile title username to keep formatting.

* Implement Google Analytics tags and config. (#101)

* Push application api and dashboard changes.

* More application changes and added /apply slash command.

* Fix invalid applicationId

* Fix application modal displaying same application description

---------

Co-authored-by: Aron Brown <webmaster@birdwingfx.com>
Co-authored-by: Ben Robson <ben@reliableit.net.au>
  • Loading branch information
3 people authored Aug 23, 2024
1 parent eed4eb8 commit 21ee43b
Show file tree
Hide file tree
Showing 76 changed files with 2,907 additions and 1,009 deletions.
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PORT=8080
siteAddress=http://localhost:8080
TZ=Australia/Sydney

discordAPIKey=APIKEY
discordClientId=CLIENTID
discordClientSecret=CLIENTSECRET
apiKey=KEY

sessionCookieSecret=THISISNOTVERYSECRETANDITHINKYOUSHOULDCHANGEIT

databaseHost=database.example.com
databasePort=3306
databaseUser=root
databasePassword=root
databaseName=zander
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ package-lock.json
sslCert.cert
sslPrivate.key
config.json
package-lock.json
google.json
features.json
11 changes: 9 additions & 2 deletions api/common.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import dotenv from "dotenv";
dotenv.config();
import config from "../config.json" assert { type: "json" };
import fetch from "node-fetch";
import { readdirSync } from "fs";
Expand Down Expand Up @@ -129,7 +131,7 @@ export async function hasPermission(permissionNode, req, res, features) {
}

if (!hasSpecificPerm(permissionNode, userPermissions)) {
res.view("session/noPermission", {
return res.view("session/noPermission", {
pageTitle: `Access Restricted`,
config: config,
req: req,
Expand All @@ -138,7 +140,6 @@ export async function hasPermission(permissionNode, req, res, features) {
globalImage: await getGlobalImage(),
announcementWeb: await getWebAnnouncement(),
});
return false;
}
return true;
}
Expand Down Expand Up @@ -170,6 +171,7 @@ export async function postAPIRequest(
"x-access-token": process.env.apiKey,
},
});

const data = await response.json();

console.log(data);
Expand Down Expand Up @@ -311,3 +313,8 @@ export async function expandString(string, filter) {
export function removeHtmlTags(html) {
return html.replace(/<(?!\/?(a)\b)[^<]*?>/gi, "");
}

export async function generateVerifyCode() {
const code = Math.floor(Math.random() * 900000) + 100000;
return code;
}
9 changes: 9 additions & 0 deletions api/internal_redirect/announcement.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default function announcementRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/create", async function (req, res) {
if (!hasPermission("zander.web.announcements", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/announcement/create`,
req.body,
Expand All @@ -21,6 +24,9 @@ export default function announcementRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/edit", async function (req, res) {
if (!hasPermission("zander.web.announcements", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/announcement/edit`,
req.body,
Expand All @@ -36,6 +42,9 @@ export default function announcementRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/delete", async function (req, res) {
if (!hasPermission("zander.web.announcements", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/announcement/delete`,
req.body,
Expand Down
9 changes: 9 additions & 0 deletions api/internal_redirect/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default function applicationRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/create", async function (req, res) {
if (!hasPermission("zander.web.application", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/application/create`,
req.body,
Expand All @@ -21,6 +24,9 @@ export default function applicationRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/edit", async function (req, res) {
if (!hasPermission("zander.web.application", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/application/edit`,
req.body,
Expand All @@ -36,6 +42,9 @@ export default function applicationRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/delete", async function (req, res) {
if (!hasPermission("zander.web.application", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/application/delete`,
req.body,
Expand Down
9 changes: 9 additions & 0 deletions api/internal_redirect/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default function serverRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/create", async function (req, res) {
if (!hasPermission("zander.web.server", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/server/create`,
req.body,
Expand All @@ -21,6 +24,9 @@ export default function serverRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/edit", async function (req, res) {
if (!hasPermission("zander.web.server", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/server/edit`,
req.body,
Expand All @@ -36,6 +42,9 @@ export default function serverRedirectRoute(app, config, lang) {
app.post(baseEndpoint + "/delete", async function (req, res) {
if (!hasPermission("zander.web.server", req, res)) return;

// Add userId to req.body
req.body.actioningUser = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/server/delete`,
req.body,
Expand Down
75 changes: 70 additions & 5 deletions api/internal_redirect/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,80 @@ import { postAPIRequest } from "../common";
export default function webRedirectRoute(app, config, lang) {
const baseEndpoint = "/redirect/web";

app.post(baseEndpoint + "/register", async function (req, res) {
await postAPIRequest(
`${process.env.siteAddress}/api/web/register/create`,
app.post(baseEndpoint + "/user/link", async function (req, res) {
postAPIRequest(
`${process.env.siteAddress}/api/user/link`,
req.body,
`${process.env.siteAddress}/register`,
`${process.env.siteAddress}/unregistered`,
res
);

res.redirect(`${process.env.siteAddress}/register`);
res.redirect(`${process.env.siteAddress}/`);

return res;
});

app.post(baseEndpoint + "/user/profile/display", async function (req, res) {
// Add userId to req.body
req.body.userId = req.session.user.userId;

// Make the API request
postAPIRequest(
`${process.env.siteAddress}/api/user/profile/display`,
req.body,
`${process.env.siteAddress}/`,
res
);

res.redirect(`${process.env.siteAddress}/profile/${req.session.user.username}`);

return res;
});

app.post(baseEndpoint + "/user/profile/interests", async function (req, res) {
// Add userId to req.body
req.body.userId = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/user/profile/interests`,
req.body,
`${process.env.siteAddress}/`,
res
);

res.redirect(`${process.env.siteAddress}/profile/${req.session.user.username}`);

return res;
});

app.post(baseEndpoint + "/user/profile/about", async function (req, res) {
// Add userId to req.body
req.body.userId = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/user/profile/about`,
req.body,
`${process.env.siteAddress}/`,
res
);

res.redirect(`${process.env.siteAddress}/profile/${req.session.user.username}`);

return res;
});

app.post(baseEndpoint + "/user/profile/social", async function (req, res) {
// Add userId to req.body
req.body.userId = req.session.user.userId;

postAPIRequest(
`${process.env.siteAddress}/api/user/profile/social`,
req.body,
`${process.env.siteAddress}/`,
res
);

res.redirect(`${process.env.siteAddress}/profile/${req.session.user.username}`);

return res;
});
Expand Down
2 changes: 1 addition & 1 deletion api/routes/announcement.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default function announcementApiRoute(app, config, db, features, lang) {

app.get(baseEndpoint + "/get", async function (req, res) {
isFeatureEnabled(features.announcements, res, lang);
const announcementId = optional(req.query, "announcementId");
const announcementId = optional(req.query, "id");
const announcementType = optional(req.query, "announcementType");
const enabled = optional(req.query, "enabled");

Expand Down
4 changes: 2 additions & 2 deletions api/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export default function applicationApiRoute(app, config, db, features, lang) {
try {
function getApplications(dbQuery) {
db.query(dbQuery, function (error, results, fields) {
console.log(results);

if (error) {
res.send({
success: false,
Expand Down Expand Up @@ -68,8 +70,6 @@ export default function applicationApiRoute(app, config, db, features, lang) {

let applicationCreatedLang = lang.applications.applicationCreated;

console.log(req.body);

try {
db.query(
`INSERT INTO applications
Expand Down
58 changes: 46 additions & 12 deletions api/routes/discord.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { updateAudit_lastMinecraftLogin, updateAudit_lastMinecraftMessage } from "../../controllers/auditController";
import { Webhook } from "discord-webhook-node";
import { isFeatureEnabled, required } from "../common";

Expand Down Expand Up @@ -44,6 +45,21 @@ export default function discordApiRoute(
const server = required(req.body, "server", res);
const content = required(req.body, "content", res);

//
// Update user profile for auditing
//
try {
updateAudit_lastMinecraftMessage(new Date(), username);
} catch (error) {
return res.send({
success: false,
message: `${error}`,
});
}

//
// Send Discord Message to Log
//
try {
const networkChatLogHook = new Webhook(
config.discord.webhooks.networkChatLog
Expand All @@ -66,26 +82,44 @@ export default function discordApiRoute(
isFeatureEnabled(features.discord, res, lang);
const username = required(req.body, "username", res);

try {
const networkChatLogHook = new Webhook(
config.discord.webhooks.networkChatLog
);
//
// Send Discord Message to Log
//
try {
const networkChatLogHook = new Webhook(
config.discord.webhooks.networkChatLog
);

networkChatLogHook.send(
`:ballot_box_with_check: | \`${username}\` has joined the Network.`
);
} catch (error) {
return res.send({
success: false,
message: `${error}`,
});
}
});

networkChatLogHook.send(
`:ballot_box_with_check: | \`${username}\` has joined the Network.`
);
app.post(baseEndpoint + "/leave", async function (req, res) {
isFeatureEnabled(features.discord, res, lang);
const username = required(req.body, "username", res);

//
// Update user profile for auditing
//
try {
updateAudit_lastMinecraftLogin(new Date(), username);
} catch (error) {
return res.send({
success: false,
message: `${error}`,
});
}
});

app.post(baseEndpoint + "/leave", async function (req, res) {
isFeatureEnabled(features.discord, res, lang);
const username = required(req.body, "username", res);

//
// Send Discord Message to Log
//
try {
const networkChatLogHook = new Webhook(
config.discord.webhooks.networkChatLog
Expand Down
2 changes: 2 additions & 0 deletions api/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import sessionApiRoute from "./session";
import userApiRoute from "./user";
import webApiRoute from "./web";
import filterApiRoute from "./filter";
import rankApiRoute from "./ranks";

export default (app, client, moment, config, db, features, lang) => {
announcementApiRoute(app, config, db, features, lang);
Expand All @@ -15,6 +16,7 @@ export default (app, client, moment, config, db, features, lang) => {
sessionApiRoute(app, config, db, features, lang);
userApiRoute(app, config, db, features, lang);
webApiRoute(app, config, db, features, lang);
rankApiRoute(app, config, db, features, lang);
filterApiRoute(app, config, db, features, lang);

app.get("/api/heartbeat", async function (req, res) {
Expand Down
Loading

0 comments on commit 21ee43b

Please sign in to comment.