Skip to main content

Overview

User accounts in Pro Stock Tool are stored in the usuarios table within the prostocktool MySQL database. Each account contains essential user information and authentication credentials.

Database Configuration

The system connects to the database using the following configuration (conexion.php:3-8):
$host = "localhost";
$user = "root";
$pass = "";
$db = "prostocktool";

$conn = new mysqli($host, $user, $pass, $db);
The database connection includes automatic error handling that returns HTTP 500 status codes on connection failures.

User Table Structure

Based on the registration implementation, the usuarios table contains the following fields:

Schema

ColumnData TypeConstraintsDescription
idINTPRIMARY KEY, AUTO_INCREMENTUnique user identifier
emailVARCHARUNIQUE, NOT NULLUser’s email address
nombreVARCHAR(100)NOT NULLUser’s full name
identidadVARCHAR(20)UNIQUE, NOT NULLGovernment-issued ID number
passwordVARCHAR(255)NOT NULLBCrypt hashed password
creado_enTIMESTAMPDEFAULT NOW()Account creation timestamp

Field Details

Email

  • Purpose: Primary identifier for user login
  • Validation: Must pass email format validation
  • Uniqueness: Each email can only be registered once
  • Example: [email protected]
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo json_encode(['success'=>false,'error'=>'Email inválido']);
}

Nombre (Name)

  • Purpose: User’s full name for identification
  • Length: 2-100 characters
  • Validation: Must contain at least 2 characters
  • Example: Juan David Pérez
if (strlen($nombre) < 2 || strlen($nombre) > 100) {
  echo json_encode(['success'=>false,'error'=>'Nombre inválido']);
}

Identidad (ID Number)

  • Purpose: Government-issued identification number
  • Format: Numeric only, 6-20 digits
  • Uniqueness: Each ID can only be registered once
  • Example: 1067623487
if (!preg_match('/^[0-9]{6,20}$/', $identidad)) {
  echo json_encode(['success'=>false,'error'=>'Identidad inválida']);
}
Both email and ID number must be unique. The system prevents duplicate registrations by querying existing records before insertion.

Password

  • Storage: BCrypt hashed (never plain text)
  • Minimum Length: 6 characters (enforced at registration)
  • Algorithm: PASSWORD_BCRYPT
  • Salt: Automatically generated by PHP’s password_hash()
$hash = password_hash($contrasena, PASSWORD_BCRYPT);
$hashEsc = $conn->real_escape_string($hash);
BCrypt automatically handles salt generation and produces hashes approximately 60 characters long.

Creado_en (Created At)

  • Purpose: Timestamp of account creation
  • Type: MySQL TIMESTAMP
  • Value: Auto-populated using NOW() function
  • Format: YYYY-MM-DD HH:MM:SS

Account Creation Process

When a new user registers, the following SQL query is executed (registro.php:51-52):
$sql = "INSERT INTO usuarios (email, nombre, identidad, password, creado_en) 
        VALUES ('$emailEsc', '$nombreEsc', '$identidadEsc', '$hashEsc', NOW())";

if ($conn->query($sql)) {
  echo json_encode(['success'=>true,'message'=>'Registro exitoso']);
} else {
  echo json_encode(['success'=>false,'error'=>'Error al registrar: ' . $conn->error]);
}

Data Sanitization

All user inputs are sanitized before database insertion to prevent SQL injection:
$emailEsc = $conn->real_escape_string($email);
$nombreEsc = $conn->real_escape_string($nombre);
$identidadEsc = $conn->real_escape_string($identidad);
$hashEsc = $conn->real_escape_string($hash);

Duplicate Prevention

Before creating a new account, the system checks for existing records (registro.php:42-45):
$check = $conn->query(
  "SELECT id FROM usuarios 
   WHERE email = '$emailEsc' OR identidad = '$identidadEsc' 
   LIMIT 1"
);

if ($check && $check->num_rows > 0) {
  echo json_encode([
    'success'=>false,
    'error'=>'Email o Identidad ya registrados'
  ]);
  exit;
}
1

Query existing records

Search for matching email or ID number in the usuarios table.
2

Check results

If any records are found, prevent account creation.
3

Return error

Inform user that credentials are already in use.

User Authentication Flow

Login Credentials

Users authenticate using:
  1. Email address - Entered in the email field
  2. Password - Verified against BCrypt hash
From the login form (Inicio-Sesion.html:47-50):
<label for="email">Email</label>
<input type="email" placeholder="[email protected]" 
       name="email" required id="email">

