Passed
Push — master ( 8a8111...583a39 )
by Jean-Christophe
19:52
created

AuthAccountCreationTrait::_create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Ubiquity\controllers\auth\traits;
4
5
use Ajax\semantic\components\validation\Rule;
6
use Ajax\semantic\html\collections\form\HtmlForm;
7
use Ubiquity\controllers\auth\AuthFiles;
8
use Ubiquity\controllers\auth\AuthTokens;
9
use Ubiquity\utils\base\UDateTime;
10
use Ubiquity\utils\flash\FlashMessage;
11
use Ubiquity\utils\http\URequest;
12
13
/**
14
 * Trait AuthAccountCreationTrait
15
 *
16
 */
17
trait AuthAccountCreationTrait {
18
19
	protected static string $TOKENS_VALIDATE_EMAIL='email.validation';
20
21
	abstract protected function getBaseUrl():string;
22
23
	abstract protected function fMessage(FlashMessage $fMessage, $id = null):string;
24
25
	abstract protected function useAjax():bool;
26
27
	abstract public function _addFrmAjaxBehavior($id):HtmlForm;
28
29
	abstract public function _getPasswordInputName():string;
30
31
	abstract public function _getLoginInputName():string;
32
33
	abstract protected function authLoadView($viewName, $vars = [ ]):void;
34
35
	abstract protected function rememberCaption():string;
36
37
	abstract protected function loginLabel():string;
38
39
	abstract protected function passwordConfLabel(): string;
40
41
	abstract protected function passwordLabel(): string;
42
43
	abstract protected function _getFiles(): AuthFiles;
44
45
	abstract public function _getBodySelector():string;
46
47
	/**
48
	 * Returns true for account creation.
49
	 * @return boolean
50
	 */
51 1
	protected function hasAccountCreation():bool{
52 1
		return false;
53
	}
54
55
	/**
56
	 *
57
	 * @return bool
58
	 */
59
	protected function hasEmailValidation():bool{
60
		return false;
61
	}
62
63
	/**
64
	 * Returns the default validity duration of a mail validation link.
65
	 * @return \DateInterval
66
	 */
67
	protected function emailValidationDuration():\DateInterval{
68
		return new \DateInterval('PT24H');
69
	}
70
	/**
71
	 * To override for modifying the account creation message.
72
	 *
73
	 * @param FlashMessage $fMessage
74
	 */
75
	protected function createAccountMessage(FlashMessage $fMessage) {
76
	}
77
78
	/**
79
	 * To override for modifying the account creation message information.
80
	 *
81
	 * @param FlashMessage $fMessage
82
	 */
83
	protected function canCreateAccountMessage(FlashMessage $fMessage) {
84
	}
85
86
	/**
87
	 * To override for modifying the error for account creation.
88
	 *
89
	 * @param FlashMessage $fMessage
90
	 */
91
	protected function createAccountErrorMessage(FlashMessage $fMessage) {
92
	}
93
94
	/**
95
	 * To override
96
	 * Displayed when email is valid.
97
	 * @param FlashMessage $fMessage
98
	 */
99
	protected function emailValidationSuccess(FlashMessage $fMessage){
100
101
	}
102
103
	/**
104
	 * To override
105
	 * Displayed when email is invalid or if an error occurs.
106
	 * @param FlashMessage $fMessage
107
	 */
108
	protected function emailValidationError(FlashMessage $fMessage){
109
110
	}
111
112
	/**
113
	 * To override
114
	 * For creating a new user account.
115
	 */
116 1
	protected function _create(string $login,string $password):?bool{
117 1
		return false;
118
	}
119
	
120
	/**
121
	 * To override
122
	 * Returns true if the creation of $accountName is possible.
123
	 * @param string $accountName
124
	 * @return bool
125
	 */
126
	protected function _newAccountCreationRule(string $accountName):?bool{
127
		
128
	}
129
	
130
	/**
131
	 * Sends an email for email checking.
132
	 * @param string $email
133
	 * @param string $validationURL
134
	 * @param string $expire
135
	 */
136
	protected function _sendEmailValidation(string $email,string $validationURL,string $expire):void{
137
		
138
	}
139
	
140
	/**
141
	 * To override
142
	 * Returns the email from an account object.
143
	 * @param mixed $account
144
	 * @return string
145
	 */
146
	protected function getEmailFromNewAccount($account):string{
147
		return $account;
148
	}
149
150
	/**
151
	 * To override
152
	 * Returns the AuthTokens instance used for tokens generation when sending an email for the account creation.
153
	 * @return AuthTokens
154
	 */
155
	protected function getAuthTokensEmailValidation():AuthTokens{
156
		return new AuthTokens(self::$TOKENS_VALIDATE_EMAIL,10,$this->emailValidationDuration()->s,false);
157
	}
158
159
	protected function generateEmailValidationUrl($email):array {
160
		$duration=$this->emailValidationDuration();
161
		$tokens=$this->getAuthTokensEmailValidation();
162
		$d=new \DateTime();
163
		$dExpire=$d->add($duration);
164
		$key=$tokens->store(['email'=>$email]);
165
		return ['url'=>$key.'/'.\md5($email),'expire'=>$dExpire];
166
	}
167
168
	protected function prepareEmailValidation(string $email){
169
		$data=$this->generateEmailValidationUrl($email);
170
		$validationURL=$this->getBaseUrl().'/checkEmail/'.$data['url'];
171
		$this->_sendEmailValidation($email, $validationURL,UDateTime::elapsed($data['expire']));
172
	}
173
174
	/**
175
	 * To override
176
	 * Checks an email.
177
	 *
178
	 * @param string $mail
179
	 * @return bool
180
	 */
181
	protected function validateEmail(string $mail):bool{
182
		return true;
183
	}
184
185
186
	/**
187
	 * Route for email validation checking when creating a new account.
188
	 * @param string $key
189
	 * @param string $hashMail
190
	 */
191
	public function checkEmail(string $key,string $hashMail){
192
		$isValid=false;
193
		$tokens=$this->getAuthTokensEmailValidation();
194
		if($tokens->exists($key)){
195
			if(!$tokens->expired($key)){
196
				$data=$tokens->fetch($key);
197
				$email=$data['email'];
198
				if(\md5($email)===$hashMail && $this->validateEmail($email)){
199
					$fMessage = new FlashMessage ( "Your email <b>$email</b> has been validated.", 'Account creation', 'success', 'user' );
200
					$this->emailValidationSuccess($fMessage);
201
					$isValid=true;
202
				}
203
				$msg='This validation link is not valid!';
204
			}else{
205
				$msg='This validation link is no longer active!';
206
			}
207
		}
208
		if(!$isValid){
209
			$fMessage = new FlashMessage ( $msg??'This validation link is not valid!', 'Account creation', 'error', 'user' );
210
			$this->emailValidationError($fMessage);
211
		}
212
		echo $this->fMessage($fMessage);
213
	}
214
215
	/**
216
	 * Displays the account creation form.
217
	 * Form is submited to /createAccount action
218
	 */
219 1
	public function addAccount(){
220 1
		if($this->hasAccountCreation()){
221 1
			if($this->useAjax()){
222 1
				$frm=$this->_addFrmAjaxBehavior('frm-create');
223 1
				$passwordInputName=$this->_getPasswordInputName();
224 1
				$frm->addExtraFieldRules($passwordInputName.'-conf', ['empty',"match[$passwordInputName]"]);
225 1
				if($this->_newAccountCreationRule('')!==null){
226 1
					$this->jquery->exec(Rule::ajax($this->jquery, 'checkAccount', $this->getBaseUrl () . '/newAccountCreationRule', '{}', 'result=data.result;', 'postForm', [
227 1
						'form' => 'frm-create'
228
					]), true);
229 1
					$frm->addExtraFieldRule($this->_getLoginInputName(), 'checkAccount','Account {value} is not available!');
230
				}
231
			}
232 1
			$this->authLoadView ( $this->_getFiles ()->getViewCreate(), [ 'action' => $this->getBaseUrl () . '/createAccount','loginInputName' => $this->_getLoginInputName (),'loginLabel' => $this->loginLabel (),'passwordInputName' => $this->_getPasswordInputName (),'passwordLabel' => $this->passwordLabel (),'passwordConfLabel'=>$this->passwordConfLabel(),'rememberCaption' => $this->rememberCaption () ] );
233
		}
234
	}
235
236
237
	/**
238
	 * Submit for a new account creation.
239
	 *
240
	 * @post
241
	 */
242
	#[\Ubiquity\attributes\items\router\Post]
243 1
	public function createAccount(){
244 1
		$account=URequest::post($this->_getLoginInputName());
245 1
		$msgSup='';
246 1
		if($this->_create($account,URequest::post($this->_getPasswordInputName()))){
247
			if($this->hasEmailValidation()){
248
				$email=$this->getEmailFromNewAccount($account);
249
				$this->prepareEmailValidation($email);
250
				$msgSup="<br>Confirm your email address <b>$email</b> by checking your mailbox.";
251
			}
252
			$msg=new FlashMessage ( '<b>{account}</b> account created with success!'.$msgSup, 'Account creation', 'success', 'check square' );
253
		}else{
254 1
			$msg=new FlashMessage ( 'The account <b>{account}</b> was not created!', 'Account creation', 'error', 'warning circle' );
255
		}
256 1
		$message=$this->fMessage($msg->parseContent(['account'=>$account]));
257 1
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
258
	}
259
}
260
261