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.
 
 
 
 

290 lines
10 KiB

import bcrypt from "bcrypt";
import {getClient} from "../utils/database.js";
import jwt from "jsonwebtoken";
import path, {dirname} from "path";
import fs from "fs";
import {fileURLToPath} from "url";
export async function register(req, res) {
try {
const user = {
email: req.body.email,
username: req.body.username,
password: req.body.password,
picture: req.body.picture,
}
const logger = req.body.logger;
logger.action("try to register a user with username: " + req.body.username + " and email: " + req.body.email, user);
user.password = await bcrypt.hash(req.body.password, 10);
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
let file = req.file.buffer;
if (file) {
const finalName = user.username + "." + req.file.originalname.split(".")[1];
const destinationPath = path.join(__dirname, "../uploads/profiles/" + finalName)
console.log(destinationPath)
fs.writeFileSync(destinationPath, file);
user.picture = "/api/media/profile/" + finalName;
} else {
user.picture = "/api/media/profile/default.png";
}
const client = await getClient();
const query = `INSERT INTO users (email, username, password, picture) VALUES ($1, $2, $3, $4) RETURNING id`;
const result = await client.query(query, [user.email, user.username, user.password, user.picture]);
const id = result.rows[0].id;
const playlistQuery = `INSERT INTO playlists (name, owner) VALUES ('A regarder plus tard', $1)`;
await client.query(playlistQuery, [id]);
console.log("Successfully registered");
client.end();
logger.write("successfully registered", 200);
res.status(200).send({user: user});
} catch (err) {
console.log(err);
}
}
export async function login(req, res) {
const user = {
username: req.body.username,
password: req.body.password,
}
const logger = req.body.logger;
logger.action("try to login with username '" + user.username + "'");
const client = await getClient();
let query = `SELECT id, username, email, picture, password FROM users WHERE username = $1`;
const result = await client.query(query, [user.username]);
const userInBase = result.rows[0];
if (!userInBase) {
logger.write("failed to login", 401)
res.status(401).json({error: "Invalid credentials"});
return
}
const isPasswordValid = await bcrypt.compare(req.body.password, userInBase.password);
if (!isPasswordValid) {
logger.write("failed to login", 401)
res.status(401).json({error: "Invalid credentials"});
return
}
const payload = {
id: userInBase.id,
username: userInBase.username,
}
const token = jwt.sign(payload, process.env.JWT_SECRET);
const userData = {
id: userInBase.id,
username: userInBase.username,
email: userInBase.email,
picture: userInBase.picture
}
logger.write("Successfully logged in", 200);
res.status(200).json({token: token, user: userData});
}
export async function getById(req, res) {
const id = req.params.id;
const logger = req.body.logger;
logger.action("try to retrieve user " + id);
const client = await getClient();
const query = `SELECT id, email, username, picture FROM users WHERE id = $1`;
const result = await client.query(query, [id]);
if (!result.rows[0]) {
logger.write("failed to retrieve user " + id + " because it doesn't exist", 404);
res.status(404).json({error: "Not Found"});
return
}
logger.write("successfully retrieved user " + id, 200);
return res.status(200).json({user: result.rows[0]});
}
export async function getByUsername(req, res) {
const username = req.params.username;
const client = await getClient();
const logger = req.body.logger;
logger.action("try to retrieve user " + username);
const query = `SELECT id, email, username, picture FROM users WHERE username = $1`;
const result = await client.query(query, [username]);
if (!result.rows[0]) {
logger.write("failed to retrieve user " + username + " because it doesn't exist", 404);
res.status(404).json({error: "Not Found"});
return
}
logger.write("successfully retrieved user " + username, 200);
return res.status(200).json({user: result.rows[0]});
}
export async function update(req, res) {
try {
const id = req.params.id;
let user = {
email: req.body.email,
username: req.body.username,
password: req.body.password,
picture: req.body.picture,
}
const client = await getClient();
const userQuery = `SELECT * FROM users WHERE id = $1`;
const userResult = await client.query(userQuery, [id]);
const userInBase = userResult.rows[0];
const logger = req.body.logger;
logger.action("try to update user " + id);
if (user.email !== userInBase.email) {
const emailQuery = `SELECT email FROM users WHERE email = $1`;
const emailResult = await client.query(emailQuery, [user.email]);
if (emailResult.rows[0]) {
logger.write("failed to update because email is already used", 400)
res.status(400).json({error: "Email already exists"});
}
}
if (user.username !== userInBase.username) {
const usernameQuery = `SELECT username FROM users WHERE username = $1`;
const usernameResult = await client.query(usernameQuery, [user.username]);
if (usernameResult.rows[0]) {
logger.write("failed to update because username is already used", 400)
res.status(400).json({error: "Username already exists"});
}
}
if (user.password) {
const isPasswordValid = await bcrypt.compare(req.body.password, userInBase.password);
if (!isPasswordValid) {
user.password = await bcrypt.hash(req.body.password, 10);
} else {
user.password = userInBase.password;
}
} else {
user.password = userInBase.password;
}
let __filename = fileURLToPath(import.meta.url);
let __dirname = dirname(__filename);
console.log(__dirname);
let profilePicture = userInBase.picture.split("/").pop();
fs.rename(__dirname + "../uploads/profiles/" + profilePicture, __dirname + "../uploads/profiles/" + user.username + "." + profilePicture.split(".").pop(), (err) => {
if (err) {
logger.write("failed to update profile picture", 500);
console.error("Error renaming file:", err);
throw err;
}
});
profilePicture = user.username + "." + profilePicture.split(".").pop();
const updateQuery = `UPDATE users SET email = $1, username = $2, password = $3, picture = $4 WHERE id = $5 RETURNING id, email, username, picture`;
const result = await client.query(updateQuery, [user.email, user.username, user.password, profilePicture, id]);
logger.write("successfully updated user " + id, 200);
res.status(200).send({user: result.rows[0]});
} catch (err) {
console.log(err);
res.status(500).json({error: err});
}
}
export async function deleteUser(req, res) {
const id = req.params.id;
const client = await getClient();
const logger = req.body.logger;
logger.action("try to delete user " + id);
const query = `DELETE FROM users WHERE id = $1`;
await client.query(query, [id]);
logger.write("successfully deleted user " + id);
res.status(200).json({message: 'User deleted'});
}
export async function getChannel(req, res) {
const id = req.params.id;
const client = await getClient();
const logger = req.body.logger;
logger.action("try to retrieve channel of user " + id);
const query = `SELECT * FROM channels WHERE owner = $1`;
const result = await client.query(query, [id]);
if (!result.rows[0]) {
logger.write("failed to retrieve channel of user " + id + " because it doesn't exist", 404);
res.status(404).json({error: "Channel Not Found"});
return;
}
logger.write("successfully retrieved channel of user " + id, 200);
res.status(200).json({channel: result.rows[0]});
}
export async function getHistory(req, res) {
const id = req.params.id;
const client = await getClient();
const logger = req.body.logger;
logger.action("try to retrieve history of user " + id);
const query = `SELECT
v.title, v.thumbnail, v.release_date, v.channel, c.name, u.picture, v.id
FROM history
JOIN public.videos v on history.video = v.id
JOIN public.channels c on v.channel = c.id
JOIN public.users u on c.owner = u.id
WHERE user_id = $1
LIMIT 10
`;
const result = await client.query(query, [id]);
const videos = [];
for (const video of result.rows) {
// GET VIDEO VIEW COUNT
const videoQuery = `SELECT COUNT(*) as view_count FROM history WHERE video = $1`;
const videoResult = await client.query(videoQuery, [video.id]);
const videoToAdd = {
title: video.title,
thumbnail: video.thumbnail,
release_date: video.release_date,
views: videoResult.rows[0].view_count,
id: video.id,
creator: {
id: video.channel,
name: video.name,
profilePicture: video.picture
},
user_picture: video.picture
};
videos.push(videoToAdd);
}
if (!result.rows[0]) {
logger.write("failed to retrieve history of user " + id + " because it doesn't exist", 404);
res.status(404).json({error: "History Not Found"});
return;
}
logger.write("successfully retrieved history of user " + id, 200);
res.status(200).json(videos);
}