From de6efb877c498dac888ef56e61cd2f93b7b470a4 Mon Sep 17 00:00:00 2001 From: w33b Date: Mon, 4 May 2026 20:22:51 +0200 Subject: [PATCH] Add job to sync subscription keys --- app/Console/Commands/SyncSubscriptionKeys.php | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 app/Console/Commands/SyncSubscriptionKeys.php diff --git a/app/Console/Commands/SyncSubscriptionKeys.php b/app/Console/Commands/SyncSubscriptionKeys.php new file mode 100644 index 0000000..005f41a --- /dev/null +++ b/app/Console/Commands/SyncSubscriptionKeys.php @@ -0,0 +1,102 @@ +error('Missing endpoint.'); + return self::FAILURE; + } + + $response = Http::asJson() + ->acceptJson() + ->timeout(20) + ->retry(3, 1000) + ->post($endpoint.'/api/membership/keys', [ + 'payload' => base64_encode(Crypt::encryptString('get-active-keys')), + ]); + + if (! $response->successful()) { + $this->error('Subscription API request failed: HTTP ' . $response->status()); + return self::FAILURE; + } + + try { + $decrypted = Crypt::decryptString(base64_decode($response->json('payload'))); + $activeKeys = json_decode($decrypted, true, flags: JSON_THROW_ON_ERROR); + } catch (DecryptException $e) { + $this->error('Could not decrypt API response.'); + return self::FAILURE; + } catch (\JsonException $e) { + $this->error('API returned invalid JSON.'); + return self::FAILURE; + } + + if (! is_array($activeKeys)) { + $this->error('API response payload was not an array.'); + return self::FAILURE; + } + + $activeKeys = collect($activeKeys) + ->filter(fn ($key) => is_string($key) && $key !== '') + ->values() + ->all(); + + $this->markInactiveUsers($activeKeys); + $this->markActiveUsers($activeKeys); + + return self::SUCCESS; + } + + private function markInactiveUsers(array $activeKeys) + { + User::query() + ->whereNotNull('subscription_key') + ->whereNotIn('subscription_key', $activeKeys) + ->chunk(100, function ($users) { + foreach($users as $user) { + $user->removeRole(UserRole::SUPPORTER); + } + }); + } + + private function markActiveUsers(array $activeKeys) + { + User::query() + ->whereNotNull('subscription_key') + ->whereIn('subscription_key', $activeKeys) + ->chunk(100, function ($users) { + foreach($users as $user) { + $user->addRole(UserRole::SUPPORTER); + } + }); + } +}