Skip to content

Repository files navigation

Secret Note - Node.js Version

A modern Node.js implementation of the Secret Note application - a secure, self-destructing note sharing service.

Migration from Flask to Node.js

What Changed

Aspect Flask Version Node.js Version
Framework Flask Express.js
Database sqlite3 (Python) sqlite3 (Node.js)
Templating Jinja2 EJS
Encryption cryptography (Fernet) TweetNaCl.js (secretbox)
Runtime Python 3.8+ Node.js 18+

Key Features Preserved

  • ✅ Encrypt messages with random keys or custom salts
  • ✅ Generate shareable links for encrypted notes
  • ✅ Self-destructing notes (deleted after first read)
  • ✅ SQLite database for persistence
  • ✅ Same UI/UX experience with Bootstrap 5

New Features

  • 🚀 Faster performance (Node.js vs Python)
  • 📦 Smaller deployment footprint
  • 🔄 Modern async/await patterns
  • 📝 Better error handling

Project Structure

secret-note/
├── server.js              # Main Express application
├── crypto-utils.js        # Encryption/decryption functions
├── db-utils.js            # Database operations
├── db-setup.js            # Database initialization
├── package.json           # Dependencies
├── static/                # Static files (CSS, images)
│   ├── styles.css
│   └── favicon.ico
├── views/                 # EJS templates
│   ├── layout.ejs
│   ├── index.ejs
│   ├── note_link.ejs
│   ├── display_note.ejs
│   └── display_error.ejs
├── secret.db              # SQLite database (created on first run)
└── README.md

Installation

Prerequisites

  • Node.js 18+
  • npm or yarn

Setup

  1. Install dependencies:

    npm install
  2. Initialize the database:

    npm run setup-db
  3. Start the server:

    npm start

    The app will be available at http://localhost:3000

Development Mode

For development with auto-reload:

npm run dev

Dependencies

  • express (4.18.2) - Web framework
  • sqlite3 (5.1.6) - Database driver
  • uuid (9.0.1) - Unique ID generation
  • tweetnacl (1.0.3) - Encryption library
  • tweetnacl-util (0.15.1) - TweetNaCl utilities

Encryption Details

Algorithm

The Node.js version uses TweetNaCl.js for encryption with the following approach:

  • Secret Box: NaCl's authenticated encryption (XSalsa20 + Poly1305)
  • Key Derivation: PBKDF2 with SHA-256 (100,000 iterations)
  • Random Keys: 32-byte keys generated via crypto.randomBytes()

Format

Encrypted messages are stored as:

  • Nonce (24 bytes) + Encrypted data (variable)
  • Everything is Base64-encoded for storage

API Routes

GET /

Display the form to create a new secret note.

POST /

Create a new encrypted note.

Request Body:

  • message (required): The text to encrypt
  • salt (optional): Custom salt for key derivation

Response: Displays a page with a shareable link

GET /note/:noteId

Retrieve and decrypt a note. The note is automatically deleted after viewing (self-destruct).

Response: Displays the decrypted message or an error page

Comparison: Flask vs Node.js Implementation

Flask Version

@app.route('/note/<note_id>')
def note(note_id):
    row = cursor.execute('SELECT message, salt FROM notes WHERE id = ?', (note_id,)).fetchone()
    if row:
        message = functions.decrypt_message(row[0], row[1])
        delete_message(note_id)
        return render_template('display_note.html', message=message)

Node.js Version

app.get('/note/:noteId', async (req, res) => {
  const row = await db.getNote(req.params.noteId);
  if (row) {
    const message = crypto.decryptMessage(row.message, row.salt);
    await db.deleteNote(req.params.noteId);
    res.render('display_note', { message });
  }
});

Environment Variables

Optional configuration via .env file:

PORT=3000

Database Schema

CREATE TABLE IF NOT EXISTS notes (
  id TEXT PRIMARY KEY,
  message TEXT,
  salt TEXT
)
  • id: UUID for the note
  • message: Base64-encoded encrypted message (with nonce)
  • salt: Base64-encoded key (either generated or derived from user's salt)

Security Notes

⚠️ Production Considerations:

  1. HTTPS Only: Always use HTTPS in production
  2. Salt Storage: The hardcoded salt in crypto-utils.js should be environment-specific
  3. Database: Use a proper database backend instead of SQLite for production
  4. Rate Limiting: Consider implementing rate limiting on POST requests
  5. Input Validation: Additional validation may be needed for production
  6. Error Handling: Generic error messages are recommended in production

Troubleshooting

Port already in use

PORT=3001 npm start

Database locked

Delete the secret.db* files and reinitialize:

rm secret.db*
npm run setup-db

Module not found errors

npm install
npm audit fix

Contributing

Contributions are welcome! Please feel free to fork the repository, make changes, and submit a pull request. If you have any suggestions or issues, please post them in the issues section of the GitHub repository.

Author

License

Creative Commons Attribution-ShareAlike (CC BY-SA 4.0)

Creative Commons Attribution-ShareAlike (CC BY-SA 4.0)

Credits

⚠️ Security Notice

This is a proof of concept application for educational purposes only. NOT SUITABLE FOR PRODUCTION.

Security considerations:

  • Uses a hardcoded salt for key derivation (compromises custom salt functionality)
  • No rate limiting or DDoS protection
  • Not recommended for sensitive data on public networks

About

A modern node.js conversion of the secret note flask app.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages