makaveli/laravel-login-history

Advanced Login History for Laravel

Maintainers

Package info

github.com/Ma1kaveli/laravel-login-history

pkg:composer/makaveli/laravel-login-history

Statistics

Installs: 8

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

1.1.4 2026-03-28 11:21 UTC

This package is auto-updated.

Last update: 2026-03-28 11:22:04 UTC


README

Packagist Version Packagist Downloads License

🌍 Languages

Table of Contents

  1. Introduction
  2. Requirements
  3. Installation
  4. Configuration
  5. Core Components
  6. Database Schema
  7. Quick Start
  8. Integration with BaseRepository
  9. Extending the Package
  10. Recommendations
  11. Useful Links

Introduction

makaveli/laravel-login-history is a Laravel package that provides advanced logging of user authentication events. It records the user ID and a fingerprint – structured data about the session or device used to log in. The package supports asynchronous logging via queues, flexible filtering, pagination, and integrates seamlessly with makaveli/laravel-core and makaveli/laravel-query-builder.

Key features:

  • Recording login history with user binding and arbitrary JSON fingerprint.
  • Asynchronous logging through Laravel queues.
  • Filtering and pagination of login history data.
  • Console commands to generate test data and run migrations.
  • Configurable support for roles and organizations (optional).
  • Easy adaptation via filter transformers.

Requirements

Installation

  1. Install the package via Composer:

    composer require makaveli/laravel-login-history
  2. (Optional) Publish the configuration file to customize settings:

    php artisan vendor:publish --tag=login-history-config

    This will copy the configuration file to config/login-history.php.

  3. Run the package migrations to create the history table:

    php artisan migrate:login-history

    This creates the users.user_login_histories table.

Configuration

The file config/login-history.php allows you to configure the following parameters:

Parameter Description Default
user_model User model class App\Models\User::class
search_filter_fields Model fields to search via the search parameter ['name', 'patronymic', 'family_name', 'phone', 'email']
with_role Whether the user model has a role relationship (affects role filtering) true
with_organization Whether the role model has an organization_id field (affects organization filtering) true
advanced_filters Callback for adding custom filters null
user_login_history Number of test records generated by the seeder 100
transformers Array of functions to transform filter parameters []
user_resource Resource class for formatting user data [\App\Modules\Base\Resources\UserShortResource::class, 'once']

Example configuration:

return [
    'user_model' => App\Modules\Base\Models\User::class,
    'search_filter_fields' => ['name', 'patronymic', 'family_name', 'phone', 'email'],
    'with_role' => true,
    'advanced_filters' => function (\LoginHistory\Filters\UserLoginHistoryFilters $self) {
        $self->applyInteger('user_id');
    },
    'with_organization' => true,
    'user_login_history' => env('USER_LOGIN_HISTORY_FACTORY', 100),
    'transformers' => [
        'role_id' => [\App\Modules\Role\Helpers\TransformRoleFilter::class, 'getRealRoleIdFromListRequest'],
        'user_id' => [\App\Modules\User\Helpers\TransformUserFilter::class, 'getRealUserIdFromListRequest'],
        'organization_id' => [\App\Modules\Organization\Helpers\TransformOrganizationFilter::class, 'getRealOrganizationIdFromListRequest'],
    ],
    'user_resource' => [\App\Modules\Base\Resources\UserShortResource::class, 'once'],
];

Core Components

LoginHistory Trait

The trait is added to the controller or any class where authentication occurs. It provides two methods:

  • writeLoginHistory(Request $request, ?Authenticatable $user = null): Synchronous history record.
  • writeAsyncLoginHistory(Request $request, ?Authenticatable $user = null): Asynchronous record via queue.
use LoginHistory\Traits\LoginHistory;

class AuthController extends Controller
{
    use LoginHistory;

    public function login(Request $request)
    {
        // ... authentication ...
        $this->writeLoginHistory($request);
        // or $this->writeAsyncLoginHistory($request);
    }
}

If no user is explicitly passed, the method uses auth()->user().

UserLoginHistoryActions

An action class that encapsulates the history writing logic. Can be used without the trait:

$actions = new UserLoginHistoryActions();
$actions->writeToHistory($user, $request);

UserLoginHistoryRepository

The repository for working with the UserLoginHistory model. It extends BaseRepository from makaveli/laravel-core and adds a getPaginatedList method that accepts a UserLoginHistoryListDTO and returns a paginated result.

use LoginHistory\Repositories\UserLoginHistoryRepository;
use LoginHistory\DTO\UserLoginHistoryListDTO;

$repository = new UserLoginHistoryRepository();
$dto = UserLoginHistoryListDTO::fromRequest($request);
$paginator = $repository->getPaginatedList($dto);

