Update NotificationAppGatewayService

This commit is contained in:
Daniel Supernault 2024-09-28 03:52:58 -06:00
parent dba012840c
commit 92ad62e735
No known key found for this signature in database
GPG key ID: 23740873EE6F76A1
2 changed files with 122 additions and 4 deletions

View file

@ -2,8 +2,9 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Services\NotificationAppGatewayService; use App\Services\NotificationAppGatewayService;
use Illuminate\Console\Command;
use function Laravel\Prompts\select; use function Laravel\Prompts\select;
class PushGatewayRefresh extends Command class PushGatewayRefresh extends Command
@ -34,6 +35,7 @@ class PushGatewayRefresh extends Command
if ($currentState) { if ($currentState) {
$this->info('Push Notification support is active!'); $this->info('Push Notification support is active!');
return; return;
} else { } else {
$this->error('Push notification support is NOT active'); $this->error('Push notification support is NOT active');
@ -48,18 +50,22 @@ class PushGatewayRefresh extends Command
$recheck = NotificationAppGatewayService::forceSupportRecheck(); $recheck = NotificationAppGatewayService::forceSupportRecheck();
if ($recheck) { if ($recheck) {
$this->info('Success! Push Notifications are now active!'); $this->info('Success! Push Notifications are now active!');
return; return;
} else { } else {
$this->error('Error, please ensure you have a valid API key.'); $this->error('Error, please ensure you have a valid API key.');
$this->line(' '); $this->line(' ');
$this->line('For more info, visit https://docs.pixelfed.org/running-pixelfed/push-notifications.html'); $this->line('For more info, visit https://docs.pixelfed.org/running-pixelfed/push-notifications.html');
$this->line(' '); $this->line(' ');
return; return;
} }
return; return;
} else { } else {
exit; exit;
} }
return; return;
} }
} }

View file

@ -2,10 +2,122 @@
namespace App\Services; namespace App\Services;
use Cache;
use Exception;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
class NotificationAppGatewayService class NotificationAppGatewayService
{ {
const GATEWAY_SUPPORT_CHECK = 'px:nags:gateway-support-check';
public static function config() public static function config()
{ {
return config('instance.notifications.nag'); return config('instance.notifications.nag');
} }
public static function enabled()
{
if ((bool) config('instance.notifications.nag.enabled') === false) {
return false;
}
$apiKey = config('instance.notifications.nag.api_key');
if (! $apiKey || empty($apiKey) || strlen($apiKey) !== 45) {
return false;
}
return Cache::remember(self::GATEWAY_SUPPORT_CHECK, 43200, function () {
return self::checkServerSupport();
});
}
public static function checkServerSupport()
{
$endpoint = 'https://'.config('instance.notifications.nag.endpoint').'/api/v1/instance-check?domain='.config('pixelfed.domain.app');
try {
$res = Http::withHeaders(['X-PIXELFED-API' => 1])
->retry(3, 500)
->throw()
->get($endpoint);
$data = $res->json();
} catch (RequestException $e) {
return false;
} catch (Exception $e) {
return false;
}
if ($res->successful() && isset($data['active']) && $data['active'] === true) {
return true;
}
return false;
}
public static function forceSupportRecheck()
{
Cache::forget(self::GATEWAY_SUPPORT_CHECK);
return self::enabled();
}
public static function isValidExpoPushToken($token)
{
if (! $token || empty($token)) {
return false;
}
$starts = str_starts_with($token, 'Expo');
if (! $starts) {
return false;
}
if (! str_contains($token, 'PushToken[') || ! str_contains($token, ']')) {
return false;
}
if (substr($token, -1) !== ']') {
return false;
}
return true;
}
public static function send($userToken, $type, $actor = '')
{
if (! self::enabled()) {
return false;
}
if (! $userToken || empty($userToken) || ! self::isValidExpoPushToken($userToken)) {
return false;
}
$types = ['new_follower', 'like', 'comment', 'share'];
if (! $type || empty($type) || ! in_array($type, $types)) {
return false;
}
$apiKey = config('instance.notifications.nag.api_key');
if (! $apiKey || empty($apiKey)) {
return false;
}
$url = 'https://'.config('instance.notifications.nag.endpoint').'/api/v1/relay/deliver';
try {
$response = Http::withToken($apiKey)
->withHeaders(['X-PIXELFED-API' => 1])
->post($url, [
'token' => $userToken,
'type' => $type,
'actor' => $actor,
]);
$response->throw();
} catch (RequestException $e) {
return;
} catch (Exception $e) {
return;
}
}
} }