From ce209cd14d4d3985f734a0639e2b732c9f916a52 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 16 Jun 2026 11:46:56 +0000 Subject: [PATCH] Deps: Add passport --- .agents/skills/passport-development/SKILL.md | 205 ++++ .github/skills/passport-development/SKILL.md | 205 ++++ AGENTS.md | 3 +- CLAUDE.md | 3 +- boost.json | 1 + bootstrap/app.php | 1 + composer.json | 11 +- composer.lock | 948 +++++++++++++++++- config/auth.php | 4 + config/passport.php | 50 + ...6_114211_create_oauth_auth_codes_table.php | 41 + ...14212_create_oauth_access_tokens_table.php | 43 + ...4213_create_oauth_refresh_tokens_table.php | 39 + ...6_16_114214_create_oauth_clients_table.php | 44 + ...114215_create_oauth_device_codes_table.php | 44 + routes/api.php | 8 + 16 files changed, 1639 insertions(+), 11 deletions(-) create mode 100644 .agents/skills/passport-development/SKILL.md create mode 100644 .github/skills/passport-development/SKILL.md create mode 100644 config/passport.php create mode 100644 database/migrations/2026_06_16_114211_create_oauth_auth_codes_table.php create mode 100644 database/migrations/2026_06_16_114212_create_oauth_access_tokens_table.php create mode 100644 database/migrations/2026_06_16_114213_create_oauth_refresh_tokens_table.php create mode 100644 database/migrations/2026_06_16_114214_create_oauth_clients_table.php create mode 100644 database/migrations/2026_06_16_114215_create_oauth_device_codes_table.php create mode 100644 routes/api.php diff --git a/.agents/skills/passport-development/SKILL.md b/.agents/skills/passport-development/SKILL.md new file mode 100644 index 0000000..e5dce35 --- /dev/null +++ b/.agents/skills/passport-development/SKILL.md @@ -0,0 +1,205 @@ +--- +name: passport-development +description: "Develops OAuth2 API authentication with Laravel Passport. Activates when installing or configuring Passport; setting up OAuth2 grants (authorization code, client credentials, personal access tokens, device authorization); managing OAuth clients; protecting API routes with token authentication; defining or checking token scopes; configuring SPA cookie authentication; handling token lifetimes and refresh tokens; or when the user mentions Passport, OAuth2, API tokens, bearer tokens, or API authentication. Make sure to use this skill whenever the user works with OAuth2, API tokens, or third-party API access, even if they don't explicitly mention Passport." +license: MIT +metadata: + author: laravel +--- + +# Passport OAuth2 Authentication + +## Documentation First + +**Always use `search-docs` before writing Passport code.** The documentation covers every grant type, configuration option, and edge case in detail. This skill teaches you how to navigate Passport — the docs have the implementation specifics. + +``` +search-docs(queries: ["Passport installation"], packages: ["laravel/framework@12.x"]) +``` + +The Passport docs live under the `laravel/framework` package — not `laravel/passport`. + +## When to Apply + +Activate this skill when: + +- Installing or configuring Passport +- Setting up OAuth2 authorization grants +- Creating or managing OAuth clients +- Protecting API routes with token authentication +- Defining or checking token scopes +- Configuring SPA cookie-based authentication +- Choosing between Passport and Sanctum + +## Passport vs. Sanctum + +**Passport** is a full OAuth2 server — use it when third-party applications need to consume your API and when you need OAuth2 authorization code grants, client credentials for machine-to-machine auth, or device authorization flow. + +**Sanctum** is simpler — use it when first-party SPAs, third parties, or mobile apps consume the API but you don't need the full OAuth2 grant flows. + +## Installation + +Three steps are always required: + +### 1. Install Passport + +```bash +php artisan install:api --passport +``` + +This publishes migrations, generates encryption keys, and registers routes. + +### 2. Configure the User model + +The User model needs both the `HasApiTokens` trait AND the `OAuthenticatable` interface. Missing the interface is the most common Passport setup mistake — it causes runtime errors that can be confusing to debug. + +```php +use Laravel\Passport\Contracts\OAuthenticatable; +use Laravel\Passport\HasApiTokens; + +class User extends Authenticatable implements OAuthenticatable +{ + use HasApiTokens; +} +``` + +### 3. Configure the auth guard + +The `api` guard must use the `passport` driver in `config/auth.php`. Using `token` or `sanctum` here silently breaks Passport authentication. + +```php +'guards' => [ + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], +], +``` + +## Choosing a Grant Type + +Matching the right grant to the use case is the most important Passport decision. Use `search-docs` for implementation details of any grant. + +| Use Case | Grant Type | Client Flag | +|----------|-----------|-------------| +| Third-party app accessing user data | Authorization Code | (default) | +| Mobile/SPA without client secret | Authorization Code + PKCE | `--public` | +| Machine-to-machine, no user context | Client Credentials | `--client` | +| User-generated API keys | Personal Access Tokens | `--personal` | +| Smart TV, CLI, IoT devices | Device Authorization | `--device` | + +**Legacy grants** (Password, Implicit) are disabled by default and not recommended. They must be explicitly enabled with `Passport::enablePasswordGrant()` or `Passport::enableImplicitGrant()`. + +## Client Management + +Create clients with the appropriate flag for the grant type: + +```bash +php artisan passport:client # Authorization code + +php artisan passport:client --public # PKCE (no secret) + +php artisan passport:client --client # Client credentials + +php artisan passport:client --personal # Personal access tokens + +php artisan passport:client --device # Device authorization + +``` + +Additional flags: `--name=`, `--redirect_uri=`, `--provider=`. + +Client secrets are hashed by default — the plain-text secret is only shown at creation time and cannot be retrieved later. + +## Protecting Routes + +Apply `auth:api` middleware. Clients send tokens via the `Authorization: Bearer ` header. + +```php +Route::get('/user', function (Request $request) { + return $request->user(); +})->middleware('auth:api'); +``` + +### Scope Enforcement + +Scope middleware must come alongside `auth:api`: + +- `CheckToken::using('scope1', 'scope2')` — requires ALL listed scopes +- `CheckTokenForAnyScope::using('scope1', 'scope2')` — requires ANY listed scope +- `EnsureClientIsResourceOwner::using('scope1')` — restricts to client credential tokens + +```php +use Laravel\Passport\Http\Middleware\CheckToken; + +Route::get('/orders', function () { + // ... +})->middleware(['auth:api', CheckToken::using('orders:read')]); +``` + +### Programmatic scope checking + +```php +if ($request->user()->tokenCan('place-orders')) { + // ... +} +``` + +Use `search-docs` for full scope middleware registration and usage patterns. + +## Key Configuration + +Configure in `AppServiceProvider::boot()`. Use `search-docs` for the full list of options. + +```php +// Token lifetimes (each is independent) +Passport::tokensExpireIn(now()->addDays(15)); +Passport::refreshTokensExpireIn(now()->addDays(30)); +Passport::personalAccessTokensExpireIn(now()->addMonths(6)); + +// Define scopes +Passport::tokensCan([ + 'place-orders' => 'Place orders', + 'check-status' => 'Check order status', +]); +``` + +## SPA Cookie Authentication + +For first-party SPAs, the `CreateFreshApiToken` middleware issues a `laravel_token` cookie containing an encrypted JWT. The SPA must include CSRF tokens — missing the `X-CSRF-TOKEN` or `X-XSRF-TOKEN` header causes 419 errors. + +Use `search-docs` for setup details — this feature has specific CSRF and cookie configuration requirements. + +## Testing + +Passport provides helpers to bypass full OAuth flows in tests: + +```php +Passport::actingAs($user, ['scope1', 'scope2']); +Passport::actingAsClient($client, ['scope1']); +``` + +## Token Maintenance + +```bash +php artisan passport:purge # Purge revoked & expired + +php artisan passport:purge --revoked # Only revoked + +php artisan passport:purge --expired # Only expired + +``` + +Schedule `passport:purge` for regular expired token clean-up. + +## Events + +All in `Laravel\Passport\Events`: `AccessTokenCreated`, `AccessTokenRevoked`, `RefreshTokenCreated`. + +## Common Pitfalls + +- **Missing `OAuthenticatable` interface** — both the `HasApiTokens` trait and the `OAuthenticatable` interface are required on the User model. Missing the interface causes runtime errors. +- **Wrong guard driver** — the `api` guard must use `passport`, not `token` or `sanctum`. This fails silently. +- **Token lifetime confusion** — access token, refresh token, and personal access token lifetimes are all independent settings. +- **Missing CSRF for SPA cookie auth** — `CreateFreshApiToken` requires CSRF tokens. Use `Passport::ignoreCsrfToken()` only if you understand the security implications. +- **Client secrets are hashed** — the plain-text secret is only available at creation time. +- **Legacy grants are disabled** — Password and Implicit grants must be explicitly enabled and are not recommended. diff --git a/.github/skills/passport-development/SKILL.md b/.github/skills/passport-development/SKILL.md new file mode 100644 index 0000000..e5dce35 --- /dev/null +++ b/.github/skills/passport-development/SKILL.md @@ -0,0 +1,205 @@ +--- +name: passport-development +description: "Develops OAuth2 API authentication with Laravel Passport. Activates when installing or configuring Passport; setting up OAuth2 grants (authorization code, client credentials, personal access tokens, device authorization); managing OAuth clients; protecting API routes with token authentication; defining or checking token scopes; configuring SPA cookie authentication; handling token lifetimes and refresh tokens; or when the user mentions Passport, OAuth2, API tokens, bearer tokens, or API authentication. Make sure to use this skill whenever the user works with OAuth2, API tokens, or third-party API access, even if they don't explicitly mention Passport." +license: MIT +metadata: + author: laravel +--- + +# Passport OAuth2 Authentication + +## Documentation First + +**Always use `search-docs` before writing Passport code.** The documentation covers every grant type, configuration option, and edge case in detail. This skill teaches you how to navigate Passport — the docs have the implementation specifics. + +``` +search-docs(queries: ["Passport installation"], packages: ["laravel/framework@12.x"]) +``` + +The Passport docs live under the `laravel/framework` package — not `laravel/passport`. + +## When to Apply + +Activate this skill when: + +- Installing or configuring Passport +- Setting up OAuth2 authorization grants +- Creating or managing OAuth clients +- Protecting API routes with token authentication +- Defining or checking token scopes +- Configuring SPA cookie-based authentication +- Choosing between Passport and Sanctum + +## Passport vs. Sanctum + +**Passport** is a full OAuth2 server — use it when third-party applications need to consume your API and when you need OAuth2 authorization code grants, client credentials for machine-to-machine auth, or device authorization flow. + +**Sanctum** is simpler — use it when first-party SPAs, third parties, or mobile apps consume the API but you don't need the full OAuth2 grant flows. + +## Installation + +Three steps are always required: + +### 1. Install Passport + +```bash +php artisan install:api --passport +``` + +This publishes migrations, generates encryption keys, and registers routes. + +### 2. Configure the User model + +The User model needs both the `HasApiTokens` trait AND the `OAuthenticatable` interface. Missing the interface is the most common Passport setup mistake — it causes runtime errors that can be confusing to debug. + +```php +use Laravel\Passport\Contracts\OAuthenticatable; +use Laravel\Passport\HasApiTokens; + +class User extends Authenticatable implements OAuthenticatable +{ + use HasApiTokens; +} +``` + +### 3. Configure the auth guard + +The `api` guard must use the `passport` driver in `config/auth.php`. Using `token` or `sanctum` here silently breaks Passport authentication. + +```php +'guards' => [ + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], +], +``` + +## Choosing a Grant Type + +Matching the right grant to the use case is the most important Passport decision. Use `search-docs` for implementation details of any grant. + +| Use Case | Grant Type | Client Flag | +|----------|-----------|-------------| +| Third-party app accessing user data | Authorization Code | (default) | +| Mobile/SPA without client secret | Authorization Code + PKCE | `--public` | +| Machine-to-machine, no user context | Client Credentials | `--client` | +| User-generated API keys | Personal Access Tokens | `--personal` | +| Smart TV, CLI, IoT devices | Device Authorization | `--device` | + +**Legacy grants** (Password, Implicit) are disabled by default and not recommended. They must be explicitly enabled with `Passport::enablePasswordGrant()` or `Passport::enableImplicitGrant()`. + +## Client Management + +Create clients with the appropriate flag for the grant type: + +```bash +php artisan passport:client # Authorization code + +php artisan passport:client --public # PKCE (no secret) + +php artisan passport:client --client # Client credentials + +php artisan passport:client --personal # Personal access tokens + +php artisan passport:client --device # Device authorization + +``` + +Additional flags: `--name=`, `--redirect_uri=`, `--provider=`. + +Client secrets are hashed by default — the plain-text secret is only shown at creation time and cannot be retrieved later. + +## Protecting Routes + +Apply `auth:api` middleware. Clients send tokens via the `Authorization: Bearer ` header. + +```php +Route::get('/user', function (Request $request) { + return $request->user(); +})->middleware('auth:api'); +``` + +### Scope Enforcement + +Scope middleware must come alongside `auth:api`: + +- `CheckToken::using('scope1', 'scope2')` — requires ALL listed scopes +- `CheckTokenForAnyScope::using('scope1', 'scope2')` — requires ANY listed scope +- `EnsureClientIsResourceOwner::using('scope1')` — restricts to client credential tokens + +```php +use Laravel\Passport\Http\Middleware\CheckToken; + +Route::get('/orders', function () { + // ... +})->middleware(['auth:api', CheckToken::using('orders:read')]); +``` + +### Programmatic scope checking + +```php +if ($request->user()->tokenCan('place-orders')) { + // ... +} +``` + +Use `search-docs` for full scope middleware registration and usage patterns. + +## Key Configuration + +Configure in `AppServiceProvider::boot()`. Use `search-docs` for the full list of options. + +```php +// Token lifetimes (each is independent) +Passport::tokensExpireIn(now()->addDays(15)); +Passport::refreshTokensExpireIn(now()->addDays(30)); +Passport::personalAccessTokensExpireIn(now()->addMonths(6)); + +// Define scopes +Passport::tokensCan([ + 'place-orders' => 'Place orders', + 'check-status' => 'Check order status', +]); +``` + +## SPA Cookie Authentication + +For first-party SPAs, the `CreateFreshApiToken` middleware issues a `laravel_token` cookie containing an encrypted JWT. The SPA must include CSRF tokens — missing the `X-CSRF-TOKEN` or `X-XSRF-TOKEN` header causes 419 errors. + +Use `search-docs` for setup details — this feature has specific CSRF and cookie configuration requirements. + +## Testing + +Passport provides helpers to bypass full OAuth flows in tests: + +```php +Passport::actingAs($user, ['scope1', 'scope2']); +Passport::actingAsClient($client, ['scope1']); +``` + +## Token Maintenance + +```bash +php artisan passport:purge # Purge revoked & expired + +php artisan passport:purge --revoked # Only revoked + +php artisan passport:purge --expired # Only expired + +``` + +Schedule `passport:purge` for regular expired token clean-up. + +## Events + +All in `Laravel\Passport\Events`: `AccessTokenCreated`, `AccessTokenRevoked`, `RefreshTokenCreated`. + +## Common Pitfalls + +- **Missing `OAuthenticatable` interface** — both the `HasApiTokens` trait and the `OAuthenticatable` interface are required on the User model. Missing the interface causes runtime errors. +- **Wrong guard driver** — the `api` guard must use `passport`, not `token` or `sanctum`. This fails silently. +- **Token lifetime confusion** — access token, refresh token, and personal access token lifetimes are all independent settings. +- **Missing CSRF for SPA cookie auth** — `CreateFreshApiToken` requires CSRF tokens. Use `Passport::ignoreCsrfToken()` only if you understand the security implications. +- **Client secrets are hashed** — the plain-text secret is only available at creation time. +- **Legacy grants are disabled** — Password and Implicit grants must be explicitly enabled and are not recommended. diff --git a/AGENTS.md b/AGENTS.md index f1c8848..faf73fc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,9 +9,10 @@ ## Foundational Context This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. -- php - 8.4 +- php - 8.5 - laravel/fortify (FORTIFY) - v1 - laravel/framework (LARAVEL) - v13 +- laravel/passport (PASSPORT) - v13 - laravel/prompts (PROMPTS) - v0 - livewire/flux (FLUXUI_FREE) - v2 - livewire/livewire (LIVEWIRE) - v4 diff --git a/CLAUDE.md b/CLAUDE.md index f1c8848..faf73fc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,9 +9,10 @@ ## Foundational Context This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. -- php - 8.4 +- php - 8.5 - laravel/fortify (FORTIFY) - v1 - laravel/framework (LARAVEL) - v13 +- laravel/passport (PASSPORT) - v13 - laravel/prompts (PROMPTS) - v0 - livewire/flux (FLUXUI_FREE) - v2 - livewire/livewire (LIVEWIRE) - v4 diff --git a/boost.json b/boost.json index 1129526..cd2f194 100644 --- a/boost.json +++ b/boost.json @@ -12,6 +12,7 @@ "skills": [ "fortify-development", "laravel-best-practices", + "passport-development", "fluxui-development", "livewire-development", "pest-testing", diff --git a/bootstrap/app.php b/bootstrap/app.php index ded1166..a0d6053 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -8,6 +8,7 @@ return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', + api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) diff --git a/composer.json b/composer.json index 5e338b9..f6c6508 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,14 @@ "license": "MIT", "require": { "php": "^8.3", + "ext-dom": "*", + "ext-libxml": "*", + "ext-openssl": "*", + "ext-zlib": "*", "gehrisandro/tailwind-merge-laravel": "^1.4", "laravel/fortify": "^1.34", "laravel/framework": "^13.7", + "laravel/passport": "^13.0", "laravel/tinker": "^3.0", "livewire/flux": "^2.13.1", "livewire/livewire": "^4.3", @@ -21,11 +26,7 @@ "robsontenorio/mary": "^2.8", "spatie/laravel-activitylog": "^5.0", "spatie/laravel-data": "^4.22", - "spatie/laravel-permission": "^7.4", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-dom": "*", - "ext-libxml": "*" + "spatie/laravel-permission": "^7.4" }, "require-dev": { "captainhook/captainhook": "^5.29", diff --git a/composer.lock b/composer.lock index effab57..1d4fc3b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "de341bcfc1ad1d03eb12923ae8f0a9d2", + "content-hash": "b3aa0d920261f901b2242b3f9b1afb8c", "packages": [ { "name": "bacon/bacon-qr-code", @@ -390,6 +390,73 @@ }, "time": "2025-09-16T12:23:56+00:00" }, + { + "name": "defuse/php-encryption", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/f53396c2d34225064647a05ca76c1da9d99e5828", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5|^6|^7|^8|^9|^10", + "yoast/phpunit-polyfills": "^2.0.0" + }, + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.4.0" + }, + "time": "2023-06-19T06:10:36+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -811,6 +878,72 @@ ], "time": "2025-03-06T22:45:56+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v7.1.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/php-jwt.git", + "reference": "b374a5d1a4f1f67fadc2165cdb284645945e2fc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/b374a5d1a4f1f67fadc2165cdb284645945e2fc0", + "reference": "b374a5d1a4f1f67fadc2165cdb284645945e2fc0", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", + "phpseclib/phpseclib": "~3.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", + "phpseclib/phpseclib": "Support PS256 (RSASSA-PSS) signatures" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/googleapis/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.1.0" + }, + "time": "2026-06-11T17:54:14+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.4.0", @@ -2095,6 +2228,81 @@ }, "time": "2026-05-18T16:26:00+00:00" }, + { + "name": "laravel/passport", + "version": "v13.7.5", + "source": { + "type": "git", + "url": "https://github.com/laravel/passport.git", + "reference": "90053dc4ba681c076855779250109bb624f961f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/passport/zipball/90053dc4ba681c076855779250109bb624f961f6", + "reference": "90053dc4ba681c076855779250109bb624f961f6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "firebase/php-jwt": "^6.4|^7.0", + "illuminate/auth": "^11.35|^12.0|^13.0", + "illuminate/console": "^11.35|^12.0|^13.0", + "illuminate/container": "^11.35|^12.0|^13.0", + "illuminate/contracts": "^11.35|^12.0|^13.0", + "illuminate/cookie": "^11.35|^12.0|^13.0", + "illuminate/database": "^11.35|^12.0|^13.0", + "illuminate/encryption": "^11.35|^12.0|^13.0", + "illuminate/http": "^11.35|^12.0|^13.0", + "illuminate/support": "^11.35|^12.0|^13.0", + "league/oauth2-server": "^9.2", + "php": "^8.2", + "php-http/discovery": "^1.20", + "phpseclib/phpseclib": "^3.0", + "psr/http-factory-implementation": "*", + "symfony/console": "^7.1|^8.0", + "symfony/psr-http-message-bridge": "^7.1|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^9.15|^10.8|^11.0", + "phpstan/phpstan": "^2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Passport\\PassportServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Passport\\": "src/", + "Laravel\\Passport\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Passport provides OAuth2 server support to Laravel.", + "keywords": [ + "laravel", + "oauth", + "passport" + ], + "support": { + "issues": "https://github.com/laravel/passport/issues", + "source": "https://github.com/laravel/passport" + }, + "time": "2026-04-16T14:00:29+00:00" + }, { "name": "laravel/prompts", "version": "v0.3.18", @@ -2284,6 +2492,143 @@ }, "time": "2026-03-17T14:54:13+00:00" }, + { + "name": "lcobucci/clock", + "version": "3.6.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/4cdd88f761e9be9095ccbedf3e08d61ae216c643", + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643", + "shasum": "" + }, + "require": { + "php": "~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "infection/infection": "^0.32", + "lcobucci/coding-standard": "^12.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^13.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/3.6.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2026-04-13T21:30:16+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "5.6.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/bb3e9f21e4196e8afc41def81ef649c164bca25e", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-sodium": "*", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" + }, + "require-dev": { + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" + }, + "suggest": { + "lcobucci/clock": ">= 3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/5.6.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2025-10-17T11:30:53+00:00" + }, { "name": "league/commonmark", "version": "2.8.2", @@ -2473,6 +2818,65 @@ ], "time": "2022-12-11T20:36:23+00:00" }, + { + "name": "league/event", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "shasum": "" + }, + "require": { + "php": ">=7.2.0", + "psr/event-dispatcher": "^1.0" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.45", + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "support": { + "issues": "https://github.com/thephpleague/event/issues", + "source": "https://github.com/thephpleague/event/tree/3.0.3" + }, + "time": "2024-09-04T16:06:53+00:00" + }, { "name": "league/flysystem", "version": "3.34.0", @@ -2661,6 +3065,103 @@ ], "time": "2024-09-21T08:32:55+00:00" }, + { + "name": "league/oauth2-server", + "version": "9.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-server.git", + "reference": "b96b4a12f87c2cb208cce9436116bc2b7920f796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/b96b4a12f87c2cb208cce9436116bc2b7920f796", + "reference": "b96b4a12f87c2cb208cce9436116bc2b7920f796", + "shasum": "" + }, + "require": { + "defuse/php-encryption": "^2.4", + "ext-json": "*", + "ext-openssl": "*", + "lcobucci/clock": "^3.3", + "lcobucci/jwt": "^5.6", + "league/event": "^3.0", + "league/uri": "^7.8", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/http-message": "^2.0", + "psr/http-server-middleware": "^1.0" + }, + "replace": { + "league/oauth2server": "*", + "lncd/oauth2": "*" + }, + "require-dev": { + "laminas/laminas-diactoros": "^3.8", + "paragonie/random_compat": "^9.99.100", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.38", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0.12", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.50", + "roave/security-advisories": "dev-master", + "slevomat/coding-standard": "^8.27.1", + "squizlabs/php_codesniffer": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Andy Millington", + "email": "andrew@noexceptions.io", + "homepage": "https://www.noexceptions.io", + "role": "Developer" + } + ], + "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", + "homepage": "https://oauth2.thephpleague.com/", + "keywords": [ + "Authentication", + "api", + "auth", + "authorisation", + "authorization", + "oauth", + "oauth 2", + "oauth 2.0", + "oauth2", + "protect", + "resource", + "secure", + "server" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth2-server/issues", + "source": "https://github.com/thephpleague/oauth2-server/tree/9.4.0" + }, + "funding": [ + { + "url": "https://github.com/sephster", + "type": "github" + } + ], + "time": "2026-06-14T08:12:22+00:00" + }, { "name": "league/uri", "version": "7.8.1", @@ -3625,6 +4126,135 @@ }, "time": "2025-09-24T15:06:41+00:00" }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -3876,6 +4506,116 @@ ], "time": "2025-12-27T19:41:33+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.55", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "db9744e6d47e742b1f974e965ad49bdd041105af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db9744e6d47e742b1f974e965ad49bdd041105af", + "reference": "db9744e6d47e742b1f974e965ad49bdd041105af", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.55" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2026-06-14T23:24:10+00:00" + }, { "name": "phpstan/phpdoc-parser", "version": "2.3.2", @@ -4286,6 +5026,119 @@ }, "time": "2023-04-04T09:54:51+00:00" }, + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" + }, + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" + }, + "time": "2023-04-11T06:14:47+00:00" + }, { "name": "psr/log", "version": "3.0.2", @@ -7426,6 +8279,93 @@ ], "time": "2026-05-29T05:06:50+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "67fd34de15ded1763aa1e330fe345f080a94022c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/67fd34de15ded1763aa1e330fe345f080a94022c", + "reference": "67fd34de15ded1763aa1e330fe345f080a94022c", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "psr/http-message": "^1.0|^2.0", + "symfony/http-foundation": "^7.4|^8.0" + }, + "conflict": { + "php-http/discovery": "<1.15" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "php-http/discovery": "^1.15", + "psr/log": "^1.1.4|^2|^3", + "symfony/browser-kit": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/runtime": "^7.4|^8.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "https://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, { "name": "symfony/routing", "version": "v8.1.0", @@ -12943,10 +13883,10 @@ "prefer-lowest": false, "platform": { "php": "^8.3", - "ext-openssl": "*", - "ext-zlib": "*", "ext-dom": "*", - "ext-libxml": "*" + "ext-libxml": "*", + "ext-openssl": "*", + "ext-zlib": "*" }, "platform-dev": {}, "plugin-api-version": "2.9.0" diff --git a/config/auth.php b/config/auth.php index ffe7b03..4cd9449 100644 --- a/config/auth.php +++ b/config/auth.php @@ -44,6 +44,10 @@ 'driver' => 'session', 'provider' => 'users', ], + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], ], /* diff --git a/config/passport.php b/config/passport.php new file mode 100644 index 0000000..ebfe824 --- /dev/null +++ b/config/passport.php @@ -0,0 +1,50 @@ + 'web', + + 'middleware' => [], + + /* + |-------------------------------------------------------------------------- + | Encryption Keys + |-------------------------------------------------------------------------- + | + | Passport uses encryption keys while generating secure access tokens for + | your application. By default, the keys are stored as local files but + | can be set via environment variables when that is more convenient. + | + */ + + 'private_key' => env('PASSPORT_PRIVATE_KEY'), + + 'public_key' => env('PASSPORT_PUBLIC_KEY'), + + /* + |-------------------------------------------------------------------------- + | Passport Database Connection + |-------------------------------------------------------------------------- + | + | By default, Passport's models will utilize your application's default + | database connection. If you wish to use a different connection you + | may specify the configured name of the database connection here. + | + */ + + 'connection' => env('PASSPORT_CONNECTION'), + +]; diff --git a/database/migrations/2026_06_16_114211_create_oauth_auth_codes_table.php b/database/migrations/2026_06_16_114211_create_oauth_auth_codes_table.php new file mode 100644 index 0000000..cb6ce44 --- /dev/null +++ b/database/migrations/2026_06_16_114211_create_oauth_auth_codes_table.php @@ -0,0 +1,41 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->index(); + $table->foreignUuid('client_id'); + $table->text('scopes')->nullable(); + $table->boolean('revoked'); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_auth_codes'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_06_16_114212_create_oauth_access_tokens_table.php b/database/migrations/2026_06_16_114212_create_oauth_access_tokens_table.php new file mode 100644 index 0000000..7224853 --- /dev/null +++ b/database/migrations/2026_06_16_114212_create_oauth_access_tokens_table.php @@ -0,0 +1,43 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->foreignUuid('client_id'); + $table->string('name')->nullable(); + $table->text('scopes')->nullable(); + $table->boolean('revoked'); + $table->timestamps(); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_access_tokens'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_06_16_114213_create_oauth_refresh_tokens_table.php b/database/migrations/2026_06_16_114213_create_oauth_refresh_tokens_table.php new file mode 100644 index 0000000..14fa35d --- /dev/null +++ b/database/migrations/2026_06_16_114213_create_oauth_refresh_tokens_table.php @@ -0,0 +1,39 @@ +char('id', 80)->primary(); + $table->char('access_token_id', 80)->index(); + $table->boolean('revoked'); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_refresh_tokens'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_06_16_114214_create_oauth_clients_table.php b/database/migrations/2026_06_16_114214_create_oauth_clients_table.php new file mode 100644 index 0000000..cba5c67 --- /dev/null +++ b/database/migrations/2026_06_16_114214_create_oauth_clients_table.php @@ -0,0 +1,44 @@ +uuid('id')->primary(); + $table->nullableMorphs('owner'); + $table->string('name'); + $table->string('secret')->nullable(); + $table->string('provider')->nullable(); + $table->text('redirect_uris'); + $table->text('grant_types'); + $table->boolean('revoked'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_clients'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/database/migrations/2026_06_16_114215_create_oauth_device_codes_table.php b/database/migrations/2026_06_16_114215_create_oauth_device_codes_table.php new file mode 100644 index 0000000..5d4a084 --- /dev/null +++ b/database/migrations/2026_06_16_114215_create_oauth_device_codes_table.php @@ -0,0 +1,44 @@ +char('id', 80)->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->foreignUuid('client_id')->index(); + $table->char('user_code', 8)->unique(); + $table->text('scopes'); + $table->boolean('revoked'); + $table->dateTime('user_approved_at')->nullable(); + $table->dateTime('last_polled_at')->nullable(); + $table->dateTime('expires_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('oauth_device_codes'); + } + + /** + * Get the migration connection name. + */ + public function getConnection(): ?string + { + return $this->connection ?? config('passport.connection'); + } +}; diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..160b291 --- /dev/null +++ b/routes/api.php @@ -0,0 +1,8 @@ + $request->user())->middleware('auth:api');