Core Plugins Reference

SonicJS includes several essential core plugins that provide fundamental functionality for your CMS. These plugins are automatically installed and configured when you set up SonicJS.

Overview

Core plugins extend SonicJS with critical features like authentication, media management, caching, and database administration. They follow the same plugin architecture as custom plugins, making them excellent examples for plugin development.

Available Core Plugins

🔐

Authentication

JWT-based authentication with session management and token refresh

📧

Email

Transactional email sending via Resend with pre-built templates

🔗

Magic Link Auth

Passwordless authentication using secure email magic links

📸

Media

Media file management with R2 storage and image processing

Cache

Three-tier caching system with memory, KV, and database layers

🛠️

Database Tools

Database administration, migrations, and query tools

🌱

Seed Data

Sample data generation for development and testing


Authentication Plugin

The authentication plugin provides comprehensive user authentication and session management functionality.

Features

  • JWT Token Authentication - Secure token-based authentication
  • Session Management - Track and manage active user sessions
  • Token Refresh - Automatic token renewal without re-authentication
  • Rate Limiting - Protect authentication endpoints from abuse
  • User Context - Inject authenticated user data into request context

Configuration

Plugin Configuration

{
  name: 'core-auth',
  version: '1.0.0-beta.1',
  settings: {
    tokenExpiration: 3600,      // Token TTL in seconds (1 hour)
    refreshExpiration: 604800,   // Refresh token TTL (7 days)
    sessionTracking: true,       // Enable session tracking
    rateLimitWindow: 900,        // Rate limit window (15 minutes)
    rateLimitMaxAttempts: 5      // Max login attempts per window
  }
}

API Endpoints

POST /api/auth/login Authenticate a user and receive JWT tokens

Login Request

curl -X POST http://localhost:8787/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123"
  }'

POST /api/auth/logout Invalidate current session

GET /api/auth/me Get current authenticated user information

POST /api/auth/refresh Refresh an expired access token

Services

Auth Service

// Available auth service methods
const authService = {
  // Validate JWT token
  validateToken(token: string): { valid: boolean; userId: number }

  // Generate new JWT token
  generateToken(userId: number): string

  // Hash password for storage
  hashPassword(password: string): string

  // Verify password against hash
  verifyPassword(password: string, hash: string): boolean
}

Hooks

  • auth:login - Triggered when user attempts login
  • auth:logout - Triggered when user logs out
  • request:start - Injects authentication status into requests

Admin Pages

  • /admin/auth/sessions - View and manage active sessions
  • /admin/auth/tokens - Manage API tokens and access keys

Email Plugin

The email plugin provides transactional email functionality using Resend, with pre-built templates for common authentication and notification scenarios.

Features

  • Resend Integration - Send emails via the Resend API
  • Email Templates - Pre-built templates for registration, verification, password reset, and one-time codes
  • Template Customization - Code-based templates that can be customized
  • Logo Support - Add your company logo to email templates
  • Settings Management - Admin UI for configuring email settings
  • Test Email - Send test emails to verify configuration

Configuration

Plugin Configuration

{
  name: 'email',
  version: '1.0.0-beta.1',
  settings: {
    apiKey: 're_...',              // Resend API key
    fromEmail: 'noreply@yourdomain.com',  // From email address
    fromName: 'Your App Name',     // From name
    replyTo: 'support@yourdomain.com',    // Reply-to address (optional)
    logoUrl: 'https://yourdomain.com/logo.png'  // Logo URL (optional)
  }
}

Setup

  1. Sign up for Resend and get your API key
  2. Navigate to /admin/plugins/email/settings in your SonicJS admin
  3. Configure your Resend API key and email settings
  4. Send a test email to verify configuration

Included Email Templates

Registration Confirmation Sent when a new user registers an account

Email Verification Sent to verify user email addresses

Password Reset Sent when users request to reset their password

One-Time Code (2FA) Sent for two-factor authentication codes

API Usage

Sending Emails

// Get email plugin instance
const emailPlugin = context.plugins.get('email')

// Send a custom email
await emailPlugin.sendEmail({
  to: 'user@example.com',
  subject: 'Welcome to SonicJS',
  html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>'
})

