Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to add a way for visitors to register an account? #1270

Open
hestiacn opened this issue Jan 19, 2025 · 5 comments
Open

Is it possible to add a way for visitors to register an account? #1270

hestiacn opened this issue Jan 19, 2025 · 5 comments

Comments

@hestiacn
Copy link

Can you add a way for visitors to register an account? The logic is to use a hash code to generate a password, load the hashed password into the registration configuration to make the configuration effective, and prompt the user to remember your password. If you forget, you can only contact the administrator to help you update it! I believe this is a good idea. Thank you for developing such a great product.

@hestiacn
Copy link
Author

hestiacn commented Jan 21, 2025

I created a tinyfilemanager to allow users to register and log in.
This is the register.php configuration code where I changed the tinyfilemanager file name to index.php file to implement registration and login The following is the code for register.php file

<?php
date_default_timezone_set('Asia/Shanghai');
$userJsonFile = 'user.json';
$contentsJsonFile = 'contents.json';
$rootFolderPath = __DIR__ . '/root/docs/';
$ipLogFilePath = __DIR__ . '/ip_log.json';
 
$error = null;
$success = null;
 
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    $terms = isset($_POST['terms']) && $_POST['terms'] === 'on';
    $ip = $_SERVER['REMOTE_ADDR'];
    $currentTimestamp = time();
    
    if (!$terms) {
        $error = "You must agree to the terms of service to complete registration!";
    } else {
        $ipLogContent = file_exists($ipLogFilePath) ? json_decode(file_get_contents($ipLogFilePath), true) : [];
        $lastRegistrationTime = $ipLogContent[$ip] ?? 0;
        
        if ($currentTimestamp - $lastRegistrationTime < 3600) {
            $error = "Only one registration per IP address is allowed per hour. Please try again later!";
        } else {
            if (empty($username) || empty($password)) {
                $error = "Username and password cannot be empty!";
            } else {
                if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $username)) {
                    $error = "Username cannot contain Chinese characters!";
                } else {
                    // Read or initialize user.json
                    $userContent = file_exists($userJsonFile) ? json_decode(file_get_contents($userJsonFile), true) : [];
                    
                    if (array_key_exists($username, $userContent)) {
                        $error = "Username already exists. Please enter a new username!";
                    } else {
                        // Read or initialize contents.json
                        $contentsContent = file_exists($contentsJsonFile) ? json_decode(file_get_contents($contentsJsonFile), true) : [];
                        
                        if (array_key_exists($username, $contentsContent)) {
                            $error = "Username already exists in the database. Please enter a different username!";
                        } else {
                            $hash = password_hash($password, PASSWORD_DEFAULT);
                            $userContent[$username] = $hash;
                            
                            // Update user.json
                            file_put_contents($userJsonFile, json_encode($userContent, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
                            
                            // Update contents.json
                            $contentsContent[$username] = "root/docs/{$username}";
                            file_put_contents($contentsJsonFile, json_encode($contentsContent, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
                            
                            // Create user directory
                            $userPath = $rootFolderPath . DIRECTORY_SEPARATOR . $username;
                            if (!is_dir($userPath)) {
                                mkdir($userPath, 0755, true);
                                chmod($userPath, 0755);
                            }
                            
                            // Update IP log
                            $ipLogContent[$ip] = $currentTimestamp;
                            file_put_contents($ipLogFilePath, json_encode($ipLogContent));
                            
                            $success = "Registration successful!";
                        }
                    }
                }
            }
        }
    }
}
 
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>File Manager - User Registration</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <div class="header-container">
            <h2>User Registration</h2>
            <p>Contact the <a href="mailto:[email protected]">site administrator</a> to reset your password</p>
        </div>
        <?php if (!empty($success)): ?>
            <div class="message success"><?= $success ?></div>
        <?php elseif (!empty($error)): ?>
            <div class="message error"><?= $error ?></div>
        <?php endif; ?>
        <form method="post" action="" id="registrationForm" onsubmit="return validateForm()">
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" id="username" name="username" placeholder="Please enter letters or numbers, no Chinese characters allowed" required>
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" name="password" placeholder="Please enter your password, it will be securely stored as a hash" required>
            </div>
            <br>
            <div class="form-group checkbox">
                <input type="checkbox" id="terms" name="terms">
                <label for="terms">I have read and agree to the <a href="policy.php" target="_blank">terms of service</a></label>
                <div class="message error" id="terms-error" style="display: none;">You must agree to the terms of service to register!</div>
            </div>
            <br>
            <div class="form-group">
                <button type="submit">Register</button>
            </div>
        </form>
        <br>
        <div class="button-group" style="text-align: right; margin-top: 15px;">
            <a href="../index.php" class="login-button">Already have an account? Login now</a>
            <a href="#" class="info-button" onclick="showHashInfo()">Hint:⚠</a>
            <br>
        </div>
    </div>
    <div id="hashInfoModal" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 20px; border: 1px solid #ccc; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);">
        <p>Please remember your password, as the administrator cannot retrieve it if forgotten.</p>
        <ul>
            <li>Passwords are stored as hashes, and can only be reset by contacting the administrator via the top right.</li>
            <li>A hashed password is a form of encryption that converts a plaintext password into a format that is extremely difficult to reverse-engineer back to the original password.</li>
            <li>Even if the database is compromised, attackers will find it hard to obtain users' plaintext passwords.</li>
            <li>This increases the security of password storage.</li>
        </ul>
        <button onclick="closeHashInfo()">Close</button>
    </div>
    <script src="script.js"></script>
    <script>
        function validateForm() {
            var checkbox = document.getElementById('terms');
            var errorDiv = document.getElementById('terms-error');
            if (!checkbox.checked) {
                errorDiv.style.display = 'block';
                return false;
            } else {
                errorDiv.style.display = 'none';
                return true;
            }
        }
        function showHashInfo() {
            document.getElementById('hashInfoModal').style.display = 'block';
        }
        function closeHashInfo() {
            document.getElementById('hashInfoModal').style.display = 'none';
        }
    </script>
</body>
</html>

This is the complete code that needs to modify the $auth_users = array(); part and $directories_users = array(); of the tinyfilemanager.php file

// Path to the JSON file (assuming both files are in the root directory)
$jsonFilePath = __DIR__ . '/contents.json';

// Ensure the file exists before trying to read it (optional but recommended)
if (!file_exists($jsonFilePath)) {
    die('Error: JSON file does not exist.');
}

// Read the JSON file and decode it into a PHP array
$directories_users = json_decode(file_get_contents($jsonFilePath), true);

// Check if decoding was successful
if (json_last_error() !== JSON_ERROR_NONE) {
    // Output the error message (do not output file content in production)
    die('Error decoding JSON file: ' . json_last_error_msg());
}
$jsonFilePath = 'user.json';
$auth_users = [];

if (file_exists($jsonFilePath)) {
    // Instead of decoding JSON into an array, decode it into an object
    $users = json_decode(file_get_contents($jsonFilePath));
    // Check if $users is not null (i.e. if the JSON was successfully decoded)
    if ($users !== null) {
        $auth_users = (array) $users;
    }
};

As long as you create the contents.json and user.json files, they will be automatically generated.

Please like if you need it, thanks to tinyfilemanager

Added registration restrictions, and recorded the IP in the ip_log.json file to prevent duplicate registration of the registration machine.

@imcraftsman
Copy link
Contributor

the owner has provided another file name config.php, he allowed you to add or modify your login info. https://tinyfilemanager.github.io/config-sample.txt

@prasathmani
Copy link
Owner

This updated script allows for login functionality through a database, and you can tailor it further to meet your specific requirements.

tfm-db.zip

@hestiacn
Copy link
Author

hestiacn commented Jan 26, 2025

This updated script allows for login functionality through a database, and you can tailor it further to meet your specific requirements.

tfm-db.zip

There is a great PHP Chinese forum program. Do you have time to update it? Most of the source code is in Chinese comments! It needs to be refactored to meet international requirements. This is a great project. It has not been updated for twelve years since it was acquired by Alibaba! It has been abandoned! If you are interested, you can consider adding it to your development plan! This is a very good forum program! Register a new domain name! Revive it? Its updates stopped at the php5.6 version, so it was revitalized in php8.0-8.4! Most of the source code is written very poorly!
Address: Alibaba Both repositories are related to phpwind!
For example, you need to interpret the Chinese code annotations through google to understand its meaning.
Example:C:\Users\Administrator\Downloads\nextwind-master\wind\db\WindConnection.php

/**
 * 数据库链接,提供了数据库连接服务,以及基本的数据操作方法.
 * 
 * 提供了基本的数据连接服务,使用例子如下:<code>
 * $connection = new WindConnection('mysql:host=localhost;dbname=test', 'root', 'root');
 * $stm = $connection->createStatement('SELECT * FROM {members} WHERE uid<=:uid', true);
 * $stm->queryAll();
 * //组件配置实用实例:
 * 'db' => array(
 * 'path' => 'WIND:db.WindConnection',
 * 'scope' => 'singleton',
 * 'config' => array(
 * 'resource' => 'db_config.php',
 * ),),
 * //db_config 配置内容:
 * array(
 * 'dsn' => 'mysql:host=localhost;dbname=test',
 * 'user' => 'root',
 * 'pwd' => 'root',
 * 'charset' => 'utf8')
 * </code>
 *
 * @author Qiong Wu <[email protected]> 2011-9-23
 * @copyright ©2003-2103 phpwind.com
 * @license http://www.windframework.com
 * @version $Id: WindConnection.php 3904 2013-01-08 07:01:26Z yishuo $
 * @package db
 */
/**
* Database connection, provides database connection services and basic data operation methods.
*
* Provides basic data connection services, usage examples are as follows:<code>
* $connection = new WindConnection('mysql:host=localhost;dbname=test', 'root', 'root');
* $stm = $connection->createStatement('SELECT * FROM {members} WHERE uid<=:uid', true);
* $stm->queryAll();
* //Component configuration practical example:
* 'db' => array(
* 'path' => 'WIND:db.WindConnection',
* 'scope' => 'singleton',
* 'config' => array(
* 'resource' => 'db_config.php',
* ),),
* //db_config configuration content:
* array(
* 'dsn' => 'mysql:host=localhost;dbname=test',
* 'user' => 'root', * 'pwd' => 'root', * 'charset' => 'utf8') * </code> * * @author Qiong Wu <[email protected]> 2011-9-23 * @copyright ©2003-2103 phpwind.com * @license http://www.windframework.com * @version $Id: WindConnection.php 3904 2013-01-08 07:01:26Z yishuo $ * @packagedb */

@hestiacn
Copy link
Author

If you are not interested in this! Or think it is too much work, can you fix its errors? For example: unable to upload avatar, unable to use local search, unable to copy code! Editor does not support markdown! Cannot run in the new version of PHP environment! And other errors!

If possible, I really hope that there are enthusiastic developers willing to update this project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants