Skip to content

Commit

Permalink
Merge pull request #102 from rappasoft/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rappasoft committed Mar 30, 2024
2 parents ab9c521 + b4322c9 commit a916caa
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 11 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to `Laravel Authentication Log` will be documented in this file.

### 4.0.0 - 2024-03-28

- Laravel 11 Support (https://github.com/rappasoft/laravel-authentication-log/pull/100)
- Add config listeners (https://github.com/rappasoft/laravel-authentication-log/pull/92)
- Use real user IP behind Cloudflare
- Check for AuthenticationLoggable trait on event (https://github.com/rappasoft/laravel-authentication-log/pull/94)
- Added PHPDocs to allow autocompletion in IDE (https://github.com/rappasoft/laravel-authentication-log/pull/80)
- Fixes the down method for php artisan migrate:rollback (https://github.com/rappasoft/laravel-authentication-log/pull/93)

### 3.0.0 - 2023-02-23

- Laravel 10 Support - https://github.com/rappasoft/laravel-authentication-log/pull/70
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
![Package Logo](https://banners.beyondco.de/Laravel%20Authentication%20Log.png?theme=dark&packageManager=composer+require&packageName=rappasoft%2Flaravel-authentication-log&pattern=hideout&style=style_1&description=Log+user+authentication+details+and+send+new+device+notifications.&md=1&showWatermark=0&fontSize=100px&images=lock-closed)

[![Latest Version on Packagist](https://img.shields.io/packagist/v/rappasoft/laravel-authentication-log.svg?style=flat-square)](https://packagist.org/packages/rappasoft/laravel-authentication-log)
[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/rappasoft/laravel-authentication-log/run-tests?label=tests)](https://github.com/rappasoft/laravel-authentication-log/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/rappasoft/laravel-authentication-log/Check%20&%20fix%20styling?label=code%20style)](https://github.com/rappasoft/laravel-authentication-log/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/rappasoft/laravel-authentication-log.svg?style=flat-square)](https://packagist.org/packages/rappasoft/laravel-authentication-log)

Laravel Authentication Log is a package which tracks your user's authentication information such as login/logout time, IP, Browser, Location, etc. as well as sends out notifications via mail, slack, or sms for new devices and failed logins.
Expand All @@ -18,6 +16,7 @@ See the [documentation](https://rappasoft.com/docs/laravel-authentication-log) f
8.x | 1.x
9.x | 2.x
10.x | 3.x
11.x | 4.x

## Installation

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
],
"require": {
"php": "^8.1",
"illuminate/contracts": "^10.0",
"illuminate/contracts": "^10.0|^11.0",
"spatie/laravel-package-tools": "^1.4.3"
},
"require-dev": {
Expand Down
16 changes: 16 additions & 0 deletions config/authentication-log.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
'logout-other-devices' => \Illuminate\Auth\Events\OtherDeviceLogout::class,
],

'listeners' => [
'login' => \Rappasoft\LaravelAuthenticationLog\Listeners\LoginListener::class,
'failed' => \Rappasoft\LaravelAuthenticationLog\Listeners\FailedLoginListener::class,
'logout' => \Rappasoft\LaravelAuthenticationLog\Listeners\LogoutListener::class,
'logout-other-devices' => \Rappasoft\LaravelAuthenticationLog\Listeners\OtherDeviceLogoutListener::class,
],

'notifications' => [
'new-device' => [
// Send the NewDevice notification
Expand All @@ -42,4 +49,13 @@
// When the clean-up command is run, delete old logs greater than `purge` days
// Don't schedule the clean-up command if you want to keep logs forever.
'purge' => 365,

// If you are behind an CDN proxy, set 'behind_cdn.http_header_field' to the corresponding http header field of your cdn
// For cloudflare you can have look at: https://developers.cloudflare.com/fundamentals/get-started/reference/http-request-headers/
// 'behind_cdn' => [
// 'http_header_field' => 'HTTP_CF_CONNECTING_IP' // used by Cloudflare
// ],

// If you are not a cdn user, use false
'behind_cdn' => false,
];
5 changes: 5 additions & 0 deletions database/migrations/create_authentication_log_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ return new class extends Migration
$table->json('location')->nullable();
});
}

public function down(): void
{
Schema::dropIfExists(config('authentication-log.table_name'));
}
};
14 changes: 14 additions & 0 deletions resources/lang/pt_BR.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"A failed login to your account": "Um login com falha em sua conta",
"Account:": "Conta",
"Browser:": "Navegador:",
"If this was you, you can ignore this alert. If you suspect any suspicious activity on your account, please change your password.": "Se foi você, pode ignorar este alerta. Se você suspeitar de qualquer atividade suspeita em sua conta, altere sua senha.",
"IP Address:": "Endereço de IP:",
"Location:": "Localização:",
"Regards,": "Obrigado,",
"There has been a failed login attempt to your :app account.": "Houve uma falha na tentativa de login em seu :app conta.",
"Time:": "Data:",
"Unknown City": "Cidade Desconhecida",
"Unknown State": "Estado Desconhecido",
"Your :app account logged in from a new device.": "Sua :app foi acessada em um novo dispositivo"
}
8 changes: 4 additions & 4 deletions src/LaravelAuthenticationLogServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public function configurePackage(Package $package): void
->hasCommand(PurgeAuthenticationLogCommand::class);

$events = $this->app->make(Dispatcher::class);
$events->listen(config('authentication-log.events.login', Login::class), LoginListener::class);
$events->listen(config('authentication-log.events.failed', Failed::class), FailedLoginListener::class);
$events->listen(config('authentication-log.events.logout', Logout::class), LogoutListener::class);
$events->listen(config('authentication-log.events.other-device-logout', OtherDeviceLogout::class), OtherDeviceLogoutListener::class);
$events->listen(config('authentication-log.events.login', Login::class), config('authentication-log.listeners.login', LoginListener::class));
$events->listen(config('authentication-log.events.failed', Failed::class), config('authentication-log.listeners.failed', FailedLoginListener::class));
$events->listen(config('authentication-log.events.logout', Logout::class), config('authentication-log.listeners.logout', LogoutListener::class));
$events->listen(config('authentication-log.events.other-device-logout', OtherDeviceLogout::class), config('authentication-log.listeners.other-device-logout', OtherDeviceLogoutListener::class));
}
}
14 changes: 13 additions & 1 deletion src/Listeners/FailedLoginListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Auth\Events\Failed;
use Illuminate\Http\Request;
use Rappasoft\LaravelAuthenticationLog\Notifications\FailedLogin;
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;

class FailedLoginListener
{
Expand All @@ -18,13 +19,24 @@ public function __construct(Request $request)
public function handle($event): void
{
$listener = config('authentication-log.events.failed', Failed::class);

if (! $event instanceof $listener) {
return;
}

if ($event->user) {
if(! in_array(AuthenticationLoggable::class, class_uses_recursive(get_class($event->user)))) {
return;
}

if (config('authentication-log.behind_cdn')) {
$ip = $this->request->server(config('authentication-log.behind_cdn.http_header_field'));
} else {
$ip = $this->request->ip();
}

$log = $event->user->authentications()->create([
'ip_address' => $ip = $this->request->ip(),
'ip_address' => $ip,
'user_agent' => $this->request->userAgent(),
'login_at' => now(),
'login_successful' => false,
Expand Down
13 changes: 12 additions & 1 deletion src/Listeners/LoginListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Rappasoft\LaravelAuthenticationLog\Notifications\NewDevice;
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;

class LoginListener
{
Expand All @@ -19,13 +20,23 @@ public function __construct(Request $request)
public function handle($event): void
{
$listener = config('authentication-log.events.login', Login::class);

if (! $event instanceof $listener) {
return;
}

if ($event->user) {
if(! in_array(AuthenticationLoggable::class, class_uses_recursive(get_class($event->user)))) {
return;
}

if (config('authentication-log.behind_cdn')) {
$ip = $this->request->server(config('authentication-log.behind_cdn.http_header_field'));
} else {
$ip = $this->request->ip();
}

$user = $event->user;
$ip = $this->request->ip();
$userAgent = $this->request->userAgent();
$known = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->whereLoginSuccessful(true)->first();
$newUser = Carbon::parse($user->{$user->getCreatedAtColumn()})->diffInMinutes(Carbon::now()) < 1;
Expand Down
14 changes: 13 additions & 1 deletion src/Listeners/LogoutListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Auth\Events\Logout;
use Illuminate\Http\Request;
use Rappasoft\LaravelAuthenticationLog\Models\AuthenticationLog;
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;

class LogoutListener
{
Expand All @@ -18,13 +19,24 @@ public function __construct(Request $request)
public function handle($event): void
{
$listener = config('authentication-log.events.logout', Logout::class);

if (! $event instanceof $listener) {
return;
}

if ($event->user) {
if(! in_array(AuthenticationLoggable::class, class_uses_recursive(get_class($event->user)))) {
return;
}

$user = $event->user;
$ip = $this->request->ip();

if (config('authentication-log.behind_cdn')) {
$ip = $this->request->server(config('authentication-log.behind_cdn.http_header_field'));
} else {
$ip = $this->request->ip();
}

$userAgent = $this->request->userAgent();
$log = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->orderByDesc('login_at')->first();

Expand Down
14 changes: 13 additions & 1 deletion src/Listeners/OtherDeviceLogoutListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Auth\Events\OtherDeviceLogout;
use Illuminate\Http\Request;
use Rappasoft\LaravelAuthenticationLog\Models\AuthenticationLog;
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;

class OtherDeviceLogoutListener
{
Expand All @@ -18,13 +19,24 @@ public function __construct(Request $request)
public function handle($event): void
{
$listener = config('authentication-log.events.other-device-logout', OtherDeviceLogout::class);

if (! $event instanceof $listener) {
return;
}

if ($event->user) {
if(! in_array(AuthenticationLoggable::class, class_uses_recursive(get_class($event->user)))) {
return;
}

$user = $event->user;
$ip = $this->request->ip();

if (config('authentication-log.behind_cdn')) {
$ip = $this->request->server(config('authentication-log.behind_cdn.http_header_field'));
} else {
$ip = $this->request->ip();
}

$userAgent = $this->request->userAgent();
$authenticationLog = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->first();

Expand Down
12 changes: 12 additions & 0 deletions src/Models/AuthenticationLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;

/**
* @property int $id
* @property string $authenticatable_type
* @property int $authenticatable_id
* @property string|null $ip_address
* @property string|null $user_agent
* @property \Illuminate\Support\Carbon|null $login_at
* @property bool $login_successful
* @property \Illuminate\Support\Carbon|null $logout_at
* @property bool $cleared_by_user
* @property array|null $location
*/
class AuthenticationLog extends Model
{
public $timestamps = false;
Expand Down

0 comments on commit a916caa

Please sign in to comment.