Go to file
2026-05-05 23:26:12 +00:00
src Update auto-reply: logo+text left-aligned in header, dark info box to match header 2026-05-05 23:26:12 +00:00
.env.example feat: add email notifications for contact form submissions 2026-05-05 21:05:37 +00:00
.gitignore Initial commit: Express backend with user management and SQLite database 2026-03-27 21:33:56 +00:00
package-lock.json feat: add email notifications for contact form submissions 2026-05-05 21:05:37 +00:00
package.json feat: add email notifications for contact form submissions 2026-05-05 21:05:37 +00:00
README.md feat: add email notifications for contact form submissions 2026-05-05 21:05:37 +00:00

Moxie Backend

Express.js backend API for user management of an AI site, built with ESM syntax, Auth0 authentication, and SQLite database.

Features

  • Auth0 Authentication: Secure authentication via Auth0
  • User Management: Auto-creation of users on first login, profile management
  • Credit System: Track and manage user credits
  • API Keys: Generate and manage API keys for programmatic access
  • Payment Webhooks: Ready for Stripe and PayPal integration
  • Admin Endpoints: User management for administrators
  • SQLite Database: Lightweight, file-based storage

Quick Start

# Install dependencies
npm install

# Copy environment file and configure
cp .env.example .env
# Edit .env with your Auth0 credentials

# Start the server
npm start

# Start in development mode (with auto-reload)
npm run dev

The server runs on port 9991 by default.

Auth0 Setup

1. Create Auth0 Application

  1. Go to Auth0 Dashboard > Applications > Applications
  2. Create a new "Single Page Application" or "Regular Web Application"
  3. Configure the following URLs:
    • Allowed Callback URLs: https://moxiegen.client.guacamolebox.net/api/callback
    • Allowed Logout URLs: https://moxiegen.client.guacamolebox.net
    • Allowed Web Origins: https://moxiegen.client.guacamolebox.net
    • Application Login URI: https://moxiegen.client.guacamolebox.net/login

2. Create Auth0 API (Optional)

For machine-to-machine authentication:

  1. Go to Auth0 Dashboard > Applications > APIs
  2. Create a new API
  3. Set the identifier as your audience
  4. Enable RBAC if needed

3. Configure Environment Variables

AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
APP_URL=https://moxiegen.client.guacamolebox.net

API Endpoints

Auth Endpoints

Method Endpoint Description
GET /api/login Redirect to Auth0 login
GET /api/callback Handle Auth0 callback
GET /api/logout Logout and redirect

User Endpoints (Requires Auth0 Token)

All authenticated endpoints require Authorization: Bearer <access_token> header.

Method Endpoint Description
GET /api/users/me Get current user profile
PUT /api/users/me Update profile
DELETE /api/users/me Deactivate account
GET /api/users/credits Get credits and history
GET /api/users/api-keys List API keys
POST /api/users/api-keys Create new API key
DELETE /api/users/api-keys/:keyId Revoke API key

Admin Endpoints (Requires role: 'admin')

Method Endpoint Description
GET /api/users List all users
GET /api/users/:userId Get user by ID
PUT /api/users/:userId Update user
DELETE /api/users/:userId Delete user
POST /api/users/:userId/credits Adjust user credits
PUT /api/users/:userId/role Change user role

Webhook Endpoints

Method Endpoint Description
POST /api/webhooks/stripe Stripe webhook handler
POST /api/webhooks/paypal PayPal webhook handler

Frontend Integration

Login Flow

// Redirect to Auth0 login
window.location.href = '/api/login';

// Handle callback (tokens in URL params)
const urlParams = new URLSearchParams(window.location.search);
const accessToken = urlParams.get('access_token');
const idToken = urlParams.get('id_token');

// Store token and use for API calls
localStorage.setItem('access_token', accessToken);

// Make authenticated requests
fetch('/api/users/me', {
  headers: {
    'Authorization': `Bearer ${accessToken}`
  }
});

Using Auth0 SPA SDK

import { Auth0Client } from '@auth0/auth0-spa-js';

const auth0 = new Auth0Client({
  domain: 'your-tenant.auth0.com',
  client_id: 'your-client-id',
  redirect_uri: window.location.origin
});

