{"id":28974848,"url":"https://github.com/plcoster/fcc_infosec_project2","last_synced_at":"2026-04-27T18:04:36.416Z","repository":{"id":299016092,"uuid":"542237806","full_name":"PLCoster/fcc_infosec_project2","owner":"PLCoster","description":"FreeCodeCamp Information Security Project 2: Anonymous Message Board","archived":false,"fork":false,"pushed_at":"2022-10-14T00:53:18.000Z","size":150,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-14T06:32:58.107Z","etag":null,"topics":["express","mocha-chai"],"latest_commit_sha":null,"homepage":"https://fcc-infosec-project2.plcoster.repl.co","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PLCoster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-27T18:41:44.000Z","updated_at":"2022-10-14T01:43:33.000Z","dependencies_parsed_at":"2025-06-14T06:33:08.140Z","dependency_job_id":"f3b61561-0a28-4c94-ba2d-ebb08326b66d","html_url":"https://github.com/PLCoster/fcc_infosec_project2","commit_stats":null,"previous_names":["plcoster/fcc_infosec_project2"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PLCoster/fcc_infosec_project2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLCoster%2Ffcc_infosec_project2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLCoster%2Ffcc_infosec_project2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLCoster%2Ffcc_infosec_project2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLCoster%2Ffcc_infosec_project2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PLCoster","download_url":"https://codeload.github.com/PLCoster/fcc_infosec_project2/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLCoster%2Ffcc_infosec_project2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261669008,"owners_count":23192362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["express","mocha-chai"],"created_at":"2025-06-24T12:07:08.921Z","updated_at":"2026-04-27T18:04:36.380Z","avatar_url":"https://github.com/PLCoster.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Free Code Camp: Information Security Project 2\n\n## Anonymous Message Board\n\nThe aim of this project was to build an Anonymous Message Board app with functionality similar to: https://anonymous-message-board.freecodecamp.rocks/\n\nThe project was built using the following technologies:\n\n- **HTML**\n- **JavaScript** with **[Node.js](https://nodejs.org/en/) / [NPM](https://www.npmjs.com/)** for package management.\n- **[Express](https://expressjs.com/)** web framework to build the web API.\n- **[mongoose](https://mongoosejs.com/)** for MongoDB object modeling, interacting with a **[MongoDB Atlas](https://www.mongodb.com/atlas/database)** database.\n- **[Helmet](https://helmetjs.github.io/)** for Express.js security with HTTP headers.\n- **[bcrypt](https://www.npmjs.com/package/bcryptjs)** for hashing and comparing Thread and Reply deletion passwords.\n- **[Bootstrap](https://getbootstrap.com/)** for styling with some custom **CSS**.\n- **[FontAwesome](https://fontawesome.com/)** for icons.\n- **[Mocha](https://mochajs.org/)** test framework with **[Chai](https://www.chaijs.com/)** assertions for testing.\n- **[nodemon](https://nodemon.io/)** for automatic restarting of server during development.\n\n### Project Requirements:\n\n- **User Story #1:** Only allow your site to be loaded in an iFrame on your own pages, using `helmet.js`.\n\n- **User Story #2:** Do not allow DNS prefetching, using `helmet.js`.\n\n- **User Story #3** Only allow your site to send the referrer for your own pages, using `helmet.js`.\n\n- **User Story #4** You can send a POST request to `/api/threads/{board}` with form data including `text` and `delete_password`. The saved database record will have at least the fields `_id`, `text`, `created_on`(date \u0026 time), `bumped_on`(date \u0026 time, starts same as `created_on`), `reported` (boolean), `delete_password`, \u0026 `replies` (array).\n\n- **User Story #5** You can send a POST request to `/api/replies/{board}` with form data including `text`, `delete_password`, \u0026 `thread_id`. This will update the `bumped_on` date to the comment's date. In the thread's `replies` array, an object will be saved with at least the properties `_id`, `text`, `created_on`, `delete_password`, \u0026 `reported`.\n\n- **User Story #6** You can send a GET request to `/api/threads/{board}`. Returned will be an array of the most recent 10 bumped threads on the board with only the most recent 3 replies for each. The `reported` and `delete_password` fields will not be sent to the client.\n\n- **User Story #7** You can send a GET request to `/api/replies/{board}?thread_id={thread_id}`. Returned will be the entire thread with all its replies, also excluding the same fields from the client as the previous test.\n\n- **User Story #8** You can send a DELETE request to `/api/threads/{board}` and pass along the `thread_id` \u0026 `delete_password` to delete the thread. Returned will be the string `incorrect password` or `success`.\n\n- **User Story #9** You can send a DELETE request to `/api/replies/{board}` and pass along the `thread_id`, `reply_id`, \u0026 `delete_password`. Returned will be the string `incorrect password` or `success`. On success, the text of the `reply_id` will be changed to `[deleted]`.\n\n- **User Story #10** You can send a PUT request to `/api/threads/{board}` and pass along the `thread_id`. Returned will be the string `reported`. The `reported` value of the `thread_id` will be changed to `true`.\n\n- **User Story #11** You can send a PUT request to `/api/replies/{board}` and pass along the `thread_id` \u0026 `reply_id`. Returned will be the string `reported`. The `reported` value of the `reply_id` will be changed to `true`.\n\n- **User Story #12** The 10 following function tests for the app API routes are complete and passing:\n  - Creating a new thread: POST request to `/api/threads/{board}`\n  - Viewing the 10 most recent threads with 3 replies each: GET request to `/api/threads/{board}`\n  - Deleting a thread with the incorrect password: DELETE request to `/api/threads/{board}` with an invalid `delete_password`\n  - Deleting a thread with the correct password: DELETE request to `/api/threads/{board}` with a valid `delete_password`\n  - Reporting a thread: PUT request to `/api/threads/{board}`\n  - Creating a new reply: POST request to `/api/replies/{board}`\n  - Viewing a single thread with all replies: GET request to `/api/replies/{board}`\n  - Deleting a reply with the incorrect password: DELETE request to `/api/replies/{board}` with an invalid `delete_password`\n  - Deleting a reply with the correct password: DELETE request to `/api/replies/{board}` with a valid `delete_password`\n  - Reporting a reply: PUT request to `/api/replies/{board}`\n\n### Project Writeup:\n\nThe second Free Code Camp: Information Security Project is a basic Anonymous Message Board App and API. Users can anonymously post Threads, and add Replies to existing Threads. Created Threads and Replies can be deleted using a password that is input by the user as they create their Thread or Reply. Passwords are hashed using `bcrypt` before being stored in a MongoDB database, for added security.\n\nUsers can:\n\n- View the 10 Most Recently Active Threads on a Board by visiting the board on the web app, or by sending a GET request to `/api/threads/\u003cBOARD\u003e` where `\u003cBOARD\u003e` is the name of the desired board to view.\n\n- View a single Thread and all its Replies by visiting a thread on the web app, or by sending a GET request to `/api/replies/\u003cBOARD\u003e?thread_id=\u003cTHREAD_ID\u003e` with the desired Board and Thread id.\n\n- Create a Thread using the web app (visiting the page corresponding to the board they wish to post on), or by sending a POST request to `/api/threads/\u003cBOARD\u003e` with a body consisting of url encoded or JSON encoded fields of `text` (Thread text) and `delete-password`.\n\n- Report a Thread using the web app, or by sending a PUT request to `/api/threads/\u003cBOARD\u003e` with a body containing a url or JSON encoded field of `thread_id` (id of the thread to be reported).\n\n- Delete a Thread using the web app, or by sending a DELETE request to `/api/threads/\u003cBOARD\u003e` with a body containing url or JSON encoded fields of `thread_id` and `delete-password`.\n\n- Add a Reply to a Thread using the web app, or by sending a POST request to `/api/replies/\u003cBOARD\u003e` with a body containing url or JSON encoded fields of `thread_id`, `text` (Reply text) and `delete_password` (password to delete the created Reply).\n\n- Report a Reply using the web app, or by sending a PUT request to `/api/replies/\u003cBOARD\u003e` with a body containing url or JSON encoded fields of `thread_id` and `reply_id`.\n\n- Delete a Reply using the web app, or by sending a DELETE request to `/api/replies/\u003cBOARD\u003e` with a body containing url or JSON encoded fields of thread_id, reply_id and delete_password (password of the Reply to be deleted).\n\nA test suite has been written for the app:\n\n- `tests/2_functional-tests.js` contains functional tests of the application routes (GET/POST/PUT/DELETE requests to `/api/threads` and `/api/replies`).\n\n### Project Files:\n\n- `server.js` - the main entry point of the application, an express web server handling the routes defined in the specification.\n\n- `/routes/api.js` - contains the major API routes for the express web app.\n\n- `controllers/` - contains the `threadcontroller.js` middleware, with methods to Create, Read, Update (report) and Delete Threads and Replies.\n\n- `models/` - contains `mongoose` database schema (`Thread` and `Reply`) and middleware for the application. A middleware has been added to the `Thread` schema to hash Thread deletion passwords automatically when a Thread is created.\n\n- `public/` - contains static files for the web app (stylesheet, logo, favicons etc), served by express using `express.static()`.\n\n- `views/` - contains the html pages for the web app:\n\n  - `index.html`, which is served by express on `GET` requests to `/`\n  - `board.html`, which is served by express on `GET` requests to `/b/\u003cBOARD_NAME\u003e`\n  - `thread.html`, which is served by express on `GET` requests to `/b/\u003cBOARD_NAME\u003e/\u003cTHREAD_ID\u003e`\n\n- `tests/` - contains the test suite for the application.\n\n### Usage:\n\nRequires Node.js / NPM in order to install required packages. After downloading the repo, install required dependencies with:\n\n`npm install`\n\nTo run the app locally, valid production and testing MongoDB database URIs are required to be entered as environmental variables (`MONGO_URI`, `TEST_MONGO_URI`), which can be done via a `.env` file (see sample.env). One possible MongoDB service is **[MongoDB Atlas](https://www.mongodb.com/atlas/database)**.\n\nA development mode (with auto server restart on file save), can be started with:\n\n`npm run dev`\n\nThe application can then be viewed at `http://localhost:3000/` in the browser.\n\nTo start the server without auto-restart on file save:\n\n`npm start`\n\nTo run the test suite:\n\n`npm test`\n\n# Anonymous Message Board\n\nThe initial boilerplate for this app can be found at https://anonymous-message-board.freecodecamp.rocks/\n\nInstructions for building the project can be found at https://www.freecodecamp.org/learn/information-security/information-security-projects/anonymous-message-board\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplcoster%2Ffcc_infosec_project2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplcoster%2Ffcc_infosec_project2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplcoster%2Ffcc_infosec_project2/lists"}