Ty Clifford 5ca55bf7c1 - Playback: Fixed future Chrome recordings in cyberchat-app.js (line 865):
Records one finalized WebM instead of 250ms fragments.
Waits for final audio data before releasing the microphone.
Handles startup/finalization failures cleanly.
Bumped frontend cache version to .8.
Verified JavaScript syntax, JSON, browser rendering, and no console 
errors. Existing uploaded clips remain unchanged. A real microphone test 
wasn’t available in the browser runner.
References: MDN MediaRecorder, Chromium WebM metadata issue.
2026-06-09 11:19:28 -04:00
2026-06-08 12:26:08 -04:00
2026-06-08 12:26:08 -04:00
2026-06-09 02:21:42 -04:00
2026-06-09 05:29:15 -04:00
2026-06-09 02:21:42 -04:00

CyberChat 2.2.0

CyberChat 2.2.0 is the current baseline release. It is a framework-free PHP, SQLite, JavaScript, and HTML5 chat application with text and voice messaging, configurable service tiers, Stripe subscriptions, Mailgun email verification, private archives, resilient queued polling, an administrator dashboard, and optional FFmpeg and MySQL/MariaDB integrations.

Current Capabilities

Chat and Interface

  • Authenticated public chat with text and voice messages
  • Reply-to controls for text and voice with configurable thread depth
  • Chronological message reconciliation with the newest message at the bottom
  • Single-worker cursor polling with catch-up batches, deduplication, request timeouts, retry backoff, and immediate wake-up after sending
  • Poll recovery when the browser returns online or the tab becomes visible
  • Configurable poll interval, timeout, maximum retry delay, batch size, and browser message limit
  • Online-user count and connection-status indicator
  • Configurable message and username length limits
  • Automatic link detection for HTTP and HTTPS URLs
  • Dark cyberpunk interface with neon green, blue, purple, pink, red, and orange accents
  • Saved light-mode toggle
  • Configurable application title, subtitle, and username color palette
  • Embeddable frontend through CyberChat.init()

Voice and Audio

  • Browser microphone recording with a configurable duration and upload-size limit
  • Per-tier recording and FFmpeg output bitrate from 48 to 320 kbps
  • WebM/Opus recording by default on supported browsers
  • MP4/AAC and AAC recording fallback for Safari and iPhone
  • Upload validation for WebM, WAV, MP4/M4A, and AAC
  • Recording preview with explicit send and discard controls
  • Configurable automatic voice sending by tier
  • Configurable recording-status indication by tier; entitled users can both send and see the is recording... status
  • Configurable sequential playback of newly received voice clips by tier
  • Saved per-browser automatic-play preference
  • Automatic-play queue recovery and a user notice when browser autoplay policy blocks playback
  • Custom cyberpunk audio player for chat and archives
  • Audio play/pause, seek bar, elapsed and total time, mute control, playback animation, and single-active-player behavior
  • MIME-aware <source> elements and inline mobile playback
  • Voice duration, MIME type, source filename, and storage path tracking
  • Administrator playback, filtering, manual archiving, deletion, file-size display, and missing-file indication
  • Optional FFmpeg transcoding with a configurable executable, bitrate, timeout, output profile, and source fallback
  • Recommended AAC-LC audio in an M4A container for iPhone, Safari, Android, and desktop playback
  • Optional MP4 profile with a small H.264 baseline video track and AAC-LC audio
  • Original browser recording retained when transcoding is disabled
  • Existing voice files remain unchanged when transcoding settings are enabled or modified

Accounts and Security

  • Registration with username and password; email is not required
  • Case-insensitive unique usernames using letters, numbers, underscores, and hyphens
  • Bcrypt password hashing with a configurable cost
  • Optional IP conflict restriction when an account already has an active session
  • Configurable session lifetime with HTTP-only, strict SameSite cookies and the secure flag under HTTPS
  • Email verification by six-digit code or verification link
  • Verified email required only before premium checkout
  • Unique verified email addresses
  • Mailgun-based email delivery through a reusable cURL mailer
  • Tier-configurable email two-factor authentication
  • Six-digit login challenges with expiration and attempt limits
  • Registration/login-only internal arithmetic CAPTCHA
  • Invisible registration/login honeypot fields that reject bot-like submissions
  • Optional Google reCAPTCHA v2 checkbox or v3 score/action verification
  • Account view for email verification, 2FA, plan details, billing, and current feature entitlements
  • Tier-configurable custom username colors
  • Administrator user creation, username/color/password editing, session termination, and deletion
  • CSRF protection on administrator actions

Plans and Subscriptions

  • Fully configurable plans, prices, currencies, billing intervals, descriptions, ordering, and active status
  • Dashboard creation of additional tiers
  • Per-tier feature toggles and archive retention
  • Current configurable entitlements:
    • Voice messages
    • Voice bitrate
    • Recording-status sending and viewing
    • Automatic voice send
    • Automatic voice play
    • Custom username color
    • Text archive retention
    • Text export
    • Voice archive access
    • Voice export
    • Email 2FA
  • Stripe Price ID assignment per paid tier
  • Stripe Checkout with promotion-code support
  • Stripe Billing Portal for payment details and plan management
  • Subscription cancellation at the end of the billing period
  • Signed webhook verification and duplicate event protection
  • Stripe customer, subscription, status, plan, billing-period end, and cancellation-state synchronization
  • Paid statuses include active, trialing, and past due
  • Global subscription visibility switch
  • New plans and checkout are hidden when subscriptions are disabled
  • Existing Stripe customers retain billing-management and cancellation access while new subscriptions are hidden
  • Administrator tier overrides that grant features without payment and take precedence over Stripe
  • Subscriber table showing email verification, effective plan, status, period end, cancellation state, and Stripe customer ID

Archives and Exports

  • Automatic prior-day SQLite archival during chat activity
  • Configurable archive path using year, month, and day placeholders
  • Authenticated personal archive; users can access only their own messages
  • Minimum text retention of 30 days, configurable upward by tier
  • Search across live and archived personal messages
  • Voice history included only when the tier has voice archive access
  • JSON and CSV exports when the tier has text export access
  • Voice URLs included in exports only when the tier has voice export access
  • Administrator archive-day browser with user and message filters
  • Administrator editing and deletion of archived messages
  • Manual movement of live voice clips into the appropriate daily archive
  • Whole-day archive deletion with associated voice-file cleanup
  • Legacy public archive browser redirects to the authenticated personal archive

Administrator Dashboard

  • Password-protected dashboard with configurable administrator password
  • Overview totals for users, live messages, voice clips, daily messages, sessions, and active users
  • Recent-message and recent-user panels
  • Searchable live-message management by user, text, day, and message type
  • Edit displayed sender and message text
  • Individual, bulk, day-level, and full live-message deletion
  • Dedicated voice library covering live and archived clips
  • Voice filters by user, date, and source
  • Voice playback, format, duration, file-size, archive, deletion, and missing-file status
  • Archive list with message totals and database file sizes
  • User creation and account editing
  • Manual tier assignment without Stripe payment
  • User kicking and deletion
  • Active and expired session inspection
  • Individual, expired, and all-session termination
  • Plans, pricing, Stripe, Mailgun, FFmpeg, subscription visibility, and MySQL configuration
  • Subscriber tracking and 30-day event totals
  • Live config.json editor with JSON validation and formatting
  • Manual MySQL mirror action

Storage, Statistics, and Integration

  • SQLite is the required primary database
  • Automatic schema creation and additive migrations
  • SQLite WAL mode and foreign-key enforcement
  • Dynamic/searchable records stored in SQLite
  • Runtime/service settings stored in dashboard-editable JSON
  • Optional MySQL/MariaDB mirror of the main and archive SQLite databases
  • Configurable automatic mirror interval and manual mirror execution
  • Visitor and feature event tracking with salted IP hashes and truncated user agents
  • Statistics can be disabled globally
  • Apache and Nginx examples include protected internal paths and audio MIME mappings
  • Diagnostic endpoint for PHP, SQLite, JSON configuration, storage permissions, and session support

Groups and group navigation have been removed from the application and plan system.

Requirements

  • PHP 8.1 or newer
  • PHP extensions: pdo_sqlite, curl, and fileinfo
  • PHP functions proc_open and proc_terminate when FFmpeg transcoding is enabled
  • A web server with HTTPS for production
  • Write access to db/, archive/, uploads/voice/, and config.json
  • A modern browser with MediaRecorder for voice recording
  • Optional: FFmpeg with AAC support
  • Optional: FFmpeg compiled with libx264 for the H.264 profile
  • Optional: PDO MySQL for the MySQL/MariaDB mirror

Installation

  1. Place the application in the web root.
  2. Make the runtime directories and configuration writable by the web-server user.
  3. Configure Apache with the included .htaccess, or adapt nginx-example.conf.
  4. Visit api/ping.php and resolve any failed permission or PHP checks.
  5. Open admin.php and sign in with the initial password changeme123.
  6. Immediately change admin.password in the Configuration tab.
  7. Open Plans & Platform to configure tiers, Mailgun, Stripe, optional voice transcoding, and MySQL mirroring.

The SQLite schema and default Free, Plus, and Pro tiers are created automatically on first use.

For simple shared hosting:

chmod 0777 db archive uploads/voice

For a managed server, ownership is preferable:

chown -R www-data:www-data db archive uploads/voice
chmod -R 0770 db archive uploads/voice

Replace www-data with the PHP-FPM or web-server account. SQLite must be able to create the database plus its -wal and -shm sidecar files. When the application directory is restricted, database.main_db may use an absolute path to a writable persistent directory.

Default Tiers

The defaults are starting points. Plans, prices, and every listed entitlement can be changed in the dashboard.

Feature Free Plus Pro
Voice messages Yes Yes Yes
Voice bitrate 64 kbps 96 kbps 128 kbps
Recording status send/view No Yes Yes
Automatic voice send No Yes Yes
Automatic voice play No Yes Yes
Custom username color No Yes Yes
Text archive 30 days 90 days 365 days
Text export Yes Yes Yes
Voice archive No Yes Yes
Voice export No Yes Yes
Email 2FA No Yes Yes

Administrators can assign a tier directly from Admin > Users > Edit > Tier Override. The override does not alter Stripe billing and remains effective until changed back to Follow Stripe / billing status.

Audio Configuration

Global audio settings are under Admin > Config and Admin > Plans & Platform > Voice Transcoding / FFmpeg.

Important settings:

Setting Purpose
voice.enabled Globally show or hide voice recording controls
voice.max_duration_seconds Maximum accepted recording duration
voice.max_upload_bytes Maximum uploaded voice-file size
voice.auto_play_default Initial automatic-play preference for entitled users
voice.upload_dir Voice-file storage path
voice.transcoding.enabled Enable server-side FFmpeg conversion
voice.transcoding.ffmpeg_path FFmpeg executable name or absolute path
voice.transcoding.profile m4a_aac or mp4_h264_aac
voice.transcoding.audio_bitrate_kbps Fallback AAC bitrate when no tier override is supplied
voice.transcoding.timeout_seconds Conversion timeout from 5 to 300 seconds
voice.transcoding.fallback_to_source Keep the source file if conversion fails

Recording selection is browser-driven:

  1. WebM with Opus
  2. WebM
  3. MP4 with AAC-LC
  4. MP4
  5. AAC
  6. Browser default MediaRecorder format

The recorder collects one finalized blob at stop instead of concatenating short live WebM slices. This avoids Chrome-generated fragment metadata that other browsers may reject.

When FFmpeg is disabled, the accepted browser recording is stored unchanged. WebM remains the preferred default when the browser supports it. Safari and iPhone can upload MP4/AAC directly.

When FFmpeg is enabled:

  • m4a_aac produces audio-only AAC-LC in an M4A container and is the recommended compatibility profile.
  • mp4_h264_aac adds a 16-by-16 black H.264 baseline video track with AAC-LC audio for systems requiring conventional MP4.
  • New uploads are converted; existing files are not rewritten.
  • The original file can be retained automatically if FFmpeg fails.

The authenticated user's voice_bitrate_kbps tier entitlement controls the browser MediaRecorder target and overrides the FFmpeg fallback bitrate for new clips.

The web server must serve .webm, .wav, .aac, .m4a, and .mp4 with the MIME mappings shown in .htaccess and nginx-example.conf.

Mailgun

Configure these fields under Admin > Plans & Platform:

  • API key
  • Sending domain
  • From address
  • API base, normally https://api.mailgun.net/v3
  • EU API base when applicable: https://api.eu.mailgun.net/v3

The reusable mailer in lib/mailer.php sends:

  • Email verification codes and links that expire after 30 minutes
  • Login 2FA codes and authentication links that expire after 10 minutes

Verification and login challenges are attempt-limited. When a verified account already has a Stripe customer, changing the verified email also updates that Stripe customer.

Mailgun API reference: https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages

Stripe

  1. Create recurring Stripe Prices for paid tiers.

  2. Enter each price_... ID in the matching dashboard plan.

  3. Enter the Stripe secret key and webhook signing secret.

  4. Optionally set success, cancel, and Billing Portal return URLs.

  5. Add this webhook endpoint:

    https://YOUR-DOMAIN/YOUR-PATH/api/stripe-webhook.php

  6. Subscribe the endpoint to:

    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.paid
    • invoice.payment_failed

Checkout is rejected until the account has a verified email. Stripe customer and subscription IDs, status, current period end, cancellation state, and selected plan are synchronized into SQLite.

When subscriptions.enabled is false, plans and checkout are hidden from new customers. Existing Stripe customers retain Billing Portal and cancellation access.

Stripe references:

Archives and Retention

The application moves prior-day live messages into daily SQLite databases:

archive/{year}/{month}/{day}.sqlite

User archive behavior:

  • Only the authenticated user's own messages are returned.
  • Retention is controlled by text_archive_days and cannot be configured below 30 days through the plan dashboard.
  • Search covers eligible live and archived messages.
  • Voice rows are excluded unless voice_archive is enabled for the tier.
  • JSON and CSV exports require text_export.
  • Voice URLs in exports additionally require voice_export.

Voice files remain in uploads/voice/ while their metadata moves between live and archive databases. Administrator deletion actions remove the associated recording file.

Reply IDs, reply depth, parent previews, and voice bitrate metadata are retained in daily archives and personal JSON/CSV exports.

CAPTCHA

CAPTCHA checks are scoped to registration and initial password login. Email 2FA code verification, chat messages, account updates, and dashboard actions do not invoke CAPTCHA.

Dashboard controls under Plans & Platform > Registration / Login CAPTCHA configure:

  • Registration and login protection independently
  • Invisible honeypot protection
  • Internal arithmetic challenge difficulty, expiration, and attempt limit
  • Google reCAPTCHA v2 checkbox or v3 score mode
  • Google site key, secret key, expected hostname, and v3 minimum score

Google tokens are verified server-side through the Siteverify API. For v3, CyberChat also validates the expected register or login action and the configured score threshold.

Google references:

Polling and Message Ordering

CyberChat uses one polling worker per active chat view:

  • A numeric message cursor requests only records after the last acknowledged ID.
  • Catch-up batches continue immediately while more messages are available.
  • A message map deduplicates repeated send and poll responses.
  • DOM reconciliation sorts by created_at and then message ID.
  • Existing nodes are reordered when necessary, keeping the latest message at the bottom.
  • Poll requests have a configurable abort timeout.
  • Repeated failures use bounded exponential retry delays.
  • Sending, reconnecting, and returning to the tab wake the worker immediately.
  • The browser retains only the configured maximum number of rendered messages.

This design avoids overlapping poll requests, duplicate voice players, and temporary message-order inversions.

Administrator Areas

Area Capabilities
Dashboard Usage totals, active users, recent messages, recent users, quick links
Messages Search/filter, audio playback, edit, individual/bulk/day/all deletion
Voice Clips Search live and archived audio, play, inspect, archive, delete
Archives Browse days, inspect file sizes, filter/edit/delete messages, delete days
Users Create users, edit credentials/colors, assign tiers, kick, delete
Sessions Inspect active/expired sessions and terminate one, expired, or all
Plans & Platform Plans, pricing, bitrate, replies, CAPTCHA, Stripe, Mailgun, FFmpeg, MySQL, statistics
Config Edit and validate config.json directly

Configuration Families

config.json is editable through Admin > Config. The primary groups are:

  • app: installation base URL
  • chat: text limits, polling, browser buffer, replies, and session restrictions
  • archive: archive enablement and directory
  • voice: recording, upload, playback defaults, storage, and FFmpeg
  • database: main SQLite path, archive template, and optional MySQL mirror
  • ui: application title and subtitle
  • security: password, session, bcrypt, CORS, and registration/login CAPTCHA settings
  • subscriptions: new-subscription visibility
  • mailgun: verification and 2FA delivery
  • stripe: Checkout, webhook, and Billing Portal settings
  • stats: usage tracking and IP hashing
  • admin: dashboard password
  • colors: random user-color palette

Service credentials are stored in config.json; protect that file from direct web access and restrict its filesystem permissions.

MySQL/MariaDB Mirror

SQLite remains the required primary database. The optional mirror imports the main database and all archive databases into sqlite_mirror_rows using:

  • Source database path
  • Source table
  • Row key
  • JSON row data
  • Synchronization time

Set a PDO MySQL DSN, username, and password in the dashboard. Enable the mirror and optionally automatic import. The configured interval has a minimum of 60 seconds. Run MySQL Mirror Now performs a manual synchronization.

Statistics and Diagnostics

When stats.enabled is true, the application records visits, registrations, login outcomes, text messages, voice messages, and other named events. IP addresses are stored only as salted SHA-256 hashes.

The administrator dashboard shows:

  • Visits during the previous 24 hours
  • Unique hashed visitors during the previous 24 hours
  • Paid subscriber count
  • Event totals during the previous 30 days

Open api/ping.php to check:

  • PHP version
  • PDO SQLite
  • config.json existence, writability, and JSON validity
  • Main database directory and file permissions
  • Archive directory permissions
  • SQLite database creation and WAL support
  • PHP session availability

The diagnostic endpoint exposes deployment details and should be restricted or removed after setup on sensitive installations.

Embedding

<link rel="stylesheet" href="/chat/assets/css/cyberchat.css?v=20260609.4">
<div id="my-chat" style="width:100%;height:600px"></div>
<script>
  window.CYBERCHAT_BASE = '/chat';
</script>
<script src="/chat/assets/js/cyberchat-app.js?v=20260609.8"></script>
<script>
  CyberChat.init('#my-chat');
</script>

See embed-example.html for a complete example.

Main Files

admin.php                    Administrator dashboard and moderation tools
bootstrap.php                Configuration, schema, auth, plans, archives, stats
config.json                  Runtime settings and service credentials
index.html                   Standalone chat entry page
embed-example.html           Embedding example
nginx-example.conf           Nginx deployment and MIME configuration
api/account.php              Email, color, and 2FA settings
api/archive.php              Private personal archive and export
api/auth.php                 Registration, login, 2FA, and sessions
api/billing.php              Stripe checkout, portal, and cancellation
api/config.php               Public-safe frontend configuration
api/messages.php             Text, voice, polling, and recording presence
api/ping.php                 PHP, SQLite, and permission diagnostics
api/stats.php                Usage event intake
api/stripe-webhook.php       Stripe event synchronization
assets/css/cyberchat.css     Cyberpunk and light interface themes
assets/js/cyberchat-app.js   Browser chat, audio player, polling, and account UI
lib/admin_platform.php       Plans and platform dashboard module
lib/mailer.php               Reusable Mailgun sender
lib/mysql_mirror.php         Optional SQLite-to-MySQL mirror
lib/stripe.php               Stripe REST client and subscription sync
lib/voice_transcoder.php     Optional FFmpeg voice compatibility pipeline

Production Security

  • Change the default administrator password and statistics salt.
  • Use a stronger production value than the default minimum password length.
  • Serve the application only over HTTPS.
  • Keep .htaccess rules enabled or reproduce every deny and MIME rule in the server configuration.
  • Never expose config.json, db/, archive/, or lib/.
  • Restrict or remove api/ping.php after deployment verification.
  • Use separate Stripe test and live credentials and webhook secrets.
  • Restrict admin.php by IP or additional HTTP authentication where practical.
  • Limit write access to the PHP/web-server account.
  • Back up the main SQLite database, archive databases, config.json, and voice files together.
  • Test FFmpeg and Stripe configuration in a non-production environment before enabling them.
S
Description
Chat system behind chat.tyclifford.com
https://chat.tyclifford.com
Readme Unlicense 204 KiB
2026-06-12 01:06:27 +00:00
Languages
PHP 69.9%
JavaScript 17.1%
CSS 10.1%
HTML 2.9%