Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,16 @@ class User extends Authenticatable

The package automatically saves user devices when the `Authenticated` event is fired (on every authenticated request). No manual setup required—just add the `HasUserDevices` trait to your User model.

To ignore the new login notification via request context (e.g. in middleware or controller before authentication):
To skip saving the device entirely for a request (e.g. in middleware or controller before authentication):

```php
use UserDevices\DeviceCreator;

// In middleware or controller—call before the user is authenticated
DeviceCreator::ignoreListener();
```

To ignore only the new login notification (device is still saved, but no email is sent):

```php
use UserDevices\DeviceCreator;
Expand Down Expand Up @@ -154,7 +163,7 @@ This will:

- Create or update the device record (IP + user agent)
- Update last activity timestamp
- Send a notification email on **first login** from that device (unless `ignoreNotification()` was called or `shouldSendNotificationUsing()` returns false)
- Send a notification email on **first login** from that device (unless `ignoreListener()` was called, or `ignoreNotification()` was called, or `shouldSendNotificationUsing()` returns false)

#### 3. Block Device Route

Expand Down Expand Up @@ -226,8 +235,9 @@ DeviceCreator::useUserDeviceModel(string $model): void
DeviceCreator::userAgentUsing(Closure $callback): void
DeviceCreator::shouldSendNotificationUsing(Closure $callback): void // (user, device) => bool

// Methods
DeviceCreator::ignoreNotification(): void // Add to Context to skip notification for current request
// Request context (call before authentication)
DeviceCreator::ignoreListener(): void // Skip saving the device for the current request
DeviceCreator::ignoreNotification(): void // Skip the new login notification for the current request
```

#### UserDevice Model
Expand Down
11 changes: 11 additions & 0 deletions src/DeviceCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ class DeviceCreator
*/
public static string $userDeviceModel = UserDevice::class;

/**
* Add a flag to the request context so the new login device listener is skipped.
*
* Call this before authentication (e.g. in middleware or controller) when you
* want to skip saving the device for this request.
*/
public static function ignoreListener(): void
{
Context::add('user_devices.ignore_listener', true);
}

/**
* Add a flag to the request context to ignore the new login device notification.
*
Expand Down
4 changes: 4 additions & 0 deletions src/Listeners/SaveUserDevice.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public function handle(Authenticated $event): void
/** @var mixed $user */
$user = $event->user;

if (Context::get('user_devices.ignore_listener', false)) {
return;
}

if (! in_array(HasUserDevices::class, class_uses_recursive($user))) {
return;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/Feature/UserDevicesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@
expect($user->userDevices)->toHaveCount(1);
});

test('it should not save user device when ignoreListener is called via context', function () {
$user = User::factory()->create();

expect($user->userDevices)->toHaveCount(0);

DeviceCreator::ignoreListener();

$this->actingAs($user)->get('/dashboard');

$user->refresh();
expect($user->userDevices)->toHaveCount(0);
});

test('it should not send notification when ignoreNotification is called via context', function () {
Notification::fake();

Expand Down
6 changes: 6 additions & 0 deletions tests/Unit/DeviceCreatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
expect(DeviceCreator::$userAgent)->toBe($callback);
});

test('it should add ignore listener flag to context', function () {
DeviceCreator::ignoreListener();

expect(Context::get('user_devices.ignore_listener'))->toBeTrue();
});

test('it should add ignore notification flag to context', function () {
DeviceCreator::ignoreNotification();

Expand Down