-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGuest.php
More file actions
157 lines (127 loc) · 5.22 KB
/
Guest.php
File metadata and controls
157 lines (127 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
namespace MerapiPanel\Module\Auth;
use Exception;
use MerapiPanel\Box;
use MerapiPanel\Box\Module\__Fragment;
use MerapiPanel\Box\Module\Entity\Module;
use MerapiPanel\Database\DB;
use MerapiPanel\Utility\AES;
use MerapiPanel\Utility\Http\Request;
use MerapiPanel\Utility\Util;
use MerapiPanel\Views\View;
use PDO;
class Guest extends __Fragment
{
protected $module;
function onCreate(Module $module)
{
$this->module = $module;
}
/**
* Login Method
* @guest true - Allow login method for guest
* @admin false - Deny login method for admin
*/
public function loginHandler($email, $password, $longitude, $latitude)
{
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new Exception("Please enter an valid email address", 400);
}
if (empty($password) || strlen($password) < 8) {
throw new Exception("Invalid credentials", 400);
}
if (!$user = Box::module("User")->fetch(["id", "name", "password", "email", "role", "status", "post_date", "update_date"], ["email" => $email])) {
throw new Exception("User not found");
}
if (!in_array($user['status'], [0, 1, 2]) && $user['status'] != 2) {
throw new Exception("User is not active");
}
if (!password_verify($password, $user['password'])) {
throw new Exception("Invalid credentials");
}
$config = $this->module->getConfig();
$cookie_name = $config->get("cookie_name");
$session_time = $config->get("session_time");
$geo = $config->get("geo");
$session = [
'token' => Util::uniq(32),
'user_id' => $user['id'],
'ip' => Request::getClientIP(),
'user_agent' => Request::getUserAgent(),
'logitudelatitude' => $longitude . "," . $latitude,
'post_date' => date("Y-m-d H:i:s"),
'data' => [],
"expire" => date("Y-m-d H:i:s", strtotime("+ $session_time hours"))
];
if ($geo) {
if (!filter_var($longitude, FILTER_VALIDATE_FLOAT) || !filter_var($latitude, FILTER_VALIDATE_FLOAT)) {
throw new Exception("Invalid coordinates");
}
// toggle check geo location
$this->checkGeoOptions($user['id'], $longitude, $latitude);
if ($geoLocation = GeoLocation::getGeoLocation($latitude, $longitude)) {
if (isset($geoLocation['display_name'], $geoLocation['address'])) {
$session['data'] = [
...$session['data'],
'display_name' => $geoLocation['display_name'],
'address' => $geoLocation['address'],
];
}
}
}
if (
DB::table("session")->insert([
'token' => $session['token'],
'user_id' => $session['user_id'],
'ip' => $session['ip'],
'user_agent' => $session['user_agent'],
'logitudelatitude' => $session['logitudelatitude'],
'post_date' => $session['post_date'],
'data' => !is_string($session['data']) ? json_encode($session['data']) : $session['data'],
])->execute()
) {
if (!setcookie($cookie_name, AES::getInstance()->encrypt($session['token']), strtotime($session['expire']), "/")) {
throw new Exception("Failed to set cookie");
}
return $session;
}
throw new Exception("Failed to login");
}
private function checkGeoOptions($user_id, $longitude, $latitude): ?bool
{
$cookie_name = $this->module->getConfig()->get("cookie_name");
// check config for geo location
if (empty($latitude) && empty($longitude)) {
setcookie($cookie_name, "", time() - 3600, "/");
throw new Exception("Required to verify your location");
}
if (!$this->geoInRange($user_id, $latitude, $longitude)) {
setcookie($cookie_name, "", time() - 3600, "/");
throw new Exception("Your location is out of range");
}
return true;
}
private function geoInRange($user_id, $latitude, $longitude): bool
{
$range = $this->module->getConfig()->get("geo.range");
if ($range == 0 || empty($range)) {
return true;
}
if (empty($latitude) && empty($longitude)) {
return false;
}
$SQL = "SELECT logitudelatitude FROM `session` WHERE user_id = :id ORDER BY post_date DESC LIMIT 1";
$stmt = DB::instance()->prepare($SQL);
$stmt->execute(['id' => $user_id]);
$session_geo = $stmt->fetch(PDO::FETCH_ASSOC);
if ($session_geo) {
try {
[$lastLongitude, $lastLatitude] = explode(",", $session_geo['logitudelatitude'], 2);
return GeoLocation::isWithinRange($latitude, $longitude, $lastLatitude, $lastLongitude, intval($range));
} catch (\Throwable $e) {
return false;
}
}
return true;
}
}