Add f7push v0.1: FCM device registry and push API for F7cloud.

Portable occ-based config, OCS endpoints for APK registration, notification relay, and server-side push dispatch.
This commit is contained in:
root
2026-05-24 10:26:36 +03:00
commit df4e2dddec
17 changed files with 1005 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace OCA\F7Push\Controller;
use OCA\F7Push\Model\PushMessage;
use OCA\F7Push\Service\ConfigService;
use OCA\F7Push\Service\PushDispatcher;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use OCP\IUserSession;
class PushApiController extends OCSController {
public function __construct(
string $appName,
IRequest $request,
private ConfigService $config,
private PushDispatcher $pushDispatcher,
private IUserSession $userSession,
) {
parent::__construct($appName, $request);
}
/**
* Server-to-server push (f7support and other F7cloud apps).
* Header: X-F7-Push-Secret
*
* JSON: { "userId", "title", "body", "url?", "source?", "priority?" }
*/
#[NoCSRFRequired]
public function send(): DataResponse {
if (!$this->authorizeSecret()) {
return new DataResponse(['error' => 'forbidden'], Http::STATUS_FORBIDDEN);
}
$params = $this->request->getParams();
$userId = trim((string)($params['userId'] ?? ''));
$title = trim((string)($params['title'] ?? ''));
$body = trim((string)($params['body'] ?? ''));
if ($userId === '' || $title === '') {
return new DataResponse(['error' => 'userId and title required'], Http::STATUS_BAD_REQUEST);
}
$sent = $this->pushDispatcher->dispatch(new PushMessage(
userId: $userId,
title: $title,
body: $body,
source: trim((string)($params['source'] ?? 'api')),
priority: trim((string)($params['priority'] ?? 'normal')),
url: isset($params['url']) ? trim((string)$params['url']) : null,
));
return new DataResponse(['success' => true, 'sent' => $sent]);
}
/**
* Send test push to devices of the current user (admin or self).
*/
#[NoAdminRequired]
#[NoCSRFRequired]
public function test(): DataResponse {
$user = $this->userSession->getUser();
if ($user === null) {
return new DataResponse(['error' => 'unauthorized'], Http::STATUS_UNAUTHORIZED);
}
$sent = $this->pushDispatcher->dispatch(new PushMessage(
userId: $user->getUID(),
title: 'F7 Push',
body: 'Test notification from F7cloud',
source: 'f7push',
priority: 'normal',
url: $this->config->getDefaultClickUrl(),
));
return new DataResponse(['success' => true, 'sent' => $sent]);
}
private function authorizeSecret(): bool {
$header = $this->request->getHeader('X-F7-Push-Secret');
if ($header === '') {
$header = (string)$this->request->getParam('secret', '');
}
return $this->config->verifyApiSecret($header);
}
}