Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
EmailToken
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
6 / 6
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 validateToSign
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
5
 getEmail
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 blurEmail
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 requestCode
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Service\IdentifyMethod\SignatureMethod;
10
11use OCA\Libresign\Exception\LibresignException;
12use OCA\Libresign\Service\IdentifyMethod\IdentifyService;
13use OCA\Libresign\Vendor\Wobeto\EmailBlur\Blur;
14
15class EmailToken extends AbstractSignatureMethod implements IToken {
16    public function __construct(
17        protected IdentifyService $identifyService,
18        protected TokenService $tokenService,
19    ) {
20        // TRANSLATORS Name of possible authenticator method. This signalize that the signer could be identified by email
21        $this->setFriendlyName($this->identifyService->getL10n()->t('Email token'));
22        parent::__construct(
23            $identifyService,
24        );
25    }
26
27    #[\Override]
28    public function validateToSign(): void {
29        $this->throwIfInvalidToken();
30    }
31
32    #[\Override]
33    public function toArray(): array {
34        $entity = $this->getEntity();
35
36        $email = $this->getEmail();
37
38        $emailLowercase = strtolower($email);
39
40        $code = $entity->getCode();
41        $identifiedAt = $entity->getIdentifiedAtDate();
42        $codeSentByUser = $this->codeSentByUser;
43
44        $hasConfirmCode = !empty($code);
45        $needCode = empty($code)
46            || empty($identifiedAt)
47            || empty($codeSentByUser);
48
49        return [
50            'label' => $this->getFriendlyName(),
51            'identifyMethod' => match ($entity->getIdentifierKey()) {
52                'emailToken' => 'email',
53                default => $entity->getIdentifierKey(),
54            },
55            'needCode' => $needCode,
56            'hasConfirmCode' => $hasConfirmCode,
57            'blurredEmail' => $emailLowercase ? $this->blurEmail($emailLowercase) : '',
58            'hashOfEmail' => $emailLowercase ? md5($emailLowercase) : '',
59        ];
60    }
61
62    private function getEmail(): string {
63        $entity = $this->getEntity();
64
65        return match ($entity->getIdentifierKey()) {
66            'email', 'emailToken' => $entity->getIdentifierValue(),
67            'account' => $this->identifyService->getUserManager()->get($entity->getIdentifierValue())
68                ?->getEMailAddress() ?? '',
69            default => '',
70        };
71    }
72
73    private function blurEmail(string $email): string {
74        $blur = new Blur($email);
75        return $blur->make();
76    }
77
78    #[\Override]
79    public function requestCode(): void {
80        $identifier = $this->getEmail();
81        if (!filter_var($identifier, FILTER_VALIDATE_EMAIL)) {
82            // TRANSLATORS Generic error shown when a verification code cannot be delivered.
83            throw new LibresignException($this->identifyService->getL10n()->t('Unable to send verification code.'));
84        }
85
86        $signRequestMapper = $this->identifyService->getSignRequestMapper();
87        $signRequest = $signRequestMapper->getById($this->getEntity()->getSignRequestId());
88        $displayName = $signRequest->getDisplayName();
89        if ($identifier === $displayName) {
90            $displayName = '';
91        }
92        $code = $this->tokenService->sendCodeByEmail($identifier, $displayName);
93        $this->getEntity()->setCode($code);
94        $this->identifyService->save($this->getEntity());
95    }
96}