Merge pull request #4 from Expand-sys/newapi

Newapi
This commit is contained in:
Expand-sys 2021-06-16 16:54:52 +10:00 committed by GitHub
commit 79568bb39f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 342 additions and 942 deletions

2
.gitignore vendored
View file

@ -22,3 +22,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
tmp

View file

@ -3,7 +3,8 @@ module.exports = {
if (req.session.user != undefined) {
return next();
}
req.flash("error_msg", "please login to view this resource");
req.session.errors = [];
req.session.errors.push({ msg: "please login to view this resource" });
res.redirect("/login");
},
};

View file

@ -1,16 +1,11 @@
const got = require("got");
const { CCashClient } = require("ccash-client-js");
const client = new CCashClient(process.env.BANKAPIURL);
async function postUser(name, password) {
console.log(process.env.BANKAPIURL);
try {
const { body } = await got.post(process.env.BANKAPIURL + "BankF/user", {
json: {
name: name,
init_pass: password,
},
responseType: "json",
});
return body;
return await client.addUser(name, password);
} catch (err) {
console.log(err);
}

292
index.js
View file

@ -6,7 +6,6 @@ const bodyParser = require("body-parser");
const expressValidator = require("express-validator");
const flash = require("connect-flash");
const session = require("express-session");
const { postUser } = require("./helpers/functions.js");
const { ensureAuthenticated } = require("./config/auth.js");
const app = express();
const MemoryStore = require("memorystore")(session);
@ -15,7 +14,10 @@ const dotenv = require("dotenv");
const fs = require("fs");
let Log = require("./schemas/log.js");
const mongoose = require("mongoose");
const { CCashClient } = require("ccash-client-js");
dotenv.config();
const { postUser } = require("./helpers/functions.js");
const client = new CCashClient(process.env.BANKAPIURL);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");
@ -78,59 +80,6 @@ app.use(
},
})
);
app.post("/setup", async function (req, res) {
console.log(req.body);
let { mongo, url, banksecure, marketplace } = req.body;
process.env.MONGO = mongo;
process.env.MARKETPLACE = false;
if (marketplace) {
process.env.MARKETPLACE = true;
}
if (!url.endsWith("/")) {
url = url + "/";
}
process.env.BANKAPIURL = url;
process.env.SECURE = false;
if (!banksecure) {
banksecure = false;
process.env.SECURE = false;
}
process.env.SETUP = true;
fs.writeFileSync(
".env",
"BANKAPIURL=" +
process.env.BANKAPIURL +
"\n" +
"SECURE=" +
process.env.SECURE +
"\n" +
"MARKETPLACE=" +
process.env.MARKETPLACE +
"\n" +
"MONGO=" +
process.env.MONGO +
"\nSETUP=true"
);
dotenv.config();
if (process.env.MARKETPLACE) {
mongoose.connect(process.env.MONGO, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: true,
});
let db = mongoose.connection;
db.once("open", function () {
console.log("Connected to MongoDB");
});
//check for DB errors
db.on("error", function (err) {
console.log(err);
});
}
res.redirect("/");
});
function papy() {
const rndInt = Math.floor(Math.random() * 1337);
@ -142,38 +91,30 @@ function papy() {
}
app.get("/", async function (req, res) {
if (!process.env.SETUP) {
res.render("setup");
} else {
let checkalive;
try {
checkalive = await got(process.env.BANKAPIURL + "BankF/help");
} catch (err) {
console.log(err);
}
let alive = false;
try {
if (checkalive.body) {
alive = true;
}
} catch (err) {
console.log(err);
}
res.render("index", {
user: req.session.user,
admin: req.session.admin,
alive: alive,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
let checkalive;
try {
checkalive = await client.help();
} catch (err) {
console.log(err);
}
let alive = false;
try {
if (checkalive) {
alive = true;
}
} catch (err) {
console.log(err);
}
res.render("index", {
user: req.session.user,
admin: req.session.admin,
alive: alive,
random: papy(),
});
});
app.get("/BankF", ensureAuthenticated, async function (req, res) {
let successes = [];
if (req.session.sucess == true) {
successes.push({ msg: "Transfer successful" });
}
let successes = req.session.successes;
let errors = req.session.errors;
req.session.errors = [];
let admin;
@ -184,37 +125,26 @@ app.get("/BankF", ensureAuthenticated, async function (req, res) {
}
let balance = 0;
try {
balance = await got(
process.env.BANKAPIURL + "BankF/" + req.session.user + "/bal"
);
balance = JSON.parse(balance.body);
balance = await client.balance(req.session.user);
} catch (err) {
console.log(err);
}
let logsent;
console.log("start " + Date.now());
try {
logsent = await got.post(
process.env.BANKAPIURL + "BankF/" + req.session.user + "/log",
{
json: {
attempt: req.session.password,
},
responseType: "json",
}
);
const { user, password } = req.session;
logsent = await client.log(user, password);
} catch (e) {
console.log(e);
}
console.log("query finished " + Date.now());
logsent = logsent.body.value;
console.log(logsent);
let logrec = logsent;
let graphlog = logsent;
if (graphlog != null) {
graphlog = graphlog.reverse();
}
let graphdata = "";
let currentbal = balance.value;
let currentbal = balance;
if (graphlog) {
for (i = graphlog.length - 1; i > -1; i--) {
if (graphlog[i].from == req.session.user) {
@ -230,19 +160,15 @@ app.get("/BankF", ensureAuthenticated, async function (req, res) {
}
if (graphdata != "") {
graphdata =
", [" + parseInt(graphlog.length) + "," + balance.value + "]" + graphdata;
", [" + parseInt(graphlog.length) + "," + balance + "]" + graphdata;
graphdata = '["transaction", "balance"]' + graphdata;
}
console.log(balance);
console.log(JSON.stringify(graphdata));
if (logsent == 1 || logsent == -1 || logsent == null) {
if (logsent == null) {
logsent = undefined;
} else {
logsent = await logsent.filter(({ from }) => from === req.session.user);
}
if (logrec === 1 || logrec === -1 || logrec === null) {
if (logrec == null) {
logrec = undefined;
} else {
logrec = await logrec.filter(({ to }) => to === req.session.user);
@ -271,81 +197,61 @@ app.get("/BankF", ensureAuthenticated, async function (req, res) {
logrec: logrec,
logsent: logsent,
user: req.session.user,
balance: balance.value,
balance: balance,
user: req.session.user,
admin: req.session.admin,
sucesses: successes,
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
app.post("/sendfunds", async function (req, res) {
let balance = 0;
try {
balance = await got(
process.env.BANKAPIURL + "BankF/" + req.session.user + "/bal"
);
balance = JSON.parse(balance.body);
} catch (err) {
console.log(err);
}
let { amount, name, senderpass } = req.body;
let a_name = req.session.user;
let successes = [];
req.session.errors = [];
let result = {};
result = await got.post(process.env.BANKAPIURL + "BankF/sendfunds", {
json: {
a_name: a_name,
b_name: name,
amount: parseInt(amount),
attempt: senderpass,
},
responseType: "json",
});
if (result.body.value == true || result.body.value) {
req.session.success = true;
req.session.successes = [];
let a_name = req.session.user;
let result;
result = await client.sendFunds(a_name, senderpass, name, amount);
console.log(result);
if (result == 1) {
req.session.successes.push({ msg: "Transfer successful" });
//post details
res.redirect("/BankF");
} else {
req.session.errors.push({ msg: "Transfer Unsuccessful" });
} else if (result == -1) {
req.session.errors.push({ msg: "Transfer Unsuccessful: User not Found" });
res.redirect("/Bankf");
} else if (result == -2) {
req.session.errors.push({ msg: "Transfer Unsuccessful: Wrong Password" });
res.redirect("/Bankf");
}
});
app.post("/register", async function (req, res) {
var { name, password, password2 } = req.body;
let checkuser = await got(process.env.BANKAPIURL + "BankF/contains/" + name);
checkuser = JSON.parse(checkuser.body).value;
req.session.errors = [];
req.session.successes = [];
if (checkuser == false) {
if (!name || !password || !password2) {
req.session.errors.push({ msg: "please fill in all fields" });
}
if (password !== password2) {
req.session.errors.push({ msg: "Passwords don't match" });
}
if (password.length < 6) {
req.session.errors.push({
msg: "Password must be at least 6 characters",
});
}
if (req.session.errors[0]) {
if (!name || !password || !password2) {
req.session.errors.push({ msg: "please fill in all fields" });
} else if (password !== password2) {
req.session.errors.push({ msg: "Passwords don't match" });
} else if (password.length < 6) {
req.session.errors.push({
msg: "Password must be at least 6 characters",
});
} else {
let checkuser = await postUser(name, password);
console.log(checkuser);
if (checkuser == -4) {
req.session.errors.push({ msg: "Error: Name too long" });
res.redirect("/register");
} else if (checkuser == -5) {
req.session.errors.push({ msg: "Error: User Already Exists" });
res.redirect("/register");
} else {
if (postUser(name, password)) {
req.session.successes.push({ msg: "User Registered Please Log In" });
res.redirect("/login");
}
req.session.successes.push({ msg: "Account Created! please Log in" });
res.redirect("/login");
}
} else {
req.session.errors.push({ msg: "User already exists" });
res.redirect("/register");
}
});
@ -353,61 +259,35 @@ app.post("/login", async function (req, res) {
if (req.session.user) {
res.redirect("/");
}
let { name, password } = req.body;
req.session.regenerate(function (err) {});
const { name, password } = req.body;
let adminTest;
let errors = [];
try {
adminTest = await got.post(process.env.BANKAPIURL + "BankF/admin/vpass", {
json: {
attempt: password,
},
responseType: "json",
});
adminTest = await client.adminVerifyPassword(password);
} catch (err) {
console.log(err);
}
req.session.password = password;
if (adminTest.body.value == undefined) {
res.redirect("/");
} else {
req.session.admin = adminTest.body.value;
console.log(adminTest);
if (adminTest != -2) {
req.session.admin = adminTest;
req.session.adminp = password;
req.session.user = name;
req.session.password = password;
res.redirect("/BankF");
} else {
let verified;
try {
verified = await got.post(process.env.BANKAPIURL + "BankF/vpass", {
json: {
name: name,
attempt: password,
},
responseType: "json",
});
} catch (err) {
console.log(err);
} finally {
console.log(verified.body.value);
if (verified.body.value == 0) {
errors.push({ msg: "Password wrong" });
res.render("login", {
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
} else if (verified.body.value == 1) {
req.session.user = name;
req.session.password = password;
res.redirect("/BankF");
} else {
errors.push({ msg: "User not found" });
res.render("login", {
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
}
verified = await client.verifyPassword(name, password);
console.log(verified);
if (verified == 1) {
req.session.user = name;
req.session.password = password;
res.redirect("/BankF");
} else {
req.session.errors = [];
req.session.errors.push({ msg: "Password wrong" });
res.redirect("/login");
}
}
//res.redirect('/login')
});
let admin = require("./routes/admin");
@ -416,13 +296,9 @@ app.use("/admin", admin);
let settings = require("./routes/settings");
app.use("/settings", settings);
let marketplace = require("./routes/marketplace");
app.use("/marketplace", marketplace);
app.get("/logout", function (req, res) {
req.session.regenerate(function (err) {
res.render("login", {
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
@ -436,7 +312,6 @@ app.get("/login", function (req, res) {
successes: successes,
errors: errors,
user: req.session.user,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
@ -452,7 +327,6 @@ app.get("/register", function (req, res) {
successes: successes,
user: req.session.user,
admin: req.session.admin,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});

149
package-lock.json generated
View file

@ -8,6 +8,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"ccash-client-js": "^1.6.3",
"connect-flash": "^0.1.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",
@ -129,6 +130,11 @@
"@types/node": "*"
}
},
"node_modules/@types/validator": {
"version": "13.1.4",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.1.4.tgz",
"integrity": "sha512-19C02B8mr53HufY7S+HO/EHBD7a/R22IwEwyqiHaR19iwL37dN3o0M8RianVInfSSqP7InVSg/o0mUATM4JWsQ=="
},
"node_modules/accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@ -167,6 +173,14 @@
"resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz",
"integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw=="
},
"node_modules/axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dependencies": {
"follow-redirects": "^1.10.0"
}
},
"node_modules/babel-walk": {
"version": "3.0.0-canary-5",
"resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
@ -265,6 +279,37 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ccash-client-js": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/ccash-client-js/-/ccash-client-js-1.6.3.tgz",
"integrity": "sha512-w6izW9L9l0G78BrRwVvP7tWFbmBekq+tepTmqK28+2lcczCaNvJnCDIqW9pQgZ6u9OjI9GX8bUteQu+7PbxiLA==",
"dependencies": {
"axios": "^0.21.1",
"class-validator": "^0.13.1",
"debug": "^4.3.1"
}
},
"node_modules/ccash-client-js/node_modules/debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/ccash-client-js/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/character-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@ -273,6 +318,16 @@
"is-regex": "^1.0.3"
}
},
"node_modules/class-validator": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz",
"integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==",
"dependencies": {
"@types/validator": "^13.1.3",
"libphonenumber-js": "^1.9.7",
"validator": "^13.5.2"
}
},
"node_modules/clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
@ -560,6 +615,25 @@
"node": ">= 0.8"
}
},
"node_modules/follow-redirects": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@ -792,6 +866,11 @@
"json-buffer": "3.0.1"
}
},
"node_modules/libphonenumber-js": {
"version": "1.9.19",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.19.tgz",
"integrity": "sha512-RjStfSE63LvXQEBw7pgQHPkY35z8feiMjC9wLvL1Hbt8PbhxpRrACwMXmLQgabb+IpVdcEx+olh8ll7UDXXkfA=="
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@ -1053,9 +1132,9 @@
}
},
"node_modules/normalize-url": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
"engines": {
"node": ">=8"
}
@ -1726,6 +1805,11 @@
"@types/node": "*"
}
},
"@types/validator": {
"version": "13.1.4",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.1.4.tgz",
"integrity": "sha512-19C02B8mr53HufY7S+HO/EHBD7a/R22IwEwyqiHaR19iwL37dN3o0M8RianVInfSSqP7InVSg/o0mUATM4JWsQ=="
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@ -1755,6 +1839,14 @@
"resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz",
"integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw=="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"babel-walk": {
"version": "3.0.0-canary-5",
"resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
@ -1832,6 +1924,31 @@
"get-intrinsic": "^1.0.2"
}
},
"ccash-client-js": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/ccash-client-js/-/ccash-client-js-1.6.3.tgz",
"integrity": "sha512-w6izW9L9l0G78BrRwVvP7tWFbmBekq+tepTmqK28+2lcczCaNvJnCDIqW9pQgZ6u9OjI9GX8bUteQu+7PbxiLA==",
"requires": {
"axios": "^0.21.1",
"class-validator": "^0.13.1",
"debug": "^4.3.1"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"character-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@ -1840,6 +1957,16 @@
"is-regex": "^1.0.3"
}
},
"class-validator": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz",
"integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==",
"requires": {
"@types/validator": "^13.1.3",
"libphonenumber-js": "^1.9.7",
"validator": "^13.5.2"
}
},
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
@ -2070,6 +2197,11 @@
"unpipe": "~1.0.0"
}
},
"follow-redirects": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@ -2251,6 +2383,11 @@
"json-buffer": "3.0.1"
}
},
"libphonenumber-js": {
"version": "1.9.19",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.19.tgz",
"integrity": "sha512-RjStfSE63LvXQEBw7pgQHPkY35z8feiMjC9wLvL1Hbt8PbhxpRrACwMXmLQgabb+IpVdcEx+olh8ll7UDXXkfA=="
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@ -2426,9 +2563,9 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"normalize-url": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ=="
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="
},
"object-assign": {
"version": "4.1.1",

View file

@ -1,5 +1,6 @@
{
"dependencies": {
"ccash-client-js": "^1.6.3",
"connect-flash": "^0.1.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",

View file

@ -12,6 +12,9 @@ const got = require("got");
const MemoryStore = require("memorystore")(session);
const fs = require("fs");
const mongoose = require("mongoose");
const { CCashClient } = require("ccash-client-js");
const client = new CCashClient(process.env.BANKAPIURL);
console.log("Sen was here");
function mongo() {
@ -36,186 +39,119 @@ function mongo() {
}
router.get("/", checkAdmin, function (req, res) {
let successes = req.session.successes;
req.session.successes = [];
let errors = req.session.errors;
req.session.errors = [];
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
errors: errors,
successes: successes,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
router.post("/user", checkAdmin, async function (req, res) {
req.session.errors = [];
req.session.successes = [];
let { name, init_pass, init_bal, password2 } = req.body;
let contains = await got(process.env.BANKAPIURL + "BankF/contains/" + name);
contains = JSON.parse(contains.body).value;
let errors = [];
let successes = [];
if (contains == true) {
errors.push({ msg: "User already exists" });
res.render("adminsettings", {
errors: errors,
if (!name || !init_pass || !init_bal || !password2) {
req.session.errors.push({ msg: "please fill in all fields" });
} else if (init_pass !== password2) {
req.session.errors.push({ msg: "Passwords don't match" });
} else if (init_pass.length < 6) {
req.session.errors.push({
msg: "Password must be at least 6 characters",
});
} else {
if (!name || !init_pass || !init_bal || !password2) {
errors.push({ msg: "please fill in all fields" });
}
//check if match
if (init_pass !== password2) {
errors.push({ msg: "Passwords don't match" });
}
//check if password is more than 6 characters
if (init_pass.length < 6) {
errors.push({ msg: "Password must be at least 6 characters" });
}
let post;
let successes = [];
try {
post = await got.post(process.env.BANKAPIURL + "BankF/admin/user", {
json: {
name: name,
attempt: req.session.adminp,
init_bal: parseInt(init_bal),
init_pass: init_pass,
},
responseType: "json",
});
} catch (err) {
console.log(err);
}
if (post.body.value == true) {
successes.push({ msg: "Account Creation Successful" });
}
}
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
successes: successes,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
let post = await client.adminAddUser(
name,
req.session.adminp,
init_pass,
parseInt(init_bal)
);
console.log(post);
if (post == -3) {
req.session.errors.push({ msg: "Invalid Request" });
} else if (post == -4) {
req.session.errors.push({ msg: "Name too long" });
} else if (post == -5) {
req.session.errors.push({ msg: "User already exists" });
} else {
req.session.successes.push({ msg: "Account Creation Successful" });
}
res.redirect("/admin");
});
router.post("/baluser", checkAdmin, async function (req, res) {
let { name } = req.body;
let balance;
let successes = [];
let errors = [];
try {
balance = await got(process.env.BANKAPIURL + "BankF/" + name + "/bal");
balance = JSON.parse(balance.body);
} catch (err) {
console.log(err);
}
if (balance.value == -1 || balance.value == undefined) {
errors.push({ msg: "User not found" });
req.session.successes = [];
req.session.errors = [];
balance = await client.balance(name);
console.log(balance.body);
balance = parseInt(balance);
if (balance < 0) {
req.session.errors.push({ msg: "User not found" });
} else {
successes.push({
msg: "User: " + name + " has " + balance.value + " monies",
req.session.successes.push({
msg: "User: " + name + " has " + balance + " monies",
});
}
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
successes: successes,
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
res.redirect("/admin");
});
router.post("/bal", checkAdmin, async function (req, res) {
let { name, amount } = req.body;
let patch;
let successes = [];
try {
patch = await got.patch(
process.env.BANKAPIURL + "BankF/admin/" + name + "/bal",
{
json: {
name: name,
attempt: req.session.adminp,
amount: parseInt(amount),
},
responseType: "json",
}
);
} catch (err) {
console.log(err);
req.session.successes = [];
req.session.errors = [];
patch = await client.setBalance(name, req.session.adminp, parseInt(amount));
console.log(patch);
if (patch == -1) {
req.session.errors.push({ msg: "User not Found" });
} else if (patch == 1) {
req.session.successes.push({ msg: "Change Funds Successful" });
}
if ((await patch.body.value) == true) {
successes.push({ msg: "Change Funds Successful" });
}
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
successes: successes,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
res.redirect("/admin");
});
router.post("/userdelete", checkAdmin, async function (req, res) {
let { name, attempt } = req.body;
console.log(name);
let contains = await got(process.env.BANKAPIURL + "BankF/contains/" + name);
contains = JSON.parse(contains.body).value;
let deleteUser;
let successes = [];
let errors = [];
if (attempt != req.session.adminp) {
errors.push({ msg: "Wrong Admin Password" });
}
console.log(contains);
if (contains == true) {
deleteUser = got.delete(process.env.BANKAPIURL + "BankF/admin/user", {
json: {
name: name,
attempt: attempt,
},
responseType: "json",
});
successes.push({ msg: "User Deletion Successful" });
req.session.errors.push({ msg: "Wrong Admin Password" });
res.redirect("/admin");
} else {
errors.push({ msg: "User Deletion Failed, User Not Found" });
let deleteUser = client.adminDeleteUser(name, attempt);
if (deleteUser == -1) {
req.session.errors.push({ msg: "User Deletion Failed, User Not Found" });
res.redirect("/admin");
} else {
req.session.successes.push({ msg: "User Deletion Successful" });
res.redirect("/admin");
}
}
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
successes: successes,
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
router.post("/destroyallsessions", checkAdmin, async function (req, res) {
let { attempt } = req.body;
let adminTest;
let errors = [];
req.session.errors = [];
try {
adminTest = await got.post(process.env.BANKAPIURL + "BankF/admin/vpass", {
json: {
attempt: attempt,
},
responseType: "json",
});
adminTest = await client.adminVerifyPassword(attempt);
} catch (err) {
console.log(err);
}
console.log(adminTest.body.value);
if (adminTest) {
req.sessionStore.clear(function (err) {
console.log(err);
res.redirect("/");
});
res.redirect("/");
} else {
errors.push({ msg: "failed admin password check" });
res.render("adminsettings", {
user: req.session.user,
admin: req.session.admin,
errors: errors,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
req.session.errors.push({ msg: "failed admin password check" });
res.redirect("/admin");
}
});
@ -240,51 +176,15 @@ router.post("/changebackend", checkAdmin, async function (req, res) {
process.env.MONGO +
"\nSETUP=true"
);
fs.mkdirSync("tmp");
fs.writeFileSync("tmp/restart.txt", "");
res.redirect("../");
});
router.post("/mongodb", checkAdmin, async function (req, res) {
let { url } = req.body;
process.env.MONGO = url;
if (process.env.MONGO.length < 3) {
process.env.MARKETPLACE = false;
console.log("false");
} else {
process.env.MARKETPLACE = true;
console.log("true");
}
fs.writeFileSync(
".env",
"BANKAPIURL=" +
process.env.BANKAPIURL +
"\n" +
"SECURE=" +
process.env.SECURE +
"\n" +
"MARKETPLACE=" +
process.env.MARKETPLACE +
"\n" +
"MONGO=" +
process.env.MONGO +
"\nSETUP=true"
);
try {
mongo();
} catch (e) {
console.log(e);
}
res.redirect("../");
});
router.post("/close", checkAdmin, async function (req, res) {
let { attempt } = req.body;
let close;
close = got.post(process.env.BANKAPIURL + "BankF/admin/close", {
json: {
attempt: attempt,
},
responseType: "json",
});
close = client.close();
res.redirect("../");
});
function papy() {

View file

@ -1,246 +0,0 @@
const express = require("express");
const router = express.Router();
const bodyParser = require("body-parser");
const session = require("express-session");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const got = require("got");
const { ensureAuthenticated } = require("../config/auth.js");
let db;
function mongo() {
if (process.env.MONGO) {
console.log(process.env.MONGO);
mongoose.connect(process.env.MONGO, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: true,
});
let db = mongoose.connection;
db.once("open", function () {
console.log("Connected to MongoDB");
});
//check for DB errors
db.on("error", function (err) {
console.log(err);
});
}
}
mongo();
let Item = require("../schemas/item");
let Listing = require("../schemas/listing");
let Inventory = require("../schemas/inventory");
router.all("*", function (req, res, next) {
console.log(req.method, req.url);
next();
});
router.get("/", function (req, res) {
let columns = [0, 1, 2, 3];
Item.find({}, function (err, items) {
if (err) {
console.log(err);
} else {
res.render("marketplace", {
columns: columns,
items: items,
user: req.session.user,
admin: req.session.admin,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
}
});
});
router.get("/marketdash", ensureAuthenticated, function (req, res) {
Inventory.findOne({ user: req.session.user }, async function (
err,
inventory
) {
if (!inventory) {
let newinv = new Inventory();
newinv.user = req.session.user;
newinv.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("created new inventory for " + req.session.user);
}
});
}
res.render("marketdash", {
user: req.session.user,
admin: req.session.admin,
inventory: inventory,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
});
router.get("/:id", function (req, res) {
Item.findById(req.params.id, function (err, item) {
Listing.find({ foreignid: req.params.id }, function (err, listings) {
console.log(listings);
res.render("item", {
listings: listings,
user: req.session.user,
admin: req.session.admin,
item: item,
marketplace: process.env.MARKETPLACE,
random: papy(),
});
});
});
});
router.get("/:id/list", ensureAuthenticated, function (req, res) {
Item.findById(req.params.id, function (err, item) {
res.render("itemlist", {
user: req.session.user,
admin: req.session.admin,
item: item,
marketplace: process.env.MARKETPLACE,
});
});
});
router.get("/:id/buy", ensureAuthenticated, function (req, res) {
Listing.find({ foreignid: req.params.id }, function (err, listings) {
console.log(listings);
res.render("itembuy", {
listings: listings,
user: req.session.user,
admin: req.session.admin,
marketplace: process.env.MARKETPLACE,
});
});
});
router.post("/:id/list", ensureAuthenticated, async function (req, res) {
let body = req.body;
let item = JSON.parse(req.body.item);
console.log(item);
let listing = new Listing();
listing.itemId = item.itemId;
listing.meta = item.meta;
listing.name = item.name;
listing.foreignid = item._id;
listing.price = body.price;
listing.amount = body.amount;
listing.seller = req.session.user;
listing.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("added " + listing.name + " from " + listing.seller);
}
});
let inventory = await Inventory.findOne({ user: req.session.user }).exec();
if (inventory == null) {
let newinv = new Inventory();
newinv.user = req.session.user;
newinv.listings = listing;
newinv.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("created new inventory for " + req.session.user);
}
});
} else {
inventory.listings.push(listing);
inventory.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("pushed new listing");
}
});
}
res.redirect("/marketplace/marketdash");
});
router.post("/:id/buy", async function (req, res) {
Listing.findOne({ _id: req.params.id }, async function (err, listing) {
let inventory = await Inventory.findOne({ user: req.session.user }).exec();
if (inventory == null) {
let newinv = new Inventory();
newinv.user = req.session.user;
newinv.purchases = listing;
newinv.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("created new inventory for " + req.session.user);
}
});
} else {
inventory.purchases.push(listing);
inventory.save(function (err) {
if (err) {
console.log(err);
return;
} else {
console.log("pushed new purchase");
}
});
}
Listing.findOneAndRemove({ _id: req.params.id }).exec();
transfer = got.post(process.env.BANKAPIURL + "BankF/sendfunds", {
json: {
a_name: req.session.user,
b_name: listing.seller,
amount: parseInt(listing.amount * listing.price),
attempt: req.session.password,
},
responseType: "json",
});
res.redirect("/marketplace/marketdash");
});
});
// this thingy here populates the database with minecraft items only use once otherwise you are gonna flood your database
/*router.get('/populatedb', async function(req,res){
let response = await got('http://minecraft-ids.grahamedgecombe.com/items.json')
let json = JSON.parse(response.body)
console.log(json[1].name)
for(i in json){
let item = new Item();
item.name = json[i].name
item.meta = json[i].meta
item.itemId = json[i].type
item.text_type = json[i].text_type
item.save(function(err){
if(err){
console.log(err);
return;
} else{
console.log("added "+ json[i].name)
}
})
}
})*/
function papy() {
const rndInt = Math.floor(Math.random() * 1337);
let random = false;
if (rndInt == 420) {
random = true;
}
return random;
}
module.exports = router;

View file

@ -8,7 +8,9 @@ const flash = require("connect-flash");
const expressValidator = require("express-validator");
const session = require("express-session");
const { postUser } = require("../helpers/functions.js");
const got = require("got");
const { CCashClient } = require("ccash-client-js");
const client = new CCashClient(process.env.BANKAPIURL);
router.get("/", ensureAuthenticated, function (req, res) {
let successes = req.session.successes;
@ -27,7 +29,10 @@ router.get("/", ensureAuthenticated, function (req, res) {
router.post("/pass", ensureAuthenticated, async function (req, res) {
let { attempt, new_pass, password2 } = req.body;
let patch;
if (!attempt || !new_pass || !password2) {
if (attempt == undefined) {
attempt = "";
}
if (!new_pass || !password2) {
req.session.errors.push({ msg: "please fill in all fields" });
}
//check if match
@ -43,32 +48,19 @@ router.post("/pass", ensureAuthenticated, async function (req, res) {
console.log(req.session.errors);
res.redirect("/settings");
} else {
try {
patch = await got.patch(process.env.BANKAPIURL + "BankF/changepass", {
json: {
name: req.session.user,
attempt: attempt,
new_pass: new_pass,
},
responseType: "json",
});
} catch (err) {
console.log(err);
}
console.log(patch.body);
if (patch.body.value == 0) {
patch = await client.changePassword(req.session.user, attempt, new_pass);
console.log(patch);
if (patch == -2) {
req.session.errors.push({
msg: "Password Wrong",
});
res.redirect("/settings");
} else {
req.session.regenerate(function (err) {
if (patch.body.value == 1) {
req.session.successes = [];
req.session.successes.push({
msg: "Change Password Successful, Please Login Again",
});
}
req.session.successes = [];
req.session.successes.push({
msg: "Change Password Successful, Please Login Again",
});
res.redirect("/login");
});
}

View file

@ -68,16 +68,6 @@ block content
br
input.btn.btn-warning(type='submit',value='Submit')
br
.card.shadow-lg
h4 Change backend Mongodb URL
form(method='POST', action='/admin/mongodb')
#form-group
p WARNING DO NOT PUT WRONG URL IN YOU WILL BREAK AND HAVE TO DELETE .ENV FILE TO FIX
label Enter URL of new MongoDB or enter a space to turn off marketplace
input.form-control(name='url', type='text')
br
input.btn.btn-warning(type='submit',value='Submit')
br
.card.shadow-lg
h4 Destroy All Sessions
form(method='POST', action='/admin/destroyallsessions')

View file

@ -49,7 +49,7 @@ block content
p Date: #{log.time}
p You sent #{log.to} $#{log.amount}
hr
#received.tab-pane(role='tabpanel', aria-labelledby='contact-tab')
#received.tab-pane(role='tabpanel', aria-labelledby='recieved-tab')
.logs
if logrec
each log in logrec
@ -57,30 +57,41 @@ block content
p Date: #{log.time}
p #{log.from} sent you $#{log.amount}
hr
#balhistory.tab-pane(role='tabpanel', aria-labelledby='contact-tab')
#balhistory.tab-pane(role='tabpanel', aria-labelledby='balhistory-tab')
#chart_div(style="width:100%; height 100%")
script(type='text/javascript' src='https://www.gstatic.com/charts/loader.js')
script(type='text/javascript').
google.charts.load('current', {'packages':['corechart']});
google.charts.load('current', {'packages':['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([!{graphdata}]);
var options = {
title: 'Balance',
hAxis: {title: 'Transaction', minValue: 0, maxValue: 15, direction: 1, textPosition: 'none'},
vAxis: {title: 'Balance', minValue: 0, maxValue: 500},
legend: 'none',
hAxis: {
title: 'Transaction',
textPosition: 'out',
},
vAxis: {
title: 'Balance',
format: 'currency',
textPosition: 'out',
},
trendlines: {
0: {type: 'exponential', color: '#333', opacity: .5},
1: {type: 'linear', color: '#111', opacity: .3}
},
width: 670,
height: 350
height: 350,
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
window.onload = resize;
window.onresize = resize;
}
br

View file

@ -1,39 +0,0 @@
extends marketlayout
block content
.container
.card
.row
.col
.card
img(src="/blockimages/items/"+item.itemId+"-"+item.meta+".png")
.col
center
.row
.col
p Item:
p ID:
.col
p #{item.name}
p #{item.itemId}-#{item.meta}
.col
.row
.col
center
h4 Buy
.col
center
h4 Sell
.row
.col-xs
.col-xs
.col
center
a.btn.btn-primary(href="/marketplace/"+item._id+"/buy") Buy
.col
center
a.btn.btn-primary(href="/marketplace/"+item._id+"/list") List

View file

@ -1,41 +0,0 @@
extends marketlayout
block content
.container
.card
.row
.col
.card
img(src="/blockimages/items/"+listings[0].itemId+"-"+listings[0].meta+".png")
.col
.row
.col-sm-2
p Item:
p ID:
.col-sm-4
p #{listings[0].name}
p #{listings[0].itemId}-#{listings[0].meta}
.col
h4 Buy
.row
.col
p Seller
.col
p Price
.col
p Amount
.col
p Link
for i in listings
.row
.col
p #{i.seller}
.col
p #{i.price}
.col
p #{i.amount}
.col
form(method='POST', action='/marketplace/'+i._id+"/buy")
input(type="hidden" value=i name="listing")
input.btn.btn-primary.btn-sm(type='submit', value='Buy')

View file

@ -1,33 +0,0 @@
extends marketlayout
block content
.container
.card
.row
.col
.card
img(src="/blockimages/items/"+item.itemId+"-"+item.meta+".png")
.col
.row
.col-sm-2
p Item:
p ID:
.col-sm-2
p #{item.name}
p #{item.itemId}-#{item.meta}
.col
h4 Sell
form(method='POST', action='/marketplace/'+item._id+'/list')
label Selling Price:
br
input.form-control-lg.shadow(type="number" min="0" name="price")
br
br
label Amount:
br
input.form-control-lg.shadow(type="number" min="0" name="amount")
br
br
input(type="hidden" value=item name="item")
input.btn.btn-primary(type='submit', value='Submit')

View file

@ -32,11 +32,6 @@ html
a.nav-link(href='/logout').text-white Log out
li.nav-item
a.nav-link(href='/BankF').text-white Bank
if marketplace
li.nav-item
a.nav-link(href='/marketplace').text-white MarketPlace
li.nav-item
a.nav-link(href='/marketplace/marketdash').text-white MarketPlace-Dashboard
li.nav-item
a.nav-link(href='/settings').text-white Settings
if admin == true

View file

@ -1,4 +0,0 @@
extends marketlayout
block content

View file

@ -1,63 +0,0 @@
extends layout
block content
.container
h2 Welcome to the marketplace dashboard #{inventory.user}
.card
ul#market.nav.nav-tabs.card-header-tabs(role='tablist')
li.nav-item
a.nav-link.active.text-black(href='#purchases', role='tab', aria-controls='purchases', aria-selected='true') Purchases
li.nav-item
a.nav-link.text-black(href='#selling', role='tab', aria-controls='selling', aria-selected='false') Selling
.tab-content.mt-3
#purchases.tab-pane.active(role='tabpanel' aria-labelledby='purchases-tab')
.row
.col
p itemID
.col
p Item Name
.col
p Price
.col
p Amount
.col
p Seller
for i in inventory.purchases
.row
.col
p #{i.itemId}-#{i.meta}
.col
p #{i.name}
.col
p #{i.price}
.col
p #{i.amount}
.col
p #{i.seller}
#selling.tab-pane(role='tabpanel', aria-labelledby='selling-tab')
.row
.col
p itemID
.col
p Item Name
.col
p Price
.col
p Amount
.col
p Seller
for i in inventory.listings
.row
.col
p #{i.itemId}-#{i.meta}
.col
p #{i.name}
.col
p #{i.price}
.col
p #{i.amount}
.col
p #{i.seller}

View file

@ -1,60 +0,0 @@
doctype html
html
head
title CCashBank
link(rel="stylesheet", href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css", integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z", crossorigin="anonymous")
link(rel="preconnect" href="https://fonts.gstatic.com")
link(href="https://fonts.googleapis.com/css2?family=Lato&family=Montserrat&display=swap" rel="stylesheet")
link(rel='stylesheet' href='/css/style.css')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
body
nav.navbar.navbar-expand-lg.navbar-dark.navbarrr.shadow-lg
.container
a.navbar-brand(href='/')
img(src="/CCashLogo3.png" style="width:75px; height:74px")
button.navbar-toggler(type='button', data-toggle='collapse', data-target='#navbars', aria-controls='navbars', aria-expanded='false', aria-label='Toggle navigation')
span.navbar-toggler-icon
#navbars.collapse.navbar-collapse
ul.navbar-nav.mr-auto
ul.navbar-nav.mr-right.text-white
if user == undefined
li.nav-item
a.nav-link(href='/login').text-white Login
li.nav-item
a.nav-link(href='/register').text-white Register
li.nav-item
a.nav-link(href='/marketplace').text-white MarketPlace
if user
li.nav-item
a.nav-link(href='/logout').text-white Log out
li.nav-item
a.nav-link(href='/BankF').text-white Bank
if marketplace == true
li.nav-item
a.nav-link(href='/marketplace').text-white MarketPlace
li.nav-item
a.nav-link(href='/marketplace/marketdash').text-white MarketPlace-Dashboard
li.nav-item
a.nav-link(href='/settings').text-white Settings
if admin == true
li.nav-item
a.nav-link(href='/admin').text-white Admin
.container
!= messages('message', locals)
if errors
each error, i in errors
div(class="alert alert-danger") #{error.msg}
if successes
each success, i in successes
div(class="alert alert-success") #{success.msg}
br
br
block content
br
hr
script(src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI="
crossorigin="anonymous")
script(src='/js/main.js')
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js", integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV", crossorigin="anonymous")

View file

@ -1,12 +0,0 @@
extends marketlayout
block content
.container
.row
each item in items
.col.col-xs-12
a(href="/marketplace/"+item._id)
.card(style="height: 130px;width:140px;margin:10px")
p #{item.name}
img(src="/blockimages/items/"+item.itemId+"-"+item.meta+".png")
br