Skip to content

Commit 53781b2

Browse files
authored
Merge pull request #10 from iazaran/features/enhancements
Features/enhancements
2 parents b887419 + 439ec82 commit 53781b2

File tree

19 files changed

+123
-17
lines changed

19 files changed

+123
-17
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/9b13bf034af64123821121d191acfaff)](https://app.codacy.com/manual/eazaran/php-mvc?utm_source=github.com&utm_medium=referral&utm_content=iazaran/php-mvc&utm_campaign=Badge_Grade_Dashboard)
44

5-
> This project tries to cover most of PHP features in a simple MVC structure without installing composer packages. Then developers can use packages for specific requirements. Please add your ideas in Discussions or report bugs in issues.
5+
> This project tries to cover most of PHP features in a simple MVC structure with minimum installed composer packages. Then developers can use packages for specific requirements. Please add your ideas in Discussions or report bugs in issues.
6+
7+
🚧 WIP: Email verification
68

79
#### Features:
810
**List of features related with structure**
@@ -43,7 +45,7 @@ Check Cross-site request forgery token
4345
- **Helper::slug(...)**
4446
Slugify string to make user-friendly URL
4547
- **Cache::checkCache(...)**, **Cache::cache(...)** & **Cache::clearCache(...)**
46-
Check existed cache and cache data if needed by Memcached (needs installed and enabled Memcached)
48+
Check existed cache, cache data and clear cache, by Memcached (needs installed and enabled Memcached)
4749
- **UserInfo::current()**
4850
Return current user information
4951
- **UserInfo::info(...)**

src/App/HandleForm.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static function validations(array $validates): array
1919
{
2020
$output = [];
2121
$output['status'] = 'OK';
22-
$output['message'] = 'Process complete successfully!';
22+
$output['message'] = 'The process has been completed successfully!';
2323

2424
$defaultMessages = [
2525
'required' => 'The field should not be empty!',

src/App/Helper.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use JetBrains\PhpStorm\NoReturn;
66
use PHPMailer\PHPMailer\PHPMailer;
7-
use PHPMailer\PHPMailer\SMTP;
87
use PHPMailer\PHPMailer\Exception;
98

109
/**

src/App/Middleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private static function getAuthorizationHeader(): ?string
106106
$headers = null;
107107
if (isset($_SERVER['Authorization'])) {
108108
$headers = trim($_SERVER["Authorization"]);
109-
} else if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
109+
} elseif (isset($_SERVER['HTTP_AUTHORIZATION'])) {
110110
/**
111111
* Nginx or fast CGI
112112
*/

src/App/Router.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public static function dispatch()
170170
echo '404 Page not found';
171171
exit();
172172
};
173-
} else if (is_string(self::$error_callback)) {
173+
} elseif (is_string(self::$error_callback)) {
174174
self::get($_SERVER['REQUEST_URI'], self::$error_callback);
175175
self::$error_callback = null;
176176
self::dispatch();

src/Controllers/AuthController.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ public function registerForm()
4242
public function register()
4343
{
4444
$request = json_decode(json_encode($_POST));
45+
4546
$secret = md5(uniqid(rand(), true));
4647
$request->secret = $secret;
48+
$user_token = md5(uniqid(rand(), true));
49+
$request->user_token = $user_token;
4750

4851
$output = HandleForm::validations([
4952
[$request->email, 'email', 'Please enter a valid Email address!'],
@@ -58,7 +61,9 @@ public function register()
5861
$output['status'] = 'ERROR';
5962
$output['message'] = 'This Email registered before!';
6063
} elseif ($output['status'] == 'OK' && Helper::csrf($request->token) && Auth::register($request)) {
61-
Helper::mailto($request->email, 'Welcome to PHPMVC! Your API secret key', '<p>Hi dear friend,</p><hr /><p>This is your API secret key to access authenticated API routes:</p><p><strong>' . $secret . '</strong></p><p>Please keep it in a safe place.</p><hr /><p>Good luck,</p><p><a href="http://localhost:8080" target="_blank" rel="noopener">PPMVC</a></p>');
64+
Helper::mailto($request->email, 'Welcome to PHPMVC! Email Verification', '<p>Hi dear friend,</p><hr /><p>Please click on this link to verify your email</p><hr /><p>Good luck,</p><p><a href="http://localhost:8080?email=' . $request->email . '&user_token=' . $user_token . '" target="_blank" rel="noopener">Verify your email at PHPMVC</a></p>');
65+
66+
setcookie('message', 'Verification has been sent to your email, please check your inbox.', time() + 60);
6267
} else {
6368
$output['status'] = 'ERROR';
6469
$output['message'] = 'There is an error! Please try again.';
@@ -68,6 +73,33 @@ public function register()
6873
echo json_encode($output);
6974
}
7075

76+
/**
77+
* Email verification
78+
*
79+
* @return void
80+
*/
81+
public function verify()
82+
{
83+
$request = json_decode(json_encode($_POST));
84+
85+
if (Auth::verify($request) && $secret = Auth::getSecret($request)) {
86+
Helper::mailto($request->email, 'PHPMVC! Your API secret key', '<p>Hi dear friend,</p><hr /><p>This is your API secret key to access authenticated API routes:</p><p><strong>' . $secret . '</strong></p><p>Please keep it in a safe place.</p><hr /><p>Good luck,</p><p><a href="http://localhost:8080" target="_blank" rel="noopener">PHPMVC</a></p>');
87+
88+
setcookie('message', 'Thanks for verification. Now you can publish a post!', time() + 60);
89+
90+
header('location: ' . URL_ROOT, true, 303);
91+
exit();
92+
} else {
93+
Helper::render(
94+
'Auth/verify',
95+
[
96+
'page_title' => 'Email Verification',
97+
'page_subtitle' => 'Verification process failed! Please register again with a new email address.'
98+
]
99+
);
100+
}
101+
}
102+
71103
/**
72104
* Login from
73105
*

src/Controllers/BlogController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public function delete(string $slug)
201201

202202
if (Blog::delete($slug)) {
203203
$output['status'] = 'OK';
204-
$output['message'] = 'Process complete successfully!';
204+
$output['message'] = 'The process has been completed successfully!';
205205

206206
XmlGenerator::feed();
207207
Cache::clearCache('blog.show.' . $slug);

src/Models/Auth.php

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,61 @@ public static function register(object $request): bool
2222
`email`,
2323
`password`,
2424
`secret`,
25+
`user_token`,
2526
`tagline`
2627
) VALUES (:email, :password, :secret, :tagline)");
2728
Database::bind([
2829
':email' => $request->email,
2930
':password' => password_hash($request->password1, PASSWORD_DEFAULT),
3031
':secret' => $request->secret,
32+
':user_token' => $request->user_token,
3133
':tagline' => $request->tagline,
3234
]);
3335

34-
if (Database::execute() && setcookie('loggedin', base64_encode($request->email), time() + (86400 * COOKIE_DAYS))) return true;
36+
if (Database::execute()) return true;
37+
return false;
38+
}
39+
40+
/**
41+
* Email verification
42+
*
43+
* @param object $request
44+
* @return bool
45+
*/
46+
public static function verify(object $request): bool
47+
{
48+
Database::query("SELECT * FROM users WHERE email = :email");
49+
Database::bind(':email', $request->email);
50+
51+
if (
52+
!is_null(Database::fetch())
53+
&& !is_null(Database::fetch()['user_token'])
54+
&& $request->user_token == Database::fetch()['user_token']
55+
&& setcookie('loggedin', base64_encode($request->email), time() + (86400 * COOKIE_DAYS))
56+
) {
57+
Database::query("UPDATE users SET verified = :verified WHERE email = :email");
58+
Database::bind([
59+
':verified' => 1,
60+
':email' => $request->email,
61+
]);
62+
63+
if (Database::execute()) return true;
64+
}
65+
return false;
66+
}
67+
68+
/**
69+
* Retrieve token
70+
*
71+
* @param object $request
72+
* @return mixed
73+
*/
74+
public static function getSecret(object $request): mixed
75+
{
76+
Database::query("SELECT * FROM users WHERE email = :email");
77+
Database::bind(':email', $request->email);
78+
79+
if (!is_null(Database::fetch()) && !is_null(Database::fetch()['secret'])) return Database::fetch()['secret'];
3580
return false;
3681
}
3782

@@ -61,7 +106,13 @@ public static function login(object $request): bool
61106
Database::query("SELECT * FROM users WHERE email = :email");
62107
Database::bind(':email', $request->email);
63108

64-
if (!is_null(Database::fetch()) && password_verify($request->password, Database::fetch()['password']) && setcookie('loggedin', base64_encode($request->email), time() + (86400 * COOKIE_DAYS))) return true;
109+
if (
110+
!is_null(Database::fetch())
111+
&& password_verify($request->password, Database::fetch()['password'])
112+
&& !is_null(Database::fetch()['user_token'])
113+
&& Database::fetch()['verified']
114+
&& setcookie('loggedin', base64_encode($request->email), time() + (86400 * COOKIE_DAYS))
115+
) return true;
65116
return false;
66117
}
67118

src/Views/Auth/login.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@
2525
</div>
2626
</div>
2727
</div>
28-
<?php require_once APP_ROOT . '/src/Views/Include/footer.php'; ?>
28+
29+
<?php require_once APP_ROOT . '/src/Views/Include/footer.php'; ?>

src/Views/Auth/register.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@
6868
</small></code></pre>
6969
</div>
7070
</div>
71+
7172
<?php require_once APP_ROOT . '/src/Views/Include/footer.php'; ?>

0 commit comments

Comments
 (0)