// Send using built-in templates
await emailPlugin.sendVerificationEmail({
  to: 'user@example.com',
  verificationUrl: 'https://yoursite.com/verify?token=...'
})

await emailPlugin.sendPasswordResetEmail({
  to: 'user@example.com',
  resetUrl: 'https://yoursite.com/reset?token=...'
})

await emailPlugin.sendOneTimeCodeEmail({
  to: 'user@example.com',
  code: '123456',
  expiryMinutes: 10
})

Admin Pages

  • /admin/plugins/email/settings - Configure Resend API and email settings

The magic link auth plugin provides passwordless authentication via secure, one-time email links. Users can sign in without remembering passwords.

Features

  • Passwordless Authentication - No passwords required
  • Secure One-Time Links - Links expire after 15 minutes and can only be used once
  • Rate Limiting - Prevent abuse with configurable rate limits
  • Email Integration - Works with the Email plugin for sending magic links
  • Auto User Creation - Optionally create new users when they request a magic link
  • Security Tracking - Logs IP addresses and user agents for security auditing

How It Works

  1. User enters their email address
  2. System generates a secure, random token
  3. Email is sent with a magic link containing the token
  4. User clicks the link to authenticate
  5. Token is validated and marked as used
  6. User is signed in with a JWT session

Configuration

Plugin Configuration

{
  name: 'magic-link-auth',
  version: '1.0.0',
  dependencies: ['email'],
  settings: {
    linkExpiryMinutes: 15,         // Magic link expiry time
    rateLimitPerHour: 5,           // Max requests per hour per email
    allowNewUsers: false,          // Auto-create users who don't exist
    requireEmailVerification: true // Require verified emails
  }
}

API Endpoints

POST /auth/magic-link/request Request a magic link to be sent via email

Request Magic Link

curl -X POST http://localhost:8787/auth/magic-link/request \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

GET /auth/magic-link/verify?token=... Verify magic link token and sign in the user

Database Schema

Magic Links Table

CREATE TABLE magic_links (
  id TEXT PRIMARY KEY,
  user_email TEXT NOT NULL,
  token TEXT NOT NULL UNIQUE,
  expires_at INTEGER NOT NULL,
  used INTEGER DEFAULT 0,
  used_at INTEGER,
  created_at INTEGER NOT NULL,
  ip_address TEXT,
  user_agent TEXT
)

Security Features

Token Generation Tokens are generated using crypto.randomUUID() twice and concatenated for maximum entropy

Rate Limiting Limits users to 5 magic link requests per hour to prevent abuse

Expiration Links automatically expire after 15 minutes

One-Time Use Each link can only be used once - it's marked as used immediately after verification

IP Tracking IP addresses and user agents are logged for security auditing

Usage Example

Adding Magic Link to Login Page

<form id="magicLinkForm">
  <label>Email Address</label>
  <input type="email" name="email" required />
  <button type="submit">Send Magic Link</button>
</form>

<script>
document.getElementById('magicLinkForm').addEventListener('submit', async (e) => {
  e.preventDefault()
  const email = new FormData(e.target).get('email')

  const response = await fetch('/auth/magic-link/request', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email })
  })

  if (response.ok) {
    alert('Check your email for a magic link!')
  }
})
</script>

Email Template

The magic link email includes:

  • A prominent "Sign In" button with the magic link
  • Expiration time warning
  • Security notice if the user didn't request it
  • Modern, responsive design

Media Plugin

The media plugin provides comprehensive media file management with cloud storage integration.

Features

  • File Upload - Upload images, videos, and documents to R2 storage
  • Media Library - Browse and search uploaded media files
  • Image Processing - Resize, compress, and transform images
  • Folder Organization - Organize files into folders
  • Metadata Extraction - Automatic extraction of file metadata
  • Thumbnail Generation - Auto-generate thumbnails for images
  • Bulk Operations - Move, delete, and process multiple files

Configuration

Plugin Configuration

{
  name: 'core-media',
  version: '1.0.0-beta.1',
  settings: {
    maxFileSize: 10485760,        // Max file size (10MB)
    allowedTypes: [                // Allowed MIME types
      'image/jpeg',
      'image/png',
      'image/gif',
      'image/webp',
      'video/mp4',
      'application/pdf'
    ],
    thumbnailSize: { width: 300, height: 300 },
    storageProvider: 'r2',        // Storage backend
    autoGenerateThumbnails: true
  }
}

