diff --git a/app/Http/Controllers/MigrationController.php b/app/Http/Controllers/MigrationController.php new file mode 100644 index 0000000..54a55c4 --- /dev/null +++ b/app/Http/Controllers/MigrationController.php @@ -0,0 +1,54 @@ +migrate(); + } + + return 'done'; + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 1bfdb6b..d643758 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Facades\Date; +use Laravel\Sanctum\HasApiTokens; /** * @property int $id @@ -28,6 +29,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar use Notifiable; use UserAdjustments; + use HasApiTokens; /** * The attributes that are mass assignable. diff --git a/bootstrap/app.php b/bootstrap/app.php index c183276..c3928c5 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware; 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 e3b9f04..1dafcc3 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "halaxa/json-machine": "^1.2", "joaopaulolndev/filament-edit-profile": "^2.0", "laravel/framework": "^12.0", + "laravel/sanctum": "^4.0", "laravel/tinker": "^2.10.1", "laravel/ui": "^4.6", "mpdf/mpdf": "^8.2", diff --git a/composer.lock b/composer.lock index d128e1c..953dd81 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": "3fe345d22ddaf5b75cd17aaecee2b718", + "content-hash": "018635a80495002683ac3d2f58dd6eaf", "packages": [ { "name": "abdulmajeed-jamaan/filament-translatable-tabs", @@ -3355,6 +3355,69 @@ }, "time": "2025-11-21T20:52:52+00:00" }, + { + "name": "laravel/sanctum", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664", + "reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0|^12.0", + "illuminate/contracts": "^11.0|^12.0", + "illuminate/database": "^11.0|^12.0", + "illuminate/support": "^11.0|^12.0", + "php": "^8.2", + "symfony/console": "^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.15|^10.8", + "phpstan/phpstan": "^1.10" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2025-11-21T13:59:03+00:00" + }, { "name": "laravel/serializable-closure", "version": "v2.0.7", diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100644 index 0000000..44527d6 --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,84 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort(), + // Sanctum::currentRequestHost(), + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. This will override any values set in the token's + | "expires_at" attribute, but first-party sessions are not affected. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Token Prefix + |-------------------------------------------------------------------------- + | + | Sanctum can prefix new tokens in order to take advantage of numerous + | security scanning initiatives maintained by open source platforms + | that notify developers if they commit tokens into repositories. + | + | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning + | + */ + + 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, + 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, + 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + ], + +]; diff --git a/database/migrations/2025_12_21_194719_create_personal_access_tokens_table.php b/database/migrations/2025_12_21_194719_create_personal_access_tokens_table.php new file mode 100644 index 0000000..40ff706 --- /dev/null +++ b/database/migrations/2025_12_21_194719_create_personal_access_tokens_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('tokenable'); + $table->text('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable()->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 3020eb3..da452b0 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -13,9 +13,7 @@ class DatabaseSeeder extends Seeder public function run(): void { $this->call([ - FillJsonData::class, - // UsersTableSeeder::class, - // ShieldSeeder::class, + ShieldSeeder::class, ]); } } diff --git a/database/seeders/FillJsonData.php b/database/seeders/FillJsonData.php index 7fa204a..dbeb0a6 100644 --- a/database/seeders/FillJsonData.php +++ b/database/seeders/FillJsonData.php @@ -9,7 +9,10 @@ class FillJsonData extends Seeder /** * Run the database seeds. */ - public function run(): void {} + public function run(): void + { + + } protected function seedUsers(): void { diff --git a/database/seeders/Migrators/PersonalAccessTokensMigrator.php b/database/seeders/Migrators/PersonalAccessTokensMigrator.php new file mode 100644 index 0000000..3b10a63 --- /dev/null +++ b/database/seeders/Migrators/PersonalAccessTokensMigrator.php @@ -0,0 +1,26 @@ +truncate(); + + $path = database_path('data/tested/personal_access_tokens.json'); + + $rawData = File::json($path); + + foreach ($rawData as $data) { + DB::table('personal_access_tokens') + ->insert($data); + } + + DB::statement("SELECT setval('personal_access_tokens_id_seq', (SELECT MAX(id) from personal_access_tokens));"); + DB::statement("SELECT nextval('personal_access_tokens_id_seq');"); + } +} \ No newline at end of file diff --git a/database/seeders/Migrators/ProvincesMigrator.php b/database/seeders/Migrators/ProvincesMigrator.php index 05f77fa..afd9c5a 100644 --- a/database/seeders/Migrators/ProvincesMigrator.php +++ b/database/seeders/Migrators/ProvincesMigrator.php @@ -11,7 +11,7 @@ class ProvincesMigrator { DB::table('provinces')->truncate(); - $path = database_path('data/nurmuhammetsdb/provinces.json'); + $path = database_path('data/tested/provinces.json'); $rawData = File::json($path); diff --git a/database/seeders/Migrators/VerificationsMigrator.php b/database/seeders/Migrators/VerificationsMigrator.php new file mode 100644 index 0000000..1550915 --- /dev/null +++ b/database/seeders/Migrators/VerificationsMigrator.php @@ -0,0 +1,26 @@ +truncate(); + + $path = database_path('data/tested/verifications.json'); + + $rawData = File::json($path); + + foreach ($rawData as $data) { + DB::table('verifications') + ->insert($data); + } + + DB::statement("SELECT setval('verifications_id_seq', (SELECT MAX(id) from verifications));"); + DB::statement("SELECT nextval('verifications_id_seq');"); + } +} \ No newline at end of file diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..ccc387f --- /dev/null +++ b/routes/api.php @@ -0,0 +1,8 @@ +user(); +})->middleware('auth:sanctum'); diff --git a/routes/web.php b/routes/web.php index 5f4eca0..707e3c6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,16 +1,12 @@ migrate(); - - return 'done'; -}); +Route::get('test', [MigrationController::class, 'index']); // Route::middleware(['auth'])->group(function () { // Route::get('password-change', [PasswordChangeController::class, 'index'])->name('password-change'); // Route::post('password-change', [PasswordChangeController::class, 'update'])->name('password-change.update');