Initial Commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..445071a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,147 @@
+# Created by https://www.toptal.com/developers/gitignore/api/node
+# Edit at https://www.toptal.com/developers/gitignore?templates=node
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.pnpm-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+web_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variable files
+.env
+.env.development.local
+.env.test.local
+.env.production.local
+.env.local
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+out
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+.temp
+
+# Docusaurus cache and generated files
+.docusaurus
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# yarn v2
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.yarn/install-state.gz
+.pnp.*
+
+### Node Patch ###
+# Serverless Webpack directories
+.webpack/
+
+# Optional stylelint cache
+
+# SvelteKit build / generate output
+.svelte-kit
+
+# End of https://www.toptal.com/developers/gitignore/api/node
+
+config/
+.DS_Store
\ No newline at end of file
diff --git a/backend/checkAuth.js b/backend/checkAuth.js
new file mode 100644
index 0000000..39db231
--- /dev/null
+++ b/backend/checkAuth.js
@@ -0,0 +1,5 @@
+module.exports = async (req, res, next) => {
+ if (req.isAuthenticated()) return next();
+ req.session.backURL = req.url;
+ res.redirect("/login");
+}
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
new file mode 100755
index 0000000..cb1f98c
--- /dev/null
+++ b/bun.lockb
Binary files differ
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..86430e1
--- /dev/null
+++ b/index.js
@@ -0,0 +1,42 @@
+const {
+ Client,
+ GatewayIntentBits
+} = require('discord.js');
+
+const client = new Client({
+ intents: [
+ GatewayIntentBits.Guilds,
+ GatewayIntentBits.GuildMembers,
+ GatewayIntentBits.DirectMessages,
+ ],
+});
+
+require("dotenv").config({
+ path: "config/.env"
+});
+
+require('./utils/functions')(client);
+
+client.mongoose = require('./utils/mongoose');
+
+client.on('ready', () => {
+ console.log(`Starting Server`);
+ const webPortal = require('./server');
+ webPortal.load(client);
+});
+
+// Listening for error & warn events.
+client.on("error", console.error);
+client.on("warn", console.warn);
+
+process.on('unhandledRejection', error => {
+ console.error('Unhandled promise rejection:', error);
+});
+
+process.on('uncaughtException', function (err) {
+ console.log('Caught exception: ' + err);
+});
+
+client.mongoose.init();
+
+client.login(process.env.TOKEN);
\ No newline at end of file
diff --git a/models/auth.js b/models/auth.js
new file mode 100644
index 0000000..eca7725
--- /dev/null
+++ b/models/auth.js
@@ -0,0 +1,9 @@
+const mongoose = require('mongoose');
+
+const authSchema = mongoose.Schema({
+ discord: { type: String, require: true },
+ minecraft: { type: String, require: false },
+ banned: { type: Boolean, require: true, default: false },
+});
+
+module.exports = mongoose.model('Auth', authSchema);
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..20e016e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "Appeel",
+ "version": "0.1.0",
+ "description": "Appeel bot",
+ "main": "node index.js",
+ "scripts": {
+ "start": "node index.js"
+ },
+ "engines": {
+ "node": "17.x"
+ },
+ "author": "Cleo",
+ "license": "MIT",
+ "dependencies": {
+ "body-parser": "^1.20.0",
+ "discord.js": "^14.3.0",
+ "dotenv": "^16.0.2",
+ "ejs": "^3.1.8",
+ "express": "^4.18.1",
+ "express-session": "^1.17.3",
+ "mongoose": "^6.6.1",
+ "passport": "^0.6.0",
+ "passport-discord": "^0.1.4"
+ },
+ "devDependencies": {
+ "eslint": "^8.15.0",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-promise": "^6.0.0"
+ }
+}
diff --git a/public/assets/blahaj.png b/public/assets/blahaj.png
new file mode 100644
index 0000000..8d24d08
--- /dev/null
+++ b/public/assets/blahaj.png
Binary files differ
diff --git a/public/assets/boat.png b/public/assets/boat.png
new file mode 100644
index 0000000..1e2bfe2
--- /dev/null
+++ b/public/assets/boat.png
Binary files differ
diff --git a/public/assets/bush_left.png b/public/assets/bush_left.png
new file mode 100644
index 0000000..efa019d
--- /dev/null
+++ b/public/assets/bush_left.png
Binary files differ
diff --git a/public/assets/bush_right.png b/public/assets/bush_right.png
new file mode 100644
index 0000000..df90408
--- /dev/null
+++ b/public/assets/bush_right.png
Binary files differ
diff --git a/public/assets/cloud_left.png b/public/assets/cloud_left.png
new file mode 100644
index 0000000..9ea751d
--- /dev/null
+++ b/public/assets/cloud_left.png
Binary files differ
diff --git a/public/assets/cloud_right.png b/public/assets/cloud_right.png
new file mode 100644
index 0000000..72e8dcd
--- /dev/null
+++ b/public/assets/cloud_right.png
Binary files differ
diff --git a/public/assets/embed.png b/public/assets/embed.png
new file mode 100644
index 0000000..65afc0b
--- /dev/null
+++ b/public/assets/embed.png
Binary files differ
diff --git a/public/assets/favicon.png b/public/assets/favicon.png
new file mode 100644
index 0000000..9c09d02
--- /dev/null
+++ b/public/assets/favicon.png
Binary files differ
diff --git a/public/assets/icon/discord.jpg b/public/assets/icon/discord.jpg
new file mode 100644
index 0000000..4f6d534
--- /dev/null
+++ b/public/assets/icon/discord.jpg
Binary files differ
diff --git a/public/assets/icon/reddit.png b/public/assets/icon/reddit.png
new file mode 100644
index 0000000..a403178
--- /dev/null
+++ b/public/assets/icon/reddit.png
Binary files differ
diff --git a/public/assets/icon/revolt.png b/public/assets/icon/revolt.png
new file mode 100644
index 0000000..7a4357a
--- /dev/null
+++ b/public/assets/icon/revolt.png
Binary files differ
diff --git a/public/assets/lake.png b/public/assets/lake.png
new file mode 100644
index 0000000..46b10ab
--- /dev/null
+++ b/public/assets/lake.png
Binary files differ
diff --git a/public/assets/mountains.png b/public/assets/mountains.png
new file mode 100644
index 0000000..ab8c007
--- /dev/null
+++ b/public/assets/mountains.png
Binary files differ
diff --git a/public/assets/sky.png b/public/assets/sky.png
new file mode 100644
index 0000000..1af09ae
--- /dev/null
+++ b/public/assets/sky.png
Binary files differ
diff --git a/public/css/style.css b/public/css/style.css
new file mode 100644
index 0000000..0629490
--- /dev/null
+++ b/public/css/style.css
@@ -0,0 +1,230 @@
+@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap");
+
+html,
+body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden; /* Prevent page scrolling */
+}
+
+body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.background {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: -1;
+}
+
+.bush {
+ position: fixed;
+ top: 3%;
+ width: 100%;
+ height: 100%;
+ z-index: 7;
+ filter: blur(5px);
+}
+
+.bush-left-overlay {
+ left: -3%;
+ background-image: url("./../assets/bush_left.png");
+ background-size: cover;
+ background-position: center bottom;
+}
+
+.bush-right-overlay {
+ left: 3%;
+ background-image: url("./../assets/bush_right.png");
+ background-size: cover;
+ background-position: center bottom;
+}
+
+.blahaj-overlay {
+ background-image: url("./../assets/blahaj.png");
+ background-size: cover;
+ background-position: calc(50% - 50px) bottom;
+ z-index: 6;
+}
+
+.boat-overlay {
+ background-image: url("./../assets/boat.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ z-index: 5;
+}
+
+.cloud-left-overlay {
+ background-image: url("./../assets/cloud_left.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ top: -10px;
+ z-index: 4;
+}
+
+.cloud-right-overlay {
+ background-image: url("./../assets/cloud_right.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ top: -20px;
+ z-index: 4;
+}
+
+.lake-overlay {
+ background-image: url("./../assets/lake.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ z-index: 3;
+}
+
+.mountains-overlay {
+ background-image: url("./../assets/mountains.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ z-index: 2;
+}
+
+.sky-overlay {
+ background-image: url("./../assets/sky.png");
+ background-size: cover;
+ background-position: calc(50% + 250px) bottom;
+ z-index: 1;
+}
+
+.canvas-overlay {
+ position: relative;
+ top: 100px;
+ left: -250px;
+ z-index: 1;
+ filter: blur(5px);
+}
+
+.discord {
+ background-color: #5865f2;
+}
+
+.revolt {
+ background-color: rgb(255, 70, 84);
+}
+
+.reddit {
+ background-color: #ff4300;
+}
+
+.image-button {
+ display: inline-block;
+ padding: 13px;
+ border-radius: 5px;
+ color: white;
+ border: none;
+ font-size: px;
+ text-align: left;
+ text-decoration: none;
+ margin-bottom: 10px;
+ font-family: "Poppins", "San Francisco", sans-serif;
+ font-weight: 400;
+ text-align: center;
+ width: 90%;
+}
+
+
+.button-icon {
+ display: inline-block;
+ vertical-align: middle;
+ width: 20px;
+ height: 20px;
+ margin-right: 13px;
+}
+
+.container {
+ position: absolute;
+ right: 50px;
+ background-color: #a789a8a2;
+ padding: 50px 50px;
+ border-radius: 5px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+ transition: background-color 2s ease-out;
+ max-width: 300px;
+ flex-direction: column;
+ align-items: center;
+ z-index: 9;
+}
+
+h1 {
+ margin-top: 0;
+ font-family: "Poppins", "San Francisco", sans-serif;
+ font-weight: 600;
+ color: rgb(236, 236, 236);
+ text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+ font-size: 40px;
+}
+
+h2 {
+ margin-top: -35px;
+ font-family: "Poppins", "San Francisco", sans-serif;
+ font-weight: 500;
+ color: rgb(236, 236, 236);
+ text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+ font-size: 25px;
+}
+
+p {
+ margin-top: -20px; /* Adjust the margin as needed */
+ padding-bottom: 7px;
+ font-family: "Poppins", "San Francisco", sans-serif;
+ font-weight: 400;
+ color: rgb(236, 236, 236);
+ text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+ font-size: 17px;
+}
+
+p.indent {
+ font-weight: 400;
+ margin-top: -10px;
+ margin-left: 25px;
+}
+
+.blur {
+ backdrop-filter: blur(7px);
+}
+
+@media only screen and (max-width: 700px) {
+ .container {
+ right: auto;
+ padding: 50px 30px;
+ max-width: 400px;
+ }
+
+ h1 {
+ font-size: 30px;
+ }
+
+ p {
+ margin-top: -25px;
+ font-size: 15px;
+ }
+
+ .image-button {
+ font-size: 15px;
+ }
+
+ .button-icon {
+ width: 15px;
+ height: 15px;
+ }
+
+ .discord {
+ padding: 10px;
+ }
+
+ .revolt {
+ padding: 10px;
+ }
+
+}
diff --git a/public/grayscale aroace.png b/public/grayscale aroace.png
new file mode 100644
index 0000000..96efcbe
--- /dev/null
+++ b/public/grayscale aroace.png
Binary files differ
diff --git a/public/grayscale barcode.png b/public/grayscale barcode.png
new file mode 100644
index 0000000..e256ee4
--- /dev/null
+++ b/public/grayscale barcode.png
Binary files differ
diff --git a/public/grayscale prideplace.png b/public/grayscale prideplace.png
new file mode 100644
index 0000000..e5604dd
--- /dev/null
+++ b/public/grayscale prideplace.png
Binary files differ
diff --git a/public/grayscale trans 1.png b/public/grayscale trans 1.png
new file mode 100644
index 0000000..a088dc8
--- /dev/null
+++ b/public/grayscale trans 1.png
Binary files differ
diff --git a/public/grayscale trans 2.png b/public/grayscale trans 2.png
new file mode 100644
index 0000000..0cb02c3
--- /dev/null
+++ b/public/grayscale trans 2.png
Binary files differ
diff --git a/public/grayscale trans pikmin.png b/public/grayscale trans pikmin.png
new file mode 100644
index 0000000..1d6c5f2
--- /dev/null
+++ b/public/grayscale trans pikmin.png
Binary files differ
diff --git a/public/js/canvas.js b/public/js/canvas.js
new file mode 100644
index 0000000..3d2c1cc
--- /dev/null
+++ b/public/js/canvas.js
@@ -0,0 +1,98 @@
+const canvas = document.querySelector("canvas");
+const ctx = canvas.getContext("2d");
+
+let amplitud = 10;
+let speed = 0.025;
+let points = [];
+
+let cw = (canvas.width = 1500),
+ cx = cw / 2;
+let ch = (canvas.height = 1500),
+ cy = ch / 2;
+ctx.fillStyle = "#ffffff";
+ctx.strokeStyle = "transparent";
+
+let corners = [];
+let n = 15;
+let r = cx - amplitud - 100;
+for (var i = 0; i < n; i++) {
+ corners.push([
+ cx + r * Math.cos((2 * Math.PI * i) / n),
+ cy + r * Math.sin((2 * Math.PI * i) / n),
+ ]);
+}
+
+class Point {
+ constructor(x, y, hv) {
+ this.cx = x;
+ this.cy = y;
+ this.a = Math.random() * 2 * Math.PI;
+ this.hv = hv;
+
+ this.update();
+ }
+
+ update() {
+ this.a += speed;
+
+ if (this.hv == 0) {
+ this.x = this.cx;
+ this.y = this.cy + amplitud * Math.cos(this.a);
+ } else {
+ this.x = this.cx + amplitud * Math.cos(this.a);
+ this.y = this.cy;
+ }
+ }
+}
+
+function divide(n, a, b) {
+ for (var i = 0; i <= n; i++) {
+ let p = {
+ x: ((b[0] - a[0]) * i) / n + a[0],
+ y: ((b[1] - a[1]) * i) / n + a[1],
+ hv: b[1] - a[1],
+ };
+ points.push(new Point(p.x, p.y, p.hv));
+ }
+}
+
+for (let i = 0; i < corners.length; i++) {
+ let currentCorner = corners[i];
+ let nextCorner = corners[(i + 1) % corners.length];
+ divide(10, currentCorner, nextCorner);
+ points.pop();
+}
+
+function drawCurves() {
+ let p = {};
+ p.x = (points[points.length - 1].x + points[0].x) / 2;
+ p.y = (points[points.length - 1].y + points[0].y) / 2;
+ ctx.beginPath();
+ ctx.moveTo(p.x, p.y);
+ for (var i = 0; i < points.length - 1; i++) {
+ let mp = {};
+ mp.x = (points[i].x + points[i + 1].x) / 2;
+ mp.y = (points[i].y + points[i + 1].y) / 2;
+ ctx.quadraticCurveTo(points[i].x, points[i].y, mp.x, mp.y);
+ }
+
+ ctx.quadraticCurveTo(
+ points[points.length - 1].x,
+ points[points.length - 1].y,
+ p.x,
+ p.y
+ );
+ ctx.stroke();
+ ctx.fill();
+}
+
+function Draw() {
+ window.requestAnimationFrame(Draw);
+ ctx.clearRect(0, 0, cw, ch);
+ points.map((p) => {
+ p.update();
+ });
+ drawCurves();
+}
+
+Draw();
diff --git a/public/js/script.js b/public/js/script.js
new file mode 100644
index 0000000..e9a51f2
--- /dev/null
+++ b/public/js/script.js
@@ -0,0 +1,66 @@
+function changeContainerColor(color) {
+ const container = document.querySelector(".container");
+ container.style.backgroundColor = color;
+}
+
+const blahajOverlay = document.querySelector(".blahaj-overlay");
+const boatOverlay = document.querySelector(".boat-overlay");
+const cloudLeftOverlay = document.querySelector(".cloud-left-overlay");
+const cloudRightOverlay = document.querySelector(".cloud-right-overlay");
+const lakeOverlay = document.querySelector(".lake-overlay");
+const mountainsOverlay = document.querySelector(".mountains-overlay");
+
+const bushLeftOverlay = document.querySelector(".bush-left-overlay");
+const bushRightOverlay = document.querySelector(".bush-right-overlay");
+const canvasOverlay = document.querySelector(".canvas-overlay");
+
+blahajOverlay.style.transition = "transform 2s ease-out";
+boatOverlay.style.transition = "transform 2s ease-out";
+lakeOverlay.style.transition = "transform 2s ease-out";
+cloudLeftOverlay.style.transition = "transform 2s ease-out";
+cloudRightOverlay.style.transition = "transform 2s ease-out";
+bushLeftOverlay.style.transition = "transform 2s ease-out";
+bushRightOverlay.style.transition = "transform 2s ease-out";
+
+canvasOverlay.style.transform = "scale(0.9)";
+
+window.addEventListener("resize", () => {
+ canvasOverlay.style.transform =
+ "scale(" + scaleValue(window.innerWidth) + ")";
+});
+
+function parallaxStart() {
+ blahajOverlay.style.transform = "scale(1.01)";
+ boatOverlay.style.transform = "scale(1.01)";
+ lakeOverlay.style.transform = "scale(1.003)";
+ cloudLeftOverlay.style.transform = "translateX(-5px)";
+ cloudRightOverlay.style.transform = "translateX(5px)";
+ bushLeftOverlay.style.transform = "translateX(-100px)";
+ bushRightOverlay.style.transform = "translateX(150px)";
+}
+
+function parallaxEnd() {
+ blahajOverlay.style.transform = "scale(1)";
+ boatOverlay.style.transform = "scale(1)";
+ lakeOverlay.style.transform = "scale(1)";
+ cloudLeftOverlay.style.transform = "translateX(0px)";
+ cloudRightOverlay.style.transform = "translateX(0px)";
+ bushLeftOverlay.style.transform = "translateX(0px)";
+ bushRightOverlay.style.transform = "translateX(0px)";
+}
+
+function scaleValue(windowWidth) {
+ const minWindowWidth = 500; // Minimum window.innerWidth value
+ const maxWindowWidth = 2000; // Maximum window.innerWidth value
+ const minValue = 0.8; // Minimum scaled value
+ const maxValue = 0.9; // Maximum scaled value
+
+ // Scale the value based on the window.innerWidth
+ const scaledValue =
+ minValue +
+ ((windowWidth - minWindowWidth) / (maxWindowWidth - minWindowWidth)) *
+ (maxValue - minValue);
+
+ // Return the scaled value (rounded to the nearest integer)
+ return scaledValue;
+}
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..04cda75
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,6 @@
+User-agent: *
+Disallow: /css/
+Disallow: /js/
+Disallow: /assets/
+
+Sitemap: https://trans.gg/sitemap.xml
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..eb9ed83
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset
+ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
+ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
+
+<url>
+ <loc>https://trans.gg/</loc>
+ <lastmod>2023-06-23T02:21:30+00:00</lastmod>
+</url>
+
+</urlset>
\ No newline at end of file
diff --git a/public/template.json b/public/template.json
new file mode 100644
index 0000000..f1d7612
--- /dev/null
+++ b/public/template.json
@@ -0,0 +1,121 @@
+{
+ "contact": "discord.gg/TransPlace",
+ "notifications": "https://broadcaster.trans.gg",
+ "templates": [
+ {
+ "name": "First Trans Flag Grayscaled",
+ "sources": [
+ "https://i.imgur.com/IRfl6TH.png"
+ ],
+ "x": 1548,
+ "y": 997
+ },
+ {
+ "name": "Second Trans Flag Grayscaled",
+ "sources": [
+ "https://i.imgur.com/TNw7fGE.png"
+ ],
+ "x": 864,
+ "y": 816
+ },
+ {
+ "name": "Aro/Ace flags",
+ "sources": [
+ "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20aroace.png"
+ ],
+ "x": 1134,
+ "y": 1588
+ },
+ {
+ "name": "Barcode trans pikmin",
+ "sources": [
+ "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20trans%20pikmin.png"
+ ],
+ "x": 542,
+ "y": 1755
+ },
+ {
+ "name": "barcode flags",
+ "sources": [
+ "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20barcode.png"
+ ],
+ "x": 500,
+ "y": 1754
+ },
+ {
+ "name": "Whiteout",
+ "sources": [
+ "https://place.army/default_target.png?cachebust=1"
+ ],
+ "x": 0,
+ "y": 0
+ }
+ ],
+ "whitelist": [
+ {
+ "name": "Tally Hall",
+ "url": "https://raw.githubusercontent.com/TransPlace-Devs/rplace-tallyhall/production/tallyhall.json"
+ },
+ {
+ "name": "r/PlacePride",
+ "url": "https://pride.place/template.json"
+ },
+ {
+ "name": "Outer Wilds",
+ "url": "https://raw.githubusercontent.com/souleaub/TGR_Overlay/main/outer_wilds.json"
+ },
+ {
+ "name": "YTTD",
+ "url": "https://rentry.co/yttdgang2/raw"
+ },
+ {
+ "name": "r/Femboy",
+ "url": "https://pastebin.com/raw/ESaN3Csh"
+ },
+ {
+ "name": "SeverslvtEvents",
+ "url": "https://raw.githubusercontent.com/Celarye/r-place-alliance/master/templates/JVNEPlace.json"
+ },
+ {
+ "name": "Echoplace",
+ "url": "https://raw.githubusercontent.com/DancingNerd/echoplace/main/echoplace.json"
+ },
+ {
+ "name": "eighty six",
+ "url": "https://raw.githubusercontent.com/Celarye/r-place-alliance/master/templates/86Place.json"
+ },
+ {
+ "name": "Celeste",
+ "url": "https://raw.githubusercontent.com/GabRioBlu/place2023celeste/main/template.json"
+ },
+ {
+ "name": "Chibi",
+ "url": "https://rentry.co/SDRA2Sora/raw"
+ },
+ {
+ "name": "Furryirl",
+ "url": "https://gist.githubusercontent.com/Furryirlburner1/09ce4195fada18db6dc5e32e30a8e34b/raw"
+ },
+ {
+ "name": "DutchGekte",
+ "url": "https://cdn.discordapp.com/attachments/982274631538987078/1132727141595881602/gekteDutch.json"
+ },
+ {
+ "name": "One Piece",
+ "url": "https://raw.githubusercontent.com/Lopeh/onepiece-place/main/oneplace-template.json"
+ },
+ {
+ "name": "Fuck Spez",
+ "url": "https://fmxal.mooo.com/fuck-spez-live/template.json"
+ },
+ {
+ "name": "Anarchy",
+ "url": "https://rentry.co/scc3v/raw"
+ },
+ {
+ "name": "barcode",
+ "url": "https://pride.place/barcode.png"
+ }
+ ],
+ "blacklist": []
+}
diff --git a/routes/index.js b/routes/index.js
new file mode 100644
index 0000000..4e7590f
--- /dev/null
+++ b/routes/index.js
@@ -0,0 +1,56 @@
+const express = require("express");
+
+const passport = require("passport");
+
+const router = express.Router();
+
+router.get("/", async (req, res) => {
+ res.render("index", {});
+});
+router.get("/auth", async (req, res) => {
+ let auth;
+ if (req.user?.id) {
+ auth = await req.client.getUserData(req.user.id);
+
+ console.log(auth.minecraft)
+ console.log(req.query.minecraft)
+ console.log(!auth.minecraft && req.query.minecraft)
+
+ if (!auth.minecraft && req.query.minecraft) {
+ console.log("hit")
+ auth = await req.client.setMC(req.user.id, req.query.minecraft);
+
+ }
+ } else auth = null;
+
+ res.render("auth", {
+ tag: req.user ? req.user.tag : "Auth",
+ auth: auth,
+ bot: req.client,
+ user: req.user || null,
+ });
+});
+
+router.get(
+ "/login",
+ passport.authenticate("discord", {
+ failureRedirect: "/",
+ }),
+ async function (req, res) {
+ if (!req.user.id || !req.user.guilds) {
+ // failed auth page
+ res.redirect("/");
+ } else {
+ res.redirect("/auth");
+ }
+ }
+);
+
+router.get("/logout", async function (req, res, next) {
+ req.session.destroy(() => {
+ req.logout(function () {});
+ res.redirect("/");
+ });
+});
+
+module.exports = router;
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..9ce7823
--- /dev/null
+++ b/server.js
@@ -0,0 +1,62 @@
+const express = require('express');
+const app = express();
+const bodyparser = require('body-parser');
+const session = require('express-session');
+const ejs = require('ejs');
+const passport = require('passport');
+const { Strategy } = require('passport-discord');
+
+module.exports.load = async (client) => {
+ app.use(bodyparser.json());
+ app.use(bodyparser.urlencoded({ extended: true }));
+ app.engine('html', ejs.renderFile);
+ app.set('view engine', 'ejs');
+ app.set('views', "./views");
+ app.use(express.static("./public"));
+ app.use(session({
+ secret: 'BotDashboardExample101',
+ resave: false,
+ saveUninitialized: false,
+ }));
+
+ app.use(async function(req, res, next) {
+ req.client = client;
+ next();
+ });
+
+ app.use(passport.initialize());
+ app.use(passport.session());
+
+ passport.serializeUser((user, done) => {
+ done(null, user);
+ });
+ passport.deserializeUser((obj, done) => {
+ done(null, obj);
+ });
+
+ passport.use(new Strategy({
+ clientID: process.env.CLIENT_ID,
+ clientSecret: process.env.CLIENT_SECRET,
+ callbackURL: process.env.CALLBACK_URL,
+ scope: [ 'identify', 'guilds' ],
+ }, function(accessToken, refreshToken, profile, done) {
+ process.nextTick(function() {
+ return done(null, profile);
+ });
+ }));
+
+ app.use('/', require('./routes/index'));
+ // app.use('/dashboard', require('./routes/dashboard'));
+ // app.use('/appeal', require('./routes/appeal'));
+
+ app.get('*', (req, res) => {
+ res.render('../views/404', {
+ bot: req.client,
+ user: req.user,
+ });
+ });
+
+ app.listen(process.env.PORT, () => {
+ console.log(`Web Server now online on port ${process.env.PORT} | Dashboard: http://localhost:${process.env.PORT}/`);
+ });
+};
\ No newline at end of file
diff --git a/utils/functions.js b/utils/functions.js
new file mode 100644
index 0000000..ad1fc03
--- /dev/null
+++ b/utils/functions.js
@@ -0,0 +1,22 @@
+const Auth = require('../models/auth');
+
+module.exports = client => {
+
+ client.createUser = async (userID) => {
+ let merged = Object.assign({discord: userID});
+ const newAuth = await new Auth(merged);
+ return newAuth.save()
+ };
+
+ client.getUserData = async (userID) => {
+ let data = await Auth.findOne({ discord: userID });
+ if (data) return data;
+ else return await client.createUser(userID)
+ };
+
+ client.setMC = async (userID, username) => {
+ let data = await client.getUserData(userID);
+ data.minecraft == username;
+ return data.save()
+ }
+}
\ No newline at end of file
diff --git a/utils/mongoose.js b/utils/mongoose.js
new file mode 100644
index 0000000..93f5558
--- /dev/null
+++ b/utils/mongoose.js
@@ -0,0 +1,21 @@
+const mongoose = require('mongoose');
+
+module.exports = {
+ init: () => {
+ mongoose.connect(process.env.MONGO_URL).catch(err => console.log(err.reason));
+
+ mongoose.Promise = global.Promise;
+
+ mongoose.connection.on('connected', () => {
+ console.log('\nMongoose connection successfully opened');
+ });
+
+ mongoose.connection.on('err', err => {
+ console.error(`Mongoose connection Error\n ${err.stack}`);
+ });
+
+ mongoose.connection.on('disconnected', () => {
+ console.log('Mongoose connection disconnected');
+ });
+ }
+};
\ No newline at end of file
diff --git a/views/404.ejs b/views/404.ejs
new file mode 100644
index 0000000..f8cd59e
--- /dev/null
+++ b/views/404.ejs
@@ -0,0 +1,9 @@
+<title>TransGG » 404 Not Found</title>
+
+<div style="padding-top: 65px;">
+ <div>
+ <div class="container">
+ <h2>404 - Not Found</h2>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/views/auth.ejs b/views/auth.ejs
new file mode 100644
index 0000000..c53be71
--- /dev/null
+++ b/views/auth.ejs
@@ -0,0 +1,37 @@
+<div>
+ <% if (user) { %>
+ <p>You are logged in</p>
+
+ <% if (auth && auth.minecraft) { %>
+ <p>Already Linked MC</p>
+ <p>MC username = <%= auth.minecraft %></p>
+
+ <% } else { %>
+ <p>No Minecraft Added</p>
+ <form action="/auth" method="GET`">
+ <label for="minecraft">Enter your Minecraft username:</label><br />
+ <input
+ type="text"
+ id="minecraft"
+ name="minecraft"
+ pattern="^[a-zA-Z0-9_]{2,16}$"
+ title="Please enter a valid Minecraft username (2-16 characters, only letters, numbers, and underscores)"
+ required
+ />
+ <input type="submit" value="Link Minecraft" />
+ </form>
+ <% } %>
+
+ <!-- If not ask them for their minecraft username -->
+ <% } else { %>
+ <h2>Welcome to the TransGG Minecraft Server!</h2>
+ <p>
+ To join our Minecraft server, you must first become a member of one of our
+ partnered Minecraft communities and get verified. If you're not already part
+ of a community, you can join one below. Otherwise, if you're already
+ verified, please log in below:
+ </p>
+ <a href="/login">Login</a>
+
+ <% } %>
+</div>
diff --git a/views/index.ejs b/views/index.ejs
new file mode 100644
index 0000000..b4510e5
--- /dev/null
+++ b/views/index.ejs
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>TransPlace - A Place For Trans People</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta charset="UTF-8" />
+ <meta property="og:title" content="TransPlace" />
+ <meta
+ property="og:description"
+ content="A community and safe space to talk about gaming, art, and more, while being you."
+ />
+ <meta property="og:image" content="https://trans.gg/assets/embed.png" />
+ <meta property="og:image:type" content="image/jpeg" />
+ <meta property="og:image:width" content="1920" />
+ <meta property="og:image:height" content="1080" />
+ <meta property="og:url" content="Trans.gg" />
+ <meta property="og:type" content="website" />
+ <meta name="twitter:title" content="TransPlace" />
+ <meta
+ name="twitter:description"
+ content="A community and safe space to talk about gaming, art, and more, while being you."
+ />
+ <meta name="twitter:card" content="summary_large_image" />
+ <meta name="twitter:image" content="https://trans.gg/assets/embed.png" />
+ <meta name="'twitter:image:alt" content="TransPlace Boat" />
+
+ <meta
+ name="description"
+ content="A community and safe space to talk about gaming, art, and more, while being you."
+ />
+ <meta
+ name="keywords"
+ content="TransPlace, Trans, Transgender, Non Binary, LGBT, LGBTQ, community, safe space, gaming, art, community forum, Discord, Revolt, Reddit"
+ />
+ <meta name="theme-color" content="#f6c4bb" />
+ <link
+ rel="icon"
+ href="./assets/favicon.png"
+ type="image/png"
+ sizes="16x16"
+ />
+ <link rel="stylesheet" href="./css/style.css" />
+ </head>
+
+ <body>
+ <div class="bush bush-left-overlay"></div>
+ <div class="bush bush-right-overlay"></div>
+
+ <div class="background blahaj-overlay"></div>
+ <div class="background boat-overlay"></div>
+ <div class="background cloud-left-overlay"></div>
+ <div class="background cloud-right-overlay"></div>
+ <div class="background lake-overlay"></div>
+ <div class="background mountains-overlay"></div>
+ <div class="background sky-overlay"></div>
+
+ <canvas class="canvas-overlay"></canvas>
+
+ <section
+ class="container blur"
+ onmouseover="parallaxStart()"
+ onmouseout="parallaxEnd()"
+ >
+ <h1>TransPlace</h1>
+ <h2>/ˈtrænspleɪs/</h2>
+
+ <p>noun</p>
+ <p class="indent">
+ A community and safe space to talk about gaming, art, and more, while
+ being you.
+ </p>
+ <div>
+ <a
+ href="https://discord.gg/TransPlace"
+ class="image-button discord"
+ onmouseover="changeContainerColor('rgba(65, 71, 140, 0.75)')"
+ onmouseout="changeContainerColor('#a789a8a2')"
+ >
+ <img
+ src="./assets/icon/discord.jpg"
+ alt="Discord Icon"
+ class="button-icon"
+ />
+ Join our Discord!
+ </a>
+ <a
+ href="https://rvlt.gg/wEXFtr9s"
+ class="image-button revolt"
+ onmouseover="changeContainerColor('rgba(135, 61, 66, 0.75)')"
+ onmouseout="changeContainerColor('#a789a8a2')"
+ >
+ <img
+ src="./assets/icon/revolt.png"
+ alt="Revolt Icon"
+ class="button-icon"
+ />
+ Join our Revolt!
+ </a>
+ </div>
+ <div>
+ <a
+ href="https://reddit.com/r/TransPlace"
+ class="image-button reddit"
+ onmouseover="changeContainerColor('rgba(135, 59, 32, 0.75)')"
+ onmouseout="changeContainerColor('#a789a8a2')"
+ >
+ <img
+ src="./assets/icon/reddit.png"
+ alt="Reddit Icon"
+ class="button-icon"
+ />
+ Join our Reddit!
+ </a>
+ </div>
+ <div>
+ <a
+ href="/auth"
+ class="image-button minectaft"
+ onmouseover="changeContainerColor('rgba(143, 114, 126, 0.75)')"
+ onmouseout="changeContainerColor('#8f727ea2')"
+ >
+ Login / Authenticate
+ </a>
+ </div>
+ </section>
+ <script src="./js/script.js"></script>
+ <script src="./js/canvas.js"></script>
+ </body>
+</html>