Skip to content

ratulhub/SecureNote-Hub

Repository files navigation

📓 Note Hub — Complete Setup Guide

A personal note gallery with file uploads, folders, tags, and password protection. Backend powered by Supabase (free tier). No Firebase needed.


📋 Table of Contents

  1. What You Need (Prerequisites)
  2. Download & Extract the Project
  3. Create a Free Supabase Account
  4. Create a Supabase Project
  5. Run the Database Migrations (SQL)
  6. Deploy the Edge Functions
  7. Get Your Supabase API Keys
  8. Edit the .env File
  9. Install & Run the App
  10. Set Your Admin Password
  11. Log In & Use the App
  12. Troubleshooting
  13. How the App Works (Quick Reference)

1. What You Need

Before starting, make sure you have these installed on your computer:

Tool Purpose Download
Node.js (v18 or newer) Runs the app https://nodejs.org → click "LTS"
npm Installs packages (comes with Node.js) Included with Node.js
Supabase CLI Deploys backend functions See Step 6 below
A web browser Chrome, Firefox, Edge Already have it
A text editor Edit config files VS Code: https://code.visualstudio.com

Check Node.js is installed — open your Terminal and run:

node --version

You should see something like v20.0.0. If you see an error, install Node.js first.


2. Download & Extract the Project

  1. Download the ratulnotehub-clean.zip file (the one Claude gave you).

  2. Open your Downloads folder.

  3. Right-click on ratulnotehub-clean.zipExtract Here (or Extract All on Windows).

  4. You will now have a folder called notehub-clean-src inside a folder called ratulnotehub-clean.

  5. Open your Terminal (or Command Prompt on Windows) and navigate into the project:

cd ~/Downloads/ratulnotehub-clean/notehub-clean-src

💡 Tip: On Windows, use cd %USERPROFILE%\Downloads\ratulnotehub-clean\notehub-clean-src

  1. Confirm you are in the right place:
ls

You should see files like: index.html, package.json, vite.config.ts, src/, supabase/


3. Create a Free Supabase Account

Supabase is a free backend service that stores your files, notes, and password.

  1. Go to https://supabase.com

  2. Click "Start your project" (green button, top right).

  3. Sign up with GitHub (easiest) or your email.

  4. Verify your email if asked.

  5. You are now on the Supabase Dashboard.