UserLoginHistoryListDTO

A DTO for filtering the login history list. It extracts parameters from the request and applies transformers (if defined). Supported fields:

Parameter Type Description
dateFrom string Start date (Y-m-d)
dateTo string End date (Y-m-d)
roleId int Filter by role ID (requires with_role = true)
userId int Filter by user ID
organizationId int Filter by organization ID (requires with_role = true and with_organization = true)
search string Search across fields defined in search_filter_fields

Transformers (functions in the config) allow modifying these parameter values based on the current user’s permissions.

Filters

The package uses makaveli/laravel-query-builder. The UserLoginHistoryFilters class (extends BaseQueryBuilder) applies filters based on the DTO. You can extend it via the advanced_filters configuration parameter by providing a callback.

Example of adding a custom filter:

'advanced_filters' => function (\LoginHistory\Filters\UserLoginHistoryFilters $self) {
    $self->applyInteger('user_id');
},

Resources

  • UserLoginHistoryResource: Formats a single history record. By default it includes id, fingerprint, created_at, and the user formatted via user_resource.
  • PaginatedCollection from laravel-query-builder is used for pagination.

Console Commands

Command Description
php artisan seed:test-user-login-histories Creates test history records (count set by user_login_history)
php artisan migrate:login-history Runs the package migrations

Database Schema

The package creates the table users.user_login_histories:

Column Type Description
id bigint (PK) Auto‑increment ID
user_id bigint (FK) ID of the user who logged in
fingerprint jsonb Arbitrary session/device data
created_at timestamp Login time
updated_at timestamp Last update time

Quick Start

1. Configure the package (if needed)

Edit config/login-history.php – specify the correct user model, search fields, user resource, etc.

2. Add the trait to your authentication controller

use LoginHistory\Traits\LoginHistory;

class AuthController extends Controller
{
    use LoginHistory;

    public function login(Request $request)
    {
        // ... credentials check ...
        if (auth()->attempt($credentials)) {
            // Record history (synchronously)
            $this->writeLoginHistory($request);
            // or asynchronously:
            // $this->writeAsyncLoginHistory($request);
            return response()->json(['message' => 'Login successful']);
        }
        return response()->json(['message' => 'Invalid credentials'], 401);
    }
}

3. Retrieve the history list in a controller

use LoginHistory\Repositories\UserLoginHistoryRepository;
use LoginHistory\DTO\UserLoginHistoryListDTO;
use QueryBuilder\Resources\PaginatedCollection;
use LoginHistory\Resources\UserLoginHistoryResource;

class UserLoginHistoryController extends Controller
{
    public function index(Request $request)
    {
        $dto = UserLoginHistoryListDTO::fromRequest($request);
        
        $repository = new UserLoginHistoryRepository();
        
        $paginator = $repository->getPaginatedList($dto);

        return new PaginatedCollection(
            $paginator,
            UserLoginHistoryResource::collection($paginator)
        );
    }
}

Integration with BaseRepository

UserLoginHistoryRepository already extends BaseRepository, so it can be used in a service provider or injected via the container. In a controller:

use LoginHistory\Repositories\UserLoginHistoryRepository;

class UserLoginHistoryController extends Controller
{
    public function __construct(
        private UserLoginHistoryRepository $repository
    ) {}

    public function index(Request $request)
    {
        $dto = UserLoginHistoryListDTO::fromRequest($request);
        
        $paginator = $this->repository->getPaginatedList($dto);
        
        return UserLoginHistoryResource::collection($paginator);
    }
}

The getPaginatedList method automatically applies the filters defined in the DTO and configuration.

Extending the Package

You can customize the package by overriding:

  • Model: Extend LoginHistory\Models\UserLoginHistory and bind your own model in a service provider if necessary.
  • Filters: Extend UserLoginHistoryFilters and override the list() method, or use advanced_filters to add custom conditions.
  • DTO: Create your own DTO extending UserLoginHistoryListDTO and override fromRequest.
  • Resources: Create your own resource class and use it in UserLoginHistoryResource (or directly in the controller).
  • Transformers: Define functions in the configuration to transform the role_id, user_id, and organization_id parameters.

Recommendations

  • Always configure user_model according to your actual user model.
  • Use asynchronous logging (writeAsyncLoginHistory) in production to avoid increasing response time.
  • Define transformers if you need to restrict data access based on the user’s role.
  • Adjust the search fields in search_filter_fields to match your user model.
  • When using roles and organizations, ensure your user model has the corresponding relationships.
  • Add database indexes on user_id and created_at for faster queries.

Useful Links