Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.86% covered (warning)
75.86%
22 / 29
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
TwofactorGatewayListener
75.86% covered (warning)
75.86%
22 / 29
40.00% covered (danger)
40.00%
2 / 5
11.41
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 transport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 supportedEvents
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handle
60.00% covered (warning)
60.00%
6 / 10
0.00% covered (danger)
0.00%
0 / 1
1.06
 sendNotification
87.50% covered (warning)
87.50%
14 / 16
0.00% covered (danger)
0.00%
0 / 1
6.07
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2025-2026 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Listener;
10
11use OCA\Libresign\Db\File as FileEntity;
12use OCA\Libresign\Db\SignRequest;
13use OCA\Libresign\Events\SendSignNotificationEvent;
14use OCA\Libresign\Events\SignedEvent;
15use OCA\Libresign\Service\IdentifyMethod\IIdentifyMethod;
16use OCA\Libresign\Service\IdentifyMethodService;
17use OCA\Libresign\Service\Notification\GatewayChannel;
18use OCA\Libresign\Service\Notification\GatewayNotificationComposer;
19use OCA\Libresign\Service\Notification\NotificationMessage;
20use OCA\Libresign\Service\Notification\NotificationModule;
21use OCA\Libresign\Service\NotificationDeliveryService;
22use OCA\Libresign\Service\TwofactorGatewayService;
23use OCP\EventDispatcher\Event;
24
25/** Plan gateway deliveries, not transport execution or message rendering. */
26class TwofactorGatewayListener implements NotificationModule {
27    public function __construct(
28        private TwofactorGatewayService $twofactorGatewayService,
29        private NotificationDeliveryService $deliveryService,
30        private GatewayChannel $channel,
31        private GatewayNotificationComposer $composer,
32    ) {
33    }
34
35    #[\Override]
36    public function transport(): \OCA\Libresign\Service\Notification\NotificationChannel {
37        return $this->channel;
38    }
39
40    /** @return list<class-string<Event>> */
41    #[\Override]
42    public static function supportedEvents(): array {
43        return [SendSignNotificationEvent::class, SignedEvent::class];
44    }
45
46    #[\Override]
47    public function handle(Event $event): void {
48        match ($event::class) {
49            SendSignNotificationEvent::class => $this->sendNotification(
50                $event->getSignRequest(), $event->getIdentifyMethod(), $event->getLibreSignFile(),
51                'sign_request', $event->getDeliveryEventId(),
52            ),
53            SignedEvent::class => $this->sendNotification(
54                $event->getSignRequest(), $event->getIdentifyMethod(), $event->getLibreSignFile(),
55                'file_signed', $event->getDeliveryEventId(),
56            ),
57        };
58    }
59
60    private function sendNotification(
61        SignRequest $signRequest,
62        IIdentifyMethod $identifyMethod,
63        FileEntity $file,
64        string $eventType,
65        string $eventId,
66    ): void {
67        $entity = $identifyMethod->getEntity();
68        if ($entity->isDeletedAccount()
69            || !in_array($entity->getIdentifierKey(), IdentifyMethodService::IDENTIFY_TWOFACTOR_GATEWAY_METHODS, true)) {
70            return;
71        }
72        if (!$this->twofactorGatewayService->isEnabled()) {
73            return;
74        }
75        $recipient = $entity->getIdentifierValue();
76        if (trim($recipient) === '') {
77            return;
78        }
79        $gatewayName = IdentifyMethodService::resolveTwofactorGatewayName($entity->getIdentifierKey());
80        $payload = $this->composer->composePayload($eventType, $signRequest, $file, $entity->getIdentifierKey(), $gatewayName);
81        $this->deliveryService->dispatch(new NotificationMessage(
82            $eventId, $eventType, 'gateway:' . $gatewayName, $file, $signRequest,
83            $recipient, $payload,
84            $eventType === 'sign_request' ? $entity->getIdentifierKey() : null,
85        ), $this->channel);
86    }
87}