Skip to content

ayushkaneriya05/notes-application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ Notes Application

Node.js Express MongoDB Mongoose React Vite JWT Deploy with Vercel

A full-stack multi-tenant Notes application (backend + frontend) built with strict tenant isolation using a shared-schema approach.
This repository demonstrates multi-tenancy, authentication & authorization, tenant-scoped routing, and a complete frontend workflow.


πŸ“‘ Table of Contents


πŸ”Ž Overview

This application implements a multi-tenant notes system where multiple organizations can sign up and manage their own notes.

  • Strict isolation ensures that users from one tenant can never access another tenant’s data.
  • Includes backend (Node.js/Express/MongoDB) and frontend (React/Vite).
  • Comes with seeded tenants (Acme and Globex) for local testing.

πŸ— Multi-Tenancy Approach

Approach: Shared schema with tenant identifier (tenant ObjectId).

Why this approach?

  • Simple, efficient, and works well with MongoDB + Mongoose.
  • Matches existing code structure: models already include a tenant field.
  • Seed script supports multiple tenants (Acme, Globex) out of the box.

Isolation Enforcement

  1. Schema-level
    • All tenant-scoped models include tenant: ObjectId (ref: Tenant) as a required field.
  2. Authentication Middleware
    • Populates req.user with tenant info from JWT.
  3. Route-level Filtering
    • All queries filter by tenant: req.user.tenant._id.
  4. Seed Validation
    • Use provided tenants (Acme, Globex) to validate isolation.

πŸ“‚ Data Models

Tenant (notes-backend/models/Tenant.js)

  • name: String (required)
  • slug: String (required, unique)
  • plan: Enum (FREE, PRO), default: FREE

User (notes-backend/models/User.js)

  • name: String
  • email: String (required, unique)
  • password: String (hashed, required)
  • role: Enum (ADMIN, MEMBER), default: MEMBER
  • tenant: ObjectId (ref: Tenant, required)

Note (notes-backend/models/Note.js)

  • title: String
  • content: String
  • tenant: ObjectId (ref: Tenant, required)
  • createdBy: ObjectId (ref: User, required)

πŸ” Authentication & Authorization

  • Login: POST /auth/login β†’ returns JWT + user + tenant info.
  • JWT Middleware: verifies token, attaches req.user with tenant.
  • Role Guard: requireRole('ADMIN') β†’ ensures admin-only access.
  • Change Password: POST /auth/change-password.

🚏 Backend Routes

Route Method Description Auth Required Notes
/auth/login POST Authenticate user ❌ Returns token + tenant info
/auth/change-password POST Change password βœ… Verifies old password
/notes GET List notes βœ… Tenant-scoped
/notes POST Create note βœ… Enforces tenant + plan limit
/notes/:id GET View note βœ… Tenant filter applied
/notes/:id PUT Update note βœ… Tenant filter applied
/notes/:id DELETE Delete note βœ… Tenant filter applied
/tenants/:slug/upgrade POST Upgrade plan βœ… (Admin) Validates tenant slug
/tenants/invite POST Invite user βœ… (Admin) Creates new user in tenant

🌱 Seeded Tenants & Test Accounts

Run the seed script:

MONGO_URI="your-mongo-uri" JWT_SECRET="a-secret" node seed.js

Tenants

  • Acme (slug: acme, plan: FREE)
  • Globex (slug: globex, plan: FREE)

Users (default password: password)

  • admin@acme.test β†’ Admin (Acme)
  • user@acme.test β†’ Member (Acme)
  • admin@globex.test β†’ Admin (Globex)
  • user@globex.test β†’ Member (Globex)

πŸš€ Vercel Deployment

This project is configured for a monorepo deployment on Vercel, with separate projects for the backend and frontend.

1. Database Setup (MongoDB Atlas)

  • Create a free cluster on MongoDB Atlas.
  • In the Network Access tab, add 0.0.0.0/0 to the IP Access List.

    This is required to allow Vercel's serverless functions to connect.

  • In the Database Access tab, create a database user and save the password.
  • Get your connection string (Drivers β†’ Node.js) and replace <password> with your user's password.
    This is your MONGO_URI.

2. Backend Deployment

  • Create a New Vercel Project: Import your Git repository.
  • Configure Project:
    • Project Name: e.g., notes-application-backend
    • Root Directory: notes-backend
  • Environment Variables:
    • MONGO_URI: The full connection string from MongoDB Atlas.
    • JWT_SECRET: A secure, random string for signing tokens.
  • Deploy: Vercel will use the notes-backend/vercel.json file to deploy the Express app as a serverless function.
    Note the deployed URL (e.g., https://your-backend.vercel.app).

3. Frontend Deployment

  • Create Another Vercel Project: Import the same Git repository again.
  • Configure Project:
    • Project Name: e.g., notes-application-frontend
    • Root Directory: notes-frontend
  • Environment Variables:
    • VITE_API_URL: The URL of your deployed backend from the previous step.
  • Deploy: Vercel will use the notes-frontend/vercel.json file to correctly handle client-side routing.

🎨 Frontend Structure

Located in notes-frontend/src/:

  • components/ β†’ UI components (Navbar, NoteModal, InviteModal, etc.)
  • context/ β†’ AuthContext, ToastContext for global state & messages
  • lib/ β†’ api.js (centralized API helper)
  • pages/ β†’ LoginPage, NotesPage, UpgradePage
  • App.jsx β†’ App bootstrap & routing

Frontend Auth Flow

  1. User logs in β†’ token stored in AuthContext + localStorage.
  2. All API calls attach Authorization: Bearer <token>.
  3. On 401 Unauthorized, user is logged out automatically.

Local Setup

Backend

cd notes-backend
npm install
# Required ENV variables
export MONGO_URI="your-mongo-uri"
export JWT_SECRET="your-secret"
npm run seed   # seeds Acme & Globex
npm start

Frontend

cd notes-frontend
npm install
npm run dev
# App runs on http://localhost:5173 (default Vite port)

πŸ“‘ API Endpoints Reference

  • POST /auth/login β†’ { token, user, tenant }
  • POST /auth/change-password β†’ Change password
  • GET /notes β†’ List tenant notes
  • POST /notes β†’ Create tenant note (enforces plan limits)
  • GET /notes/:id β†’ View note
  • PUT /notes/:id β†’ Update note
  • DELETE /notes/:id β†’ Delete note
  • POST /tenants/:slug/upgrade β†’ Upgrade plan (Admin only)
  • POST /tenants/invite β†’ Invite user (Admin only)

πŸ”’ Security & Hardening

  • βœ… Indexes: { tenant, createdAt } on notes, { tenant, email } on users

  • βœ… JWT best practices: rotate keys, use HTTPS, HttpOnly cookies if needed

  • βœ… Input validation: enforce via Joi / express-validator

  • βœ… Rate limiting: mitigate brute force attacks

  • πŸ”œ Suggested:

    • Tenant scoping middleware
    • Mongoose plugin to auto-enforce tenant presence

πŸ“¬ Contact

Built and maintained by Ayush Kaneriya.


About

A full-stack multi-tenant Notes application built with React, Vite, Express, Node.js, and MongoDB. Features authentication with JWT, CRUD operations, tenant isolation, and seamless deployment on Vercel (monorepo setup).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors