mirror of
https://github.com/bubblecup-12/VogelSocialMedia.git
synced 2025-07-08 03:28:50 +00:00
installed minIO and added Endpoints for creating posts and retrieving a post with the ID
This commit is contained in:
parent
38e796ca22
commit
ece95c7130
12 changed files with 962 additions and 71 deletions
143
code/backend/src/controllers/postController.ts
Normal file
143
code/backend/src/controllers/postController.ts
Normal file
|
@ -0,0 +1,143 @@
|
|||
import express, { Request, Response } from "express";
|
||||
import dotenv from "dotenv";
|
||||
import { StatusCodes } from "http-status-codes";
|
||||
import { JwtPayload } from "jsonwebtoken";
|
||||
import { PrismaClient, Post } from "@prisma/client";
|
||||
import { minioClient } from "../server";
|
||||
import { object } from "zod";
|
||||
import { uploadPostSchema } from "../schemas/postSchemas";
|
||||
dotenv.config();
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export const uploadPost = async (req: Request, res: Response) => {
|
||||
const files = req.files as Express.Multer.File[]; // Mehrere Dateien // Cast req.file to Express.Multer.File there is no need to check if file is undefined since it is already checked in the middleware
|
||||
const user: JwtPayload = req.user!; // Get the user from the request
|
||||
const { description, status, tags } = uploadPostSchema.parse(req.body);
|
||||
const BUCKET = "images"; // Name of the bucket where the images are stored
|
||||
console.log(tags);
|
||||
try {
|
||||
const uploads = await Promise.all(
|
||||
files.map(async (file) => {
|
||||
const objectName = `${user.sub}/${Date.now()}-${file.originalname}`;
|
||||
await minioClient.putObject(BUCKET, objectName, file.buffer);
|
||||
const url = await minioClient.presignedGetObject(
|
||||
BUCKET,
|
||||
objectName,
|
||||
60 * 5 // 5 Minuten Gültigkeit
|
||||
);
|
||||
|
||||
return {
|
||||
originalName: file.originalname,
|
||||
objectName: objectName,
|
||||
size: file.size,
|
||||
mimetype: file.mimetype,
|
||||
url: url,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const post: Post | null = await prisma.post.create({
|
||||
data: {
|
||||
userId: user.sub!,
|
||||
description: description,
|
||||
status: status,
|
||||
media: {
|
||||
create: uploads.map((upload) => ({
|
||||
originalFilename: upload.originalName,
|
||||
objectName: upload.objectName,
|
||||
size: upload.size,
|
||||
mimeType: upload.mimetype,
|
||||
bucket: BUCKET,
|
||||
uploader: { connect: { id: user.sub! } },
|
||||
})),
|
||||
},
|
||||
postTags: {
|
||||
create: tags.map((tag: string) => ({
|
||||
tag: {
|
||||
connectOrCreate: { where: { name: tag }, create: { name: tag } },
|
||||
},
|
||||
})),
|
||||
},
|
||||
},
|
||||
}); // create a new post in the database
|
||||
res.status(StatusCodes.CREATED).json({
|
||||
message: "Upload successful",
|
||||
post: post,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res
|
||||
.status(StatusCodes.INTERNAL_SERVER_ERROR)
|
||||
.json({ error: "Upload failed" });
|
||||
}
|
||||
};
|
||||
|
||||
// get post from postId
|
||||
export const getPost = async (req: Request, res: Response) => {
|
||||
try {
|
||||
// get the postId from the request
|
||||
const postId: string = req.query.postId as string;
|
||||
const postObject = await prisma.post.findUnique({
|
||||
// find the post by id
|
||||
where: {
|
||||
id: postId,
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
media: true,
|
||||
},
|
||||
});
|
||||
if (!postObject) {
|
||||
res.status(StatusCodes.NOT_FOUND).json({
|
||||
error: "Post not found",
|
||||
details: [
|
||||
{
|
||||
message: `The Post does not exist`,
|
||||
},
|
||||
],
|
||||
});
|
||||
return;
|
||||
}
|
||||
const post = await Promise.all(
|
||||
// generate the presigned url for each image
|
||||
postObject?.media.map(async (image) => {
|
||||
try {
|
||||
await minioClient.statObject(image.bucket, image.objectName);
|
||||
|
||||
return {
|
||||
originalName: image.originalFilename,
|
||||
mimetype: image.mimeType,
|
||||
url: await minioClient.presignedGetObject(
|
||||
image.bucket,
|
||||
image.objectName,
|
||||
60 * 5
|
||||
),
|
||||
};
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}) ?? []
|
||||
);
|
||||
res.status(StatusCodes.OK).json({
|
||||
message: "Post found",
|
||||
post: post,
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err.code === "NotFound") {
|
||||
// Handle the case where the object does not exist
|
||||
res.status(StatusCodes.NOT_FOUND).json({
|
||||
error: "Image not found",
|
||||
details: [
|
||||
{
|
||||
message: `The image does not exist in the bucket `,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
console.error(err);
|
||||
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
||||
error: "Failed to retrieve post",
|
||||
details: [{ message: "Server error" }],
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import express, { Request, Response } from "express";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { UserLoginDto, userLoginSchema } from "../schemas/userSchemas";
|
||||
import { PrismaClient, User } from "@prisma/client";
|
||||
import { UserLoginDto, UserRegistrationDto } from "../schemas/userSchemas";
|
||||
import jwt from "jsonwebtoken";
|
||||
import dotenv from "dotenv";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
@ -14,19 +14,18 @@ dotenv.config();
|
|||
const JWT_SECRET: string = process.env.TOKEN_SECRET!; // this secret is used to sign the JWT token
|
||||
|
||||
// Generate a JWT token with the username as payload and a secret from the environment variables which expires in 1800 seconds (30 minutes)
|
||||
function generateAccessToken(username: string, userId: string) {
|
||||
return jwt.sign(
|
||||
{ username: username, role: "user", sub: userId },
|
||||
JWT_SECRET,
|
||||
{ expiresIn: "1800s", issuer: "VogelApi" }
|
||||
); //TODO: change role to user role
|
||||
function generateAccessToken(username: string, userId: string, role: string) {
|
||||
return jwt.sign({ username: username, role: role, sub: userId }, JWT_SECRET, {
|
||||
expiresIn: "1800s",
|
||||
issuer: "VogelApi",
|
||||
});
|
||||
}
|
||||
|
||||
// Endpoint to register a new user
|
||||
export const registerUser = async (req: Request, res: Response) => {
|
||||
const { username, password, email } = await req.body; //gets the data from the request body
|
||||
const { username, password, email }: UserRegistrationDto = await req.body; //gets the data from the request body
|
||||
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
const existingUser: User | null = await prisma.user.findUnique({
|
||||
// check if the user already exists
|
||||
where: {
|
||||
username: username,
|
||||
|
@ -40,6 +39,21 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
const existingEmailUser: User | null = await prisma.user.findUnique({
|
||||
// check if the email is already in use
|
||||
where: {
|
||||
email: email,
|
||||
},
|
||||
});
|
||||
if (existingEmailUser) {
|
||||
// if the email is already in use, return an error message
|
||||
res.status(StatusCodes.BAD_REQUEST).json({
|
||||
error: "Invalid data",
|
||||
details: [{ message: `User with "${email}" already exists` }],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const hashedPassword = await bcrypt.hash(password, 10); // hash the password with bcrypt
|
||||
if (!hashedPassword) {
|
||||
// check if the password was hashed successfully
|
||||
|
@ -55,7 +69,7 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||
email: email,
|
||||
password: hashedPassword,
|
||||
};
|
||||
const user = await prisma.user.create({ data: userData }); // create a new user in the database
|
||||
const user: User | null = await prisma.user.create({ data: userData }); // create a new user in the database
|
||||
if (!user) {
|
||||
// check if the user was created successfully
|
||||
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
|
||||
|
@ -64,7 +78,7 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload
|
||||
const token: string = generateAccessToken(user.username, user.id, user.role); // generate a JWT token with the username and userId as payload
|
||||
res.set("Authorization", `Bearer ${token}`); // set the token in the response header
|
||||
res.status(StatusCodes.CREATED).json({
|
||||
message: "user created",
|
||||
|
@ -74,9 +88,9 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||
|
||||
// Endpoint to login a user (unfinished)
|
||||
export const loginUser = async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body; // get the data from the request body
|
||||
const { username, password }: UserLoginDto = req.body; // get the data from the request body
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
const user: User | null = await prisma.user.findUnique({
|
||||
// check if the user exists
|
||||
where: {
|
||||
username: username,
|
||||
|
@ -99,7 +113,7 @@ export const loginUser = async (req: Request, res: Response) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload
|
||||
const token: string = generateAccessToken(user.username, user.id, user.role); // generate a JWT token with the username and userId as payload
|
||||
res.set("Authorization", `Bearer ${token}`); // set the token in the response header
|
||||
res.status(StatusCodes.OK).json({ message: "User logged in successfully" });
|
||||
};
|
||||
|
@ -114,7 +128,7 @@ export const getUser = async (req: Request, res: Response) => {
|
|||
});
|
||||
return;
|
||||
}
|
||||
const user = await prisma.user.findUnique({
|
||||
const user: User | null = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: username,
|
||||
},
|
||||
|
@ -128,6 +142,11 @@ export const getUser = async (req: Request, res: Response) => {
|
|||
}
|
||||
res.json({
|
||||
message: "User found",
|
||||
data: { username: user.username, email: user.email },
|
||||
data: {
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
userId: user.id,
|
||||
userInfo: user.bio,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue