ponepaste/login.php

129 lines
5 KiB
PHP
Raw Normal View History

2021-07-10 19:18:17 +01:00
<?php
2021-07-12 10:44:39 -04:00
define('IN_PONEPASTE', 1);
2021-07-10 18:21:03 -04:00
require_once('includes/common.php');
2021-07-10 19:18:17 +01:00
require_once('includes/functions.php');
2021-07-17 12:33:08 -04:00
require_once('includes/passwords.php');
2021-07-10 19:18:17 +01:00
// Current Date & User IP
2021-07-11 12:50:24 -04:00
$date = date('jS F Y');
$ip = $_SERVER['REMOTE_ADDR'];
2021-07-10 19:18:17 +01:00
2021-07-10 19:18:17 +01:00
// Check if already logged in
if ($current_user !== null) {
2021-07-11 12:50:24 -04:00
header("Location: ./");
die();
2021-07-10 19:18:17 +01:00
}
2021-07-10 18:21:03 -04:00
updatePageViews($conn);
2021-07-10 19:18:17 +01:00
2021-07-16 10:32:25 -04:00
if (isset($_POST['forgot'])) {
if (!empty($_POST['username']) && !empty($_POST['recovery_code'])) {
$username = trim($_POST['username']);
$recovery_code = trim($_POST['recovery_code']);
$query = $conn->query("SELECT id, recovery_code_hash FROM users WHERE username = ?", [$username]);
2021-07-16 10:32:25 -04:00
$row = $query->fetch();
2021-07-17 12:33:08 -04:00
if ($row && pp_password_verify($_POST['recovery_code'], $row['recovery_code_hash'])) {
$new_password = pp_random_password();
2021-07-17 12:33:08 -04:00
$new_password_hash = pp_password_hash($new_password);
2021-07-16 10:32:25 -04:00
$recovery_code = pp_random_token();
2021-07-17 12:33:08 -04:00
$new_recovery_code_hash = pp_password_hash($recovery_code);
2021-07-16 10:32:25 -04:00
$conn->prepare('UPDATE users SET password = ?, recovery_code_hash = ? WHERE id = ?')
->execute([$new_password_hash, $new_recovery_code_hash, $row['id']]);
$success = 'Your password has been changed. A new recovery code has also been generated. Please note the recovery code and then sign in with the new password.';
} else {
2021-08-26 05:35:21 -04:00
$error = 'Incorrect username or password.';
2021-07-16 10:32:25 -04:00
}
} else {
2021-08-26 05:35:21 -04:00
$error = 'All fields must be filled out.';
}
2021-07-26 17:42:43 -04:00
} elseif (isset($_POST['signin'])) { // Login process
2021-07-16 10:32:25 -04:00
if (!empty($_POST['username']) && !empty($_POST['password'])) {
2021-08-22 22:05:26 -04:00
$remember_me = (bool) $_POST['remember_me'];
2021-07-16 10:32:25 -04:00
$username = trim($_POST['username']);
$row = $conn->query("SELECT id, password, banned FROM users WHERE username = ?", [$username])
2021-07-26 17:42:43 -04:00
->fetch();
2021-07-17 12:33:08 -04:00
$needs_rehash = false;
/* This is designed to be a constant time lookup, hence the warning suppression operator so that
* we always call pp_password_verify, even if row is null.
*/
if (pp_password_verify($_POST['password'], @$row['password'], $needs_rehash)) {
$user_id = $row['id'];
2021-07-11 12:50:24 -04:00
2021-07-17 12:33:08 -04:00
if ($needs_rehash) {
$new_password_hash = pp_password_hash($_POST['password']);
$conn->query('UPDATE users SET password = ? WHERE id = ?',
2021-07-26 17:42:43 -04:00
[$new_password_hash, $user_id]);
2021-07-17 12:33:08 -04:00
}
2021-07-16 10:32:25 -04:00
if ($row['banned']) {
// User is banned
2021-08-26 05:35:21 -04:00
$error = 'You are banned.';
2021-07-17 12:36:21 -04:00
} else {
2021-07-16 10:32:25 -04:00
// Login successful
2021-08-22 22:05:26 -04:00
$_SESSION['user_id'] = (string) $user_id;
if ($remember_me) {
$remember_token = pp_random_token();
2021-07-24 15:12:19 -04:00
$expire_at = (new DateTime())->add(new DateInterval('P1Y'));
2021-07-24 15:12:19 -04:00
$conn->query('INSERT INTO user_sessions (user_id, token, expire_at) VALUES (?, ?, FROM_UNIXTIME(?))', [$user_id, $remember_token, $expire_at->format('U')]);
setcookie(User::REMEMBER_TOKEN_COOKIE, $remember_token, [
2021-08-22 22:05:26 -04:00
'expires' => (int) $expire_at->format('U'),
'secure' => !empty($_SERVER['HTTPS']), /* Local dev environment is non-HTTPS */
'httponly' => true,
'samesite' => 'Lax'
]);
}
2021-07-16 10:32:25 -04:00
header('Location: ' . $_SERVER['HTTP_REFERER']);
exit();
2021-07-10 19:18:17 +01:00
}
} else {
2021-07-16 10:32:25 -04:00
// Username not found or password incorrect.
2021-08-26 05:35:21 -04:00
$error = 'Incorrect username or password.';
2021-07-10 19:18:17 +01:00
}
2021-07-16 10:32:25 -04:00
} else {
2021-08-26 05:35:21 -04:00
$error = 'All fields must be filled out.';
2021-07-10 19:18:17 +01:00
}
2021-07-26 17:42:43 -04:00
} elseif (isset($_POST['signup'])) { // Registration process
2021-07-11 12:50:24 -04:00
$username = htmlentities(trim($_POST['username'], ENT_QUOTES));
2021-07-17 12:33:08 -04:00
$password = pp_password_hash($_POST['password']);
2021-07-11 12:50:24 -04:00
2021-07-16 10:08:21 -04:00
if (empty($_POST['password']) || empty($_POST['username'])) {
2021-08-26 05:35:21 -04:00
$error = 'All fields must be filled out.';
} elseif (strlen($username) > 25) {
$error = 'Username too long.'; // "Username already taken.";
2021-08-20 16:41:49 -04:00
} elseif (preg_match('/[^A-Za-z0-9._\\-$]/', $username)) {
2021-08-26 05:35:21 -04:00
$error = 'Username is invalid - please use A-Za-z0-9, periods, hyphens, and underscores only.';
2021-07-11 12:50:24 -04:00
} else {
2021-08-09 04:21:39 -04:00
if ($conn->querySelectOne('SELECT 1 FROM users WHERE username = ?', [$username])) {
2021-08-26 05:35:21 -04:00
$error = 'That username has already been taken.';
2021-07-11 12:50:24 -04:00
} else {
$recovery_code = pp_random_token();
2021-07-17 12:33:08 -04:00
$recovery_code_hash = pp_password_hash($recovery_code);
2021-08-09 04:21:39 -04:00
$conn->query(
"INSERT INTO users (username, password, recovery_code_hash, picture, date, ip, badge) VALUES (?, ?, ?, 'NONE', ?, ?, '0')",
[$username, $password, $recovery_code_hash, $date, $ip]
2021-07-16 10:08:21 -04:00
);
2021-08-26 05:35:21 -04:00
$success = 'Your account was successfully registered.';
2021-07-10 19:18:17 +01:00
}
}
}
// Theme
2021-08-22 21:45:26 -04:00
$page_template = 'login';
2021-08-26 05:35:21 -04:00
$page_title = 'Login / Register';
2021-08-22 21:45:26 -04:00
require_once('theme/' . $default_theme . '/common.php');