3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
6 * Temporay links for galette, to send direct links to invoices, recipts,
7 * and member cards directly by email
11 * Copyright © 2020 The Galette Team
13 * This file is part of Galette (http://galette.tuxfamily.org).
15 * Galette is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
20 * Galette is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
31 * @author Johan Cwiklinski <johan@x-tnd.be>
32 * @copyright 2020 The Galette Team
33 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.9.4 - 2020-03-11
38 namespace Galette\Core
;
41 use Galette\Entity\Adherent
;
42 use Galette\Entity\Contribution
;
45 * Temporary password managment
50 * @author Johan Cwiklinski <johan@x-tnd.be>
51 * @copyright 2020 The Galette Team
52 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
53 * @link http://galette.tuxfamily.org
54 * @since Available since 0.9.4 - 2020-03-11
59 const TABLE
= 'tmplinks';
62 const TARGET_MEMBERCARD
= 1;
63 const TARGET_INVOICE
= 2;
64 const TARGET_RECEIPT
= 3;
71 * @param Db $zdb Database instance:
72 * @param boolean $clean Whether we should clean expired links in database
74 public function __construct(Db
$zdb, $clean = true)
77 if ($clean === true) {
78 $this->cleanExpired();
83 * Remove all old entry
85 * @param int $target Target (one of self::TARGET_* constants)
86 * @param int $id Target identifier
90 private function removeOldEntry($target, $id)
93 $delete = $this->zdb
->delete(self
::TABLE
);
99 $del = $this->zdb
->execute($delete);
102 'Temporary link for `' . $target . '-' . $id . '` has been removed.',
106 } catch (\Exception
$e) {
108 'An error has occurred removing old temporary link ' .
117 * Generates a new link for specified target
119 * @param int $target Target (one of self::TARGET_* constants)
120 * @param int $id Target identifier
122 * @return false|string
124 public function generateNewLink($target, $id)
126 //first of all, we'll remove all existant entries for specified id
127 $this->removeOldEntry($target, $id);
129 //second, generate a new hash and store it in the database
131 $select = $this->zdb
->select(Adherent
::TABLE
);
132 $select->columns([Adherent
::PK
, 'email_adh']);
134 if ($target === Links
::TARGET_MEMBERCARD
) {
137 //get member id from contribution
138 $cselect = $this->zdb
->select(Contribution
::TABLE
);
139 $cselect->columns([Adherent
::PK
])->where([Contribution
::PK
=> $id]);
140 $cresults = $this->zdb
->execute($cselect);
141 $cresult = $cresults->current();
142 $id_adh = $cresult->id_adh
;
145 $select->where([Adherent
::PK
=> $id_adh]);
146 $results = $this->zdb
->execute($select);
147 $result = $results->current();
148 $code = $result->email_adh
;
149 $hash = password_hash($code, PASSWORD_BCRYPT
);
154 'creation_date' => date('Y-m-d H:i:s'),
158 $insert = $this->zdb
->insert(self
::TABLE
);
159 $insert->values($values);
161 $add = $this->zdb
->execute($insert);
164 'New temporary link set for `' . $target . '-' . $id . '`.',
167 return base64_encode($hash);
170 } catch (\Exception
$e) {
172 "An error occurred trying to add temporary link entry. " .
181 * Get expiration date
185 private function getExpirationDate()
187 $date = new \
DateTime();
188 $date->sub(new \
DateInterval('P1W'));
193 * Remove expired links queries (older than 1 week)
197 protected function cleanExpired()
200 $date = $this->getExpirationDate();
201 $delete = $this->zdb
->delete(self
::TABLE
);
202 $delete->where
->lessThan(
204 $date->format('Y-m-d H:i:s')
206 $del = $this->zdb
->execute($delete);
209 'Expired temporary links has been deleted.',
215 } catch (\Exception
$e) {
217 'An error occurred deleting expired temporary links. ' .
226 * Check if requested hash is valid
228 * @param string $hash the hash, base64 encoded
229 * @param string $code Code sent to validate link
231 * @return false if hash is not valid, array otherwise
233 public function isHashValid($hash, $code)
236 $hash = base64_decode($hash);
237 $select = $this->zdb
->select(self
::TABLE
);
238 $select->where(array('hash' => $hash));
240 $date = $this->getExpirationDate();
241 $select->where
->greaterThanOrEqualTo(
243 $date->format('Y-m-d')
246 $results = $this->zdb
->execute($select);
248 if ($results->count() > 0) {
249 $result = $results->current();
250 if (password_verify($code, $result->hash
)) {
251 return [(int)$result->target
, (int)$result->id
];
255 } catch (\Exception
$e) {
257 'An error occurred getting requested hash. ' . $e->getMessage(),