Nvite Subscription Platform Documentation

Welcome to the Nvite Subscription Platform documentation. This guide will help you get started with building and deploying your email subscription and invitation management system.

What is Nvite?

Nvite is an open-source email subscription and invitation management platform designed for developers who need a flexible, secure, and scalable solution for managing subscriber lists, creating beautiful email templates, and tracking campaign analytics.

Visual Builder

Drag-and-drop email template editor

List Management

CSV import/export and segmentation

Analytics

Real-time performance tracking

Installation

Prerequisites

  • Node.js 16.x or higher
  • npm or yarn package manager
  • Git for version control
  • Database (SQLite, MySQL, or PostgreSQL)

Step 1: Clone the Repository

git clone https://github.com/rbenzing/nvite-subscription-platform.git
cd nvite-subscription-platform

Step 2: Install Dependencies

npm install

Step 3: Configure Environment

cp .env.example .env

Edit the .env file with your configuration.

Step 4: Build and Start

# Development mode (frontend + backend)
npm run dev:full

# Or separately
npm run dev      # Frontend only (port 8080)
npm run server   # Backend only (port 3001)

# Production build
npm run build
npm start

Configuration

Environment Variables

Configure your application using the following environment variables:

Database Configuration

# Database type: sqlite, mysql, or postgres
DB_TYPE=sqlite

# SQLite (default)
# No additional configuration needed

# MySQL
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=yourpassword
MYSQL_DATABASE=nvite_db

# PostgreSQL
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=yourpassword
POSTGRES_DATABASE=nvite_db

Security Configuration

# JWT Secret (generate with: openssl rand -base64 32)
JWT_SECRET=your-secret-key-here

# Session Secret
SESSION_SECRET=your-session-secret

# Bcrypt Rounds (default: 12)
BCRYPT_ROUNDS=12

# Encryption Key (generate with: openssl rand -hex 32)
ENCRYPTION_KEY=your-encryption-key

SMTP Configuration

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM=noreply@yourdomain.com

OAuth Configuration (Optional)

# Google OAuth
VITE_GOOGLE_CLIENT_ID=your-google-client-id

# Microsoft OAuth
VITE_MICROSOFT_CLIENT_ID=your-microsoft-client-id

Architecture

Project Structure

nvite-subscription-platform/
├── src/
│   ├── components/          # React components
│   │   ├── ui/             # Shadcn/ui components
│   │   ├── auth/           # Authentication components
│   │   ├── builder/        # Invitation builder
│   │   ├── layout/         # Layout components
│   │   └── lists/          # List management
│   ├── pages/              # Page components (lazy loaded)
│   ├── services/           # Frontend services (TypeScript)
│   ├── contexts/           # React Context providers
│   ├── types/              # TypeScript type definitions
│   ├── hooks/              # Custom React hooks
│   └── utils/              # Utility functions
├── server.cjs              # Express backend server
├── db-config.cjs           # Database adapter
├── schema/                 # Database schemas
│   ├── sqlite.sql
│   ├── mysql.sql
│   └── postgresql.sql
└── .env                    # Environment configuration

Service Layer Pattern

Nvite uses a service layer architecture for clean separation of concerns:

Frontend Services (TypeScript)

// src/services/authService.ts
export class AuthService {
  static async login(data: LoginData): Promise {
    const response = await fetch('/api/auth/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify(data)
    });
    return await response.json();
  }
}

Backend Services (CommonJS)

// Backend service using dbAdapter
const { dbAdapter } = require('./db-config.cjs');

async function getUserByEmail(email) {
  const [rows] = await dbAdapter.execute(
    'SELECT * FROM users WHERE email = ? LIMIT 1',
    [email]
  );
  return rows[0] || null;
}

module.exports = { getUserByEmail };

Database Abstraction

The database adapter provides a unified interface for SQLite, MySQL, and PostgreSQL:

const { dbAdapter } = require('./db-config.cjs');

// Initialize (auto-runs on server start)
await dbAdapter.initialize();

// Execute queries (returns [rows] format)
const [users] = await dbAdapter.execute(
  'SELECT * FROM users WHERE active = ?',
  [true]
);

Features

Invitation Builder

Drag-and-drop visual builder for creating email templates:

  • Block-based design system (text, images, buttons, containers)
  • Real-time preview
  • Custom styling and properties
  • Template save and export

Subscriber List Management

