Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/ocs-endpoint-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ In order to find out if notifications is installed/enabled on the server you can
"delete",
"delete-all",
"icons",
"rich-strings"
"rich-strings",
"action-web"
]
}
}
Expand Down Expand Up @@ -138,7 +139,7 @@ Field name | Type | Value description
---------- | ---- | -----------------
label | string | Translated short label of the action/button that should be presented to the user
link | string | A link that should be followed when the action is performed/clicked
type | string | HTTP method that should be used for the request against the link: GET, POST, DELETE
type | string | HTTP method that should be used for the request against the link: GET, POST, DELETE, PUT or WEB. In case of WEB a redirect should happen instead.
primary | bool | If the action is the primary action for the notification or not


Expand Down
38 changes: 36 additions & 2 deletions docs/push-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ In order to find out if notifications support push on the server you can run a r
"push": [
...
"devices",
"object-data"
"object-data",
"delete"
]
}
}
Expand Down Expand Up @@ -211,6 +212,8 @@ The pushed notifications is defined by the [Firebase Cloud Messaging HTTP Protoc

### Encrypted subject data

#### Normal content notification

If you are missing any information necessary to parse the notification in a more usable way, use the `nid` to get the full notification information via [OCS API](ocs-endpoint-v2.md)

```json
Expand All @@ -220,7 +223,6 @@ If you are missing any information necessary to parse the notification in a more
"type" : "chat",
"id" : "t0k3n",
"nid" : 1337
}
}
```

Expand All @@ -233,6 +235,38 @@ If you are missing any information necessary to parse the notification in a more
| `nid` | Numeric identifier of the notification in order to get more information via the [OCS API](ocs-endpoint-v2.md) | `object-data` |


#### Silent delete notification (single)

These notifications should not be shown to the user. Instead you should delete pending system notifications for the respective id

```json
{
"delete" : true,
"nid" : 1337
}
```

| Attribute | Meaning | Capability |
| ----------- | ---------------------------------------- |------------|
| `nid` | Numeric identifier of the notification in order to get more information via the [OCS API](ocs-endpoint-v2.md) | `object-data` |
| `delete` | Delete all notifications related to `nid` | `delete` |


#### Silent delete notification (all)

These notifications should not be shown to the user. Instead you should delete all pending system notifications for this account

```json
{
"delete-all" : true
}
```

| Attribute | Meaning | Capability |
| ----------- | ---------------------------------------- |------------|
| `delete-all` | Delete all notifications related to this account | `delete` |


### Verification
So a device should verify the signature using the user´s public key.
If the signature is okay, the subject can be decrypted using the device´s private key.
6 changes: 3 additions & 3 deletions js/notifications.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/notifications.js.map

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions lib/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function __construct(Handler $handler, Push $push) {
* @throws \InvalidArgumentException When the notification is not valid
* @since 8.2.0
*/
public function notify(INotification $notification) {
public function notify(INotification $notification): void {
$notificationId = $this->handler->add($notification);

try {
Expand All @@ -66,7 +66,13 @@ public function getCount(INotification $notification): int {
* @param INotification $notification
* @since 8.2.0
*/
public function markProcessed(INotification $notification) {
$this->handler->delete($notification);
public function markProcessed(INotification $notification): void {
$deleted = $this->handler->delete($notification);

foreach ($deleted as $user => $notifications) {
foreach ($notifications as $notificationId) {
$this->push->pushDeleteToDevice($user, $notificationId);
}
}
}
}
29 changes: 12 additions & 17 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,26 @@ public function __construct() {
});
}

public function register() {
public function register(): void {
$this->registerNotificationApp();
$this->registerAdminNotifications();
$this->registerUserInterface();
}

protected function registerNotificationApp() {
$container = $this->getContainer();
$container->getServer()->getNotificationManager()->registerApp(function() use($container) {
return $container->query(App::class);
});
protected function registerNotificationApp(): void {
$this->getContainer()
->getServer()
->getNotificationManager()
->registerApp(App::class);
}
protected function registerAdminNotifications() {
$this->getContainer()->getServer()->getNotificationManager()->registerNotifier(function() {
return $this->getContainer()->query(AdminNotifications::class);
}, function() {
$l = $this->getContainer()->getServer()->getL10NFactory()->get('notifications');
return [
'id' => 'admin_notifications',
'name' => $l->t('Admin notifications'),
];
});
protected function registerAdminNotifications(): void {
$this->getContainer()
->getServer()
->getNotificationManager()
->registerNotifierService(AdminNotifications::class);
}

protected function registerUserInterface() {
protected function registerUserInterface(): void {
// Only display the app on index.php except for public shares
$server = $this->getContainer()->getServer();
$request = $server->getRequest();
Expand Down
2 changes: 2 additions & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ public function getCapabilities(): array {
'delete-all',
'icons',
'rich-strings',
'action-web',
],
'push' => [
'devices',
'object-data',
'delete',
],
'admin-notifications' => [
'ocs',
Expand Down
23 changes: 18 additions & 5 deletions lib/Controller/EndpointController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

use OCA\Notifications\Exceptions\NotificationNotFoundException;
use OCA\Notifications\Handler;
use OCA\Notifications\Push;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
Expand All @@ -37,15 +38,15 @@
class EndpointController extends OCSController {
/** @var Handler */
private $handler;

/** @var IManager */
private $manager;

/** @var IConfig */
private $config;
/** @var IUserSession */
private $session;
/** @var Push */
private $push;

/** @var IConfig */
private $config;

/**
* @param string $appName
Expand All @@ -54,14 +55,22 @@ class EndpointController extends OCSController {
* @param IManager $manager
* @param IConfig $config
* @param IUserSession $session
* @param Push $push
*/
public function __construct($appName, IRequest $request, Handler $handler, IManager $manager, IConfig $config, IUserSession $session) {
public function __construct(string $appName,
IRequest $request,
Handler $handler,
IManager $manager,
IConfig $config,
IUserSession $session,
Push $push) {
parent::__construct($appName, $request);

$this->handler = $handler;
$this->manager = $manager;
$this->config = $config;
$this->session = $session;
$this->push = $push;
}

/**
Expand All @@ -81,6 +90,7 @@ public function listNotifications(string $apiVersion): DataResponse {
$filter = $this->manager->createNotification();
$filter->setUser($this->getCurrentUser());
$language = $this->config->getUserValue($this->getCurrentUser(), 'core', 'lang', null);
$language = $language ?? $this->config->getSystemValue('default_language', 'en');

$notifications = $this->handler->get($filter);

Expand Down Expand Up @@ -131,6 +141,7 @@ public function getNotification(string $apiVersion, int $id): DataResponse {
}

$language = $this->config->getUserValue($this->getCurrentUser(), 'core', 'lang', null);
$language = $language ?? $this->config->getSystemValue('default_language', 'en');

try {
$notification = $this->manager->prepare($notification, $language);
Expand All @@ -154,6 +165,7 @@ public function deleteNotification(int $id): DataResponse {
}

$this->handler->deleteById($id, $this->getCurrentUser());
$this->push->pushDeleteToDevice($this->getCurrentUser(), $id);
return new DataResponse();
}

Expand All @@ -164,6 +176,7 @@ public function deleteNotification(int $id): DataResponse {
*/
public function deleteAllNotifications(): DataResponse {
$this->handler->deleteByUser($this->getCurrentUser());
$this->push->pushDeleteToDevice($this->getCurrentUser(), 0);
return new DataResponse();
}

Expand Down
27 changes: 24 additions & 3 deletions lib/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,33 @@ public function count(INotification $notification): int {
* Delete the notifications matching the given Notification
*
* @param INotification $notification
* @return array A Map with all deleted notifications [user => [notifications]]
*/
public function delete(INotification $notification) {
public function delete(INotification $notification): array {
$sql = $this->connection->getQueryBuilder();
$sql->delete('notifications');
$sql->select('notification_id', 'user')
->from('notifications');

$this->sqlWhere($sql, $notification);
$sql->execute();
$statement = $sql->execute();

$deleted = [];
while ($row = $statement->fetch()) {
if (!isset($deleted[$row['user']])) {
$deleted[$row['user']] = [];
}

$deleted[$row['user']][] = (int) $row['notification_id'];
}
$statement->closeCursor();

foreach ($deleted as $user => $notifications) {
foreach ($notifications as $notificationId) {
$this->deleteById($notificationId, $user);
}
}

return $deleted;
}

/**
Expand Down
24 changes: 23 additions & 1 deletion lib/Notifier/AdminNotifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

use OCP\IURLGenerator;
use OCP\L10N\IFactory;
use OCP\Notification\AlreadyProcessedException;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;

Expand All @@ -45,13 +46,34 @@ public function __construct(IFactory $l10nFactory, IURLGenerator $urlGenerator)
$this->urlGenerator = $urlGenerator;
}

/**
* Identifier of the notifier, only use [a-z0-9_]
*
* @return string
* @since 17.0.0
*/
public function getID(): string {
return 'admin_notifications';
}

/**
* Human readable name describing the notifier
*
* @return string
* @since 17.0.0
*/
public function getName(): string {
return $this->l10nFactory->get('notifications')->t('Admin notifications');
}

/**
* @param INotification $notification
* @param string $languageCode The code of the language that should be used to prepare the notification
* @return INotification
* @throws \InvalidArgumentException When the notification was not prepared by a notifier
* @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted
*/
public function prepare(INotification $notification, $languageCode): INotification {
public function prepare(INotification $notification, string $languageCode): INotification {
if ($notification->getApp() !== 'admin_notifications') {
throw new \InvalidArgumentException('Unknown app');
}
Expand Down
Loading