// Login
await auth0.loginWithRedirect();

// Get token
const token = await auth0.getTokenSilently();

// Use token
fetch('/api/users/me', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

Database Schema

Users Table

  • id - Primary key (UUID)
  • auth0_id - Auth0 user ID (sub claim)
  • email - Email address
  • name - Display name
  • picture - Profile picture URL
  • role - User role ('user' or 'admin')
  • credits - Available credits
  • subscription_status - Subscription state
  • subscription_tier - Subscription level
  • stripe_customer_id - Stripe customer reference
  • paypal_customer_id - PayPal customer reference
  • is_active - Account status flag

API Keys Table

  • id - Key ID
  • user_id - Foreign key to users
  • key_hash - Hashed API key
  • name - Key name/description
  • is_active - Key status

Credit Transactions Table

  • id - Transaction ID
  • user_id - Foreign key to users
  • amount - Credit amount (+/-)
  • type - 'credit' or 'debit'
  • description - Transaction description

Payments Table

  • id - Payment ID
  • user_id - Foreign key to users
  • amount - Payment amount
  • provider - 'stripe' or 'paypal'
  • status - Payment status

Caddy Configuration

moxiegen.client.guacamolebox.net {
    # Static site
    root * /path/to/static/site
    file_server
    
    # API proxy
    handle /api/* {
        reverse_proxy localhost:9991
    }
}

Making a User Admin

To promote a user to admin role:

  1. Find the user ID from the database
  2. Use the admin API (requires an existing admin)
  3. Or directly update the database:
UPDATE users SET role = 'admin' WHERE email = 'admin@example.com';

Payment Integration

Stripe Setup

  1. Create a Stripe account and get API keys
  2. Add keys to environment variables
  3. Create a webhook endpoint in Stripe dashboard pointing to https://moxiegen.client.guacamolebox.net/api/webhooks/stripe
  4. Copy the webhook signing secret to STRIPE_WEBHOOK_SECRET

PayPal Setup

  1. Create a PayPal Developer account
  2. Create a REST API application
  3. Add credentials to environment variables
  4. Configure webhook in PayPal dashboard pointing to https://moxiegen.client.guacamolebox.net/api/webhooks/paypal

Email Configuration (Contact Form)

Contact form submissions are automatically emailed to a configured address using Nodemailer with SMTP.

Setup

Add the following to your .env file:

# SMTP Email Configuration
SMTP_HOST=smtp.gmail.com        # Your SMTP server
SMTP_PORT=587                   # Usually 587 (TLS) or 465 (SSL)
SMTP_USER=your-email@gmail.com  # Email address to send from
SMTP_PASS=your-app-password     # Password or app-specific password
SMTP_SECURE=false               # true for port 465, false for 587
SMTP_FROM=Moxie <your-email@gmail.com>  # From display name & address

# Where contact form emails are sent (defaults to SMTP_USER)
CONTACT_EMAIL=notifications@yourdomain.com

Gmail Users

If you use Gmail, you must generate an App Password because regular passwords no longer work with SMTP:

  1. Go to Google Account Security
  2. Enable 2-Step Verification (if not already enabled)
  3. Go to App passwords (search in security settings)
  4. Create a new app password for "Mail"
  5. Use that 16-character password as SMTP_PASS

Other Providers

Provider SMTP_HOST SMTP_PORT Notes
Gmail smtp.gmail.com 587 Requires App Password
Outlook / Office 365 smtp.office365.com 587
SendGrid smtp.sendgrid.net 587 Use API key as password
Mailgun smtp.mailgun.org 587
AWS SES email-smtp.[region].amazonaws.com 587 Use SMTP credentials

How It Works

When someone submits the contact form (POST /api/contact):

  1. The submission is saved to the database (always succeeds)
  2. An email notification is sent in the background (fire-and-forget)
  3. If email sending fails, the form still saves — a warning is logged but the user is not affected

The email includes:

  • Plain-text and HTML versions
  • The submitter's name, email, and company (if provided)
  • The full message
  • A reply-to header so you can reply directly to the submitter

License

ISC