Comprehensive list management features:

  • Create and manage multiple subscriber lists
  • CSV import/export functionality
  • Subscriber segmentation and filtering
  • Subscription status tracking (active, unsubscribed, bounced)

Security Features

Enterprise-grade security:

  • Bcrypt password hashing (12 rounds default)
  • HttpOnly cookie authentication
  • CSRF protection
  • Rate limiting
  • Input sanitization (DOMPurify)
  • OAuth integration (Google, Microsoft)

API Reference

Authentication Endpoints

POST /api/auth/register

Register a new user account.

{
  "email": "user@example.com",
  "password": "SecurePassword123!",
  "firstName": "John",
  "lastName": "Doe"
}

POST /api/auth/login

Authenticate and create session.

{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}

POST /api/auth/logout

Destroy user session.

Template Endpoints

GET /api/templates

Retrieve all templates for the authenticated user.

POST /api/templates

Create a new template.

{
  "name": "Welcome Email",
  "subject": "Welcome to Nvite!",
  "blocks": [...],
  "settings": {...}
}

PUT /api/templates/:id

Update an existing template.

DELETE /api/templates/:id

Delete a template.

List Management Endpoints

GET /api/lists

Get all subscriber lists.

POST /api/lists

Create a new subscriber list.

{
  "name": "Newsletter Subscribers",
  "description": "Main newsletter list"
}

POST /api/lists/:id/subscribers/import

Import subscribers from CSV.

Deployment

Production Build

# Build frontend assets
npm run build

# Start production server
npm start

Docker Deployment

Create a Dockerfile for containerized deployment:

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

EXPOSE 3001

CMD ["npm", "start"]

Environment-Specific Configuration

Ensure you set appropriate environment variables for production:

  • Use strong, randomly-generated secrets
  • Configure production database credentials
  • Set SMTP settings for email delivery
  • Enable HTTPS in production
  • Configure appropriate CORS settings

Security

Security Best Practices

  • Password Hashing: Server-side bcrypt with 12 rounds (configurable)
  • Authentication: HttpOnly cookies prevent XSS attacks
  • CSRF Protection: Built-in CSRF token validation
  • Rate Limiting: Prevents brute force attacks
  • Input Sanitization: All user input sanitized via SecurityService
  • XSS Prevention: DOMPurify for HTML content
  • SQL Injection: Parameterized queries via dbAdapter

Security Headers

The following security headers are configured by default:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block
  • Strict-Transport-Security (HSTS)
  • Content-Security-Policy

Contributing

How to Contribute

We welcome contributions! Here's how to get started:

  1. Fork the repository on GitHub
  2. Clone your fork locally
  3. Create a new branch for your feature: git checkout -b feature/amazing-feature
  4. Make your changes and commit with clear messages
  5. Run npm run lint to ensure code quality
  6. Push to your fork: git push origin feature/amazing-feature
  7. Open a Pull Request with a detailed description

Code Guidelines

  • Follow the existing code style and patterns
  • Use TypeScript for frontend code with explicit types
  • Use CommonJS for backend code
  • Always use dbAdapter for database queries
  • Write clear commit messages
  • Add comments for complex logic
  • Ensure all ESLint rules pass

License

Nvite Subscription Platform is licensed under the GNU Affero General Public License v3.0 (AGPLv3). This means you are free to use, modify, and distribute the software, but any modifications must also be open-sourced under the same license.

Frequently Asked Questions

Which database should I use?

SQLite is great for development and small deployments. For production with multiple users, we recommend MySQL or PostgreSQL for better performance and scalability.

How do I configure OAuth?

Set up OAuth credentials in Google Cloud Console or Azure AD, then add the client IDs to your .env file as VITE_GOOGLE_CLIENT_ID and VITE_MICROSOFT_CLIENT_ID.

Can I customize the email templates?

Yes! The invitation builder provides a drag-and-drop interface for creating custom templates. You can also modify the template components in src/components/builder/.

How do I import subscribers?

Use the CSV import feature in the Lists page. Your CSV should have columns for email, firstName, lastName, and any custom fields you've configured.

Is demo mode available?

Yes! Set VITE_DEMO_MODE=true in your .env file. Demo mode uses SQLite and blocks email sending for testing purposes.

How do I report a bug or request a feature?

Open an issue on GitHub Issues with a detailed description.

Need More Help?

Check out these resources for additional support: