Admin

Account Sync (Panel → Mail)

How Opterius Panel's Go agent automatically keeps Opterius Mail's account database in sync with Panel account changes.

Last updated 2026-04-12
  • Response Codes
  • Standalone Mode
  • Configuration
  • Sync Direction Is One-Way
  • Triggering a Full Resync
  • Troubleshooting
  • Account Sync (Panel → Mail)

    When Opterius Panel creates, modifies, or deletes an email account, it automatically notifies Opterius Mail via an internal HTTP API call. This keeps the mail_accounts and mail_domains tables in sync without any manual intervention.

    How It Works

    User/Admin performs action in Opterius Panel
           ↓
    Panel's Go agent handles the operation
    (creates Dovecot account, provisions Maildir, etc.)
           ↓
    Agent posts to Opterius Mail's sync endpoint:
    POST http://127.0.0.1:8090/api/sync/account
    Headers: X-Sync-Secret: {MAIL_SYNC_SECRET}
    Body: JSON payload describing the action
           ↓
    Opterius Mail validates the secret and processes the sync
           ↓
    mail_accounts / mail_domains tables updated
    

    The call is made on 127.0.0.1 (loopback) — the agent and Opterius Mail are on the same server in a standard deployment. The X-Sync-Secret header is a shared 32-character hex secret that proves the request comes from a trusted source.

    API Endpoint

    POST /api/sync/account
    Host: 127.0.0.1:8090
    X-Sync-Secret: {MAIL_SYNC_SECRET}
    Content-Type: application/json
    

    Action: create

    Creates or updates a domain and account record.

    {
        "action":   "create",
        "email":    "jane@example.com",
        "password": "$2y$12$...",
        "quota_mb": 1024,
        "domain":   "example.com"
    }
    

    Behaviour:

    • Upserts the mail_domains row for example.com (creates if absent, no-op if present).
    • Upserts the mail_accounts row — creates if new, updates password + quota if account already exists.

    Action: delete

    Soft-deletes an account (marks it inactive; does not remove Maildir data).

    {
        "action": "delete",
        "email":  "jane@example.com"
    }
    

    The account row remains in the database with deleted_at set. The account can no longer authenticate via IMAP. Maildir data on disk is managed by the Panel agent separately.

    Action: password

    Updates the stored password hash for an existing account.

    {
        "action":   "password",
        "email":    "jane@example.com",
        "password": "$2y$12$..."
    }
    

    Called when a user changes their password in the Panel. Overwrites any password previously set in Opterius Mail's admin panel.

    Response Codes

    HTTP status Meaning
    200 OK Sync processed successfully
    401 Unauthorized X-Sync-Secret header is missing or does not match MAIL_SYNC_SECRET
    404 Not Found MAIL_SYNC_SECRET is not configured in Opterius Mail (standalone mode)
    422 Unprocessable Entity Request body is malformed or missing required fields

    Standalone Mode

    If MAIL_SYNC_SECRET is not set in Opterius Mail's .env, the entire sync route is unregistered and returns 404. This is intentional — it makes standalone mode (no Panel) safe without additional firewall rules.

    In standalone mode, accounts are created and managed manually in the Opterius Mail admin panel.

    Configuration

    Automatic (Installer)

    When installed via the Opterius Panel installer, the sync secret is generated and configured in both places automatically:

    • Panel agent config: mail_sync_secret=...
    • Opterius Mail .env: MAIL_SYNC_SECRET=...

    Manual Setup

    Step 1 — Generate the secret

    openssl rand -hex 32
    # Example: b7e2a1c9d4f38...
    

    Step 2 — Add to Opterius Mail's .env

    MAIL_SYNC_SECRET=b7e2a1c9d4f38...
    

    Step 3 — Add to the Panel agent config

    Edit /opt/opterius-agent/config.yaml (or equivalent):

    mail_sync_secret: "b7e2a1c9d4f38..."
    mail_url: "http://127.0.0.1:8090"
    

    Step 4 — Clear config cache

    cd /opt/opterius-mail
    php artisan config:clear
    

    Step 5 — Restart the Panel agent

    sudo systemctl restart opterius-agent
    

    Sync Direction Is One-Way

    The sync is strictly Panel → Mail. Opterius Mail never pushes changes back to the Panel. This means:

    • Password resets performed in the Opterius Mail admin panel are not sent to the Panel. They will be overwritten the next time the Panel syncs that account.
    • Quota changes in Opterius Mail are not reflected in the Panel.
    • If you need to make a change that persists, make it in the Panel, not in Opterius Mail.

    Triggering a Full Resync

    If the mail_accounts database is lost or corrupted, trigger a full resync from all accounts:

    # On the Panel server — forces agent to resync all email accounts
    opterius-agent resync-mail
    
    # Or target a specific domain
    opterius-agent resync-mail --domain=example.com
    

    Troubleshooting

    Sync Events Not Arriving

    Check the agent log on the Panel server:

    tail -f /var/log/opterius-agent.log
    

    Look for sync_account entries. Common errors:

    • connection refused — Opterius Mail is not running or not listening on port 8090.
    • 401 UnauthorizedMAIL_SYNC_SECRET mismatch.
    • 404 Not FoundMAIL_SYNC_SECRET not set in Mail's .env.

    Verifying the Secret Manually

    curl -s -X POST http://127.0.0.1:8090/api/sync/account \
      -H "X-Sync-Secret: your-secret-here" \
      -H "Content-Type: application/json" \
      -d '{"action":"create","email":"test@example.com","password":"$2y$12$test","quota_mb":1024,"domain":"example.com"}' \
      -w "\nHTTP %{http_code}\n"
    

    A 200 response confirms the endpoint is reachable and the secret matches.