madbox-99/laravel-user-team-sync

User and team synchronization between a subscriber hub and secondary Laravel apps

Installs: 32

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/madbox-99/laravel-user-team-sync

v1.3.0 2026-02-12 11:42 UTC

This package is auto-updated.

Last update: 2026-02-13 12:31:20 UTC


README

Laravel package for synchronizing users and teams across multiple Laravel applications using a Publisher/Receiver pattern.

Requirements

  • PHP 8.3+
  • Laravel 11 or 12

Installation

composer require madbox-99/laravel-user-team-sync

Then run the install command:

php artisan user-team-sync:install

This will:

  • Ask for your sync mode (publisher/receiver/both)
  • Generate or accept an API key
  • Update your .env file
  • Publish the config and migration files
  • Optionally run migrations

Manual Installation

If you prefer to install manually:

php artisan vendor:publish --tag=user-team-sync-config
php artisan vendor:publish --tag=user-team-sync-migrations
php artisan migrate

Then add these to your .env:

USER_TEAM_SYNC_MODE=receiver
USER_TEAM_SYNC_API_KEY=your-secret-key

Configuration

Modes

Mode Description
publisher Sends sync events to other apps
receiver Receives sync events from a publisher
both Sends and receives

Publisher Setup

Set mode to publisher. Receiver apps can be stored in the config file or in the database.

Option A: Config-based apps (default)

Define apps in config/user-team-sync.php:

'publisher' => [
    'app_source' => 'config', // default
    'api_key' => env('USER_TEAM_SYNC_API_KEY'),
    'apps' => [
        'crm' => [
            'url' => env('CRM_APP_URL'),
            'api_key' => env('CRM_APP_API_KEY'), // optional, falls back to default
            'active' => true,
        ],
        'shop' => [
            'url' => env('SHOP_APP_URL'),
            'api_key' => env('SHOP_APP_API_KEY'),
            'active' => true,
        ],
    ],
],

Option B: Database-based apps (recommended)

Store apps in the sync_apps table for dynamic management:

USER_TEAM_SYNC_APP_SOURCE=database

The install command (php artisan user-team-sync:install) can set this up interactively, or you can manage apps manually:

use Madbox99\UserTeamSync\Models\SyncApp;

// Add a new app
SyncApp::create([
    'name' => 'crm',
    'url' => 'https://crm.example.com',
    'api_key' => 'secret-key', // stored encrypted
    'is_active' => true,
]);

// Deactivate an app
SyncApp::where('name', 'crm')->update(['is_active' => false]);

API keys are stored using Laravel's encrypted cast. Make sure your APP_KEY is set.

Receiver Setup

Set mode to receiver and configure the API key:

'receiver' => [
    'api_key' => env('USER_TEAM_SYNC_API_KEY'),
    'route_prefix' => 'api',
    'role_driver' => 'spatie',
    'default_role' => 'subscriber',
    'default_active' => false,
],

The receiver API key must match the publisher's key for that app.

Usage

Automatic Sync (Observer)

When auto_observe is enabled (default), the package automatically watches your User model for changes to configured fields (email, role by default) and syncs them to all active receiver apps.

// This automatically triggers sync to all receiver apps
$user->update(['role' => 'admin']);

Manual Sync via Facade

use Madbox99\UserTeamSync\Facades\UserTeamSync;

// Create a user on all receiver apps
UserTeamSync::createUser(
    email: 'john@example.com',
    name: 'John Doe',
    password: 'plain-text-password', // hashed automatically before sending
    role: 'editor',
    ownerEmail: 'owner@example.com',
);

// Sync user changes
UserTeamSync::syncUser('john@example.com', [
    'new_email' => 'john.doe@example.com',
    'role' => 'admin',
]);

// Create a team on all receiver apps
UserTeamSync::createTeam(
    teamName: 'Marketing',
    userEmail: 'john@example.com',
    slug: 'marketing', // optional, auto-generated from name
);

// Toggle user active status on a specific app
UserTeamSync::toggleUserActive(
    userEmail: 'john@example.com',
    isActive: true,
    appKey: 'crm',
);

API Endpoints (Receiver)

All endpoints are protected by Bearer token authentication.

Method Endpoint Description
POST /api/create-user Create a new user
POST /api/sync-user Update user fields
POST /api/toggle-user-active Set active/inactive status
POST /api/create-team Create a team
GET /api/user-teams Get user's teams
POST /api/sync-password Sync password hash

Events

Listen to these events for custom logic:

Event When
UserCreatedFromSync User created on receiver
UserSynced User fields updated
PasswordSynced Password synced to receiver
UserActiveToggled Active status changed
TeamCreatedFromSync Team created on receiver
SyncFailed Any sync operation failed
// In EventServiceProvider or listener
use Madbox99\UserTeamSync\Events\UserCreatedFromSync;

class HandleSyncedUser
{
    public function handle(UserCreatedFromSync $event): void
    {
        // $event->user
    }
}

Logging

All sync operations are logged to the sync_logs table. Configure in config/user-team-sync.php:

'logging' => [
    'enabled' => true,
    'table' => 'sync_logs',
    'retention_days' => 30,
],

Environment Variables

Variable Description Default
USER_TEAM_SYNC_MODE Sync mode receiver
USER_TEAM_SYNC_API_KEY API key for authentication
USER_TEAM_SYNC_APP_SOURCE App storage: config or database config
USER_TEAM_SYNC_USER_MODEL User model class App\Models\User
USER_TEAM_SYNC_TEAM_MODEL Team model class App\Models\Team
USER_TEAM_SYNC_QUEUE Queue name for jobs default
USER_TEAM_SYNC_QUEUE_CONNECTION Queue connection null
USER_TEAM_SYNC_TRIES Job retry attempts 3
USER_TEAM_SYNC_BACKOFF Seconds between retries 60
USER_TEAM_SYNC_TIMEOUT HTTP timeout in seconds 10

Testing

vendor/bin/pest

License

MIT License. See LICENSE for details.