mirror of
https://github.com/Neetpone/ponepaste.git
synced 2025-03-12 14:40:09 +01:00
Various fixes and improvements, implement remember me (I think)
This commit is contained in:
parent
86609d5d32
commit
16fbc1b029
9 changed files with 70 additions and 44 deletions
|
@ -25,12 +25,4 @@ class DatabaseHandle {
|
||||||
|
|
||||||
return $stmt;
|
return $stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get() {
|
|
||||||
if (DatabaseHandle::$instance === null) {
|
|
||||||
DatabaseHandle::$instance = new DatabaseHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
return DatabaseHandle::$instance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ class User {
|
||||||
public string $username;
|
public string $username;
|
||||||
|
|
||||||
private function __construct(array $row) {
|
private function __construct(array $row) {
|
||||||
$this->user_id = intval($row['user_id']);
|
$this->user_id = intval($row['id']);
|
||||||
$this->username = $row['username'];
|
$this->username = $row['username'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ function recentupdate($conn, $count) {
|
||||||
|
|
||||||
function monthpop($conn, $count) {
|
function monthpop($conn, $count) {
|
||||||
$query = $conn->prepare(
|
$query = $conn->prepare(
|
||||||
"SELECT pastes.id AS id, views, title, created_at, visible, tagsys, users.username AS member
|
"SELECT pastes.id AS id, views, title, created_at, updated_at, visible, tagsys, users.username AS member
|
||||||
FROM pastes
|
FROM pastes
|
||||||
INNER JOIN users ON users.id = pastes.user_id
|
INNER JOIN users ON users.id = pastes.user_id
|
||||||
WHERE MONTH(created_at) = MONTH(NOW()) AND visible = '0' ORDER BY views DESC LIMIT ?");
|
WHERE MONTH(created_at) = MONTH(NOW()) AND visible = '0' ORDER BY views DESC LIMIT ?");
|
||||||
|
@ -178,7 +178,7 @@ function decrypt(string $value) : string {
|
||||||
|
|
||||||
function getRecent($conn, $count) {
|
function getRecent($conn, $count) {
|
||||||
$query = $conn->prepare("
|
$query = $conn->prepare("
|
||||||
SELECT pastes.id, visible, title, created_at, users.username AS member, tagsys
|
SELECT pastes.id, visible, title, created_at, updated_at, users.username AS member, tagsys
|
||||||
FROM pastes
|
FROM pastes
|
||||||
INNER JOIN users ON pastes.user_id = users.id
|
INNER JOIN users ON pastes.user_id = users.id
|
||||||
WHERE visible = '0'
|
WHERE visible = '0'
|
||||||
|
@ -201,7 +201,7 @@ function getRecentadmin($conn, $count = 5) {
|
||||||
|
|
||||||
function getpopular(DatabaseHandle $conn, int $count) : array {
|
function getpopular(DatabaseHandle $conn, int $count) : array {
|
||||||
$query = $conn->prepare("
|
$query = $conn->prepare("
|
||||||
SELECT pastes.id AS id, visible, title, pastes.created_at AS created_at, views, users.username AS member, tagsys
|
SELECT pastes.id AS id, visible, title, pastes.created_at AS created_at, updated_at, views, users.username AS member, tagsys
|
||||||
FROM pastes INNER JOIN users ON users.id = pastes.user_id
|
FROM pastes INNER JOIN users ON users.id = pastes.user_id
|
||||||
WHERE visible = '0'
|
WHERE visible = '0'
|
||||||
ORDER BY views DESC
|
ORDER BY views DESC
|
||||||
|
@ -213,7 +213,7 @@ function getpopular(DatabaseHandle $conn, int $count) : array {
|
||||||
|
|
||||||
function getrandom(DatabaseHandle $conn, int $count) : array {
|
function getrandom(DatabaseHandle $conn, int $count) : array {
|
||||||
$query = $conn->prepare("
|
$query = $conn->prepare("
|
||||||
SELECT pastes.id, visible, title, created_at, views, users.username AS member, tagsys
|
SELECT pastes.id, visible, title, created_at, updated_at, views, users.username AS member, tagsys
|
||||||
FROM pastes
|
FROM pastes
|
||||||
INNER JOIN users ON users.id = pastes.user_id
|
INNER JOIN users ON users.id = pastes.user_id
|
||||||
WHERE visible = '0'
|
WHERE visible = '0'
|
||||||
|
@ -231,11 +231,11 @@ function getUserPastes(DatabaseHandle $conn, int $user_id) : array {
|
||||||
return $query->fetchAll();
|
return $query->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTotalPastes(DatabaseHandle $conn, string $username) : int {
|
function getTotalPastes(DatabaseHandle $conn, int $user_id) : int {
|
||||||
$query = $conn->prepare("SELECT COUNT(*) AS total_pastes
|
$query = $conn->prepare("SELECT COUNT(*) AS total_pastes
|
||||||
FROM pastes INNER JOIN users ON users.id = pastes.user_id
|
FROM pastes INNER JOIN users ON users.id = pastes.user_id
|
||||||
WHERE users.username = ?");
|
WHERE users.id = ?");
|
||||||
$query->execute([$username]);
|
$query->execute([$user_id]);
|
||||||
|
|
||||||
return intval($query->fetch(PDO::FETCH_NUM)[0]);
|
return intval($query->fetch(PDO::FETCH_NUM)[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,3 +22,24 @@ function pp_password_verify(string $password, string $hash, bool &$needs_rehash
|
||||||
|
|
||||||
return password_verify($password, $hash);
|
return password_verify($password, $hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pp_random_bytes(int $length) : string {
|
||||||
|
try {
|
||||||
|
return random_bytes($length);
|
||||||
|
} catch (Exception) {
|
||||||
|
/* Out of entropy! */
|
||||||
|
die('Error generating random bytes - this should never be seen!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pp_random_token() : string {
|
||||||
|
return hash('SHA512', pp_random_bytes(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
function pp_random_password() : string {
|
||||||
|
/* MD-5 is OK to use here because it is not being used to protect secure data,
|
||||||
|
* but rather to reduce the size of the string a little bit into something that
|
||||||
|
* can reasonably be handled by a user.
|
||||||
|
*/
|
||||||
|
return hash('MD5', pp_random_bytes(64));
|
||||||
|
}
|
48
login.php
48
login.php
|
@ -41,14 +41,14 @@ if (isset($_POST['forgot'])) {
|
||||||
$username = trim($_POST['username']);
|
$username = trim($_POST['username']);
|
||||||
$recovery_code = trim($_POST['recovery_code']);
|
$recovery_code = trim($_POST['recovery_code']);
|
||||||
|
|
||||||
$query = $conn->prepare("SELECT id, recovery_code_hash FROM users WHERE username = ?");
|
$query = $conn->query("SELECT id, recovery_code_hash FROM users WHERE username = ?", [$username]);
|
||||||
$query->execute([$username]);
|
|
||||||
$row = $query->fetch();
|
$row = $query->fetch();
|
||||||
|
|
||||||
if ($row && pp_password_verify($_POST['recovery_code'], $row['recovery_code_hash'])) {
|
if ($row && pp_password_verify($_POST['recovery_code'], $row['recovery_code_hash'])) {
|
||||||
$new_password = md5(random_bytes(64));
|
$new_password = pp_random_password();
|
||||||
$new_password_hash = pp_password_hash($new_password);
|
$new_password_hash = pp_password_hash($new_password);
|
||||||
|
|
||||||
$recovery_code = hash('SHA512', random_bytes(64));
|
$recovery_code = pp_random_token();
|
||||||
$new_recovery_code_hash = pp_password_hash($recovery_code);
|
$new_recovery_code_hash = pp_password_hash($recovery_code);
|
||||||
|
|
||||||
$conn->prepare('UPDATE users SET password = ?, recovery_code_hash = ? WHERE id = ?')
|
$conn->prepare('UPDATE users SET password = ?, recovery_code_hash = ? WHERE id = ?')
|
||||||
|
@ -63,21 +63,24 @@ if (isset($_POST['forgot'])) {
|
||||||
}
|
}
|
||||||
} else if (isset($_POST['signin'])) { // Login process
|
} else if (isset($_POST['signin'])) { // Login process
|
||||||
if (!empty($_POST['username']) && !empty($_POST['password'])) {
|
if (!empty($_POST['username']) && !empty($_POST['password'])) {
|
||||||
|
$remember_me = (bool) $_POST['remember_me'];
|
||||||
$username = trim($_POST['username']);
|
$username = trim($_POST['username']);
|
||||||
$query = $conn->prepare("SELECT id, password, banned FROM users WHERE username = ?");
|
$row = $conn->query("SELECT id, password, banned FROM users WHERE username = ?", [$username])
|
||||||
$query->execute([$username]);
|
->fetch();
|
||||||
$row = $query->fetch();
|
|
||||||
$needs_rehash = false;
|
$needs_rehash = false;
|
||||||
if ($row && pp_password_verify($_POST['password'], $row['password'], $needs_rehash)) {
|
|
||||||
// Username found
|
/* This is designed to be a constant time lookup, hence the warning suppression operator so that
|
||||||
$db_ip = $row['ip'];
|
* we always call pp_password_verify, even if row is null.
|
||||||
$db_id = $row['id'];
|
*/
|
||||||
|
if (pp_password_verify($_POST['password'], @$row['password'], $needs_rehash)) {
|
||||||
|
$user_id = $row['id'];
|
||||||
|
|
||||||
if ($needs_rehash) {
|
if ($needs_rehash) {
|
||||||
$new_password_hash = pp_password_hash($_POST['password']);
|
$new_password_hash = pp_password_hash($_POST['password']);
|
||||||
|
|
||||||
$conn->prepare('UPDATE users SET password = ? WHERE id = ?')
|
$conn->query('UPDATE users SET password = ? WHERE id = ?',
|
||||||
->execute([$new_password_hash, $row['id']]);
|
[$new_password_hash, $user_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($row['banned']) {
|
if ($row['banned']) {
|
||||||
|
@ -85,7 +88,19 @@ if (isset($_POST['forgot'])) {
|
||||||
$error = $lang['banned'];
|
$error = $lang['banned'];
|
||||||
} else {
|
} else {
|
||||||
// Login successful
|
// Login successful
|
||||||
$_SESSION['user_id'] = $row['id'];
|
$_SESSION['user_id'] = (string) $user_id;
|
||||||
|
|
||||||
|
if ($remember_me) {
|
||||||
|
$remember_token = pp_random_token();
|
||||||
|
|
||||||
|
$conn->query('INSERT INTO user_sessions (user_id, token) VALUES (?, ?)', [$user_id, $remember_token]);
|
||||||
|
|
||||||
|
setcookie(User::REMEMBER_TOKEN_COOKIE, $remember_token, [
|
||||||
|
'secure' => !empty($_SERVER['HTTPS']), /* Local dev environment is non-HTTPS */
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Lax'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
header('Location: ' . $_SERVER['HTTP_REFERER']);
|
header('Location: ' . $_SERVER['HTTP_REFERER']);
|
||||||
exit();
|
exit();
|
||||||
|
@ -109,13 +124,12 @@ if (isset($_POST['forgot'])) {
|
||||||
} elseif (!isValidUsername($username)) {
|
} elseif (!isValidUsername($username)) {
|
||||||
$error = $lang['usrinvalid']; // "Username not valid. Usernames can't contain special characters.";
|
$error = $lang['usrinvalid']; // "Username not valid. Usernames can't contain special characters.";
|
||||||
} else {
|
} else {
|
||||||
$query = $conn->prepare('SELECT 1 FROM users WHERE username = ?');
|
$query = $conn->query('SELECT 1 FROM users WHERE username = ?', [$username]);
|
||||||
$query->execute([$username]);
|
|
||||||
|
|
||||||
if ($query->fetch()) {
|
if ($query->fetch()) {
|
||||||
$error = $lang['userexists']; // "Username already taken.";
|
$error = $lang['userexists']; // "Username already taken.";
|
||||||
} else {
|
} else {
|
||||||
$recovery_code = hash('SHA512', random_bytes('64'));
|
$recovery_code = pp_random_token();
|
||||||
$recovery_code_hash = pp_password_hash($recovery_code);
|
$recovery_code_hash = pp_password_hash($recovery_code);
|
||||||
$query = $conn->prepare(
|
$query = $conn->prepare(
|
||||||
"INSERT INTO users (username, password, recovery_code_hash, picture, date, ip, badge) VALUES (?, ?, ?, 'NONE', ?, ?, '0')"
|
"INSERT INTO users (username, password, recovery_code_hash, picture, date, ip, badge) VALUES (?, ?, ?, 'NONE', ?, ?, '0')"
|
||||||
|
|
11
profile.php
11
profile.php
|
@ -16,6 +16,7 @@
|
||||||
define('IN_PONEPASTE', 1);
|
define('IN_PONEPASTE', 1);
|
||||||
require_once('includes/common.php');
|
require_once('includes/common.php');
|
||||||
require_once('includes/functions.php');
|
require_once('includes/functions.php');
|
||||||
|
require_once('includes/passwords.php');
|
||||||
|
|
||||||
// UTF-8
|
// UTF-8
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
@ -35,11 +36,9 @@ if ($current_user === null) {
|
||||||
|
|
||||||
$user_username = $current_user->username;
|
$user_username = $current_user->username;
|
||||||
|
|
||||||
$query = $conn->prepare('SELECT * FROM users WHERE username = ?');
|
$query = $conn->query('SELECT * FROM users WHERE id = ?', [$current_user->user_id]);
|
||||||
$query->execute([$user_username]);
|
|
||||||
$row = $query->fetch();
|
$row = $query->fetch();
|
||||||
$user_id = $row['id'];
|
$user_id = $row['id'];
|
||||||
$user_full_name = $row['full_name'];
|
|
||||||
$user_platform = Trim($row['platform']);
|
$user_platform = Trim($row['platform']);
|
||||||
$user_date = $row['date'];
|
$user_date = $row['date'];
|
||||||
$user_ip = $row['ip'];
|
$user_ip = $row['ip'];
|
||||||
|
@ -52,8 +51,8 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
if (pp_password_verify($user_old_pass, $user_password)) {
|
if (pp_password_verify($user_old_pass, $user_password)) {
|
||||||
$user_new_cpass = pp_password_hash($_POST['password']);
|
$user_new_cpass = pp_password_hash($_POST['password']);
|
||||||
|
|
||||||
$conn->prepare('UPDATE users SET full_name = ?, password = ? WHERE username = ?')
|
$conn->prepare('UPDATE users SET password = ? WHERE id = ?')
|
||||||
->execute([$user_new_full, $user_new_cpass, $user_username]);
|
->execute([$user_new_cpass, $user_id]);
|
||||||
|
|
||||||
$success = $lang['profileupdated']; //" Your profile information is updated ";
|
$success = $lang['profileupdated']; //" Your profile information is updated ";
|
||||||
} else {
|
} else {
|
||||||
|
@ -66,7 +65,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
|
||||||
updatePageViews($conn);
|
updatePageViews($conn);
|
||||||
|
|
||||||
$total_user_pastes = getTotalPastes($conn, $user_username);
|
$total_user_pastes = getTotalPastes($conn, $current_user->user_id);
|
||||||
|
|
||||||
// Theme
|
// Theme
|
||||||
require_once('theme/' . $default_theme . '/header.php');
|
require_once('theme/' . $default_theme . '/header.php');
|
||||||
|
|
|
@ -222,7 +222,7 @@ $start = $time;
|
||||||
<input class="button is-link is-fullwidth my-4" type="submit" name="signin" value="Login"
|
<input class="button is-link is-fullwidth my-4" type="submit" name="signin" value="Login"
|
||||||
value="<?php echo md5($date . $ip); ?>">
|
value="<?php echo md5($date . $ip); ?>">
|
||||||
<div class="checkbox checkbox-primary">
|
<div class="checkbox checkbox-primary">
|
||||||
<input id="rememberme" name="rememberme" type="checkbox" checked="">
|
<input id="rememberme" name="remember_me" type="checkbox" checked="">
|
||||||
<label for="rememberme">
|
<label for="rememberme">
|
||||||
<?php echo $lang['rememberme']; ?>
|
<?php echo $lang['rememberme']; ?>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="b-checkbox is-info is-inline">
|
<div class="b-checkbox is-info is-inline">
|
||||||
<input class="is-checkradio is-info" id="rememberme" name="rememberme"
|
<input class="is-checkradio is-info" id="rememberme" name="remember_me"
|
||||||
type="checkbox" checked="">
|
type="checkbox" checked="">
|
||||||
<label for="rememberme">
|
<label for="rememberme">
|
||||||
<?php echo $lang['rememberme']; ?>
|
<?php echo $lang['rememberme']; ?>
|
||||||
|
|
|
@ -178,8 +178,8 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
||||||
<div class="column is-4 has-text-right">
|
<div class="column is-4 has-text-right">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="panel-tools">
|
<div class="panel-tools">
|
||||||
<?php if ($current_user) {
|
<?php if ($current_user !== null) {
|
||||||
$fav_paste = checkFavorite($conn, $paste_id, $current_user['id']);
|
$fav_paste = checkFavorite($conn, $paste_id, $current_user->user_id);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<a class="icon tool-icon" class="flip" onclick="openreport()"><i
|
<a class="icon tool-icon" class="flip" onclick="openreport()"><i
|
||||||
|
@ -247,7 +247,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
||||||
} ?>
|
} ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- Guests -->
|
<!-- Guests -->
|
||||||
<?php if (!$current_user || $current_user['id'] !== $paste['user_id']) { ?>
|
<?php if ($current_user === null || $current_user->user_id !== $paste['user_id']) { ?>
|
||||||
<hr>
|
<hr>
|
||||||
<label class="label">More from this Author </label>
|
<label class="label">More from this Author </label>
|
||||||
<?php
|
<?php
|
||||||
|
|
Loading…
Add table
Reference in a new issue