156 lines
7.1 KiB
PHP
156 lines
7.1 KiB
PHP
<?php
|
|
require '../../../session.php';
|
|
require '../../../config.php';
|
|
require '../../../dbconn.php';
|
|
require '../../../assets/utils/db_helpers.php';
|
|
require '../../../assets/utils/classes/PasswordManager.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$answer = ['success' => 0, 'message' => ''];
|
|
|
|
// ─── CSRF ─────────────────────────────────────────────────────────────────
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$csrf = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
|
|
if (empty($csrf) || $csrf !== ($_SESSION['csrf_token'] ?? '')) {
|
|
http_response_code(403);
|
|
exit(json_encode(['message' => 'Invalid request.']));
|
|
}
|
|
}
|
|
|
|
$data = json_decode($_POST['json'] ?? '{}', true) ?: [];
|
|
|
|
try {
|
|
|
|
$name = trim($data['name'] ?? '');
|
|
$surname = trim($data['surname'] ?? '');
|
|
$username = strtolower(trim($data['username'] ?? ''));
|
|
$email = strtolower(trim($data['email'] ?? ''));
|
|
$password = $data['password'] ?? '';
|
|
$confirm = $data['confirm_password'] ?? '';
|
|
|
|
// ── Required fields ───────────────────────────────────────
|
|
if (!$name || !$surname || !$username || !$email || !$password || !$confirm) {
|
|
$answer['message'] = 'All fields are required.';
|
|
http_response_code(422);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Username format ───────────────────────────────────────
|
|
if (!preg_match('/^[a-z0-9_]+$/', $username)) {
|
|
$answer['message'] = 'Username may only contain lowercase letters, numbers and underscores.';
|
|
http_response_code(422);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Email format ──────────────────────────────────────────
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
$answer['message'] = 'Invalid email address.';
|
|
http_response_code(422);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Password match ────────────────────────────────────────
|
|
if ($password !== $confirm) {
|
|
$answer['message'] = 'Passwords do not match.';
|
|
http_response_code(422);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Duplicate username ────────────────────────────────────
|
|
$sth = $pdo1->prepare('SELECT user_id FROM user WHERE username = :u LIMIT 1');
|
|
$sth->execute([':u' => $username]);
|
|
db_check($sth, $answer);
|
|
if ($sth->fetchColumn()) {
|
|
$answer['message'] = 'Username is already taken.';
|
|
http_response_code(409);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Duplicate email ───────────────────────────────────────
|
|
$sth = $pdo1->prepare('SELECT user_id FROM user WHERE email = :e LIMIT 1');
|
|
$sth->execute([':e' => $email]);
|
|
db_check($sth, $answer);
|
|
if ($sth->fetchColumn()) {
|
|
$answer['message'] = 'An account with that email already exists.';
|
|
http_response_code(409);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Password strength ─────────────────────────────────────
|
|
$pm = new PasswordManager($pdo1, $include_url);
|
|
$result = $pm->checkStrength($password, [$name, $surname, $username, $email]);
|
|
if ($result['score'] < PasswordManager::MIN_SCORE) {
|
|
$msg = $result['warning'] ?: ($result['suggestions'][0] ?? 'Please choose a stronger password.');
|
|
$answer['message'] = 'Password is too weak. ' . $msg;
|
|
http_response_code(422);
|
|
exit(json_encode($answer));
|
|
}
|
|
|
|
// ── Insert user with status=pending ───────────────────────
|
|
$hashed = password_hash($password, PASSWORD_BCRYPT);
|
|
$token = bin2hex(random_bytes(32));
|
|
|
|
$expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));
|
|
|
|
$sth = $pdo1->prepare("
|
|
INSERT INTO user
|
|
(username, name, surname, email, password, status, profile_picture, verify_token, verify_expires_at)
|
|
VALUES
|
|
(:username, :name, :surname, :email, :password, 'pending', '', :token, :expires)
|
|
");
|
|
$sth->execute([
|
|
':username' => $username,
|
|
':name' => $name,
|
|
':surname' => $surname,
|
|
':email' => $email,
|
|
':password' => $hashed,
|
|
':token' => $token,
|
|
':expires' => $expires_at,
|
|
]);
|
|
db_check($sth, $answer);
|
|
|
|
// ── Send verification email via default SMTP ──────────────
|
|
// Build absolute URL
|
|
$base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')
|
|
. '://' . $_SERVER['HTTP_HOST']
|
|
. rtrim($server_url, '/');
|
|
$verify_url = $base_url . '/login/verify.php?token=' . $token;
|
|
|
|
require_once $include_url . 'assets/utils/module/mailer.php';
|
|
|
|
$mailer = new mailer(['pdo1' => $pdo1]);
|
|
$mailer->send_email([
|
|
'company_id' => 0,
|
|
'smtp' => $SMTP,
|
|
'to' => $email,
|
|
'subject' => 'Verify your email — WMS',
|
|
'message' => implode("\n", [
|
|
"Hi {$name},",
|
|
"",
|
|
"Thanks for registering. Please verify your email address by clicking the button below:",
|
|
"",
|
|
"<a href=\"{$verify_url}\" style=\"display:inline-block;padding:12px 28px;background:#E66239;color:#ffffff;text-decoration:none;border-radius:6px;font-weight:600;\">Verify Email Address</a>",
|
|
"",
|
|
"Or copy and paste this link into your browser:",
|
|
"<a href=\"{$verify_url}\">{$verify_url}</a>",
|
|
"",
|
|
"This link will expire in 30 days.",
|
|
"",
|
|
"If you did not create an account, you can ignore this email.",
|
|
]),
|
|
'channel_name' => 'WMS',
|
|
'key' => $pinkey,
|
|
]);
|
|
|
|
$answer['success'] = 1;
|
|
$answer['message'] = 'Account created! Please check your email to verify your account.';
|
|
|
|
} catch (Exception $e) {
|
|
error_log('[register] ' . $e->getMessage());
|
|
$answer['message'] = 'Registration failed. Please try again.';
|
|
http_response_code(500);
|
|
}
|
|
|
|
exit(json_encode($answer));
|
|
?>
|