Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
TOTPSecret
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
6 / 6
6
100.00% covered (success)
100.00%
1 / 1
 createRandom
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 createOTP
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRegularExpression
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUrl
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getQrCodeUri
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 verify
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\OtpValueObjects;
3
4use Apie\Core\ApieLib;
5use Apie\Core\Attributes\Description;
6use Apie\Core\Attributes\FakeMethod;
7use Apie\Core\Attributes\ProvideIndex;
8use Apie\Core\ValueObjects\Interfaces\StringValueObjectInterface;
9use Apie\Core\ValueObjects\IsStringWithRegexValueObject;
10use Apie\OtpValueObjects\Concerns\NoIndexing;
11use chillerlan\QRCode\QRCode;
12use OTPHP\TOTP;
13
14#[FakeMethod('createRandom')]
15#[ProvideIndex('noIndexing')]
16#[Description('A TOTP secret value')]
17class TOTPSecret implements StringValueObjectInterface
18{
19    use IsStringWithRegexValueObject;
20    use NoIndexing;
21
22    public static function createRandom(): self
23    {
24        $totp = TOTP::create(clock: ApieLib::getPsrClock());
25        return new self($totp->getSecret());
26    }
27
28    public function createOTP(): OTP
29    {
30        return new OTP(TOTP::create($this->internal, clock: ApieLib::getPsrClock())->now());
31    }
32
33    public static function getRegularExpression(): string
34    {
35        return '/^[A-Z0-9]{103}$/';
36    }
37
38    public function getUrl(string $label): string
39    {
40        $tmp = TOTP::create($this->internal, clock: ApieLib::getPsrClock());
41        $tmp->setLabel($label);
42        return (new QRCode)->render($tmp->getProvisioningUri());
43    }
44
45    public function getQrCodeUri(string $label): string
46    {
47        $tmp = TOTP::create($this->internal, clock: ApieLib::getPsrClock());
48        $tmp->setLabel($label);
49        return $tmp->getQrCodeUri(
50            'https://api.qrserver.com/v1/create-qr-code/?data=[DATA]&size=300x300&ecc=M',
51            '[DATA]'
52        );
53    }
54
55    public function verify(OTP $otp): bool
56    {
57        // Use OTPHP library to generate a TOTP and compare it with the inputOTP
58        $totp = TOTP::create($this->internal, clock: ApieLib::getPsrClock());
59        return $totp->verify($otp->toNative());
60    }
61}