From 8208d454cac2bbfd8c9bc9abd9b9f0ba94f5a400 Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Thu, 7 May 2026 14:43:37 -0700 Subject: [PATCH 1/5] Set the user_id on the oauth client --- database/seeders/UserSeeder.php | 4 +- ..._07_212653_set_user_id_on_oauth_client.php | 60 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 8d016fb936..27de4dc101 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -55,7 +55,9 @@ public function run(ClientRepository $clients) ]); // Create client so we can generate tokens - $clients->createPersonalAccessGrantClient('PmApi'); + $personalAccessClient = $clients->createPersonalAccessGrantClient('PmApi'); + $personalAccessClient->user_id = $user->id; + $personalAccessClient->save(); // Create client OAuth (for 3-legged auth) - Authorization Code Grant for Swagger UI $clients->createAuthorizationCodeGrantClient( diff --git a/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php b/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php new file mode 100644 index 0000000000..a54365c7bf --- /dev/null +++ b/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php @@ -0,0 +1,60 @@ +where('is_administrator', true) + ->orderBy('id') + ->value('id'); + + if ($adminUserId === null) { + return; + } + + DB::table('oauth_clients') + ->where('name', 'PmApi') + ->update(['user_id' => $adminUserId]); + } + + /** + * Reverse the upgrade migration. + * + * @return void + */ + public function down() + { + DB::table('oauth_clients') + ->where('name', 'PmApi') + ->update(['user_id' => null]); + } +} From 6efca9c0d75bf3ff83dbc65175d6e5d9ed0041a6 Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Mon, 18 May 2026 17:46:31 -0700 Subject: [PATCH 2/5] Update all clients and add an observer --- .../Providers/ProcessMakerServiceProvider.php | 19 +++++++++++++++++++ ..._07_212653_set_user_id_on_oauth_client.php | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ProcessMaker/Providers/ProcessMakerServiceProvider.php b/ProcessMaker/Providers/ProcessMakerServiceProvider.php index 56d38de1d3..c19ded9d5f 100644 --- a/ProcessMaker/Providers/ProcessMakerServiceProvider.php +++ b/ProcessMaker/Providers/ProcessMakerServiceProvider.php @@ -23,6 +23,7 @@ use Laravel\Horizon\Horizon; use Laravel\Horizon\SystemProcessCounter; use Laravel\Horizon\WorkerCommandString; +use Laravel\Passport\Client as PassportClient; use Lavary\Menu\Menu; use OpenApi\Analysers\AttributeAnnotationFactory; use OpenApi\Analysers\DocBlockAnnotationFactory; @@ -354,6 +355,24 @@ protected static function bootObservers(): void Models\ProcessRequestToken::observe(Observers\ProcessRequestTokenObserver::class); Models\ProcessCollaboration::observe(Observers\ProcessCollaborationObserver::class); + + // Due to this change https://github.com/laravel/passport/blob/ea020190123953426a439f0267c6cfa478f6e6e7/src/Guards/TokenGuard.php#L146 + // user ID is now required for bearer tokens clients. Any user will work here, the token itself + // is what's associated with the real user. For now, we'll use the first administrator user. + PassportClient::creating(function (PassportClient $client): void { + if (!$client->personal_access_client || $client->user_id !== null) { + return; + } + + $adminUserId = Models\User::query() + ->where('is_administrator', true) + ->orderBy('id') + ->value('id'); + + if ($adminUserId !== null) { + $client->user_id = $adminUserId; + } + }); } /** diff --git a/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php b/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php index a54365c7bf..2b9f183677 100644 --- a/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php +++ b/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php @@ -42,7 +42,8 @@ public function up() } DB::table('oauth_clients') - ->where('name', 'PmApi') + ->where('personal_access_client', true) + ->whereNull('user_id') ->update(['user_id' => $adminUserId]); } @@ -53,8 +54,18 @@ public function up() */ public function down() { + $adminUserId = DB::table('users') + ->where('is_administrator', true) + ->orderBy('id') + ->value('id'); + + if ($adminUserId === null) { + return; + } + DB::table('oauth_clients') - ->where('name', 'PmApi') + ->where('personal_access_client', true) + ->where('user_id', $adminUserId) ->update(['user_id' => null]); } } From 671ed38570b5543762fa5f1fa10faacc2f3267cc Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Tue, 19 May 2026 10:30:58 -0700 Subject: [PATCH 3/5] Use migration suggested in docs --- .../Providers/ProcessMakerServiceProvider.php | 19 ----- ...26_05_19_102552_update_passport_schema.php | 52 ++++++++++++++ ..._07_212653_set_user_id_on_oauth_client.php | 71 ------------------- 3 files changed, 52 insertions(+), 90 deletions(-) create mode 100644 database/migrations/2026_05_19_102552_update_passport_schema.php delete mode 100644 upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php diff --git a/ProcessMaker/Providers/ProcessMakerServiceProvider.php b/ProcessMaker/Providers/ProcessMakerServiceProvider.php index c19ded9d5f..56d38de1d3 100644 --- a/ProcessMaker/Providers/ProcessMakerServiceProvider.php +++ b/ProcessMaker/Providers/ProcessMakerServiceProvider.php @@ -23,7 +23,6 @@ use Laravel\Horizon\Horizon; use Laravel\Horizon\SystemProcessCounter; use Laravel\Horizon\WorkerCommandString; -use Laravel\Passport\Client as PassportClient; use Lavary\Menu\Menu; use OpenApi\Analysers\AttributeAnnotationFactory; use OpenApi\Analysers\DocBlockAnnotationFactory; @@ -355,24 +354,6 @@ protected static function bootObservers(): void Models\ProcessRequestToken::observe(Observers\ProcessRequestTokenObserver::class); Models\ProcessCollaboration::observe(Observers\ProcessCollaborationObserver::class); - - // Due to this change https://github.com/laravel/passport/blob/ea020190123953426a439f0267c6cfa478f6e6e7/src/Guards/TokenGuard.php#L146 - // user ID is now required for bearer tokens clients. Any user will work here, the token itself - // is what's associated with the real user. For now, we'll use the first administrator user. - PassportClient::creating(function (PassportClient $client): void { - if (!$client->personal_access_client || $client->user_id !== null) { - return; - } - - $adminUserId = Models\User::query() - ->where('is_administrator', true) - ->orderBy('id') - ->value('id'); - - if ($adminUserId !== null) { - $client->user_id = $adminUserId; - } - }); } /** diff --git a/database/migrations/2026_05_19_102552_update_passport_schema.php b/database/migrations/2026_05_19_102552_update_passport_schema.php new file mode 100644 index 0000000000..eb8aef7e21 --- /dev/null +++ b/database/migrations/2026_05_19_102552_update_passport_schema.php @@ -0,0 +1,52 @@ +nullableMorphs('owner', after: 'user_id'); + + $table->after('provider', function (Blueprint $table) { + $table->text('redirect_uris')->nullable(); + $table->text('grant_types')->nullable(); + }); + }); + + foreach (Passport::client()->cursor() as $client) { + Model::withoutTimestamps(fn () => $client->forceFill([ + 'owner_id' => $client->user_id, + 'owner_type' => $client->user_id + ? config('auth.providers.' . ($client->provider ?: config('auth.guards.api.provider')) . '.model') + : null, + 'redirect_uris' => $client->redirect_uris, + 'grant_types' => $client->grant_types, + ])->save()); + } + + Schema::table('oauth_clients', function (Blueprint $table) { + $table->dropColumn(['user_id', 'redirect', 'personal_access_client', 'password_client']); + + $table->text('redirect_uris')->nullable(false)->change(); + $table->text('grant_types')->nullable(false)->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php b/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php deleted file mode 100644 index 2b9f183677..0000000000 --- a/upgrades/2026_05_07_212653_set_user_id_on_oauth_client.php +++ /dev/null @@ -1,71 +0,0 @@ -where('is_administrator', true) - ->orderBy('id') - ->value('id'); - - if ($adminUserId === null) { - return; - } - - DB::table('oauth_clients') - ->where('personal_access_client', true) - ->whereNull('user_id') - ->update(['user_id' => $adminUserId]); - } - - /** - * Reverse the upgrade migration. - * - * @return void - */ - public function down() - { - $adminUserId = DB::table('users') - ->where('is_administrator', true) - ->orderBy('id') - ->value('id'); - - if ($adminUserId === null) { - return; - } - - DB::table('oauth_clients') - ->where('personal_access_client', true) - ->where('user_id', $adminUserId) - ->update(['user_id' => null]); - } -} From 9c4ed30c46b797aec51d9ca5e04bf7fbec093094 Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Tue, 19 May 2026 11:16:10 -0700 Subject: [PATCH 4/5] Fix grant types --- .../2026_05_19_102552_update_passport_schema.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/database/migrations/2026_05_19_102552_update_passport_schema.php b/database/migrations/2026_05_19_102552_update_passport_schema.php index eb8aef7e21..128d351855 100644 --- a/database/migrations/2026_05_19_102552_update_passport_schema.php +++ b/database/migrations/2026_05_19_102552_update_passport_schema.php @@ -24,13 +24,18 @@ public function up(): void }); foreach (Passport::client()->cursor() as $client) { + if ($client->personal_access_client === true && $client->password_client === false) { + $grantTypes = ['personal_access']; + } else { + $grantTypes = $client->grant_types; + } Model::withoutTimestamps(fn () => $client->forceFill([ 'owner_id' => $client->user_id, 'owner_type' => $client->user_id ? config('auth.providers.' . ($client->provider ?: config('auth.guards.api.provider')) . '.model') : null, 'redirect_uris' => $client->redirect_uris, - 'grant_types' => $client->grant_types, + 'grant_types' => $grantTypes, ])->save()); } From 123596c313fd54218fcce28155b3aa2c67e1a5fa Mon Sep 17 00:00:00 2001 From: Nolan Ehrstrom Date: Tue, 19 May 2026 12:33:52 -0700 Subject: [PATCH 5/5] Remove setting user_id on client --- database/seeders/UserSeeder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 27de4dc101..53c6abaf4d 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -56,7 +56,6 @@ public function run(ClientRepository $clients) // Create client so we can generate tokens $personalAccessClient = $clients->createPersonalAccessGrantClient('PmApi'); - $personalAccessClient->user_id = $user->id; $personalAccessClient->save(); // Create client OAuth (for 3-legged auth) - Authorization Code Grant for Swagger UI