added endpoints for profile and feed

This commit is contained in:
Kai Ritthaler 2025-06-26 11:10:52 +02:00 committed by mrProm3theus
parent d5d6641fd8
commit 7bf50a333d
22 changed files with 952 additions and 110 deletions

View file

@ -0,0 +1,57 @@
import express from "express";
import { feed } from "../controllers/feedController";
const feedRouter = express.Router();
/**
* @swagger
* /api/feed:
* get:
* summary: Get a paginated feed of public posts
* description: Returns public posts sorted by creation date descending with cursor pagination.
* tags:
* - Feed
* parameters:
* - in: query
* name: createdAt
* schema:
* type: string
* format: date-time
* required: false
* description: Cursor for pagination, ISO timestamp of last post from previous page (only fetch posts created before this date)
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* required: false
* description: Number of posts to fetch
* responses:
* 200:
* description: List of posts with pagination cursor
* content:
* application/json:
* schema:
* type: object
* properties:
* posts:
* type: array
* items:
* type: object
* properties:
* id:
* type: string
* format: uuid
* createdAt:
* type: string
* format: date-time
* description:
* type: string
* nextCursor:
* type: string
* format: uuid
* nullable: true
* description: Cursor for the next page or null if no more posts
* 500:
* description: Server error
*/
feedRouter.get("/", feed);
export default feedRouter;

View file

@ -0,0 +1,50 @@
import express from "express";
import { authenticateToken } from "../middleware/authenticateToken";
import { followUser, unfollowUser } from "../controllers/followerController";
const followerRouter = express.Router();
/**
* @swagger
* /api/follower/follow/{username}:
* post:
* summary: follow a User
* tags: [User]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
followerRouter.post("/follow/:username", authenticateToken(), followUser);
/**
* @swagger
* /api/follower/unfollow/{username}:
* delete:
* summary: follow a User
* tags: [User]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
followerRouter.delete("/unfollow/:username", authenticateToken(), unfollowUser);
export default followerRouter;

View file

@ -2,12 +2,16 @@ import express from "express";
import {
getPost,
getUserPosts,
like,
removeLike,
uploadPost as uploadPost,
} from "../controllers/postController";
import { upload } from "../middleware/fileUpload";
import { upload } from "../middleware/uploadMultiple";
import { validateData } from "../middleware/validationMiddleware";
import { uploadPostSchema } from "../schemas/postSchemas";
import { authenticateToken } from "../middleware/authenticateToken";
import { optionalAuthenticateToken } from "../middleware/optionalAuthenticateToken";
const router = express.Router();
/**
@ -16,7 +20,7 @@ const router = express.Router();
* post:
* summary: Upload multiple images with metadata
* tags:
* - posts
* - Posts
* requestBody:
* required: true
* content:
@ -57,13 +61,19 @@ const router = express.Router();
* 200:
* description: Images uploaded successfully
*/
router.post("/upload", upload, validateData(uploadPostSchema), uploadPost);
router.post(
"/upload",
authenticateToken(),
upload,
validateData(uploadPostSchema),
uploadPost
);
/**
* @swagger
* /api/posts/getPost/{postId}:
* get:
* summary: Get Post
* tags: [posts]
* tags: [Posts]
* security:
* - bearerAuth: []
* parameters:
@ -76,23 +86,74 @@ router.post("/upload", upload, validateData(uploadPostSchema), uploadPost);
* responses:
* 200:
* description: Ok
* 401:
* description: not authenticated
* 404:
* description: not found
*/
router.get("/getPost/:postId", getPost);
router.get("/getPost/:postId", optionalAuthenticateToken, getPost);
/**
* @swagger
* /api/posts/getUserPosts/:
* /api/posts/getUserPosts/{username}:
* get:
* summary: Get Post
* tags: [posts]
* security:
* - bearerAuth: []
* summary: Get Posts from user
* tags: [Posts]
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Ok
* 401:
* description: not authenticated
* 404:
* description: not found
*/
router.get("/getuserposts/", getUserPosts);
router.get("/getuserposts/:username", optionalAuthenticateToken, getUserPosts);
/**
* @swagger
* /api/posts/like/{postId}:
* post:
* summary: follow a User
* tags: [Posts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: postId
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
router.post("/like/:postId", authenticateToken(), like);
/**
* @swagger
* /api/posts/removeLike/{postId}:
* delete:
* summary: follow a User
* tags: [Posts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: postId
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
router.delete("/removeLike/:postId", authenticateToken(), removeLike);
export default router;

View file

@ -0,0 +1,128 @@
import express from "express";
import { authenticateToken } from "../middleware/authenticateToken";
import {
getProfile,
getProfilePicture,
updateBio,
uploadProfilePicture,
} from "../controllers/profileController";
const profileRouter = express.Router();
import { upload } from "../middleware/uploadSingle";
import { updateBioSchema } from "../schemas/feedSchemas";
import { validateData } from "../middleware/validationMiddleware";
/**
* @swagger
* /api/profile/uploadProfilePicture:
* post:
* summary: Upload profile picture
* description: Uploads a profile picture for the current user
* tags:
* - Profile
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* image:
* type: string
* format: binary
* description: File to upload
* responses:
* 201:
* description: Image uploaded successfully
* 400:
* description: Invalid file or request
* 401:
* description: Unauthorized
*/
profileRouter.post(
"/uploadProfilePicture",
authenticateToken(),
upload,
uploadProfilePicture
);
/**
* @swagger
* /api/profile/getProfilePicture/{username}:
* get:
* summary: Get Profilepicture
* tags:
* - Profile
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Ok
* 401:
* description: not authenticated
*/
profileRouter.get("/getProfilePicture/:username", getProfilePicture);
/**
* @swagger
* /api/profile/updateBio:
* post:
* summary: Update user bio
* description: Updates the bio (short description) of the currently authenticated user.
* tags:
* - Profile
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* bio:
* type: string
* description: New bio text for the user
* example: "When you program open source, you're programming COMMUNISM☭"
* responses:
* 200:
* description: Bio updated successfully
* 400:
* description: Invalid request
* 401:
* description: Unauthorized
*/
profileRouter.post(
"/updateBio",
authenticateToken(),
validateData(updateBioSchema),
updateBio
);
/**
* @swagger
* /api/profile/get/{username}:
* get:
* summary: Get user data
* tags: [Profile]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
profileRouter.get("/get/:username", getProfile);
export default profileRouter;

View file

@ -9,11 +9,7 @@ import { authenticateToken } from "../middleware/authenticateToken";
import { logout, refreshToken } from "../controllers/userController";
const userRouter = express.Router();
import {
registerUser,
loginUser,
getUser,
} from "../controllers/userController";
import { registerUser, loginUser } from "../controllers/userController";
/**
* @swagger
* components:
@ -87,28 +83,7 @@ userRouter.post(
* description: Ungültige Anmeldedaten
*/
userRouter.post("/login", validateData(userLoginSchema), loginUser);
/**
* @swagger
* /api/user/getUser/{username}:
* get:
* summary: Get user data
* tags: [User]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: username
* required: true
* schema:
* type: string
* description: Der Benutzername, nach dem gesucht werden soll
* responses:
* 200:
* description: Login erfolgreich
* 401:
* description: Ungültige Anmeldedaten
*/
userRouter.get("/getUser/:username", authenticateToken(), getUser);
/**
* @swagger
* /api/user/refreshToken:
@ -162,4 +137,5 @@ userRouter.get("/refreshToken", refreshToken);
* description: not authenticated
*/
userRouter.delete("/logout", authenticateToken(), logout);
export default userRouter;