Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c9c8807
Migrate to Livewire 4 SFCs and add optional passkeys support
produktive Jul 13, 2026
322be76
Update composer.lock for Livewire 4 and passkeys dependencies
produktive Jul 13, 2026
16151a7
Fix passkeys asset path for package dev mode
produktive Jul 13, 2026
2d7506d
Polish v3.0 release for upstream PR readiness.
produktive Jul 13, 2026
2087244
Fix CI test autoloading and document Livewire 4 event syntax.
produktive Jul 13, 2026
9db5755
Resolve Laravel bootstrap path from symlinked package tests.
produktive Jul 13, 2026
a517d88
Upgrade to Laravel 13, Livewire 4, convert Volt to SFC, deprecate Vol…
produktive Jul 16, 2026
2d42749
Name routes, implement middleware
produktive Jul 18, 2026
1950b6d
Name routes, implement middleware
produktive Jul 18, 2026
4e6d7fa
Merge branch 'main' into livewire-4-passkeys
produktive Jul 18, 2026
de8a2b5
Resyncing
produktive Jul 18, 2026
5d2478e
Update middleware, namespaces
produktive Jul 18, 2026
32ecf49
Fix middleware, passkeys setup
produktive Jul 19, 2026
d8aed64
Publish views
produktive Jul 19, 2026
9416a89
Publish views
produktive Jul 19, 2026
c0e9423
Publish views
produktive Jul 19, 2026
3c9410a
Fix layout attributes, remove passkeys from preview menu
produktive Jul 19, 2026
4cc7a0a
Merge branch 'thedevdojo:main' into main
produktive Jul 19, 2026
c27d87c
Merge branch 'main' into livewire-4-passkeys
produktive Jul 19, 2026
a1aa386
Merge pull request #1 from produktive/livewire-4-passkeys
produktive Jul 19, 2026
ad9d2b9
Update token/password reset route
produktive Jul 20, 2026
f3e009d
Fix login page
produktive Jul 20, 2026
a3b9bb2
Register the auth Blade component namespace for anonymous components.
produktive Jul 23, 2026
fab242d
Align passkeys config with Laravel Passkeys and fix throttle middleware.
produktive Jul 23, 2026
0fb8d02
Add passkey registration UI and optional reload-on-success for passke…
produktive Jul 23, 2026
0260f0f
Clean up login page Livewire component and apply guest preview middle…
produktive Jul 23, 2026
60fa356
Apply route middleware to Livewire auth pages.
produktive Jul 23, 2026
d05669e
Fix auth UI visibility for checkbox, button, and passkeys setup icon.
produktive Jul 23, 2026
ae85af5
Fix two-factor authentication page layout and button markup.
produktive Jul 23, 2026
07ebea4
Fix 2FA challenge middleware resolution in preview throttle pipeline.
produktive Jul 23, 2026
e211c70
Update composer.lock for Laravel and related dependency bumps.
produktive Jul 23, 2026
18dd79b
Resolve throttle middleware alias in 2FA preview pipeline.
produktive Jul 23, 2026
bf119dd
Remove dead middleware attributes from Livewire SFCs and restore veri…
produktive Jul 23, 2026
ab6d336
Fix two-factor code entry for Livewire 4.
produktive Jul 23, 2026
748b899
Merge pull request #3 from produktive/fix/livewire-sfc-route-middleware
produktive Jul 23, 2026
637062b
Replace Laravel Dusk with Pest 4 browser testing.
produktive Jul 23, 2026
0c2dd76
Fix feature test expectations for Laravel login route naming.
produktive Jul 23, 2026
51b2303
Use route-specific login redirect expectations in TwoFactorTest.
produktive Jul 23, 2026
3e1dbbc
Speed up CI Playwright setup and cache browser binaries.
produktive Jul 23, 2026
543a900
Replace Laravel Dusk with Pest 4 browser testing (#4)
produktive Jul 23, 2026
e21a3fc
Fix unreadable two-factor recovery codes text color.
produktive Jul 23, 2026
1732a1a
Merge pull request #5 from produktive/fix/2fa-recovery-codes-text-color
produktive Jul 23, 2026
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
50 changes: 22 additions & 28 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-version: ["8.2", "8.3", "8.4", "8.5"]
php-version: ["8.3", "8.4", "8.5"]

steps:
- uses: actions/checkout@v6
Expand All @@ -21,7 +21,12 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, xml, ctype, iconv, mysql, imagick
extensions: mbstring, xml, ctype, iconv, mysql, imagick, sockets

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Cache Composer Packages
uses: actions/cache@v5
Expand Down Expand Up @@ -83,37 +88,26 @@ jobs:
- name: Install test dependencies
run: |
composer require --dev --no-progress --with-all-dependencies \
pestphp/pest \
larastan/larastan:^3.1 \
laravel/dusk \
alebatistella/duskapiconf \
protonemedia/laravel-dusk-fakes:^1.6
pestphp/pest:^4.0 \
pestphp/pest-plugin-laravel:^4.0 \
pestphp/pest-plugin-browser:^4.0 \
larastan/larastan:^3.1
working-directory: ./laravel_app_${{ matrix.php-version }}

- name: Set port number based on PHP version
run: |
if [[ "${{ matrix.php-version }}" == "8.2" ]]; then
echo "SERVER_PORT=8000" >> $GITHUB_ENV
elif [[ "${{ matrix.php-version }}" == "8.3" ]]; then
echo "SERVER_PORT=8001" >> $GITHUB_ENV
else
echo "SERVER_PORT=8002" >> $GITHUB_ENV
fi

- name: Start Chrome Driver and PHP Server
- name: Cache Playwright browsers
uses: actions/cache@v5
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-chromium-v1
restore-keys: |
playwright-${{ runner.os }}-

- name: Install Playwright
run: |
php artisan dusk:chrome-driver --detect &
./vendor/laravel/dusk/bin/chromedriver-linux &
php artisan serve --port=${{ env.SERVER_PORT }} --no-reload &
npm install playwright@latest --no-progress
npx playwright install chromium
working-directory: ./laravel_app_${{ matrix.php-version }}

- name: Run Tests
run: ./vendor/bin/pest --parallel
working-directory: ./laravel_app_${{ matrix.php-version }}

- name: Run Dusk Tests
env:
APP_URL: "http://127.0.0.1:${{ env.SERVER_PORT }}"
APP_ENV: testing
run: php artisan dusk -vvv
working-directory: ./laravel_app_${{ matrix.php-version }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
vendor/
node_modules/
.DS_Store
.idea/
tests/Browser/Screenshots
tests/Browser/screenshots
30 changes: 27 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
# Changelog

All notable changes to `auth` will be documented in this file
## 3.0.0 - Unreleased

## 1.0.0 - 201X-XX-XX
### Breaking Changes

- initial release
- Requires Livewire 4 (`^4.0`). Livewire 3 is no longer supported.
- Removed `livewire/volt` and `laravel/folio` dependencies.
- Auth pages are now Livewire 4 single-file components registered via `Livewire::addLocation()`.
- Minimum PHP version is now 8.2.
- Minimum Laravel version is now 12 (Laravel 13 is also supported).
- Published auth assets must be republished after upgrading. See [UPGRADE.md](UPGRADE.md).

### Added

- Optional passkey authentication via `laravel/passkeys`.
- New `/auth/setup/passkeys` configuration screen to enable or disable passkey sign-in.
- `enable_passkeys` setting in `config/devdojo/auth/settings.php`.
- `auth:passkeys-config` publish tag for passkeys configuration.

### Changed

- Migrated all authentication pages from Volt/Folio to Livewire 4 SFCs.
- `Devdojo\Auth\Models\User` now implements `PasskeyUser` and uses `PasskeyAuthenticatable`.
- Setup preview modal now uses `fixed` positioning so it renders above the settings panel.
- Setup pages use Livewire 4 event syntax (`$event.target`) for toggles and inputs.

### Fixed

- Setup preview modal no longer appears behind the settings page when published assets are current.
- PHPStan configuration and `User` model property annotations.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ class User extends Devdojo\Auth\Models\User
}
```

## (Optional) Enabling Passkeys

Passkeys are disabled by default. To enable passwordless sign-in:

1. Publish the passkeys config:

```
php artisan vendor:publish --tag=auth:passkeys-config
```

2. Publish and run the passkeys migration:

```
php artisan vendor:publish --tag=passkeys-migrations --provider="Laravel\Passkeys\PasskeysServiceProvider"
php artisan migrate
```

3. Visit `/auth/setup/passkeys` and enable **Passkey Sign-In**.

Your `App\Models\User` should extend `Devdojo\Auth\Models\User`, which already includes the required `PasskeyAuthenticatable` trait.

## Upgrading from 2.x

See [UPGRADE.md](UPGRADE.md) for the v3.0 migration guide.

## License

The DevDojo Auth package is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
96 changes: 96 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Upgrading to 3.0

Version 3.0 is a breaking release. Plan for dependency updates, asset republishing, and page customizations to move from Volt/Folio to Livewire 4.

## Requirements

- PHP 8.2+
- Laravel 12 or 13
- Livewire 4 (`^4.0`)

## Upgrade steps

### 1. Update dependencies

```bash
composer require devdojo/auth:^3.0 livewire/livewire:^4.0
```

Volt and Folio are no longer required by this package. You may keep them in your app for unrelated features.

`laravel/passkeys` is included as a dependency. Passkey UI remains disabled until you enable it in `/auth/setup/passkeys`.

### 2. Republish package files

```bash
php artisan vendor:publish --tag=auth:config
php artisan vendor:publish --tag=auth:assets --force
php artisan vendor:publish --tag=auth:migrations
php artisan migrate
```

Republishing `auth:assets` is required after upgrading. The setup UI uses Tailwind v4 class names in `public/auth/build/assets/styles.css`.

### 3. Update customized auth pages

Auth screens are now Livewire 4 single-file components registered from the package via `Livewire::addLocation()`.

If you previously customized Volt/Folio pages under `resources/views/pages/auth/`, move them to the same paths and register an additional Livewire location in your app service provider:

```php
use Livewire\Livewire;

Livewire::addLocation(viewPath: resource_path('views/pages'));
```

Your application views take precedence when registered after the package provider.

To override Blade components without copying entire pages, publish to `resources/views/vendor/auth/`.

If your customized setup pages use Livewire event handlers, update Livewire 3 syntax to Livewire 4:

```blade
{{-- Before (Livewire 3) --}}
wire:change="update('key', $el.checked)"
wire:blur="update('key', $el.value)"

{{-- After (Livewire 4) --}}
wire:change="update('key', $event.target.checked)"
wire:blur="update('key', $event.target.value)"
```

Package setup pages already use `$event.target`. Alpine `$el` references inside `x-data` blocks are unchanged.

### 4. Optional: enable passkeys

```bash
php artisan vendor:publish --tag=auth:passkeys-config
php artisan vendor:publish --tag=passkeys-migrations --provider="Laravel\Passkeys\PasskeysServiceProvider"
php artisan migrate
```

Then visit `/auth/setup/passkeys` and enable **Passkey Sign-In**.

Your `App\Models\User` should extend `Devdojo\Auth\Models\User`, which already includes `PasskeyAuthenticatable`.

### 5. Clear caches

```bash
php artisan config:clear
php artisan view:clear
php artisan route:clear
```

## What changed

| Area | v2.x | v3.0 |
| --- | --- | --- |
| Page routing | Volt + Folio | Livewire 4 SFCs |
| Livewire | 3.x | 4.x |
| Passkeys | Not included | Optional via `enable_passkeys` |
| Setup preview modal | `absolute` + custom z-index | `fixed` + standard z-index utilities |
| Setup event handlers | `$el.checked` / `$el.value` | `$event.target.checked` / `$event.target.value` |

## Need help?

Open a discussion at [devdojo.com/questions](https://devdojo.com/questions) or review the [documentation](https://devdojo.com/auth/docs).
38 changes: 17 additions & 21 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,40 @@
}
],
"require": {
"php": "^7.4|^8.0|^8.1|^8.2|^8.3|^8.4",
"illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
"laravel/folio": "^1.0",
"livewire/livewire": "^3.0|^4.0",
"livewire/volt": "^1.10",
"php": "^8.2|^8.3|^8.4|^8.5",
"bacon/bacon-qr-code": "^3.0",
"calebporzio/sushi": "^2.5",
"codeat3/blade-phosphor-icons": "^2.0",
"devdojo/config-writer": "^0.0.7",
"illuminate/support": "^12.0|^13.0",
"laravel/passkeys": "^0.2.1",
"laravel/socialite": "^5.0",
"calebporzio/sushi": "^2.5",
"pragmarx/google2fa": "^8.0|^9.0",
"bacon/bacon-qr-code": "^3.0"
"livewire/livewire": "^4.0",
"pragmarx/google2fa": "^9.0"
},
"require-dev": {
"laravel/pint": "^1.15",
"orchestra/testbench": "^9.0",
"pestphp/pest": "^3.7",
"pestphp/pest-plugin-laravel": "^3.1",
"larastan/larastan": "^2.0",
"phpstan/phpstan": "^1.11",
"laravel/dusk": "^8.2",
"protonemedia/laravel-dusk-fakes": "^1.6",
"alebatistella/duskapiconf": "^1.2"
"orchestra/testbench": "^10.0|^11.0",
"pestphp/pest": "^3.7|^4.0",
"pestphp/pest-plugin-browser": "^4.0",
"pestphp/pest-plugin-laravel": "^3.1|^4.0",
"larastan/larastan": "^3.0",
"phpstan/phpstan": "^2.0"
},
"autoload": {
"psr-4": {
"Devdojo\\Auth\\": "src",
"Devdojo\\Auth\\Tests\\": "tests"
"Tests\\": "tests"
}
},
"autoload-dev": {
"psr-4": {
"Devdojo\\Auth\\Tests\\": "tests"
"Tests\\": "tests"
}
},
"scripts": {
"test": "vendor/bin/phpunit",
"test-coverage": "vendor/bin/phpunit --coverage-html coverage"

"test": "vendor/bin/pest",
"test-coverage": "vendor/bin/pest --coverage"
},
"config": {
"sort-packages": true,
Expand Down
Loading
Loading