API Endpoints

GET /api/media List media files with pagination and filtering

List Media

curl "http://localhost:8787/api/media?page=1&limit=20&type=image"

POST /api/media/upload Upload a new media file

Upload File

const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('folder', 'images')

const response = await fetch('http://localhost:8787/api/media/upload', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`
  },
  body: formData
})

const { data } = await response.json()
// data: { id, filename, url, size, type }

GET /api/media/:id Get media file information and metadata

DELETE /api/media/:id Delete a media file

POST /api/media/process Process media (resize, compress, transform)

POST /api/media/create-folder Create a new folder for organization

POST /api/media/bulk-move Move multiple files to a folder

Services

Media Service

const mediaService = {
  // Upload file to storage
  uploadFile(file: File, options?: UploadOptions): Promise<MediaFile>

  // Delete file from storage
  deleteFile(id: string): Promise<boolean>

  // Process image with operations
  processImage(id: string, operations: Operation[]): Promise<Job>

  // Extract file metadata
  getMetadata(id: string): Promise<Metadata>
}

Database Schema

Media Files Table

CREATE TABLE media_files (
  id INTEGER PRIMARY KEY,
  filename TEXT NOT NULL,
  original_name TEXT NOT NULL,
  mime_type TEXT NOT NULL,
  size INTEGER NOT NULL,
  url TEXT NOT NULL,
  thumbnail_url TEXT,
  metadata TEXT,
  uploaded_by INTEGER,
  tags TEXT,
  created_at INTEGER NOT NULL,
  updated_at INTEGER
)

Hooks

  • media:upload - Triggered when file is uploaded (auto-generates thumbnails)
  • media:delete - Triggered when file is deleted (cleanup related files)
  • content:save - Tracks media references in content

Admin Pages

  • /admin/media - Media library browser
  • /admin/media/upload - File upload interface
  • /admin/media/settings - Media processing configuration

Cache Plugin

The cache plugin implements a sophisticated three-tier caching system for optimal performance.

Features

  • Three-Tier Caching - Memory, Cloudflare KV, and D1 database
  • Automatic Invalidation - Event-based cache invalidation
  • Cache Namespaces - Separate caches for different data types
  • Performance Metrics - Hit rates, latency, and usage statistics
  • Cache Warming - Pre-populate cache with frequently accessed data
  • Pattern Invalidation - Invalidate by wildcard patterns
  • TTL Management - Configurable time-to-live per namespace

Architecture

Request

Memory Cache? ──Yes──→ Return (< 1ms)
   ↓ No
KV Cache? ──Yes──→ Populate Memory → Return (10-50ms)
   ↓ No
Database ──→ Populate KV → Populate Memory → Return (100-200ms)

Configuration

Cache Configuration

{
  name: 'cache',
  version: '1.0.0-alpha.1',
  settings: {
    memoryEnabled: true,          // Enable in-memory cache
    kvEnabled: false,             // Enable KV cache
    defaultTTL: 3600,             // Default TTL (1 hour)
    maxMemorySize: 50,            // Max memory cache size (MB)
    namespaces: {
      content: { ttl: 3600 },     // Content cache (1 hour)
      user: { ttl: 900 },          // User cache (15 minutes)
      api: { ttl: 300 }            // API response cache (5 minutes)
    }
  }
}

API Endpoints

GET /admin/cache/stats Get detailed cache statistics for all namespaces

Cache Stats

curl http://localhost:8787/admin/cache/stats

POST /admin/cache/clear Clear all cache entries across all tiers

POST /admin/cache/invalidate Invalidate cache entries matching a pattern

Invalidate Cache

curl -X POST http://localhost:8787/admin/cache/invalidate \
  -H "Content-Type: application/json" \
  -d '{
    "pattern": "content:*",
    "namespace": "content"
  }'

GET /admin/cache/browser Browse and inspect individual cache entries

POST /admin/cache/warm Pre-populate cache with frequently accessed data

Usage in Code

Using Cache Service

import { getCacheService } from '@sonicjs-cms/core'

// Get cache service for your namespace
const cache = getCacheService({
  namespace: 'my-plugin',
  ttl: 600,
  memoryEnabled: true,
  kvEnabled: false,
  invalidateOn: ['my-plugin:update'],
  version: 'v1'
})

// Get value from cache
const data = await cache.get('key')

// Set value in cache
await cache.set('key', data)

// Get or set pattern
const result = await cache.getOrSet('key', async () => {
  return await fetchExpensiveData()
})

// Invalidate by pattern
await cache.invalidate('user:*')

// Get statistics
const stats = cache.getStats()

Cache Namespaces

content - Content and pages (TTL: 1 hour) user - User data and profiles (TTL: 15 minutes) api - API response data (TTL: 5 minutes) media - Media file metadata (TTL: 1 hour) auth - Authentication tokens (TTL: 5 minutes)

Hooks

  • content:update - Invalidates content cache
  • content:delete - Invalidates content cache
  • user:update - Invalidates user cache
  • auth:login - Invalidates user cache

Database Tools

The database tools plugin provides administrative utilities for database management and development.

Features

  • Migration Runner - Execute database migrations
  • Schema Browser - View tables, columns, and indexes
  • Query Console - Execute SQL queries directly
  • Table Inspector - View table data and statistics
  • Backup and Restore - Database backup utilities
  • Performance Metrics - Query performance analysis

Configuration

Plugin Configuration

{
  name: 'database-tools-plugin',
  version: '1.0.0',
  settings: {
    enableQueryConsole: true,     // Enable SQL query console
    maxQueryRows: 1000,           // Max rows returned
    enableBackups: true,          // Enable backup functionality
    autoMigration: true           // Auto-run migrations on startup
  }
}

API Endpoints

GET /admin/database/tables List all database tables

GET /admin/database/tables/:name View table schema and data

POST /admin/database/query Execute a SQL query

Execute Query

curl -X POST http://localhost:8787/admin/database/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${token}" \
  -d '{
    "query": "SELECT * FROM content LIMIT 10"
  }'

POST /admin/database/migrations/run Run pending migrations

GET /admin/database/migrations/status Check migration status

Services

Database Service

const databaseService = {
  // List all tables
  getTables(): Promise<Table[]>

  // Get table schema
  getTableSchema(tableName: string): Promise<Schema>

  // Execute query
  executeQuery(sql: string, params?: any[]): Promise<Result>

  // Run migrations
  runMigrations(): Promise<MigrationResult[]>

  // Create backup
  createBackup(): Promise<Backup>
}

Admin Pages

  • /admin/database - Database dashboard
  • /admin/database/tables - Table browser
  • /admin/database/query - Query console
  • /admin/database/migrations - Migration manager

Seed Data Plugin

The seed data plugin generates sample data for development and testing purposes.

Features

  • Sample Content - Generate blog posts, pages, and articles
  • Test Users - Create user accounts with various roles
  • Media Files - Generate placeholder images and files
  • Collections - Populate custom collections with data
  • Relationships - Create related data (users, posts, comments)
  • Customizable - Configure data generation parameters

Configuration

Plugin Configuration

{
  name: 'seed-data-plugin',
  version: '1.0.0',
  settings: {
    enabled: false,               // Disable in production
    autoSeed: false,             // Auto-seed on first run
    contentCount: 50,            // Number of content items
    userCount: 10,               // Number of test users
    mediaCount: 20               // Number of media files
  }
}

API Endpoints

POST /admin/seed-data/generate Generate seed data

Generate Seed Data

curl -X POST http://localhost:8787/admin/seed-data/generate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${token}" \
  -d '{
    "contentCount": 50,
    "userCount": 10,
    "mediaCount": 20,
    "clearExisting": false
  }'

POST /admin/seed-data/clear Clear all seed data

GET /admin/seed-data/status Check seed data status

Usage

Seed Data Generation

import { generateSeedData } from '@sonicjs-cms/core'

// Generate seed data programmatically
await generateSeedData({
  content: {
    count: 50,
    collections: ['blog_posts', 'pages']
  },
  users: {
    count: 10,
    roles: ['admin', 'editor', 'author']
  },
  media: {
    count: 20,
    types: ['image', 'video', 'document']
  }
})

Admin Pages

  • /admin/seed-data - Seed data generator interface

Next Steps

Was this page helpful?