A multi-user note-taking application built with JavaScript, CSS, Node.js, Express, EJS, and MongoDB. This application is a single full stack note-taking app with user authentication and sesions allowing for multiple users. There is also a production mode toggle inside the envirnment file that forces things like HTTPS and restricts what type of error messages are sent to the user. However, keep in mind this is designed to be ran all together on a single server with the database also being local.
- Username and password registration with login and logout
- Sessions that are stored in the database to allow users to stay logged in
- Password hashing with bcrypt
- Each user owns their notes
- Notes can be created, read, updated, and deleted
- Request logging, route validation, centralized error handling, Helmet security headers, and graceful shutdown
- Node.js and npm
- Express
- EJS and
express-session - MongoDB using Mongoose with
connect-mongo - Passport with
passport-local - bcrypt
- Helmet
- Bootstrap
- Nodemon (for local development)
- dotenv
Install the following before running the project:
- An IDE such as VS Code
- Node.js
- npm
- MongoDB and Compass is optional but useful
git clone https://github.com/ProgrammingClone/Note-Taking-App
npm install
Development dependencies such as Nodemon are installed by the same command unless npm is configured to omit them.
Create .env beside package.json. Then NODE_ENV can be denoted as development or production where development provides more details error reporting to the user and uses LOCAL_MONGODB_URI and LOCAL_SESSION_SECRET along with only using HTTP. This isoloation was done to so that testing does not interact with your productions database.
NODE_ENV=development
PORT=3001
MONGODB_URI=
LOCAL_MONGODB_URI=mongodb://127.0.0.1:27017/local_note_taking_app
SESSION_SECRET=
LOCAL_SESSION_SECRET=Generate a local session secret using the node -e "console.log(require('node:crypto').randomBytes(48).toString('hex'))" command. Then paste it into your env file under either LOCAL_SESSION_SECRET or SESSION_SECRET depending on if you are using the development or production branch.
Development mode with automatic restarting (thanks to nodemon):
npm run dev
Normal startup:
npm start
Open the following (enter the address / port you configured):
http://localhost:3001
Check server/database health:
http://localhost:3001/health
- Note title's are required with a max length of 120 characters.
- Note content maximum is 20,000 characters.
- Usernames must be unique when ceated a new account.
- Auth is in place so users cant view other users notes even if they have its id.
express-sessionmanages the session.- Passport stores the authenticated user ID inside the session.
connect-mongostores sessions in MongoDB'ssessionscollection.- The browser stores only the signed session-ID cookie.
- The session cookie only lasts 7 days.
- Sessions can survive Node/Nodemon restarts.
| Method | Path | Authentication | Purpose |
|---|---|---|---|
GET |
/ |
No | Home page |
GET |
/health |
No | JSON health check |
GET |
/auth/register |
No | Registration page (does not work when logged in) |
POST |
/auth/register |
No | Register and log in a new user |
GET |
/auth/login |
No | Login page (does not work when logged in) |
POST |
/auth/login |
No | Authenticate with Passport Local |
POST |
/auth/logout |
Yes | Log out and destroy the session |
GET |
/notes |
Yes | Display the current user's notes |
GET |
/notes/new |
Yes | Display the create-note page |
GET |
/notes/:noteId |
Yes | Display one owned note |
GET |
/notes/:noteId/edit |
Yes | Display the edit page for one owned note |
Unknown routes redirect to /.
POST /auth/register
Fields:
username: (3 to 30 character username)
password:
confirmPassword:
Expected behavior:
- On success, creates the user, logs the user in, and redirects to
/notes. - On validation or duplicate username or failure it renders the registration page with an error.
- Passwords are never stored directly. MongoDB stores a bcrypt hash.
POST /auth/login
Fields:
username:
password:
Expected behavior:
- On success, creates an authenticated Passport session and redirects to
/notes. - On failure, redirects to
/auth/loginwith a generic invalid credentials message.
POST /auth/logout
Expected behavior:
- Removes Passport authentication state.
- Destroys the Express session.
- Clears the session cookie.
- Redirects to
/.
All note API endpoints require an authenticated session.
GET /api/notes
Success response:
{
"notes": [
{
"_id": ,
"owner": ,
"title": ,
"content": ,
"createdAt": ,
"updatedAt":
}
]
}POST /api/notes
Content-Type: application/json
Request:
{
"title": ,
"content":
}Success: 201 Created
{
"note": {
"_id": ,
"owner": ,
"title": ,
"content": ,
"createdAt": ,
"updatedAt":
}
}GET /api/notes/:noteId
Success: 200 OK
{
"note": {
"_id": ,
"owner": ,
"title": ,
"content": ,
"createdAt": ,
"updatedAt":
}
}PUT /api/notes/:noteId
Content-Type: application/json
Request:
{
"title": ,
"content":
}Success: 200 OK
{
"note": {
"_id": ,
"owner": ,
"title": ,
"content": ,
"createdAt": ,
"updatedAt":
}
}DELETE /api/notes/:noteId
Success: 204 No Content
Typical error responses use:
{
"error":
}