mirror of
https://github.com/stronk-dev/LivepeerEvents.git
synced 2025-07-05 18:55:09 +02:00
Cleanup backend code
This commit is contained in:
parent
6f9f9cfd9a
commit
6b79d1bd0c
17
backend/src/README
Normal file
17
backend/src/README
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
INDEX
|
||||||
|
src/
|
||||||
|
abi/ : Contains compiled smart contract data from https://github.com/livepeer/protocol
|
||||||
|
models/ : Database Schema
|
||||||
|
event.js : Definition of a smart contract event in the database
|
||||||
|
user.js : Definition of a user in the database
|
||||||
|
routes/ : Define API endpoints
|
||||||
|
index.js : Combines all defined routes
|
||||||
|
livepeer.js : Livepeer related API calls, like blockchain information and coin prices
|
||||||
|
session.js : Session related API calls, like logging in and setting the session cookie
|
||||||
|
user.js : User related API calls, TBD
|
||||||
|
config.js : All variables which should be kept off of GitHub, like API keys
|
||||||
|
index.js : Starts server.js
|
||||||
|
README : RecursionError: Maximum Recursion Depth Exceeded
|
||||||
|
server.js : Boilerplate stuff to boot EVERYTHING
|
||||||
|
ecosystem.config.js : In order to use the backend with pm2 to ensure the backend stays running all the time
|
||||||
|
package.json : External dependencies and define NPM commands
|
@ -1,4 +1,2 @@
|
|||||||
//Starting point of backend. Simply imports ESM and calls the actual server.js to be loaded.
|
|
||||||
|
|
||||||
require = require("esm")(module)
|
require = require("esm")(module)
|
||||||
module.exports = require("./server.js")
|
module.exports = require("./server.js")
|
@ -1,7 +1,5 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
|
||||||
//database schema for users
|
|
||||||
const EventSchema = new mongoose.Schema({
|
const EventSchema = new mongoose.Schema({
|
||||||
address: {
|
address: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -25,7 +23,5 @@ const EventSchema = new mongoose.Schema({
|
|||||||
},
|
},
|
||||||
}, { timestamps: true });
|
}, { timestamps: true });
|
||||||
|
|
||||||
//define variable User, which corresponds with the schema
|
|
||||||
const Event = mongoose.model('Event', EventSchema);
|
const Event = mongoose.model('Event', EventSchema);
|
||||||
//export for use outside of this file
|
|
||||||
export default Event;
|
export default Event;
|
@ -1,31 +0,0 @@
|
|||||||
import mongoose from 'mongoose';
|
|
||||||
|
|
||||||
const timelapseSchema = new mongoose.Schema({
|
|
||||||
ownerId: {
|
|
||||||
type: mongoose.ObjectId,
|
|
||||||
ref: 'User',
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
OwnerIp: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
fullFilename: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
upvotes: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
downvotes: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
}, { timestamps: true });
|
|
||||||
|
|
||||||
|
|
||||||
const timelapseObj = mongoose.model('timelapseSchema', timelapseSchema);
|
|
||||||
export default timelapseObj;
|
|
@ -1,34 +1,11 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
|
||||||
//database schema for users
|
|
||||||
const UserSchema = new mongoose.Schema({
|
const UserSchema = new mongoose.Schema({
|
||||||
ip: {
|
ip: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
upvotedTimelapses: {
|
|
||||||
type: [mongoose.ObjectId],
|
|
||||||
ref: 'timelapseSchema',
|
|
||||||
required: false,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
downvotedTimelapses: {
|
|
||||||
type: [mongoose.ObjectId],
|
|
||||||
ref: 'timelapseSchema',
|
|
||||||
required: false,
|
|
||||||
default: []
|
|
||||||
}
|
}
|
||||||
}, { timestamps: true });
|
}, { timestamps: true });
|
||||||
|
|
||||||
|
|
||||||
//takes a database field as input, returns T/F if entry already exists.
|
|
||||||
//iterates through entire user DB, any field
|
|
||||||
UserSchema.statics.doesNotExist = async function (field) {
|
|
||||||
return await this.where(field).countDocuments() === 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//define variable User, which corresponds with the schema
|
|
||||||
const User = mongoose.model('User', UserSchema);
|
const User = mongoose.model('User', UserSchema);
|
||||||
//export for use outside of this file
|
export default User;
|
||||||
export default User;
|
|
@ -1,7 +1,4 @@
|
|||||||
//In this document all used routes are defined.
|
|
||||||
//(in this case this is just user.js and session.js)
|
|
||||||
import userRouter from './user';
|
import userRouter from './user';
|
||||||
import sessionRouter from './session';
|
import sessionRouter from './session';
|
||||||
import livepeerRouter from './livepeer';
|
import livepeerRouter from './livepeer';
|
||||||
|
|
||||||
export { userRouter, sessionRouter, livepeerRouter };
|
export { userRouter, sessionRouter, livepeerRouter };
|
@ -1,7 +1,6 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import User from "../models/user";
|
import User from "../models/user";
|
||||||
import { SESS_NAME } from "../config";
|
import { SESS_NAME } from "../config";
|
||||||
|
|
||||||
const sessionRouter = express.Router();
|
const sessionRouter = express.Router();
|
||||||
|
|
||||||
sessionRouter.post("", async (req, res) => {
|
sessionRouter.post("", async (req, res) => {
|
||||||
@ -24,7 +23,6 @@ sessionRouter.post("", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//on delete request
|
|
||||||
sessionRouter.delete("", ({ session }, res) => {
|
sessionRouter.delete("", ({ session }, res) => {
|
||||||
try {
|
try {
|
||||||
const user = session.user;
|
const user = session.user;
|
||||||
@ -43,7 +41,6 @@ sessionRouter.delete("", ({ session }, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//on get request
|
|
||||||
sessionRouter.get("", ({ session: { user } }, res) => {
|
sessionRouter.get("", ({ session: { user } }, res) => {
|
||||||
res.send({ user });
|
res.send({ user });
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
//The userRouter is used to handle user related functions
|
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import User from '../models/user';
|
import User from '../models/user';
|
||||||
import timelapseObj from '../models/timelapse';
|
|
||||||
|
|
||||||
const userRouter = express.Router();
|
const userRouter = express.Router();
|
||||||
|
|
||||||
userRouter.post("/getVisitorStats", async (req, res) => {
|
userRouter.post("/getVisitorStats", async (req, res) => {
|
||||||
@ -19,88 +16,4 @@ userRouter.post("/getVisitorStats", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
userRouter.post("/getCurrentUserVotes", async (req, res) => {
|
|
||||||
console.log(req.session);
|
|
||||||
try {
|
|
||||||
const userObj = await User.findOne({ip: req.session.user.ip}, {upvotedTimelapses: 1, downvotedTimelapses: 1, _id: 0});
|
|
||||||
res.send(userObj);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(400).send(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
userRouter.post("/getScoreByTimelapeFilename", async (req, res) => {
|
|
||||||
try {
|
|
||||||
const filename = req.body.fullFilename;
|
|
||||||
const scoreObj = await timelapseObj.findOne({ fullFilename: filename }, { upvotes: 1, downvotes: 1, _id: 1 });
|
|
||||||
if (scoreObj) {
|
|
||||||
res.send(scoreObj);
|
|
||||||
} else {
|
|
||||||
res.send({upvotes: 0, downvotes: 0});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
res.status(400).send(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
userRouter.post("/setVoteOnTimelapse", async (req, res) => {
|
|
||||||
try {
|
|
||||||
var voteValue = req.body.voteValue;
|
|
||||||
const fullFilename = req.body.fullFilename;
|
|
||||||
const username = req.session.user.ip;
|
|
||||||
console.log("voteValue="+voteValue);
|
|
||||||
console.log("fullFilename="+fullFilename);
|
|
||||||
console.log("username="+username);
|
|
||||||
const currentUserObj = await User.findOne({ip: username});
|
|
||||||
console.log(currentUserObj);
|
|
||||||
if (!currentUserObj){
|
|
||||||
throw new Error("User not logged in");
|
|
||||||
}
|
|
||||||
var currentTimelapseObj = await timelapseObj.findOne({fullFilename: fullFilename});
|
|
||||||
if(!currentTimelapseObj){
|
|
||||||
currentTimelapseObj = new timelapseObj({ ownerId: currentUserObj._id, OwnerIp: currentUserObj.ip, fullFilename: fullFilename});
|
|
||||||
await currentTimelapseObj.save();
|
|
||||||
}else{
|
|
||||||
console.log(currentTimelapseObj);
|
|
||||||
if(currentUserObj.upvotedTimelapses.length && currentUserObj.upvotedTimelapses.includes(currentTimelapseObj._id)){
|
|
||||||
currentTimelapseObj.upvotes = currentTimelapseObj.upvotes - 1;
|
|
||||||
await currentTimelapseObj.save()
|
|
||||||
await User.updateOne({ip: username},{
|
|
||||||
$pullAll: {
|
|
||||||
upvotedTimelapses: [currentTimelapseObj._id],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else if(currentUserObj.downvotedTimelapses.length && currentUserObj.downvotedTimelapses.includes(currentTimelapseObj._id)){
|
|
||||||
currentTimelapseObj.downvotes = currentTimelapseObj.downvotes - 1;
|
|
||||||
await currentTimelapseObj.save()
|
|
||||||
await User.updateOne({ip: username},{
|
|
||||||
$pullAll: {
|
|
||||||
downvotedTimelapses: [currentTimelapseObj._id],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (voteValue == 1){
|
|
||||||
await User.updateOne(
|
|
||||||
{ ip: username },
|
|
||||||
{ $push: { upvotedTimelapses: currentTimelapseObj._id } }
|
|
||||||
);
|
|
||||||
currentTimelapseObj.upvotes = currentTimelapseObj.upvotes + 1;
|
|
||||||
}else if (voteValue == -1){
|
|
||||||
await User.updateOne(
|
|
||||||
{ ip: username },
|
|
||||||
{ $push: { downvotedTimelapses: currentTimelapseObj._id } }
|
|
||||||
);
|
|
||||||
currentTimelapseObj.downvotes = currentTimelapseObj.downvotes + 1;
|
|
||||||
}
|
|
||||||
await currentTimelapseObj.save();
|
|
||||||
console.log(currentTimelapseObj);
|
|
||||||
res.send(currentTimelapseObj);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(400).send(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default userRouter;
|
export default userRouter;
|
||||||
|
@ -7,12 +7,12 @@ import { userRouter, sessionRouter, livepeerRouter } from './routes/index';
|
|||||||
import {
|
import {
|
||||||
PORT, NODE_ENV, MONGO_URI, SESS_NAME, SESS_SECRET, SESS_LIFETIME , MONGO_URI_DEV, MONGO_URI_LOCAL
|
PORT, NODE_ENV, MONGO_URI, SESS_NAME, SESS_SECRET, SESS_LIFETIME , MONGO_URI_DEV, MONGO_URI_LOCAL
|
||||||
} from "./config";
|
} from "./config";
|
||||||
|
// Env variable which determines which DB to connect to
|
||||||
const { NODE_ENV: mode } = process.env;
|
const { NODE_ENV: mode } = process.env;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
//first connect with DB
|
// Make DB connection
|
||||||
if (mode == "production"){
|
if (mode == "production"){
|
||||||
await mongoose.connect(MONGO_URI, { useNewUrlParser: true, useFindAndModify: false});
|
await mongoose.connect(MONGO_URI, { useNewUrlParser: true, useFindAndModify: false});
|
||||||
}else if (mode == "development"){
|
}else if (mode == "development"){
|
||||||
@ -23,17 +23,16 @@ const { NODE_ENV: mode } = process.env;
|
|||||||
await mongoose.connect(MONGO_URI, { useNewUrlParser: true, useFindAndModify: false});
|
await mongoose.connect(MONGO_URI, { useNewUrlParser: true, useFindAndModify: false});
|
||||||
}
|
}
|
||||||
console.log('MongoDB connected on ' + mode);
|
console.log('MongoDB connected on ' + mode);
|
||||||
//web application framework
|
// Web application framework
|
||||||
const app = express();
|
const app = express();
|
||||||
//disable powered by message, which contains information on
|
|
||||||
app.disable('x-powered-by');
|
app.disable('x-powered-by');
|
||||||
//parses and validates requests to make things harder for malicious actors
|
// Parses and validates requests to make things harder for malicious actors
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(express.urlencoded({ extended: true }));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
//import session module
|
// Import session module
|
||||||
const MongoStore = connectStore(session);
|
const MongoStore = connectStore(session);
|
||||||
|
|
||||||
//define session data
|
// Declare session data
|
||||||
app.use(session({
|
app.use(session({
|
||||||
name: SESS_NAME,
|
name: SESS_NAME,
|
||||||
//TODO: change secret in config file
|
//TODO: change secret in config file
|
||||||
@ -54,35 +53,29 @@ const { NODE_ENV: mode } = process.env;
|
|||||||
maxAge: parseInt(SESS_LIFETIME)
|
maxAge: parseInt(SESS_LIFETIME)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
//define default router
|
|
||||||
|
// Define endpoint paths
|
||||||
const apiRouter = express.Router();
|
const apiRouter = express.Router();
|
||||||
//which handles any request starting with /api
|
// Catch any requests from /api/* and send it to the appropriate routes
|
||||||
app.use('/api', apiRouter);
|
app.use('/api', apiRouter);
|
||||||
//but changes to a different router for different paths
|
|
||||||
apiRouter.use('/users', userRouter);
|
apiRouter.use('/users', userRouter);
|
||||||
apiRouter.use('/session', sessionRouter);
|
apiRouter.use('/session', sessionRouter);
|
||||||
apiRouter.use('/livepeer', livepeerRouter);
|
apiRouter.use('/livepeer', livepeerRouter);
|
||||||
|
|
||||||
// error handler
|
// Error handler
|
||||||
app.use(function(err, req, res, next) {
|
app.use(function(err, req, res, next) {
|
||||||
|
|
||||||
res.locals.message = err.message;
|
res.locals.message = err.message;
|
||||||
// set locals, only providing error in development
|
// Also log it to the console
|
||||||
//res.locals.error = req.app.get('env') === 'development' ? err : {};
|
|
||||||
|
|
||||||
// add this line to include winston logging
|
|
||||||
console.log(`${err.status || 500} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
|
console.log(`${err.status || 500} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
|
||||||
|
// Render the error page
|
||||||
// render the error page
|
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.render('error');
|
res.render('error');
|
||||||
});
|
});
|
||||||
|
|
||||||
//actually start server
|
// Start listening on the defined port
|
||||||
app.listen(PORT, "0.0.0.0", function () {
|
app.listen(PORT, "0.0.0.0", function () {
|
||||||
console.log(`Listening on port ${PORT}`);
|
console.log(`Listening on port ${PORT}`);
|
||||||
});
|
});
|
||||||
//and log any errors to the console
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user