You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
5.9 KiB
283 lines
5.9 KiB
require("dotenv").config();
|
|
|
|
const app = require("express")();
|
|
const bodyParser = require("body-parser");
|
|
const bcrypt = require("bcryptjs");
|
|
const uuid = require("uuid").v4;
|
|
const axios = require("axios");
|
|
const mongoose = require("mongoose");
|
|
const cors = require("cors");
|
|
|
|
mongoose.connect(process.env.MONGO_URI, {
|
|
useNewUrlParser: true,
|
|
useUnifiedTopology: true,
|
|
useCreateIndex: true,
|
|
});
|
|
|
|
const User = require("./models/User");
|
|
const Movie = require("./models/Movie");
|
|
const Userdata = require("./models/Userdata");
|
|
|
|
const { WATCH_STATUS, RATINGS } = require("./util/consts");
|
|
|
|
const tmdb = axios.create({
|
|
baseURL: "https://api.themoviedb.org/3/",
|
|
timeout: 1000,
|
|
params: {
|
|
api_key: process.env.TMDB_KEY,
|
|
},
|
|
});
|
|
|
|
const getProot = () =>
|
|
tmdb
|
|
.get("/configuration", {
|
|
params: {
|
|
api_key: process.env.TMDB_KEY,
|
|
},
|
|
})
|
|
.then(res => res.data)
|
|
.then(data => data.images.base_url + "w500")
|
|
.catch(e => {
|
|
console.error("ERR on tmdb configuration", e.message);
|
|
return getProot();
|
|
});
|
|
|
|
(async function main() {
|
|
const posterRoot = await getProot();
|
|
|
|
app.use(bodyParser.json());
|
|
|
|
app.use(cors());
|
|
|
|
app.use((req, _, next) => {
|
|
console.log(req.method, req.url);
|
|
req["Container"] = {};
|
|
next();
|
|
});
|
|
|
|
app.post("/register", async (req, res) => {
|
|
if (!req.body.username || !req.body.email || !req.body.password) {
|
|
res.statusCode = 400;
|
|
res.send({
|
|
success: false,
|
|
msg: "Error! All fields were not sent.",
|
|
});
|
|
}
|
|
|
|
try {
|
|
await User.create({
|
|
email: req.body.email,
|
|
username: req.body.username,
|
|
password: await bcrypt.hash(
|
|
req.body.password,
|
|
process.env.SALT,
|
|
),
|
|
});
|
|
|
|
res.send({ success: true, msg: "Successfully created user." });
|
|
} catch (e) {
|
|
console.error("ERR on /register", e.message);
|
|
|
|
res.statusCode = 500;
|
|
res.send({
|
|
success: false,
|
|
msg:
|
|
"An error occured while creating the user! Username and email should be unique.",
|
|
});
|
|
}
|
|
});
|
|
|
|
app.post("/login", async (req, res) => {
|
|
if (!req.body.username || !req.body.password) {
|
|
res.statusCode = 400;
|
|
res.send({
|
|
success: false,
|
|
msg: "Error! All fields were not sent.",
|
|
});
|
|
}
|
|
|
|
const user = await User.findOne({ username: req.body.username });
|
|
const valid = await bcrypt.compare(req.body.password, user.password);
|
|
|
|
if (valid) {
|
|
const token = uuid();
|
|
user.tokens.push(token);
|
|
await user.save();
|
|
|
|
res.send({ success: true, token });
|
|
}
|
|
});
|
|
|
|
const verifyUser = async (req, res, next) => {
|
|
if (!req.headers["authentication"]) {
|
|
res.statusCode = 401;
|
|
return res.send({
|
|
success: false,
|
|
msg: "User not logged in. Authentication header was not found.",
|
|
});
|
|
}
|
|
|
|
const user = await User.findOne({
|
|
tokens: req.headers["authentication"],
|
|
});
|
|
|
|
if (user) {
|
|
req["Container"].user = user;
|
|
next();
|
|
} else {
|
|
res.statusCode = 401;
|
|
res.send({
|
|
success: false,
|
|
msg: "Authentication header was not valid.",
|
|
});
|
|
}
|
|
};
|
|
|
|
app.get("/search/:query", verifyUser, async (req, res) => {
|
|
try {
|
|
const results = (
|
|
await tmdb.get(`/search/movie`, {
|
|
params: {
|
|
query: req.params.query,
|
|
api_key: process.env.TMDB_KEY,
|
|
},
|
|
})
|
|
).data.results;
|
|
|
|
const movies = results.map(
|
|
({ poster_path, overview, release_date, id, title }) => {
|
|
const movie = {
|
|
poster: posterRoot + poster_path,
|
|
overview,
|
|
release: release_date,
|
|
movieId: id,
|
|
title,
|
|
};
|
|
return movie;
|
|
},
|
|
);
|
|
|
|
res.send({ success: true, results: movies });
|
|
} catch (e) {
|
|
console.error("ERR on /search", e.message);
|
|
|
|
res.statusCode = 500;
|
|
res.send({
|
|
success: false,
|
|
msg: "An error occured, please try again",
|
|
});
|
|
}
|
|
});
|
|
|
|
app.get("/movie/:id", verifyUser, async (req, res) => {
|
|
try {
|
|
const fromDB = await Movie.findOne({ movieId: req.params.id });
|
|
|
|
if (!fromDB) {
|
|
const result = (
|
|
await tmdb.get(`/movie/${req.params.id}`, {
|
|
params: { api_key: process.env.TMDB_KEY },
|
|
})
|
|
).data;
|
|
|
|
const movie = {
|
|
poster: posterRoot + result.poster_path,
|
|
overview: result.overview,
|
|
release: result.release_date,
|
|
movieId: req.params.id,
|
|
title: result.title,
|
|
};
|
|
|
|
res.send({ success: true, data: movie });
|
|
|
|
await Movie.create(movie);
|
|
} else {
|
|
const data = await Userdata.findOne({
|
|
userId: req["Container"].user._id,
|
|
movieId: req.params.id,
|
|
});
|
|
|
|
const movie = fromDB.toJSON();
|
|
|
|
if (data) {
|
|
movie.watchStatus = data.watchStatus;
|
|
movie.rating = data.rating;
|
|
}
|
|
|
|
movie.poster = posterRoot + movie.poster;
|
|
|
|
delete movie._id;
|
|
delete movie.__v;
|
|
|
|
res.send({ success: true, data: movie });
|
|
}
|
|
} catch (e) {
|
|
console.error("ERR on /movie", e.message);
|
|
|
|
res.statusCode = 500;
|
|
res.send({
|
|
success: false,
|
|
msg: "An error occured, please try again",
|
|
});
|
|
}
|
|
});
|
|
|
|
app.post("/movie/:id", verifyUser, async (req, res) => {
|
|
try {
|
|
const userId = req["Container"].user._id;
|
|
const movieId = req.params.id;
|
|
|
|
const { watchStatus, rating } = req.body;
|
|
|
|
if (!movieId) {
|
|
res.statusCode = 400;
|
|
return res.send({
|
|
success: false,
|
|
msg: "movieId was not sent.",
|
|
});
|
|
}
|
|
|
|
if (watchStatus && !WATCH_STATUS.includes(watchStatus)) {
|
|
res.statusCode = 400;
|
|
return res.send({
|
|
success: false,
|
|
msg:
|
|
"watchStatus must be one of " + WATCH_STATUS.join(", "),
|
|
});
|
|
}
|
|
|
|
if (rating && !RATINGS.includes(rating)) {
|
|
res.statusCode = 400;
|
|
return res.send({
|
|
success: false,
|
|
msg: "rating must be one of " + RATINGS.join(", "),
|
|
});
|
|
}
|
|
|
|
await Userdata.updateOne(
|
|
{ userId, movieId },
|
|
{
|
|
userId,
|
|
movieId,
|
|
watchStatus: req.body.watchStatus,
|
|
rating: req.body.rating,
|
|
},
|
|
{
|
|
upsert: true,
|
|
},
|
|
);
|
|
|
|
res.send({ success: true });
|
|
} catch {
|
|
res.statusCode = 500;
|
|
res.send({
|
|
success: false,
|
|
msg: "An error occured, please try again",
|
|
});
|
|
}
|
|
});
|
|
|
|
app.listen(process.env.PORT, () =>
|
|
console.log("Listening on port", process.env.PORT),
|
|
);
|
|
})();
|
|
|