<label for="contraseña">Contraseña</label>
<input type="password" name="Contraseña" required 
       id="Contraseña" placeholder="*****************">

Password Verification

While the login controller isn’t in the provided source, password verification typically uses:
// Retrieve stored hash from database
$stored_hash = $row['password'];

// Verify submitted password against hash
if (password_verify($submitted_password, $stored_hash)) {
  // Password correct - create session
} else {
  // Password incorrect - deny access
}
PHP’s password_verify() function is the complement to password_hash() and properly handles BCrypt comparison.

Security Considerations

Password Security

BCrypt Hashing

Industry-standard algorithm designed to be computationally expensive for brute-force attacks.

Automatic Salting

Each password hash includes a unique salt, preventing rainbow table attacks.

No Plain Text

Passwords are never stored in readable format, only as irreversible hashes.

Minimum Length

6-character minimum enforced on both client and server sides.

Data Protection

All user inputs are escaped using real_escape_string() before database queries:
$emailEsc = $conn->real_escape_string($email);
$nombreEsc = $conn->real_escape_string($nombre);
$identidadEsc = $conn->real_escape_string($identidad);

Account Data Flow

Registration Flow

Authentication Flow

API Endpoints

Registration Endpoint

URL: /database/registro.php
Method: POST
Content-Type: application/json
Request Body:
{
  "email": "[email protected]",
  "nombre": "Juan David",
  "identidad": "1067623487",
  "contrasena": "mypassword123"
}
Success Response:
{
  "success": true,
  "message": "Registro exitoso"
}
Error Response:
{
  "success": false,
  "error": "Email o Identidad ya registrados"
}

CORS Headers

The registration endpoint includes CORS headers for cross-origin requests (registro.php:2-5):
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
In production, replace Access-Control-Allow-Origin: * with specific trusted domains for better security.

User Account Lifecycle

1

Registration

User creates account through registration form with email, name, ID, and password.
2

Validation

System validates all inputs on client and server, checks for duplicates, and creates account.
3

Storage

User record is inserted into usuarios table with hashed password and timestamp.
4

Authentication

User logs in using email and password credentials.
5

Session Management

System maintains user session for authorized access to application features.

Common Queries

Check if Email Exists

SELECT id FROM usuarios 
WHERE email = '[email protected]' 
LIMIT 1;

Check if ID Number Exists

SELECT id FROM usuarios 
WHERE identidad = '1067623487' 
LIMIT 1;

Retrieve User by Email

SELECT id, email, nombre, identidad, password, creado_en 
FROM usuarios 
WHERE email = '[email protected]' 
LIMIT 1;

Count Total Users

SELECT COUNT(*) as total FROM usuarios;

Best Practices

  • Always hash passwords using BCrypt or stronger algorithms
  • Never log or display passwords in plain text
  • Enforce minimum password length (6+ characters)
  • Consider implementing password strength requirements
  • Use HTTPS to encrypt passwords in transit
  • Validate on both client and server sides
  • Use prepared statements or proper escaping for SQL queries
  • Sanitize all user inputs before database operations
  • Implement proper error handling and user feedback
  • Create unique indexes on email and identidad columns
  • Check for duplicates before insertion
  • Provide clear error messages when duplicates are detected
  • Consider implementing email verification
  • Implement proper CORS policies
  • Use Content Security Policy (CSP) headers
  • Enable HTTPS in production
  • Restrict database access to application user only

Error Handling

The account system implements comprehensive error handling:

Registration Errors

Error MessageCauseResolution
Método no permitidoNon-POST requestUse POST method
Datos inválidosInvalid JSONCheck request format
Email inválidoInvalid email formatUse valid email address
Nombre inválidoName too short/longUse 2-100 characters
Identidad inválidaInvalid ID formatUse 6-20 digits only
Contraseña muy cortaPassword < 6 charsUse 6+ character password
Email o Identidad ya registradosDuplicate credentialsUse different email/ID
Error al registrarDatabase errorCheck server logs
Error del servidorException thrownContact administrator

Connection Errors

if ($conn->connect_errno) {
    http_response_code(500);
    echo json_encode(["error" => "Error de conexión a la base de datos"]);
    exit;
}
Connection errors return HTTP 500 status code with descriptive JSON response.

Database Connection Management

The connection is properly closed after each request (registro.php:61):
$conn->close();
Properly closing database connections prevents resource leaks and ensures optimal server performance.

Next Steps

Authentication

Learn about the login system

Registration

Understand the signup process

Database Setup

Configure the database

Build docs developers (and LLMs) love