]> git.mxchange.org Git - friendica.git/blob - src/Model/TwoFactor/RecoveryCode.php
Fix birthday display and setting
[friendica.git] / src / Model / TwoFactor / RecoveryCode.php
1 <?php
2
3 namespace Friendica\Model\TwoFactor;
4
5 use Friendica\Database\DBA;
6 use Friendica\Util\DateTimeFormat;
7 use PragmaRX\Random\Random;
8 use PragmaRX\Recovery\Recovery;
9
10 /**
11  * Manages users' two-factor recovery codes in the 2fa_recovery_codes table
12  *
13  * @package Friendica\Model
14  */
15 class RecoveryCode
16 {
17     /**
18      * Returns the number of code the provided users can still use to replace a TOTP code
19      *
20      * @param int $uid User ID
21      * @return int
22      * @throws \Exception
23      */
24     public static function countValidForUser($uid)
25         {
26                 return DBA::count('2fa_recovery_codes', ['uid' => $uid, 'used' => null]);
27         }
28
29     /**
30      * Checks the provided code is available to use for login by the provided user
31      *
32      * @param  int $uid User ID
33      * @param string $code
34      * @return bool
35      * @throws \Exception
36      */
37         public static function existsForUser($uid, $code)
38         {
39                 return DBA::exists('2fa_recovery_codes', ['uid' => $uid, 'code' => $code, 'used' => null]);
40         }
41
42     /**
43      * Returns a complete list of all recovery codes for the provided user, including the used status
44      *
45      * @param  int $uid User ID
46      * @return array
47      * @throws \Exception
48      */
49         public static function getListForUser($uid)
50         {
51                 $codesStmt = DBA::select('2fa_recovery_codes', ['code', 'used'], ['uid' => $uid]);
52
53                 return DBA::toArray($codesStmt);
54         }
55
56     /**
57      * Marks the provided code as used for the provided user.
58      * Returns false if the code doesn't exist for the user or it has been used already.
59      *
60      * @param  int $uid User ID
61      * @param string $code
62      * @return bool
63      * @throws \Exception
64      */
65         public static function markUsedForUser($uid, $code)
66         {
67                 DBA::update('2fa_recovery_codes', ['used' => DateTimeFormat::utcNow()], ['uid' => $uid, 'code' => $code, 'used' => null]);
68
69                 return DBA::affectedRows() > 0;
70         }
71
72     /**
73      * Generates a fresh set of recovery codes for the provided user.
74      * Generates 12 codes constituted of 2 blocks of 6 characters separated by a dash.
75      *
76      * @param  int $uid User ID
77      * @throws \Exception
78      */
79         public static function generateForUser($uid)
80         {
81                 $Random = (new Random())->pattern('[a-z0-9]');
82
83                 $RecoveryGenerator = new Recovery($Random);
84
85                 $codes = $RecoveryGenerator
86                         ->setCount(12)
87                         ->setBlocks(2)
88                         ->setChars(6)
89                         ->lowercase(true)
90                         ->toArray();
91
92                 $generated = DateTimeFormat::utcNow();
93                 foreach ($codes as $code) {
94                         DBA::insert('2fa_recovery_codes', [
95                                 'uid' => $uid,
96                                 'code' => $code,
97                                 'generated' => $generated
98                         ]);
99                 }
100         }
101
102     /**
103      * Deletes all the recovery codes for the provided user.
104      *
105      * @param  int $uid User ID
106      * @throws \Exception
107      */
108         public static function deleteForUser($uid)
109         {
110                 DBA::delete('2fa_recovery_codes', ['uid' => $uid]);
111         }
112
113     /**
114      * Replaces the existing recovery codes for the provided user by a freshly generated set.
115      *
116      * @param  int $uid User ID
117      * @throws \Exception
118      */
119         public static function regenerateForUser($uid)
120         {
121                 self::deleteForUser($uid);
122                 self::generateForUser($uid);
123         }
124 }