Skip to main content

Overview

OdontologyApp uses a secure authentication system with bcrypt password hashing and HTTP-only cookie-based sessions. All authentication endpoints are protected and include comprehensive logging for security auditing.

Login Process

Authentication Endpoint

The login process is handled by the /api/auth/login endpoint: Location: src/routes/api/auth/login/+server.js

Login Flow

1

User Submits Credentials

The client sends a POST request with username and password:
{
  "username": "doctor",
  "password": "doctor123"
}
2

Database Lookup

The system calls the stored procedure sp_authenticate_user(?) to retrieve the user record from the database.
3

Password Verification

The submitted password is compared against the stored bcrypt hash:
const isMatch = await bcrypt.compare(password, user.password);
If the password doesn’t match, the system returns a 401 error.
4

Session Creation

Upon successful authentication, a session object is created with the following data:
{
  id: user.id,
  name: user.name,
  email: user.email,
  role: user.role,
  initials: user.initials,
  theme: user.theme || "light",
  branch: user.branch_name || "Todas las sucursales",
  avatar_url: user.avatar_url || null
}
5

Cookie Storage

The session is serialized to JSON and stored in an HTTP-only cookie named session.

Session Management

Sessions are stored with the following security settings:
SettingValuePurpose
httpOnlytruePrevents JavaScript access to the cookie
sameSitelaxCSRF protection while allowing normal navigation
securefalseAllows HTTP access for local network deployments
maxAge86400 (24 hours)Session expires after 24 hours
path/Cookie available across the entire application
The secure flag is set to false to support IP-based access on local networks. For production deployments with HTTPS, this should be set to true.

Session Hook

The application uses a server-side hook to manage sessions on every request: Location: src/hooks.server.js

Session Validation

On each request, the hook:
  1. Retrieves the session cookie
  2. Parses the JSON data and attaches it to event.locals.user
  3. Redirects authenticated users away from /login to /dashboard
  4. Redirects unauthenticated users to /login for protected routes
  5. Enforces role-based route protection

Protected Routes

The following routes are restricted to users with the admin role:
  • /admin/settings
  • /admin/treatments
  • /admin/reports
  • /users
  • /branches
  • /logs
Attempting to access these routes without admin privileges redirects to /dashboard?error=unauthorized.

Password Security

Bcrypt Hashing

All passwords are hashed using bcrypt with a cost factor of 10:
const hashedPassword = await bcrypt.hash(password, 10);
Bcrypt automatically generates a salt for each password, making rainbow table attacks ineffective. The cost factor of 10 provides a good balance between security and performance.

Default Test Accounts

The system includes three test accounts with bcrypt-hashed passwords:
UsernamePasswordRoleHash (truncated)
adminadmin123admin$2b$10$mo1jWoA/zRY1wN6x6hsfge...
doctordoctor123doctor$2b$10$aCdT80m.xivVAK0rWf.rD....
secretariasecretaria123secretary$2b$10$Zs8LX/f2nidTFspYT6QQEO...
These default credentials should be changed or removed in production environments.

Logout

The logout process is handled by sending a DELETE request to /api/auth/login:
export async function DELETE({ cookies }) {
  cookies.delete("session", {
    path: "/",
    httpOnly: true,
    sameSite: "lax",
    secure: false,
  });
  return json({ success: true });
}
This removes the session cookie and effectively logs the user out.

Security Logging

Login Audit Trail

Every successful login is logged to the logs table:
await pool.query("CALL sp_create_log(?, ?, ?, ?, ?)", [
  user.id,
  "Login",
  "Auth",
  `El usuario ${user.username} ha iniciado sesión`,
  ip,
]);
The system captures:
  • User ID
  • Action type (Login)
  • Module (Auth)
  • Description
  • IP address (from x-forwarded-for header or defaults to 127.0.0.1)
Administrators can view the complete audit trail in the Logs section, accessible only to users with the VIEW_LOGS permission.

Error Handling

The authentication system returns specific error messages:
HTTP CodeMessageCause
400”Falta usuario o contraseña”Missing credentials
401”Usuario no encontrado”Invalid username
401”Contraseña incorrecta”Invalid password
500”Error del servidor: [details]“Database or server error

Best Practices

Strong Passwords

Enforce minimum password length and complexity requirements when creating user accounts.

Regular Audits

Regularly review the logs table to detect suspicious login patterns or unauthorized access attempts.

Session Timeouts

The 24-hour session timeout helps ensure inactive users are automatically logged out.

HTTPS in Production

Always enable HTTPS and set the secure cookie flag to true in production environments.

Roles & Permissions

Learn about the three user roles and their capabilities

User Management

Managing doctor accounts and credentials

Build docs developers (and LLMs) love