diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c75149c --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +debug = true +smtp_host = smtp.foobar.com +smtp_port = 546 +smtp_encryption = tls +smtp_username = foo +smtp_password = bar123 diff --git a/.gitignore b/.gitignore index 379dd0a..4cede8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .installed database.db database.db-* +.env +logs diff --git a/public/index.php b/public/index.php index 6bdfac9..a0de9cc 100644 --- a/public/index.php +++ b/public/index.php @@ -89,7 +89,7 @@ function dotown() // Who's Online. Currently just members. Guests maybe later. if ($controlrow["showonline"] == 1) { - $onlinequery = db()->query("SELECT id, username FROM users WHERE strftime('%s', onlinetime) >= strftime('%s', 'now') - 600 ORDER BY username"); + $onlinequery = db()->query("SELECT id, username FROM users WHERE strftime('%s', onlinetime) >= strftime('%s', 'now') - 600 ORDER BY username;"); $online_count = 0; $online_rows = []; diff --git a/src/explore.php b/src/actions/explore.php similarity index 100% rename from src/explore.php rename to src/actions/explore.php diff --git a/src/heal.php b/src/actions/heal.php similarity index 100% rename from src/heal.php rename to src/actions/heal.php diff --git a/src/actions/install.php b/src/actions/install.php index d7e2bed..9cbfdb5 100644 --- a/src/actions/install.php +++ b/src/actions/install.php @@ -74,7 +74,7 @@ function second() echo $query === true ? 'Control table created.
' : 'Error creating Control table.'; - $query = db()->exec("INSERT INTO control VALUES (1, 'Dragon Knight', 250, 1, '', '', 'Mage', 'Warrior', 'Paladin', 1, 1, 1, 1);"); + $query = db()->exec("INSERT INTO control VALUES (1, 'Dragon Knight', 250, 1, {$_SERVER['SERVER_NAME']}, 'noreply@'.{$_SERVER['SERVER_NAME']}, 'Mage', 'Warrior', 'Paladin', 1, 1, 1, 1);"); echo $query === true ? 'Control table populated.
' : 'Error populating Control table.'; diff --git a/src/actions/users.php b/src/actions/users.php index 9cdd22c..576d245 100644 --- a/src/actions/users.php +++ b/src/actions/users.php @@ -191,69 +191,33 @@ function sendpassemail($emailaddress, $password) extract($controlrow); $email = <<'; - - $rp = $controlrow["adminemail"]; - $org = '$gameurl'; - $mailer = 'PHP'; - - $head = ''; - $head .= "Content-Type: text/plain \r\n"; - $head .= "Date: ". date('r'). " \r\n"; - $head .= "Return-Path: $rp \r\n"; - $head .= "From: $from \r\n"; - $head .= "Sender: $from \r\n"; - $head .= "Reply-To: $from \r\n"; - $head .= "Organization: $org \r\n"; - $head .= "X-Sender: $from \r\n"; - $head .= "X-Priority: 3 \r\n"; - $head .= "X-Mailer: $mailer \r\n"; - - $body = str_replace("\r\n", "\n", $body); - $body = str_replace("\n", "\r\n", $body); - - return mail($to, $title, $body, $head); + return send_email($emailaddress, "$gamename Account Verification", $email); } diff --git a/src/bootstrap.php b/src/bootstrap.php index d809d11..1218534 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -2,8 +2,9 @@ require_once 'lib.php'; require_once 'router.php'; -require_once 'explore.php'; -require_once 'heal.php'; +require_once 'mail.php'; +require_once 'actions/explore.php'; +require_once 'actions/heal.php'; require_once 'actions/users.php'; require_once 'actions/help.php'; require_once 'actions/towns.php'; @@ -12,6 +13,8 @@ require_once 'actions/forum.php'; require_once 'actions/install.php'; require_once 'actions/admin.php'; +env_load('../.env'); + $uri = uri(); if (!file_exists('../.installed') && $uri[0] !== 'install') { @@ -37,10 +40,8 @@ if (!file_exists('../.installed') && $uri[0] !== 'install') { } // Force verify if the user isn't verified yet. - if ($controlrow["verifyemail"] && (bool) $userrow["verify"] === false) { + if ($controlrow['verifyemail'] && $userrow['verify'] !== 'g2g') { redirect('/verify'); - header("Location: users.php?do=verify"); - exit; } // Ensure the user can't use the admin panel. diff --git a/src/lib.php b/src/lib.php index 69d3e19..fadca9b 100644 --- a/src/lib.php +++ b/src/lib.php @@ -5,7 +5,6 @@ require_once __DIR__ . '/database.php'; define('VERSION', '1.2.5'); define('BUILD', 'Reawaken'); define('START', microtime(true)); -define('DEBUG', false); /** * Open or get SQLite database connection. @@ -213,7 +212,7 @@ function display($content, $title, bool $topnav = true, bool $leftnav = true, bo "numqueries" => db()->count, "version" => VERSION, "build" => BUILD, - "querylog" => DEBUG ? db()->log : [] + "querylog" => env('debug', false) ? db()->log : [] ]); exit; @@ -569,3 +568,48 @@ function guest_only(): void if (checkcookies()) redirect('/login'); } +/** + * Load the environment variables from the .env file. + */ +function env_load(string $filePath): void +{ + if (!file_exists($filePath)) throw new Exception("The .env file does not exist. (el)"); + + $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($lines as $line) { + $line = trim($line); + + // Skip lines that are empty after trimming or are comments + if ($line === '' || str_starts_with($line, '#')) continue; + + // Skip lines without an '=' character + if (strpos($line, '=') === false) continue; + + [$name, $value] = explode('=', $line, 2); + + $name = trim($name); + $value = trim($value, " \t\n\r\0\x0B\"'"); // Trim whitespace and quotes + + if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) { + putenv("$name=$value"); + $_ENV[$name] = $value; + $_SERVER[$name] = $value; + } + } +} + + +/** + * Retrieve an environment variable. + */ +function env(string $key, mixed $default = null): mixed +{ + $v = $_ENV[$key] ?? $_SERVER[$key] ?? (getenv($key) ?: $default); + return match(true) { + $v === 'true' => true, + $v === 'false' => false, + is_numeric($v) => (int) $v, + is_float($v) => (float) $v, + default => $v + }; +} diff --git a/src/mail.php b/src/mail.php new file mode 100644 index 0000000..10814ba --- /dev/null +++ b/src/mail.php @@ -0,0 +1,113 @@ + $from_addr, + 'log_path' => '../logs/email.log', + 'method' => 'smtp', // 'smtp' or 'log' + 'smtp_host' => env('smtp_host', 'localhost'), + 'smtp_port' => env('smtp_port', 25), + 'smtp_username' => env('smtp_username', null), + 'smtp_password' => env('smtp_password', null), + 'smtp_encryption' => env('smtp_encryption', null) + ], $options); + + // Always send to log during debug + if (env('debug', false)) $config['method'] = 'log'; + + // Validate input + if (empty($to) || empty($subject) || empty($message)) { + error_log('Email sending failed: Missing required parameters'); + return false; + } + + // Prepare email headers + $headers = [ + 'From: ' . $config['from'], + 'X-Mailer: PHP/' . phpversion() + ]; + + // Choose sending method + switch ($config['method']) { + case 'log': + // Log email details to file + $logMessage = sprintf( + "[%s] To: %s, Subject: %s, Message:\n\n %s\n\n\n\n", + date('Y-m-d H:i:s'), + $to, + $subject, + $message + ); + + // Attempt to log to file + if (file_put_contents($config['log_path'], $logMessage, FILE_APPEND) === false) { + error_log('Failed to write to log file: ' . $config['log_path']); + return false; + } + return true; + + case 'smtp': + default: + // Attempt to send via SMTP + try { + // Prepare SMTP connection + $smtpConfig = [ + 'host' => $config['smtp_host'], + 'port' => $config['smtp_port'], + 'username' => $config['smtp_username'], + 'password' => $config['smtp_password'], + 'encryption' => $config['smtp_encryption'] + ]; + + // Send email using PHP's mail function (basic SMTP) + $result = mail( + $to, + $subject, + $message, + implode("\r\n", $headers) + ); + + if (!$result) { + error_log('SMTP email sending failed'); + return false; + } + + return true; + } catch (Exception $e) { + error_log('Email sending error: ' . $e->getMessage()); + return false; + } + } +} + +// Example usage: +// Send via SMTP +// send_email('recipient@example.com', 'Test Subject', 'Email body text'); + +// Send via log +// send_email('recipient@example.com', 'Test Subject', 'Email body text', ['method' => 'log']); + +// Customize SMTP settings +// send_email('recipient@example.com', 'Test Subject', 'Email body text', [ +// 'method' => 'smtp', +// 'smtp_host' => 'smtp.yourserver.com', +// 'smtp_port' => 587, +// 'smtp_username' => 'your_username', +// 'smtp_password' => 'your_password', +// 'smtp_encryption' => 'tls' +// ]);