4. Create a Supabase Project

  1. On the Supabase Dashboard, click "New project".

  2. Fill in the form:

    • Organization: Your name (auto-created)
    • Project name: notehub (or anything you like)
    • Database Password: Create a strong password and save it somewhere — you'll need it later
    • Region: Pick the one closest to you (e.g., Southeast Asia if you're in Bangladesh)
  3. Click "Create new project".

  4. Wait about 1-2 minutes while Supabase sets up your database. You'll see a loading spinner.

  5. Once done, you'll see your project dashboard. Keep this tab open — you'll need it.


5. Run the Database Migrations (SQL)

This step creates all the database tables the app needs (notes, folders, tags, password storage, file storage).

  1. In your Supabase project dashboard, look at the left sidebar.

  2. Click "SQL Editor" (the icon looks like </>).

  3. Click "New query" (top left of the SQL editor).

  4. You need to run 3 SQL files from your project. Open the folder:

    notehub-clean-src/supabase/migrations/
    

    You will see 3 .sql files. Run them in order (oldest timestamp first):


Migration 1 — Copy this entire block and paste it into the SQL editor:

-- Create auth_user table for single admin user
CREATE TABLE public.auth_user (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  username TEXT NOT NULL UNIQUE,
  password_hash TEXT NOT NULL
);

ALTER TABLE public.auth_user ENABLE ROW LEVEL SECURITY;

-- Create login_attempts table for rate limiting
CREATE TABLE public.login_attempts (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  ip_address TEXT NOT NULL,
  attempt_count INTEGER NOT NULL DEFAULT 0,
  last_attempt_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  blocked_until TIMESTAMP WITH TIME ZONE
);

CREATE UNIQUE INDEX idx_login_attempts_ip ON public.login_attempts (ip_address);

ALTER TABLE public.login_attempts ENABLE ROW LEVEL SECURITY;

-- Create sessions table
CREATE TABLE public.sessions (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID NOT NULL REFERENCES public.auth_user(id) ON DELETE CASCADE,
  token TEXT NOT NULL UNIQUE,
  expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
  last_activity TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
);

ALTER TABLE public.sessions ENABLE ROW LEVEL SECURITY;
  1. After pasting, click the green "Run" button (or press Ctrl+Enter).

  2. You should see "Success. No rows returned" at the bottom. That means it worked.


Migration 2 — Click "New query" again, paste this, then click Run:

-- Folders table
CREATE TABLE public.folders (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  name TEXT NOT NULL,
  parent_id UUID REFERENCES public.folders(id) ON DELETE CASCADE,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
);

ALTER TABLE public.folders ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all access to folders" ON public.folders FOR ALL USING (true) WITH CHECK (true);

-- Notes table
CREATE TABLE public.notes (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  title TEXT NOT NULL,
  file_url TEXT,
  file_type TEXT,
  file_size BIGINT DEFAULT 0,
  folder_id UUID REFERENCES public.folders(id) ON DELETE SET NULL,
  order_index INTEGER NOT NULL DEFAULT 0,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
);

ALTER TABLE public.notes ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all access to notes" ON public.notes FOR ALL USING (true) WITH CHECK (true);
CREATE INDEX idx_notes_folder ON public.notes(folder_id);
CREATE INDEX idx_notes_order ON public.notes(order_index);

-- Tags table
CREATE TABLE public.tags (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  name TEXT NOT NULL UNIQUE,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
);

ALTER TABLE public.tags ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all access to tags" ON public.tags FOR ALL USING (true) WITH CHECK (true);

-- Note-Tags junction
CREATE TABLE public.note_tags (
  id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  note_id UUID NOT NULL REFERENCES public.notes(id) ON DELETE CASCADE,
  tag_id UUID NOT NULL REFERENCES public.tags(id) ON DELETE CASCADE,
  UNIQUE(note_id, tag_id)
);

ALTER TABLE public.note_tags ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow all access to note_tags" ON public.note_tags FOR ALL USING (true) WITH CHECK (true);

-- Auto-update updated_at on notes
CREATE OR REPLACE FUNCTION public.update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SET search_path = public;

CREATE TRIGGER update_notes_updated_at
  BEFORE UPDATE ON public.notes
  FOR EACH ROW
  EXECUTE FUNCTION public.update_updated_at_column();

-- Storage bucket for files
INSERT INTO storage.buckets (id, name, public) VALUES ('note-files', 'note-files', true);

CREATE POLICY "Anyone can read note files" ON storage.objects FOR SELECT USING (bucket_id = 'note-files');
CREATE POLICY "Anyone can upload note files" ON storage.objects FOR INSERT WITH CHECK (bucket_id = 'note-files');
CREATE POLICY "Anyone can update note files" ON storage.objects FOR UPDATE USING (bucket_id = 'note-files');
CREATE POLICY "Anyone can delete note files" ON storage.objects FOR DELETE USING (bucket_id = 'note-files');

Click Run. You should see "Success".


Migration 3 — Click "New query" again, paste this, then click Run:

-- Add favorites column
ALTER TABLE public.notes ADD COLUMN is_favorited boolean NOT NULL DEFAULT false;

-- Version history table
CREATE TABLE public.note_versions (
  id uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
  note_id uuid NOT NULL REFERENCES public.notes(id) ON DELETE CASCADE,
  content text,
  file_url text,
  version_number integer NOT NULL DEFAULT 1,
  created_at timestamp with time zone NOT NULL DEFAULT now()
);

ALTER TABLE public.note_versions ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Allow all access to note_versions"
  ON public.note_versions FOR ALL TO public
  USING (true) WITH CHECK (true);

CREATE INDEX idx_note_versions_note_id ON public.note_versions(note_id);

Click Run. You should see "Success".

All 3 migrations done! Your database tables are now created.


6. Deploy the Edge Functions

Edge Functions are the backend logic that handles login, logout, and password management. You need to deploy them from your terminal using the Supabase CLI.

Step 6a — Install Supabase CLI

On Linux/macOS:

npm install -g supabase

On Windows (PowerShell as Administrator):

npm install -g supabase

Verify it installed:

supabase --version

You should see a version number like 1.x.x.


Step 6b — Log into Supabase CLI

supabase login

This will open your browser. Log in with your Supabase account. Then come back to the terminal — it should say "Logged in".


Step 6c — Get Your Project Reference ID

  1. Go to your Supabase project dashboard in the browser.
  2. Click "Project Settings" (gear icon, bottom of left sidebar).
  3. Click "General".
  4. Find "Reference ID" — it looks like: srmpdcpvfecpeomsgqlq
  5. Copy it.

Step 6d — Link Your Project

In your terminal, make sure you are inside the project folder:

cd ~/Downloads/ratulnotehub-clean/notehub-clean-src

Then run (replace YOUR_PROJECT_REF with your actual Reference ID):

supabase link --project-ref YOUR_PROJECT_REF

It will ask for your database password — enter the password you set in Step 4.


Step 6e — Deploy the Functions

Now deploy all 5 Edge Functions with one command:

supabase functions deploy login
supabase functions deploy logout
supabase functions deploy validate-session
supabase functions deploy change-password
supabase functions deploy setup-admin

Each one should say "Done: Deployed Function".

Edge Functions are now live on Supabase!


7. Get Your Supabase API Keys

  1. In your Supabase project dashboard, click "Project Settings" (gear icon).

  2. Click "API" in the settings menu.

  3. You will see two important things — copy both:

    • Project URL — looks like:

      https://srmpdcpvfecpeomsgqlq.supabase.co
      
    • anon / public key — a long string starting with eyJ...

      eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
      

⚠️ Do NOT share the service_role key with anyone. Only copy the anon key.


8. Edit the .env File

The .env file tells the app where your Supabase database is and how to connect to it.

  1. Open the project folder notehub-clean-src in your text editor (VS Code).

  2. Find the file named .env in the root of the folder.

    💡 On Linux/macOS, files starting with . are hidden by default. In your file manager, press Ctrl+H to show hidden files. In VS Code it shows automatically.

  3. Open .env. It looks like this:

    VITE_SUPABASE_PROJECT_ID="srmpdcpvfecpeomsgqlq"
    VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGci..."
    VITE_SUPABASE_URL="https://srmpdcpvfecpeomsgqlq.supabase.co"
    
  4. Replace all three values with YOUR values from Step 7:

    VITE_SUPABASE_PROJECT_ID="YOUR_REFERENCE_ID_HERE"
    VITE_SUPABASE_PUBLISHABLE_KEY="YOUR_ANON_KEY_HERE"
    VITE_SUPABASE_URL="YOUR_PROJECT_URL_HERE"
    

    Example (with real-looking fake values):

    VITE_SUPABASE_PROJECT_ID="abcdefghijklmnop"
    VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.abc123"
    VITE_SUPABASE_URL="https://abcdefghijklmnop.supabase.co"
    
  5. Save the file (Ctrl+S).


9. Install & Run the App

  1. Open your terminal and go to the project folder:

    cd ~/Downloads/ratulnotehub-clean/notehub-clean-src
  2. Install all dependencies (only needed once):

    npm install

    This will take 1-2 minutes. You will see a progress bar.

  3. Start the development server:

    npm run dev
  4. You will see output like:

    VITE v5.x.x  ready in 500 ms
    ➜  Local:   http://localhost:8080/
    
  5. Open your browser and go to: http://localhost:8080

You should see the Note Hub login page! 🎉


10. Set Your Admin Password

The app needs a password to protect your notes. You need to set it once using the setup-admin Edge Function.

There are two ways to do this:

Method A — Using the Supabase Dashboard (Easiest)

  1. Go to your Supabase project dashboard.
  2. Click "Edge Functions" in the left sidebar.
  3. Click on "setup-admin".
  4. Click the "Test" button (or use the "Invoke" section).
  5. In the request body, enter:
    {
      "password": "your_password_here"
    }
    Replace your_password_here with your actual password (minimum 6 characters).
  6. Click "Send".
  7. You should see: {"message": "Admin user created"}

Method B — Using curl from Terminal

curl -X POST https://YOUR_PROJECT_REF.supabase.co/functions/v1/setup-admin \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ANON_KEY" \
  -d '{"password": "your_password_here"}'

Replace:

  • YOUR_PROJECT_REF with your project Reference ID
  • YOUR_ANON_KEY with your anon/public key
  • your_password_here with your chosen password

You should see: {"message":"Admin user created"}

Your password is now saved securely in the database (hashed — not stored as plain text).


11. Log In & Use the App

  1. Go to http://localhost:8080 in your browser.
  2. You will be redirected to the login page.
  3. Enter the password you set in Step 10.
  4. Click "Continue".
  5. You are now in your Note Hub dashboard!

What you can do:

Feature How to use
Upload files Click "New" → "Upload file" or drag & drop files onto the screen
Create text notes Click "New" → "New text file"
Create folders Click "New folder" in the left sidebar
Preview notes Click on any note card
Edit text files Click menu on a note → "Edit"
View CSV files Click a .csv note — opens as a table
View Word docs Click a .docx note — renders the text
Search notes Type in the search bar at the top
Add tags Click on a note → "Add tag"
Favorite a note Click "Favorite" (pins it to top)
Move to folder Click "Move to…"
Drag & reorder Click and drag note cards to reorder them
Bulk select Click "Select" button → check multiple notes → Delete or Move
Change password Bottom of left sidebar → "Change password"

Supported file types:

  • 📄 Text: .txt, .md
  • 📊 Spreadsheet: .csv
  • 📑 Word: .docx
  • 📕 PDF: .pdf
  • 🖼️ Images: .png, .jpg, .jpeg, .gif, .webp

12. Troubleshooting

❌ "npm install" fails — "package.json not found"

You are in the wrong folder. Make sure you are inside notehub-clean-src:

cd ~/Downloads/ratulnotehub-clean/notehub-clean-src
npm install

❌ App shows blank white page or console errors

  • Open browser DevTools (F12) → Console tab
  • If you see "Failed to fetch" or "Invalid API key" — your .env file has wrong values. Re-check Step 8.
  • Make sure the .env file is saved.
  • Stop the server (Ctrl+C) and restart: npm run dev

❌ Login says "Incorrect password"

  • Make sure you completed Step 10 (set admin password).
  • The password is case-sensitive.
  • If you forgot your password, call setup-admin again with a new password — it will update it.

❌ "Too many attempts. Locked for 15 minutes"

Wait 15 minutes. This is a security feature — 5 wrong attempts triggers a lockout.

To reset immediately, go to Supabase → SQL Editor → run:

DELETE FROM public.login_attempts;

❌ File upload fails

  • Check your Supabase Storage bucket exists: Supabase dashboard → "Storage" → you should see note-files bucket.
  • If the bucket is missing, go to SQL Editor and run Migration 2 again (the storage part).

❌ Edge Functions fail to deploy

Make sure you are logged in:

supabase login
supabase link --project-ref YOUR_PROJECT_REF
supabase functions deploy setup-admin

❌ Session expires too quickly

Sessions last 30 minutes by default. To change this, edit supabase/functions/login/index.ts:

const SESSION_DURATION_MINUTES = 30;  // Change this number

Then re-deploy: supabase functions deploy login


13. How the App Works

Architecture overview:

Your Browser (React app)
        │
        ├── Supabase Database (stores notes metadata, folders, tags, password hash)
        ├── Supabase Storage (stores actual files: PDFs, images, text files)
        └── Supabase Edge Functions (handles login, logout, password change)

Security model:

  • Your password is hashed (SHA-256) before saving — Supabase never stores plain text passwords
  • Login creates a session token valid for 30 minutes
  • After 5 wrong password attempts, login is locked for 15 minutes (brute-force protection)
  • All file storage is tied to your Supabase project — only you have access

Free tier limits (Supabase):

  • Database: 500 MB
  • Storage: 1 GB
  • Edge Function calls: 500,000/month
  • All plenty for personal use

🎉 You're All Set!

Your Note Hub is running locally. Every file you upload goes to Supabase Storage, and all your note data is saved in Supabase Database — both are free and persist even after you close your computer.

To stop the app: press Ctrl+C in the terminal. To start it again later:

cd ~/Downloads/ratulnotehub-clean/notehub-clean-src
npm run dev

Then open http://localhost:8080.


Built with React, TypeScript, Vite, Tailwind CSS, shadcn/ui, and Supabase.

About

A personal note gallery with file uploads, folders, tags, and password protection. Backend powered by Supabase (free tier)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages