Skip to content

Commit

Permalink
Merge pull request #9 from redo-quest/main
Browse files Browse the repository at this point in the history
merge
  • Loading branch information
kavaliersdelikt authored Jul 13, 2024
2 parents 9f0197b + 7a1516c commit a145eb8
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 255 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 v182
Copyright (c) 2024 redo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
16 changes: 6 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
<p align="center"><a href="https://github.com/v182/nero"><img src="https://media.discordapp.net/attachments/984837636457918465/1000014634012647464/giphy.gif" alt="Gray shape shifter" height="120"/></a></p>
<h1 align="center">Nero</h1>
<p align="center">Modern & up to date Pterodactyl Client Dashboard</p>





<p align="center"><a href="https://github.com/v182/nero"></a><a href="#nastyox"><img src="http://randojs.com/images/dropShadow.png" width="75%"/></a></p><br/>

<br/><br/><br/>

## :star: Features
Expand All @@ -34,9 +27,12 @@
## :zap: Documentation
[Click here](https://nero-docs.pages.dev/)

## Demo
[Click here](https://nero-demo.pages.dev)

## Preview
<img width="2031" alt="Preview1" src="https://github.com/v182/Nero/assets/142740981/2155152d-6d39-4c46-8154-a786fb80a6e8">
<img width="2031" alt="Preview2" src="https://github.com/v182/Nero/assets/142740981/cba3cd89-63e6-4915-b65b-16ee117ebb0d">

## Support
Open a Issue or join our [Discord](https://discord.gg/Ku7chqmbCS)

## Note
Be aware that Nero is a reworked & updated version of the Client known as [NorthClient](https://github.com/northdevelopment/northclient)
Binary file modified db.sqlite
Binary file not shown.
230 changes: 136 additions & 94 deletions routes/auth/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,146 @@ const settings = require('../../handlers/readSettings').settings();
const mailer = require("../../handlers/mailer").mailer();
const makeid = require("../../handlers/makeid");
const fetch = require("node-fetch");
const Swal = require('sweetalert2');

function sendAlert(res, message) {
res.send(`
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
<body>
<script>
Swal.fire({
icon: 'error',
title: 'Oops...',
text: '${message}',
}).then(() => {
window.history.back();
});
</script>
</body>
</html>
`);
}


module.exports.load = async function(app, ejs, db) {
app.get("/auth/login", async (req, res) => {
if (!req.query.email || !req.query.password) return res.send("<br>Missing information.<br>")
const user = await db.get(`user-${req.query.email}`);
if (!user) return res.send({error: "Invalid Email or Password."});
if (user.password !== req.query.password) return res.send({error: "Invalid Email or Password."});
app.get("/auth/login", async (req, res) => {
if (!req.query.email || !req.query.password) {
return res.json({ error: "Missing information." });
}
const user = await db.get(`user-${req.query.email}`);
if (!user) {
return res.json({ error: "Invalid Email or Password." });
}
if (user.password !== req.query.password) {
return res.json({ error: "Invalid Email or Password." });
}

let cacheaccount = await fetch(
`${settings.pterodactyl.domain}/api/application/users/${await db.get(`users-${req.query.email}`)}?include=servers`,
{
method: "get",
headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${settings.pterodactyl.key}` }
}
);
if (await cacheaccount.statusText == "Not Found") return res.send("An error has occured while attempting to get your user information.");
cacheaccount = JSON.parse(await cacheaccount.text());
let cacheaccount = await fetch(
`${settings.pterodactyl.domain}/api/application/users/${await db.get(`users-${req.query.email}`)}?include=servers`,
{
method: "get",
headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${settings.pterodactyl.key}` }
}
);
if (await cacheaccount.statusText == "Not Found") {
return res.json({ error: "An error has occurred while attempting to get your user information." });
}
cacheaccount = JSON.parse(await cacheaccount.text());

req.session.pterodactyl = cacheaccount.attributes;
req.session.userinfo = user;
return res.redirect("/dashboard")
});
req.session.pterodactyl = cacheaccount.attributes;
req.session.userinfo = user;
return res.json({ success: true });
});

app.get("/auth/register", async (req, res) => {
if (!req.query.email || !req.query.username || !req.query.password) return res.send("<br> Missing information </br>")
if (await db.get(`user-${req.query.email}`)) return res.send("Already registered.");
const userinfo = {
username: req.query.username,
id: req.query.email,
password: req.query.password,
discriminator: null
}
const accountjson = await fetch(
`${settings.pterodactyl.domain}/api/application/users`, {
method: "post",
headers: {
'Content-Type': 'application/json',
"Authorization": `Bearer ${settings.pterodactyl.key}`
},
body: JSON.stringify({
username: req.query.username,
email: req.query.email,
first_name: req.query.username,
last_name: "(credentials)",
password: req.query.password
})
}
);
if (accountjson.status == 201) {
const accountinfo = JSON.parse(await accountjson.text());
await db.set(`users-${req.query.email}`, accountinfo.attributes.id);
} else {
let accountlistjson = await fetch(
`${settings.pterodactyl.domain}/api/application/users?include=servers&filter[email]=${encodeURIComponent(req.query.email)}`, {
method: "get",
headers: {
'Content-Type': 'application/json',
"Authorization": `Bearer ${settings.pterodactyl.key}`
}
}
);
const accountlist = await accountlistjson.json();
const user = accountlist.data.filter(acc => acc.attributes.email == req.query.email);
if (user.length == 1) {
let userid = user[0].attributes.id;
await db.set(`users-${userinfo.id}`, userid);
} else {
return res.send("An error has occured when attempting to create your account.");
};
}
let cacheaccount = await fetch(
`${settings.pterodactyl.domain}/api/application/users/${await db.get(`users-${req.query.email}`)}?include=servers`,
{
method: "get",
headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${settings.pterodactyl.key}` }
}
);
if (await cacheaccount.statusText == "Not Found") return res.send("An error has occured while attempting to get your user information.");
let cacheaccountinfo = JSON.parse(await cacheaccount.text());
await db.set(`user-${req.query.email}`, userinfo);
await db.set(`username-${userinfo.id}`, req.query.username);
app.get("/auth/register", async (req, res) => {
if (!req.query.email || !req.query.username || !req.query.password) {
return res.json({ error: "Missing information." });
}
if (await db.get(`user-${req.query.email}`)) {
return res.json({ error: "Already registered." });
}

const userinfo = {
username: req.query.username,
id: req.query.email,
password: req.query.password,
discriminator: null
};

let userdb = await db.get("userlist");
userdb = userdb ? userdb : [];
if (!userdb.includes(`${userinfo.id}`)) {
userdb.push(`${userinfo.id}`);
await db.set("userlist", userdb);
const accountjson = await fetch(
`${settings.pterodactyl.domain}/api/application/users`, {
method: "post",
headers: {
'Content-Type': 'application/json',
"Authorization": `Bearer ${settings.pterodactyl.key}`
},
body: JSON.stringify({
username: req.query.username,
email: req.query.email,
first_name: req.query.username,
last_name: "(credentials)",
password: req.query.password
})
}
);

if (accountjson.status == 201) {
const accountinfo = JSON.parse(await accountjson.text());
await db.set(`users-${req.query.email}`, accountinfo.attributes.id);
} else {
let accountlistjson = await fetch(
`${settings.pterodactyl.domain}/api/application/users?include=servers&filter[email]=${encodeURIComponent(req.query.email)}`, {
method: "get",
headers: {
'Content-Type': 'application/json',
"Authorization": `Bearer ${settings.pterodactyl.key}`
}
}
if (settings.smtp.enabled == true) {
mailer.sendMail({
from: settings.smtp.mailfrom,
to: userinfo.id,
subject: `Signup`,
html: `Here are your login details for ${settings.name} Panel:\n Username: ${req.query.username}\n Email: ${userinfo.id}\n Password: ${userinfo.password}`
});
}
req.session.pterodactyl = cacheaccountinfo.attributes;
req.session.userinfo = userinfo;
return res.redirect("/dashboard");
});
}
);
const accountlist = await accountlistjson.json();
const user = accountlist.data.filter(acc => acc.attributes.email == req.query.email);
if (user.length == 1) {
let userid = user[0].attributes.id;
await db.set(`users-${userinfo.id}`, userid);
} else {
return res.json({ error: "An error has occurred when attempting to create your account." });
}
}

let cacheaccount = await fetch(
`${settings.pterodactyl.domain}/api/application/users/${await db.get(`users-${req.query.email}`)}?include=servers`,
{
method: "get",
headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${settings.pterodactyl.key}` }
}
);
if (await cacheaccount.statusText == "Not Found") {
return res.json({ error: "An error has occurred while attempting to get your user information." });
}

let cacheaccountinfo = JSON.parse(await cacheaccount.text());
await db.set(`user-${req.query.email}`, userinfo);
await db.set(`username-${userinfo.id}`, req.query.username);

let userdb = await db.get("userlist");
userdb = userdb ? userdb : [];
if (!userdb.includes(`${userinfo.id}`)) {
userdb.push(`${userinfo.id}`);
await db.set("userlist", userdb);
}
if (settings.smtp.enabled == true) {
mailer.sendMail({
from: settings.smtp.mailfrom,
to: userinfo.id,
subject: `Signup`,
html: `Here are your login details for ${settings.name} Panel:\n Username: ${req.query.username}\n Email: ${userinfo.id}\n Password: ${userinfo.password}`
});
}
req.session.pterodactyl = cacheaccountinfo.attributes;
req.session.userinfo = userinfo;
return res.redirect("/dashboard");
});
}
Binary file modified sessions.db
Binary file not shown.
2 changes: 1 addition & 1 deletion settings.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Nero
defaulttheme: default
version: 1.0
version: 1.5.1
website:
port: 3000
secret: makethishard
Expand Down
2 changes: 1 addition & 1 deletion themes/default/admin.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@
<div class="card-header">
<div class="card-title">Nero Client Dashboard
<center> <a
href="https://github.com/v182/Nero"
href="https://github.com/redo-quest/Nero"
target="_blank"><i class="fab fa-github"
href="https://github.com/v182/Nero"></i>GITHUB</a>
</div>
Expand Down
5 changes: 3 additions & 2 deletions themes/default/buy.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
<% } %>
<meta content='width=device-width, initial-scale=1.0, shrink-to-fit=no' name='viewport' />
<link rel="icon"
href="<%= settings.website.logo %>" />
href="https://images-ext-1.discordapp.net/external/sMKkyuJo8Wn_AK_Foyl0aGrWwhe9fbqtPgkThvHxdxs/%3Fsize%3D1024/https/cdn.discordapp.com/icons/933803406513012807/bb763a3db98f9f0ae8d6029e8355dd06.png"
type="image/png">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="/assets/thmeneed/vendor/nucleo/css/nucleo.css" type="text/css">
<link rel="stylesheet" href="/assets/thmeneed/vendor/@fortawesome/fontawesome-free/css/all.min.css"
Expand Down Expand Up @@ -262,7 +263,7 @@
<center>
<div class="row mx-auto">
<select style="border-radius: 15px; padding: 8px;" class="form-control mx-auto" style="width:45% !important;" name="month"><option value="1">1st</option><option value="2">2nd</option><option value="3">3rd</option><option value="4">4th</option><option value="5">5th</option><option value="6">6th</option><option value="7">7th</option><option value="8">8th</option><option value="9">9th</option><option value="10">10th</option><option value="11">11th</option><option value="12">12th</option></select><br><br>
<br/><select style="border-radius: 15px; padding: 8px;" class="form-control mx-auto" style="width:45% !important;" name="year"><option value="2022">2022</option><option value="2023">2023</option><option value="2024">2024</option><option value="2025">2025</option><option value="2026">2026</option><option value="2027">2027</option><option value="2028">2028</option><option value="2029">2029</option><option value="2030">2030</option><option value="2031">2031</option><option value="2032">2032</option><option value="2033">2033</option></select>
<br/><select style="border-radius: 15px; padding: 8px;" class="form-control mx-auto" style="width:45% !important;" name="year"><option value="2024">2024</option><option value="2025">2025</option><option value="2026">2026</option><option value="2027">2027</option><option value="2028">2028</option><option value="2029">2029</option><option value="2030">2030</option><option value="2031">2031</option><option value="2032">2032</option><option value="2033">2033</option></select>
</div>
</center>
<br>
Expand Down
22 changes: 17 additions & 5 deletions themes/default/dashboard.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@
<!-- Icons. Uncomment required icon fonts -->
<link rel="stylesheet" href="../assets/vendor/fonts/boxicons.css" />


<!-- Add Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<!-- Add jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<!-- Add Bootstrap JS -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

<!-- Core CSS -->
<link rel="stylesheet" href="../assets/vendor/css/core.css" class="template-customizer-core-css" />
<link rel="stylesheet" href="../assets/vendor/css/theme-default.css" class="template-customizer-theme-css" />
Expand Down Expand Up @@ -550,11 +560,11 @@
<br />
<li class="d-flex">
<div class="avatar flex-shrink-0 me-3">
<span class="avatar-initial rounded bg-label-primary"><i class="bx bxl-discord"></i></span>
<span class="avatar-initial rounded bg-label-primary"><i class="bx bx-home-circle"></i></span>
</div>
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
<div class="me-2">
<small class="text-muted d-block mb-1">Dashboard URL:</small>
<small class="text-muted d-block mb-1">Dashboard:</small>
<a href="<%= settings.pterodactyl.domain %>" class="btn btn-primary">Go to Dashboard</a>
</div>
</div>
Expand All @@ -571,7 +581,7 @@
</div>
<div>
<a style="cursor:pointer;" data-toggle="modal" data-target="#modal-notification">
<span class="btn btn-primary">Regenrate Password</span>
<span class="btn btn-primary">Reset</span>
</a>
</div>
</div>
Expand Down Expand Up @@ -626,7 +636,7 @@
</div>
</div>
</div>
</li>
</li>
</li>
</div>
</div>
Expand Down Expand Up @@ -710,7 +720,9 @@
<script>
document.write(new Date().getFullYear());
</script>

Powered by
<a href="https://github.com/redo-quest/nero" target="_blank"
class="footer-link fw-bolder">NeroClient</a>
</div>
<div>
<a href="/404" class="footer-link me-4" target="_blank">License</a>
Expand Down
Loading

0 comments on commit a145eb8

Please sign in to comment.