Code got from past exam at Politecnico di Torino
- Route
/: it contains the Forum main page, where inside we can find all the links and buttons to interact with the application. - Route
/login: it contains the login form where you can insert your credentials to enter as user or admin. Button to access this route always accessible. - Route
/login-totp: it contains a single text place where the admin can insert the TOTP value. This form will be accessed after an admin entered the credentials inside the/loginroute. There the admin can decide if he/she wants to access as user or administrator role, and in case it will need to insert the TOTP code. - Route
/add: it contains the form to create a post. Button to access this route is accessible only after login with credentials. - Route
/*: it's a page if users try to access a route I didn't define.
Note: We can find more information about the route structure throguh route structure:.
- POST
/api/session/login- Description: We authenticate the user who is trying to login.
- Request Body:
{ "username": "u1@p.it", "password": "pwd" }- Response body:
{ "id": 1, "name": "John Doe", "canDoTotp": false, "isTotp": false }- Response state:
200 OK(success) - Error response:
401 error(Unauthorized),500 error(internal server error)
- DELETE
/api/session/logout- Description: Used by the authenticated user to logout from his/her session
- Request Body: None
- Response state:
200 OK(success)
- POST
/api/session/login-totp- Description: We use this API to authenticate and access an admin with TOTP
- Request Body:
{ "code": "064621" }- Response body:
{ "id": 3, "name": "admin1", "canDoTotp": true, "isTotp": true }- Response state:
200 OK(success) - Error response:
401 error(Unauthorized)
- GET
/api/session/current- Description: This call is done by the client's browser in case we still have some server's cookie to "automatically" login the client.
- Response body:
{ "id": 3, "name": "admin1", "canDoTotp": true, "isTotp": true }- Response state:
200 OK(success) - Error response:
401 error(Unauthorized)
- GET
/api/posts- Description: Retrieve all posts from the database. We retrieve rows of
poststable - Request Body: None
- Response body:
[ { "author": "Michael schumacher", "idAuthor": 2, "id": 4, "commentsNumber": 7, "commentsAnonymous": 4, "maxComments": 10, "text": "Here I show the newline.\n As you can see.\n Try by yourself in the creation form.", "timestamp": "2024-2-16 17:4:50", "title": "Show newline and timestamp" } ... ] - Response state:
200 OK(success) - Error response:
500 error(General server error)
- Description: Retrieve all posts from the database. We retrieve rows of
- DELETE
/api/post/remove- Description: Delete a post and all its related comments and “interesting” entries (authenticated users or admin via TOTP). We modify the
posts,comments,commentInterestingtables. - Request Body:
{ "postId": 1 } - Response body:
{ "success": "Deleted post" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Delete a post and all its related comments and “interesting” entries (authenticated users or admin via TOTP). We modify the
- POST
/api/post/add- Description: Create a new post (authenticated users only). We append a row in
poststable. - Request Body:
{ "title": "Post", "text": "Text of Post", "maxComment": "5" } - Response body:
{ "success": "Post inserted" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Create a new post (authenticated users only). We append a row in
- GET
/api/:idPost/comments/- Description: Retrieve all comments of a specific post (handles anonymous and logged-in users). We retrieve rows of
commentstable. - Request query parameters: The post Id we want to retrieve the comments
- Response body:
[ { "author": "John Doe", "idAuthor": 1, "id": 3, "text": "She studied all night for the final exam, hoping to improve her grade significantly.", "timestamp": "2024-5-16 17:4:50" }, { "author": "Anonymous", "idAuthor": -1, "id": 10, "text": "I could not believe how fast the week went by; it felt like Monday just happened yesterday.", "timestamp": "2024-5-16 12:4:50" } ... ] - Response state:
200 OK(success) - Error response:
500 error(General server error)
- Description: Retrieve all comments of a specific post (handles anonymous and logged-in users). We retrieve rows of
- DELETE
/api/comment/remove- Description: Delete a comment and its “interesting” flags (authenticated users or admin via TOTP). We remove rows in
commentInterestingtable and we reduce the counter of commentsNumber and/or commentsAnonymous for specific post inpoststable. - Request Body:
{ "idPost": 8, "commentId": 2 } - Response body:
{ "success": "Removed comment" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Delete a comment and its “interesting” flags (authenticated users or admin via TOTP). We remove rows in
- POST
/api/comment/add- Description: Add a comment to a post (possible for both anonymous and authenticated users). We modify the
commentstable and the variables of counter comments forpoststable. - Request Body:
{ "idPost": 9, "content": "Hello world" } - Response body:
{ "success": "Inserted comment" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Add a comment to a post (possible for both anonymous and authenticated users). We modify the
- PUT
/api/comment/edit- Description: Edit a user’s comment in a post (authenticated users or admin via TOTP). We append a row in
commentstable. - Request Body:
{ "commentId": 2, "text": "Run Test edit" } - Response body:
{ "success": "Comment edited" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Edit a user’s comment in a post (authenticated users or admin via TOTP). We append a row in
- GET
/api/:idPost/comments/interesting- Description: Get list of “interesting” flags for comments in a post (authenticated users only). We get the
commentInterestingrows of the database. - Request Body: None
- Response body explain:
{ "CommentId": { "counter":"number of people interested in it", "interest":"If the user who made the request is interested" }, ... } - Response body:
{ "2": { "counter": 4, "interest": 1 }, ... } - Response state:
200 OK(success) - Error response:
500 error(General server error)
- Description: Get list of “interesting” flags for comments in a post (authenticated users only). We get the
- POST
/api/commentInteresting/add- Description: Add an “interesting” flag to a comment (authenticated users only). We push an element row in the
commentInterestingtable. - Request Body:
{ "postId": 8, "commentId": 4 } - Response body:
{ "success": "Comment-Interesting inserted" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Add an “interesting” flag to a comment (authenticated users only). We push an element row in the
- DELETE
/api/commentInteresting/remove/- Description: Remove “interesting” flag from a comment (authenticated users only and if it has the interesting flag for specific comment). We delete a row value from the
commentInterestingtable. - Request Body:
{ "postId": 8, "commentId": 2 } - Response body:
{ "success": "Deleted comment-interesting" } - Response state:
200 OK(success) - Error response:
500 error(General server error),400 error(Bad request, missing arguments req.body)
- Description: Remove “interesting” flag from a comment (authenticated users only and if it has the interesting flag for specific comment). We delete a row value from the
| Column Name | Type | Constraints | Description |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique user ID |
| name | TEXT | NOT NULL | Name of the user |
| TEXT | NOT NULL, UNIQUE | Email address | |
| password | TEXT | NOT NULL | Hashed password |
| salt | TEXT | NOT NULL | Salt used for hashing the password |
| secret | TEXT | DEFAULT '' |
TOTP secret (only admins have non-empty value) |
| admin | INTEGER | NOT NULL, DEFAULT 0 |
Admin flag (1 = admin, 0 = regular) |
Note: With this table we store the credentials of both users and admin. We use the "admin" field to distinguish them. In later tables we will see that "Anonymous" user has a "-1" id. But this row isn't created inside the "users" table for developer decision, the "-1" value is only used as reference to tell that the comment was created by an anonymous user.
| Column Name | Type | Constraints | Description |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique post ID |
| title | TEXT | NOT NULL, UNIQUE | Title of the post |
| idAuthor | INTEGER | NOT NULL, FOREIGN KEY | ID of the user who created the post (users.id) |
| text | TEXT | NOT NULL | Content |
| maxComments | INTEGER | DEFAULT 0 |
Maximum number of comments allowed for the post |
| commentsAnonymous | INTEGER | DEFAULT 0 |
Counter of only Anonymous comments |
| commentsNumber | INTEGER | DEFAULT 0 |
Counter of both Anonymous and authenticated users comments |
| timestamp | TEXT | NOT NULL | Date and time when the post was created |
Note: It contains all posts of the forum application. Every post must have an associated user who created it.
| Column Name | Type | Constraints | Description |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique comment ID |
| text | TEXT | NOT NULL | Content |
| timestamp | TEXT | NOT NULL | Date and time of the creation of the comment |
| idAuthor | INTEGER | NOT NULL, -1 if anonymous |
ID of the comment's author |
| postId | INTEGER | ON DELETE CASCADE, FOREIGN KEY -> posts(id) |
Post's ID where this comment belong |
Note: It contains all the comments inside the forum application. Every comment is associated to a user who wrote that, and a specific post.
| Column Name | Type | Constraints | Description |
|---|---|---|---|
| postId | INTEGER | PRIMARY KEY, PRIMARY KEY, FOREIGN KEY -> posts(id) |
ID of the post containing the comment |
| commentId | INTEGER | ON DELETE CASCADE, PRIMARY KEY, FOREIGN KEY -> comments(id) |
ID of the comment marked as interesting (with cascade on delete) |
| userId | INTEGER | PRIMARY KEY, PRIMARY KEY, FOREIGN KEY -> users(id) |
ID of the user who marked the comment as interesting |
Note: It contains all interesting flags. Here, instead of
commentstable, we contain a foreign key to an existing user, since anonymous cannot insert a interesting flag, so we associate a real user of theuserstable.
main.jsx
└── App in `App.jsx`
└── Layout in `App.jsx` ( all with header -> Header in `App.jsx` )
├── `/` -> Posts in `components/posts.jsx`
├── `/login` -> LoginComponent in `components/authentication.jsx`
├── `/login-totp` -> LoginTotpComponent in `components/authentication.jsx`
├── `/add` -> CreatePostLayout in `components/createPost.jsx`
└── `*` -> WrongPage in `App.jsx`
Components description:
- App, we handle the route of our application. Here we implement the user state, used when we login/logout. Usage of function
logoutSessionandgetSessionAPIto logout user and to get user's session if a cookie is still stored in the client's browser in./API-user.js. - Header, we implement basic functionalities available in every route.
Posts in `posts.jsx`
└── SetPostVisual (repeated for each post) in `posts.jsx`
├── InsertComment in `./comments.jsx`
└── CommentUsers (repeated for each comment present in each post) in `./comments.jsx`
Components description:
- Posts, its the main route where we implement cyclically all the posts we get from the API server. We handle the list of posts and support states (post dirty or error message). Usage of function
getPosts,removePostin../API.jsto get posts and remove one. - SetPostVisual, it shows the post front-end with additional functionalities related to the specification required. This will show only one post, we cycle this function for every post. We implement states for comment list and support one ( dirty comment, screen message/colour before deleting, show/not show comments). There we implement the main functionalities if we need to delete a post, or to delete/edit comments or delete/edit/add interesting flags for specific comments. Usage of function
editComment,removeComment,getComments,getInterestComments,sendCommentInterestingandremoveCommentInterestingin../API.js. - InsertComment, it implements the form text-area if we need to add a comment to a specific post. Here we configure the handleSubmit to create a comment. Usage of function
sendCommentin../API.jsto send a comment to the server. - CommentUsers, main purpose to show all comments related to a post. We use the defined functions in
SetPostVisualcomponent to operate with required functions of the comments.
LoginComponent in `authentication.jsx`
└── LoginComponent
Components description:
- LoginComponent, consists of only one component which manages the form and login of the user/admin. Usage of function
loginPhasein../API-user.jsto login.
LoginTotpComponent in `authentication.jsx`
└── LoginTotpComponent
Components description:
- LoginTotpComponent, consists of only one component which manages the code insertion of the TOTP by the admin. Usage of function
loginTOTPPhasein../API-user.jsto login.
CreatePostLayout in `authentication.jsx`
└── CreatePostLayout
Components description:
- CreatePostLayout, consists of only one component which manages the post creation. Usage of function
sendPostin../API.jsto send a post to the backend.
Note: Homepage example of the form application
Note: Form to create a post
Note: Show example where we have the comment and post created by the specific authenticated user
| Name | Admin | Password | |
|---|---|---|---|
| John Doe | u1@p.it | ❌ | pwd |
| Michael schumacher | u2@p.it | ❌ | pwd |
| Carlo Magno | u3@p.it | ❌ | pwd |
| admin1 | a1@p.it | ✅ | pwd |
| admin2 | a2@p.it | ✅ | pwd |


