/**
* Get database connection link for SessionDB
* Sometimes even the unified system needs direct access to the database Force
*/
public function getDbLink()
{
return $this->db_link;
}
}
/**
* User Authentication and Data Management Functions
* The guardians of user identity and wisdom
*/
/**
* Get current user information from unified session
* Revealing the identity of the current user, as the Force guides us
*/
function GetCurrentUserInfo()
{
$sessionManager = UnifiedSessionManager::getInstance();
$userId = UnifiedSessionManager::getSessionValue('user_id', 0);
if ($userId > 0) {
$userData = GetUserDataFromDatabase('', $userId);
if ($userData) {
$contactSettings = json_decode($userData['settings_contact'], true);
$userName = '';
if (is_array($contactSettings) && isset($contactSettings['full_name'])) {
$userName = $contactSettings['full_name'];
}
if (empty($userName)) {
$userName = $userData['email'];
}
return array(
'id' => $userId,
'name' => $userName,
'email' => $userData['email'],
'role' => $userData['role']
);
}
}
// Anonymous user fallback
return array(
'id' => 0,
'name' => 'Anonymous',
'email' => '',
'role' => 'guest'
);
}
/**
* Get or set anonymous username from session
* Managing the identity of the nameless ones
*/
function GetAnonymousUserName($newName = '')
{
$cookieName = 'forum_anon_name';
if (!empty($newName)) {
// Set new name in cookie for 30 days
setcookie($cookieName, $newName, time() + (30 * 24 * 60 * 60), '/');
return $newName;
}
// Get existing name from cookie or session
$savedName = $_COOKIE[$cookieName] ?? '';
if (empty($savedName)) {
$savedName = UnifiedSessionManager::getSessionValue('anonymous_username', '');
}
return $savedName;
}
/**
* Check if current user has authentication privileges
* Determining if the user has joined the ranks of the authenticated
*/
function IsUserAuthenticated()
{
$userId = UnifiedSessionManager::getSessionValue('user_id', 0);
$isLoggedIn = UnifiedSessionManager::getSessionValue('logged_in', false);
if ($userId > 0 && $isLoggedIn === true) {
// Verify session hash to ensure password hasn't changed
$sessionHash = UnifiedSessionManager::getSessionValue('pwd_session_hash', '');
if (!empty($sessionHash)) {
$userData = GetUserDataFromDatabase('', $userId);
if ($userData) {
$passwordData = json_decode($userData['password'], true);
if (is_array($passwordData) &&
isset($passwordData['pwd_session_hash']) &&
$passwordData['pwd_session_hash'] === $sessionHash) {
return true;
}
}
}
}
return false;
}
/**
* Check if user has moderation privileges
* Determining if the user wields the power of the moderator lightsaber
*/
function IsUserModerator()
{
if (is_debug_session()) {
return true; // Debug mode grants temporary Sith powers
}
if (!IsUserAuthenticated()) {
return false;
}
$userInfo = GetCurrentUserInfo();
$userRole = $userInfo['role'];
return in_array($userRole, array('moderator', 'root'));
}
/**
* Check if user can create forums (admin only)
* Only the chosen ones may create new realms in the forum galaxy
*/
function IsUserAdmin()
{
if (is_debug_session()) {
return true; // Debug mode grants temporary Emperor powers
}
if (!IsUserAuthenticated()) {
return false;
}
$userInfo = GetCurrentUserInfo();
return $userInfo['role'] === 'root';
}
/**
* Get user data from database by email or user ID
* Consulting the user archives for wisdom and data
*/
function GetUserDataFromDatabase($email = '', $userId = 0)
{
static $userCache = array(); // Simple caching to avoid repeated queries
$cacheKey = !empty($email) ? "email_{$email}" : "id_{$userId}";
if (isset($userCache[$cacheKey])) {
return $userCache[$cacheKey];
}
try {
$database = new SessionDB();
$database->ensureUsersTableExists();
$fields = array('*');
$whereClause = !empty($email) ? array('email' => $email) : array('id' => $userId);
$queryResult = $database->query_select(Global_db_users_table_name, $fields, $whereClause);
if (count($queryResult) > 0) {
if (count($queryResult) > 1) {
$errorMessage = "ERROR! Multiple user entries found in database: " . conv_array_to_readable_str($queryResult);
error_log($errorMessage);
}
$userData = $queryResult[0];
$userCache[$cacheKey] = $userData; // Cache the result
return $userData;
}
} catch (Exception $e) {
error_log("GetUserDataFromDatabase error: " . $e->getMessage());
}
return null;
}
/**
* Check if user exists in database
* Searching the archives for traces of user existence
*/
function IsUserExists($email)
{
$userData = GetUserDataFromDatabase($email);
return $userData !== null && isset($userData['id']) && $userData['id'] > 0;
}
/**
* Authenticate user with email and password
* The trial by combat... but for passwords
*/
function AuthenticateUser($email, $password)
{
// Add slight delay to prevent password enumeration attacks
usleep(300000); // 300ms delay - invisible to users, painful for bots
if (empty($email) || empty($password)) {
return false;
}
$userData = GetUserDataFromDatabase($email);
if (!$userData) {
return false; // User not found
}
$passwordData = json_decode($userData['password'], true);
if (!is_array($passwordData) || !isset($passwordData['salt']) || !isset($passwordData['hash'])) {
return false; // Invalid password data structure
}
$enteredPasswordHash = hash('sha3-512', $password . 'KJ-12' . $passwordData['salt']);
$expectedPasswordHash = $passwordData['hash'];
if ($enteredPasswordHash === $expectedPasswordHash) {
// Authentication successful - welcome, young Padawan
$userId = $userData['id'];
$sessionHash = $passwordData['pwd_session_hash'];
SaveSessionLogin($userId, $sessionHash, $userData);
return true;
}
return false;
}
/**
* Save successful login to session
* Recording the moment when a user joins the authenticated realm
*/
function SaveSessionLogin($userId, $sessionHash, $userData = null)
{
if (empty($userId)) {
LogoutUser();
return false;
}
// Set session values
UnifiedSessionManager::setSessionValue('user_id', $userId);
UnifiedSessionManager::setSessionValue('logged_in', true);
UnifiedSessionManager::setSessionValue('logged_when', time());
UnifiedSessionManager::setSessionValue('pwd_session_hash', $sessionHash);
if ($userData) {
UnifiedSessionManager::setSessionValue('last_login_email', $userData['email']);
}
// Update login records in database
if ($userData) {
UpdateUserLoginRecords($userId, $userData['email'], $userData);
} else {
$userData = GetUserDataFromDatabase('', $userId);
if ($userData) {
UpdateUserLoginRecords($userId, $userData['email'], $userData);
}
}
return true;
}
/**
* Update user login records in database
* Chronicling the user's journey through the digital realm
*/
function UpdateUserLoginRecords($userId, $email, $userData)
{
try {
$database = new SessionDB();
$loginsData = json_decode($userData['logins'], true);
if (!is_array($loginsData)) {
$loginsData = array();
}
// Add new login record
$loginsData = AddLoginRecord($loginsData, $email);
$updateFields = array(
'logins' => json_encode($loginsData)
);
$success = $database->query_update(Global_db_users_table_name, $updateFields, 'id = ' . (int)$userId);
if (!$success) {
$errorMessage = "Failed to update login records for user ID: {$userId}";
error_log($errorMessage);
}
return $success;
} catch (Exception $e) {
error_log("UpdateUserLoginRecords error: " . $e->getMessage());
return false;
}
}
/**
* Add login record to user's login history
* Adding another chapter to the user's authentication saga
*/
function AddLoginRecord($loginsArray, $email)
{
// Clean up old records
$minRecordsToKeep = 10;
$maxAgeDays = 40;
$currentTime = time();
if (count($loginsArray) > $minRecordsToKeep) {
foreach ($loginsArray as $key => $record) {
if (isset($record['time'])) {
$recordTime = strtotime($record['time']);
$recordAgeDays = ($currentTime - $recordTime) / (60 * 60 * 24);
if ($recordAgeDays > $maxAgeDays) {
unset($loginsArray[$key]);
}
if (count($loginsArray) <= $minRecordsToKeep) {
break;
}
}
}
}
// Add new login record
$newRecord = array(
'time' => gmdate('Y-m-d H:i:s'),
'ip' => get_user_IP_address(),
'hostname' => gethostbyaddr(get_user_IP_address()),
'sys_info' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown',
'location' => GetCountryCodeFromCountryName(GetCountryFromIP(get_user_IP_address()))
);
$loginsArray[] = $newRecord;
return $loginsArray;
}
/**
* Logout current user
* Ending the user's authenticated journey in this session
*/
function LogoutUser()
{
UnifiedSessionManager::setSessionValue('user_id', 0);
UnifiedSessionManager::setSessionValue('logged_in', false);
UnifiedSessionManager::setSessionValue('logged_when', 0);
UnifiedSessionManager::setSessionValue('pwd_session_hash', '');
return true;
}
/**
* Initialize session system when this file is included
* The awakening happens automatically - like the Force, it flows through everything
*/
try {
UnifiedSessionManager::initialize();
} catch (Exception $e) {
error_log("Session initialization error: " . $e->getMessage());
}
// Register shutdown function to save session data
register_shutdown_function(function() {
try {
UnifiedSessionManager::saveSession();
} catch (Exception $e) {
error_log("Session save error: " . $e->getMessage());
}
});
/**
* 🚀 UNIFIED SESSION SYSTEM IMPLEMENTATION NOTES:
*
* ✅ FEATURES IMPLEMENTED:
* - Unified session management for dashboard.php and forum.php
* - Secure session storage in database with expiration
* - Consistent user authentication across all components
* - Role-based access control (user, moderator, root)
* - Session security with password change detection
* - Anonymous user support for forum posting
* - Login history tracking and cleanup
* - Automatic session cleanup of expired entries
*
* 🔒 SECURITY FEATURES:
* - Password enumeration protection with delays
* - Secure session ID generation
* - Session hash validation on password changes
* - SQL injection protection in all queries
* - HTTP-only and secure cookies
* - Session expiration management
*
* 🛡️ COMPATIBILITY FEATURES:
* - Backward compatibility with existing code
* - Graceful fallback for missing data
* - Error handling and logging
* - Debug mode support for development
* - Caching for performance optimization
*
* 📊 MONITORING FEATURES:
* - Login attempt tracking
* - Session activity monitoring
* - Error reporting for security issues
* - Performance optimization with caching
*
* 🔧 TECHNICAL IMPLEMENTATION:
* - Singleton pattern for session manager
* - Static methods for global access
* - Automatic initialization and cleanup
* - Database table auto-creation
* - JSON storage for complex data structures
*
* 🎯 INTEGRATION POINTS:
* - GetCurrentUserInfo() - works with both systems
* - IsUserAuthenticated() - unified authentication check
* - IsUserModerator() / IsUserAdmin() - role-based access
* - Session data persistence across requests
* - Cookie-based session tracking
*
* 🛠️ ERROR HANDLING & RECOVERY:
* - Database connection error recovery
* - Graceful degradation on schema issues
* - Automatic table creation and migration
* - Exception handling with logging
* - Fallback behaviors for critical failures
*
* May the Force be with your sessions, always! 🌟
*/
?>
Saving Folders - How Do I... - AllMyNotes Organizer Community Forum
It's enough to select parent folder and export it. All sub-folder will be exported too. Use HTML format for exporting, this way you will be able to open it even using regular web-browser on any device/platform.
tobytommy
Post #2 - Oct 12, 2019 8:41 PM
saving folders
Hello,
I have multiple sub-folders in my personal folder. A few of them have a hundred or more folders. How can I export select sub-folders. Is there a way to export them to an Ipad and read them there and store them.
Thanks,
Jeff
Post Reply
📝 Anonymous posting: Your message will be reviewed by moderators before appearing publicly.
🛡️ Vladonai Secure Community Platform [BETA]
Powered by Vladonai Minimalistic Forum Script | Designed for AllMyNotes Organizer Community