Ubiquity 2.5.2
php rapid development framework
Loading...
Searching...
No Matches
AuthAccountRecoveryTrait.php
Go to the documentation of this file.
1<?php
2
4
5use Ajax\semantic\html\collections\form\HtmlForm;
11
21
22 protected static string $TOKENS_RECOVERY_ACCOUNT='account.recovery';
23
24 abstract protected function fMessage(FlashMessage $fMessage, $id = null):string;
25
26 abstract protected function _getFiles(): AuthFiles;
27
28 abstract protected function getBaseUrl():string;
29
30 abstract protected function authLoadView($viewName, $vars = [ ]):void;
31
32 abstract protected function useAjax():bool;
33
34 abstract public function _getBodySelector():string;
35
36 abstract public function _addFrmAjaxBehavior($id):HtmlForm;
37
38 abstract public function _getPasswordInputName():string;
39
40 abstract protected function passwordConfLabel():string;
41
42 abstract protected function passwordLabel():string;
43
44 abstract public function info($force = null);
45
46 abstract protected function validateEmail(string $mail):bool;
47
51 protected function hasAccountRecovery():bool{
52 return false;
53 }
54
60 protected function recoveryInitMessage(FlashMessage $fMessage){
61
62 }
63
69 protected function recoveryEmailSendMessage(FlashMessage $fMessage){
70
71 }
72
78 protected function recoveryEmailErrorMessage(FlashMessage $fMessage){
79
80 }
81
87 protected function resetPasswordSuccessMessage(FlashMessage $fMessage){
88
89 }
90
96 protected function resetPasswordErrorMessage(FlashMessage $fMessage){
97
98 }
99
105 protected function emailAccountRecoverySuccess(FlashMessage $fMessage){
106
107 }
108
114 protected function emailAccountRecoveryError(FlashMessage $fMessage){
115
116 }
117
123 protected function recoveryAccountCaption():string{
124 return 'Forgot your password?';
125 }
126
131 protected function accountRecoveryDuration():\DateInterval{
132 return new \DateInterval('PT30M');
133 }
134
141 return new AuthTokens(self::$TOKENS_RECOVERY_ACCOUNT,10,$this->accountRecoveryDuration()->s,true);
142 }
143
150 protected function isValidEmailForRecovery(string $email):bool {
151 return true;
152 }
153
161 protected function _sendEmailAccountRecovery(string $email,string $validationURL,string $expire):bool{
162 return false;
163 }
164
172 protected function passwordResetAction(string $email,string $newPasswordHash):bool{
173 return false;
174 }
175
176 protected function getAccountRecoveryLink():string{
177 $href=$this->getBaseUrl().'/recoveryInit';
178 $target=$this->_getBodySelector();
179 $caption=$this->recoveryAccountCaption();
180 return "<a class='_recovery' href='$href' data-target='$target'>$caption</a>";
181 }
182
183 public function recoveryInit(){
184 $fMessage = new FlashMessage( 'Enter the email associated with your account to receive a password reset link.', 'Account recovery', 'info', 'user' );
185 $this->recoveryInitMessage ( $fMessage );
186 $message = $this->fMessage ( $fMessage );
187 if($this->useAjax()){
188 $frm=$this->jquery->semantic()->htmlForm('frm-account-recovery');
189 $frm->addExtraFieldRules('email',['empty','email']);
190 $frm->setValidationParams(['inline'=>true,'on'=>'blur']);
191 }
192 $this->authLoadView ( $this->_getFiles ()->getViewInitRecovery(), [ '_message' => $message,'submitURL' => $this->getBaseUrl ().'/recoveryInfo','bodySelector' => $this->_getBodySelector()] );
193 }
194
198 #[\Ubiquity\attributes\items\router\Post]
199 public function recoveryInfo(){
200 if(URequest::isPost()){
201 if($this->isValidEmailForRecovery($email=URequest::filterPost('email',FILTER_VALIDATE_EMAIL))) {
202 $this->prepareEmailAccountRecovery($email);
203 $fMessage = new FlashMessage (sprintf('A password reset email has been sent to <b>%s</b>.<br>You can only use this link temporarily, from the same machine, on this browser.',$email), 'Account recovery', 'success', 'email');
204 $this->recoveryEmailSendMessage($fMessage);
205 }else{
206 $fMessage = new FlashMessage (sprintf('No account is associated with the email address <b>%s</b>.<br><a href="%s" data-target="%s">Try again.</a>.',$email,$this->getBaseUrl().'/recoveryInit',$this->_getBodySelector()), 'Account recovery', 'error', 'user');
207 $this->recoveryEmailErrorMessage($fMessage);
208 }
209 echo $this->fMessage ( $fMessage );
210 }
211 }
212
213 public function recovery(string $key,string $hashMail) {
214 $tokens = $this->getAuthTokensAccountRecovery();
215 if ($tokens->exists($key)) {
216 if (!$tokens->expired($key)) {
217 $data = $tokens->fetch($key);
218 if(\is_array($data)) {
219 $email = $data['email'];
220 if (\md5($email) === $hashMail && $this->validateEmail($email)) {
221 $fMessage = new FlashMessage ("Enter a new password associated to the account <b>$email</b>.", 'Account recovery', 'success', 'user');
222 $this->emailAccountRecoverySuccess($fMessage);
223 $message=$this->fMessage($fMessage);
224 if($this->useAjax()) {
225 $frm = $this->_addFrmAjaxBehavior('frm-account-recovery');
226 $passwordInputName = $this->_getPasswordInputName();
227 $frm->addExtraFieldRules($passwordInputName . '-conf', ['empty', "match[$passwordInputName]"]);
228 }
229 $this->authLoadView ( $this->_getFiles ()->getViewRecovery(), [ 'key'=>$key,'email'=>$email,'_message' => $message,'submitURL' => $this->getBaseUrl ().'/recoverySubmit','bodySelector' => $this->_getBodySelector(),'passwordInputName' => $this->_getPasswordInputName (),'passwordLabel' => $this->passwordLabel (),'passwordConfLabel'=>$this->passwordConfLabel()] );
230 return ;
231 }
232 }
233 $msg = 'This recovery link was not generated on this device!';
234 } else {
235 $msg = 'This recovery link is no longer active!';
236 }
237 }
238 $fMessage = new FlashMessage ($msg ?? 'This account recovery link is not valid!', 'Account recovery', 'error', 'user');
239 $this->emailAccountRecoveryError($fMessage);
240 echo $this->fMessage($fMessage);
241 }
242
243 protected function generateEmailAccountRecoveryUrl($email):array {
244 $duration=$this->accountRecoveryDuration();
245 $tokens=$this->getAuthTokensAccountRecovery();
246 $d=new \DateTime();
247 $dExpire=$d->add($duration);
248 $key=$tokens->store(['email'=>$email]);
249 return ['url'=>$key.'/'.\md5($email),'expire'=>$dExpire];
250 }
251
252 protected function prepareEmailAccountRecovery(string $email){
253 $data=$this->generateEmailAccountRecoveryUrl($email);
254 $validationURL=$this->getBaseUrl().'/recovery/'.$data['url'];
255 $this->_sendEmailAccountRecovery($email, $validationURL,UDateTime::elapsed($data['expire']));
256 }
257
261 #[\Ubiquity\attributes\items\router\Post]
262 public function recoverySubmit(){
263 if(URequest::isPost() && URequest::has('key')){
264 $isValid=false;
265 $msg='This account recovery link is invalid!';
266 $tokens = $this->getAuthTokensAccountRecovery();
267 $key=URequest::post('key');
268 if ($tokens->exists($key)) {
269 if(!$tokens->expired($key)){
270 $data=$tokens->fetch($key);
271 $email=$data['email'];
272 if($email===URequest::post('email')){
273 if($this->passwordResetAction($email,URequest::password_hash('password'))){
274 $fMessage = new FlashMessage ("Your password has been updated correctly for the account associated with <b>$email</b>.", 'Account recovery', 'success', 'user');
275 $this->resetPasswordSuccessMessage($fMessage);
276 echo $this->info(true);
277 $isValid=true;
278 }else{
279 $msg='An error occurs when updating your password!';
280 }
281 }
282 }else{
283 $msg='This account recovery link is expired!';
284 }
285 $tokens->remove($key);
286 }
287 if(!$isValid){
288 $fMessage = new FlashMessage ($msg, 'Account recovery', 'error', 'user');
289 $this->resetPasswordErrorMessage($fMessage);
290 }
291 echo $this->fMessage($fMessage);
292 }
293 }
294
295}
296
Ubiquity\controllers\auth$AuthFiles This class is part of Ubiquity.
Definition AuthFiles.php:13
Ubiquity\controllers\auth\traits$AuthAccountRecoveryTrait This class is part of Ubiquity.
emailAccountRecoveryError(FlashMessage $fMessage)
To override Displayed when the account recovery link is not valid.
recoveryEmailSendMessage(FlashMessage $fMessage)
To override Displayed when email is sent for a recovery account operation.
isValidEmailForRecovery(string $email)
To override Checks if a valid account matches this email.
resetPasswordSuccessMessage(FlashMessage $fMessage)
To override Displayed when a new password is set with recovery account.
recoveryInitMessage(FlashMessage $fMessage)
To override Displayed when an account recovery operation is initiated.
recoveryAccountCaption()
Returns the recovery account link caption.
recoveryEmailErrorMessage(FlashMessage $fMessage)
To override Displayed when email is not associated with an existing account.
_sendEmailAccountRecovery(string $email, string $validationURL, string $expire)
Sends an email for account recovery (password reset).
emailAccountRecoverySuccess(FlashMessage $fMessage)
To override Displayed when the account recovery link is valid.
getAuthTokensAccountRecovery()
To override Returns the AuthTokens instance used for tokens generation for a recovery account.
accountRecoveryDuration()
Returns the default validity duration for an email account recovery.
passwordResetAction(string $email, string $newPasswordHash)
To override Changes the active password associated with the account corresponding to this email.
resetPasswordErrorMessage(FlashMessage $fMessage)
To override Displayed when an error occurs when a new password is set with recovery account.
DateTime utilities Ubiquity\utils\base$UDateTime This class is part of Ubiquity.
Definition UDateTime.php:14
Http Request utilities, wrapper for accessing to $_GET, $_POST and php://input.
Definition URequest.php:18