fix(security): resolve F-09 — wrap FcmService::sendToTopic in try-catch, never throw uncaught exceptions

Replaces raw Exception throw with logged error + 500 return.
Logs FCM API failures with response body for debugging.
This commit is contained in:
root
2026-06-02 23:06:58 +08:00
parent 11a2067014
commit 259ed76815

View File

@@ -41,37 +41,53 @@ class FcmService
} }
} }
public function sendToTopic(string $topic ,string $title,string $body) public function sendToTopic(string $topic, string $title, string $body)
{ {
if (!$this->credentials) { if (!$this->credentials) {
Log::error('Cannot send FCM notification: credentials not loaded'); Log::error('Cannot send FCM notification: credentials not loaded');
return 500; return 500;
} }
$scopes = ['https://www.googleapis.com/auth/firebase.messaging']; try {
$scopes = ['https://www.googleapis.com/auth/firebase.messaging'];
$creds = new ServiceAccountCredentials($scopes, $this->credentials); $creds = new ServiceAccountCredentials($scopes, $this->credentials);
$tokenArray = $creds->fetchAuthToken(); $tokenArray = $creds->fetchAuthToken();
$accessToken = $tokenArray['access_token'] ?? null; $accessToken = $tokenArray['access_token'] ?? null;
if (!$accessToken) { if (!$accessToken) {
throw new \Exception("Failed to get access token from Firebase credentials."); Log::error('Failed to get Firebase access token');
} return 500;
}
$response = Http::withToken($accessToken) $response = Http::withToken($accessToken)
->post("https://fcm.googleapis.com/v1/projects/{$this->projectid}/messages:send", [ ->post("https://fcm.googleapis.com/v1/projects/{$this->projectid}/messages:send", [
"message" => [ "message" => [
"topic" => $topic, "topic" => $topic,
"notification" => [ "notification" => [
"title" => $title, "title" => $title,
"body" => $body "body" => $body
], ],
"android" => [ "android" => [
"priority" => "high" "priority" => "high"
]
] ]
] ]);
]);
return $response->status(); if (!$response->successful()) {
Log::error('FCM send failed', [
'status' => $response->status(),
'body' => $response->body(),
]);
}
return $response->status();
} catch (\Exception $e) {
Log::error('FCM notification error', [
'error' => $e->getMessage(),
'topic' => $topic,
]);
return 500;
}
} }
} }