Files
2026-05-08 14:24:42 -04:00

394 lines
11 KiB
PHP

<?php
// ====================
// Authentication Class
// ====================
require_once "vendor/autoload.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class Authentication {
// Variables
private $settings = "";
private $ghrconnection = "";
// =================
// Class Constructor
// =================
public function __construct() {
// Get Settings
$this->settings = new SimpleXMLElement((file_exists("xml/settings.xml") ? file_get_contents("xml/settings.xml") : "<settings/>"));
if ($this->settings->count() === 0) {
error_log("GHR Authentication Class : Unable to initialize settings");
exit();
}
// Open Database Connections
$this->ghrconnection = $this->connect();
}
// ======================================
// Return a GHR MySQL Database Connection
// ======================================
public function connect() {
if ($this->settings->Environment == 'Production') {
$host = 'localhost';
} else {
$host = '192.168.1.190';
$host = '100.67.215.67';
}
try {
$database = (string) ($this->settings->DatabaseName ?? "");
$user = (string) ($this->settings->DatabaseUser ?? "");
$password = (string) ($this->settings->DatabasePassword ?? "");
$connection = new PDO("mysql:host={$host};dbname={$database};charset=utf8", $user, $password);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException | Exception $e) {
$this->debug($e->getMessage());
exit();
}
return $connection;
}
// ========================
// Generate Random Password
// ========================
private function generateRandomPassword($length = 12) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-_+=';
$password = '';
for ($i = 0; $i < $length; $i++) {
$index = rand(0, strlen($characters) - 1);
$password .= $characters[$index];
}
return $password;
}
// ===============
// Debug an Object
// ===============
private function debug($object = "") {
echo "<pre>";
print_r($object);
exit();
}
// ==============
// Reset Password
// ==============
public function resetPassword() {
$username = filter_input(INPUT_POST, "user_name") ?: "";
if (empty($username)) {
return false;
}
$exists = $this->userExists($username);
if (!$exists) {
return false;
}
$user = $this->getUser($username);
$password = $this->resetUsersPassword($user->record->user_serial);
$this->emailUserPasswordResetLink($user, $password);
$this->journalEntry("{$username} reset their password.");
return true;
}
// ===========
// User Exists
// ===========
private function userExists($username) {
$SQL = 'select user_name from view_users where user_name = :username';
$statement = $this->ghrconnection->prepare($SQL);
$statement->bindValue(':username', $username, PDO::PARAM_STR);
$statement->execute();
$user = $statement->fetch(PDO::FETCH_ASSOC);
return ($user !== false);
}
// =================
// Get a User Object
// =================
private function getUser($username) {
$SQL = 'select user_serial, user_name, user_email from view_users where user_name = :username';
$statement = $this->ghrconnection->prepare($SQL);
$statement->bindValue(':username', $username, PDO::PARAM_STR);
$statement->execute();
$user = $statement->fetch(PDO::FETCH_ASSOC);
$xml = new SimpleXMLElement('<users/>');
$record = $xml->addChild('record');
$this->arrayToXml($user, $record);
return $xml;
}
private function arrayToXml(array $data, SimpleXMLElement $xml): void {
foreach ($data as $key => $value) {
$key = is_numeric($key) ? 'item' : $key;
if (is_array($value)) {
$child = $xml->addChild($key);
$this->arrayToXml($value, $child);
} else {
$xml->addChild($key, htmlspecialchars((string) $value));
}
}
}
// ========================
// Reset the Users Password
// ========================
private function resetUsersPassword($user_serial) {
$user_random_password = $this->generateRandomPassword();
$user_temp_password = password_hash($user_random_password, PASSWORD_DEFAULT);
$SQL = "update users
set user_password = :user_password,
user_change_password = :user_change_password
where user_serial = :user_serial";
$statement = $this->ghrconnection->prepare($SQL);
$statement->bindValue(":user_serial", $user_serial);
$statement->bindValue(":user_password", $user_temp_password);
$statement->bindValue(":user_change_password", 1);
$statement->execute();
return $user_random_password;
}
// =================================
// Email a users Password Reset Link
// =================================
public function emailUserPasswordResetLink($user, $password) {
if (!$user instanceof SimpleXMLElement) {
return;
}
// Prepare the email.
$XSLParms['USER-TEMP-PASSWORD'] = $password;
$to = $user->record->user_email;
$subject = "DEC International DMS - Password Reset Request";
$message = $this->applyXSL($user, $this->getXSL("emailPasswordResetLink"), $XSLParms);
// Send the Email
$this->sendEmail($to, $subject, $message);
}
// =======================================
// Send an email with optional attachments
// =======================================
public function sendEmail($to = "", $subject = "", $message = "", $attachments = "", $attachment_names = "unknown") {
if (empty($to) or empty($subject) or empty($message)) {
return false;
}
$SmtpHost = $this->settings->SmtpServer;
$SmtpUsername = $this->settings->SmtpUserName;
$SmtpPassword = $this->settings->SmtpPassword;
$SmtpPort = $this->settings->SmtpPort;
$email = new PHPMailer(true);
// Only for development
$message = "<span style='font-family: Calibri, Arial, sans-serif;'>" . $message . "</span>";
try {
//Server settings
$email->isSMTP();
$email->Host = $SmtpHost;
$email->SMTPAuth = true;
$email->Username = $SmtpUsername; // Your Gmail address
$email->Password = $SmtpPassword; // App password from Google
// $email->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // or 'tls'
$email->Port = $SmtpPort;
$email->isHTML(true);
$email->SetFrom("info@dec-international.com", "DEC-International");
if (is_array($to)) {
foreach ($to as $address) {
$address = trim(str_replace(" ", "", $address));
if (empty($address)) {
continue;
}
$email->addAddress($address);
}
} else {
$email->addAddress($to);
}
$email->Subject = $subject;
$email->Body = $message;
if (is_array($attachments)) {
foreach ($attachments as $index => $item) {
if (!empty($item)) {
$email->addStringAttachment($item, ($attachment_names[$index] ?? "unknown"));
}
}
} else {
if (!empty($attachments)) {
$email->addStringAttachment($attachments, $attachment_names);
}
}
$success = $email->Send();
} catch (phpMailerException $e) {
$this->journalEntry($e->errorMessage());
$success = false;
} catch (Exception $e) {
$this->journalEntry($e->getMessage());
$success = false;
}
return $success;
}
// ======================
// Create a Journal Entry
// ======================
public function journalEntry($journal_entry = "") {
if (empty($journal_entry)) {
return;
}
$SQL = "insert into journal
( journal_origin,
journal_ip,
journal_entry )
VALUES ( :journal_origin,
:journal_ip,
:journal_entry )";
$statement = $this->ghrconnection->prepare($SQL);
$statement->bindValue(":journal_origin", "Authentication Class");
$statement->bindValue(":journal_ip", $_SERVER["REMOTE_ADDR"] ?? "");
$statement->bindValue(":journal_entry", $journal_entry);
$statement->execute();
}
// ==========================================
// Apply an XSL Stylesheet to an XML Document
// ==========================================
public function applyXSL($XMLString = "", $XSLString = "", $XSLParms = "") {
if ($XMLString instanceof SimpleXMLElement) {
$XMLString = $XMLString->asXML();
}
if (empty($XSLString)) {
trigger_error("No XSL Stylesheet provided.");
}
if (!is_array($XSLParms)) {
$XSLParms = array();
}
$XSLParms["RANDOM_NUMBER"] = rand();
$XSLParms["TODAY_YYYYMMDD"] = date("Y-m-d");
$XSLParms["TODAY_MMDDYYYY"] = date("m/d/Y");
$XSLParms["TODAY_HHMM"] = date("Hi");
$XSLParms["COPYRIGHT"] = date("Y");
$XML = new DOMDocument();
$XSL = new DOMDocument();
$XSLT = new XSLTProcessor();
if ($XMLString) {
$XML->loadXML($XMLString);
}
if ($XSLString) {
$XSL->loadXML($XSLString);
}
$XSLT->importStylesheet($XSL);
if ($XSLParms) {
$XSLT->setParameter("", $XSLParms);
}
$document = $XSLT->transformToXml($XML);
return $document;
}
// ========================
// Return an XSL Stylesheet
// ========================
public function getXSL($document = "") {
if (trim($document) == "") {
return "";
}
$document = "xsl/" . trim($document) . ".xsl";
$XSL = (file_exists($document) ? file_get_contents($document) : "");
return $XSL;
}
}