Chat's updates for security, db and workflow
Security and workflow regressions / regression (push) Has been cancelled

This commit is contained in:
2026-10-20 06:45:30 -04:00
parent 02223083f6
commit 1e63076123
116 changed files with 3252 additions and 2932 deletions
+28 -237
View File
@@ -1,244 +1,35 @@
<?php
// ===========
// Notes Class
// ===========
class Notes extends Base {
// Constants
const VALID_TYPES = array("User");
// Variables
private $current_user_name = "";
private $current_user_email = "";
// =================
// Class Constructor
// =================
public function __construct() {
set_error_handler(array($this, "displayError"));
date_default_timezone_set(self::TIMEZONE);
$this->current_user_name = $_SESSION[self::USER_NAME] ?? "";
$this->current_user_email = $_SESSION[self::USER_EMAIL] ?? "";
public const VALID_TYPES=['User'];
public function addNote(){
if(($_POST['step']??'prompt')==='add'){$this->write(0,$_POST['note_type']??'',MaintenanceService::id($_POST['note_reference']??null),$_POST['note_text']??'');return;}
$type=$_POST['note_type']??'';$id=MaintenanceService::id($_POST['note_reference']??null);
if(!in_array($type,self::VALID_TYPES,true))throw new AppException('Unsupported note type.');
$stmt=$this->connect()->prepare('SELECT user_serial FROM users WHERE user_serial=?');$stmt->execute([$id]);if(!$stmt->fetch())throw new AppException('User not found.',404);
$this->displayContent($this->applyXSL('<XML/>',$this->getXSL('addNote'),['NOTE_TYPE'=>$type,'NOTE_REFERENCE'=>$id]));
}
// ========
// Add Note
// ========
public function addNote() {
$step = filter_input(INPUT_POST, "step") ?: "prompt";
switch ($step) {
case "prompt":
$note_type = filter_input(INPUT_POST, "note_type") ?: "";
$note_reference = filter_input(INPUT_POST, "note_reference", FILTER_SANITIZE_NUMBER_INT) ?: 0;
if (!in_array($note_type, self::VALID_TYPES) or empty($note_reference)) {
$this->logError("Invalid Note Type ({$note_type} or Reference {$note_reference} " . __METHOD__);
}
$XSLParms["NOTE_TYPE"] = $note_type;
$XSLParms["NOTE_REFERENCE"] = $note_reference;
$content = $this->applyXSL("", $this->getXSL("addNote"), $XSLParms);
$this->displayContent($content);
break;
case "add":
$note_type = filter_input(INPUT_POST, "note_type") ?: "";
$note_reference = filter_input(INPUT_POST, "note_reference", FILTER_SANITIZE_NUMBER_INT) ?: 0;
$note_text = filter_input(INPUT_POST, "note_text") ?: "";
$SQL = "insert into notes
( note_type,
note_reference,
note_text,
note_origin )
VALUES ( :note_type,
:note_reference,
:note_text,
:note_origin )";
$statement = $this->connect()->prepare($SQL);
$statement->bindValue(":note_type", $note_type);
$statement->bindValue(":note_reference", $note_reference);
$statement->bindValue(":note_text", $note_text);
$statement->bindValue(":note_origin", $this->current_user_name);
$statement->execute();
break;
default:
$this->displayHome();
}
public function editNote(){
$id=MaintenanceService::id($_POST['note_serial']??null);$note=$this->getNote($id);
if(!$note->count())throw new AppException('Note not found.',404);
if(($_POST['step']??'prompt')==='update'){$this->write($id,(string)$note->record->note_type,(int)$note->record->note_reference,$_POST['note_text']??'');return;}
$this->displayContent($this->applyXSL($note,$this->getXSL('editNote')));
}
// ===========
// Delete Note
// ===========
public function deleteNote() {
$note_serial = filter_input(INPUT_POST, "note_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
$note = $this->getNote($note_serial);
if ($note->count() == 0) {
$this->logError("Invalid Note ({$note_serial}). " . __METHOD__);
}
$SQL = "delete from notes
where note_serial = {$note_serial}";
$this->executeSQL($SQL);
public function deleteNote(){
$stmt=$this->connect()->prepare('DELETE FROM notes WHERE note_serial=?');$stmt->execute([MaintenanceService::id($_POST['note_serial']??null)]);if(!$stmt->rowCount())throw new AppException('Note not found.',404);
}
// =========
// Edit Note
// =========
public function editNote() {
$step = filter_input(INPUT_POST, "step") ?: "prompt";
switch ($step) {
case "prompt":
$note_serial = filter_input(INPUT_POST, "note_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
$note = $this->getNote($note_serial);
if ($note->count() == 0) {
$this->logError("Invalid Note ({$note_serial}). " . __METHOD__);
}
$XML = $this->mergeXML($note, "<XML/>");
$content = $this->applyXSL($XML, $this->getXSL("editNote"));
$this->displayContent($content);
break;
case "update":
$note_serial = filter_input(INPUT_POST, "note_serial", FILTER_SANITIZE_NUMBER_INT) ?: 0;
$note_text = filter_input(INPUT_POST, "note_text") ?: "";
$SQL = "update notes
set note_text = :note_text,
note_origin = :note_origin
where note_serial = :note_serial";
$statement = $this->connect()->prepare($SQL);
$statement->bindValue(":note_serial", $note_serial);
$statement->bindValue(":note_text", $note_text);
$statement->bindValue(":note_origin", $this->current_user_name);
$statement->execute();
break;
default:
$this->displayHome();
}
}
// ====================
// Return a Note Object
// ====================
public function getNote($note_serial = 0) {
$SQL = "select view_notes.*
from view_notes
where note_serial = {$note_serial}";
return $this->getTable("notes", $SQL);
}
// =====================
// Return a Notes Object
// =====================
public function getNotes($note_type = "", $note_reference = 0) {
$SQL = "select view_notes.*
from view_notes
where note_type = '{$note_type}'
and note_reference = {$note_reference}
order by note_timestamp asc";
return $this->getTable("notes", $SQL);
}
// =====================
// Return a Notes Object
// =====================
public function getAllNotes($note_reference = 0) {
$SQL = "select view_notes.*
from view_notes
where note_reference = {$note_reference}
order by note_timestamp asc";
// $this->debug($SQL);
return $this->getTable("notes", $SQL);
}
// ==============
// Add Note Quick
// ==============
public function addNoteQuick($note_type = "", $note_reference = 0, $note_text = "") {
$SQL = "insert into notes
( note_type,
note_reference,
note_text,
note_origin )
VALUES ( :note_type,
:note_reference,
:note_text,
:note_origin )";
$statement = $this->connect()->prepare($SQL);
$statement->bindValue(":note_type", $note_type);
$statement->bindValue(":note_reference", $note_reference);
$statement->bindValue(":note_text", $note_text);
$statement->bindValue(":note_origin", $this->current_user_name);
$statement->execute();
public function write(int $id,string $type,int $reference,string $text): int {
$text=trim($text);if(!in_array($type,self::VALID_TYPES,true)||!$text||strlen($text)>65535)throw new AppException('Enter a valid user note (up to 65,535 bytes).');
$db=$this->connect();$db->beginTransaction();
try{
$stmt=$db->prepare('SELECT user_serial FROM users WHERE user_serial=? FOR UPDATE');$stmt->execute([$reference]);if(!$stmt->fetch())throw new AppException('The note must refer to an existing user.',409);
if($id){$stmt=$db->prepare('SELECT note_serial FROM notes WHERE note_serial=? AND note_type=? AND note_reference=? FOR UPDATE');$stmt->execute([$id,$type,$reference]);if(!$stmt->fetch())throw new AppException('Note not found.',404);
$stmt=$db->prepare('UPDATE notes SET note_text=?,note_origin=? WHERE note_serial=?');$stmt->execute([$text,$_SESSION[self::USER_NAME]??'',$id]);
}else{$stmt=$db->prepare('INSERT INTO notes(note_type,note_reference,note_text,note_origin) VALUES(?,?,?,?)');$stmt->execute([$type,$reference,$text,$_SESSION[self::USER_NAME]??'']);$id=(int)$db->lastInsertId();}
$db->commit();return $id;
}catch(Throwable $e){if($db->inTransaction())$db->rollBack();throw $e;}
}
public function getNote($id=0){$stmt=$this->connect()->prepare('SELECT * FROM view_notes WHERE note_serial=?');$stmt->execute([(int)$id]);return $this->getTableXML('notes',$stmt);}
public function getNotes($type='',$reference=0){$stmt=$this->connect()->prepare('SELECT * FROM view_notes WHERE note_type=? AND note_reference=? ORDER BY note_timestamp DESC,note_serial DESC');$stmt->execute([$type,(int)$reference]);return $this->getTableXML('notes',$stmt);}
public function getAllNotes($reference=0){return $this->getNotes('User',$reference);}
public function addNoteQuick($type='',$reference=0,$text=''){return $this->write(0,$type,(int)$reference,$text);}
}
?>