<?php

/**
 * Get username or email.
**/

$input['ue'] = null;
if (isset(
$_REQUEST['ue'])) {
    
$input['ue'] = $_REQUEST['ue'];
}

/**
 * Set relay parameters.
**/

$relayTo 'user/login';
$relayData $input;

/**
 * Get password
**/

$input['password'] = std_ifsetor($_REQUEST['password'], '');

/**
 * Check username and password
**/

if (std_isEmpty($input['ue'])) {
    
alerts_add('You must enter a username/email.');
    
app_redirect($relayTo$relayData);
    return;
}
if (
std_isEmpty($input['password'])) {
    
alerts_add('You must enter a password.');
    
app_redirect($relayTo$relayData);
    return;
}

/**
 * Look up user
**/

$data db_quickFetch('
    SELECT `id`, `username`, `password`
    FROM `users`
    WHERE `active` AND (`username` = ' 
db_escape($input['ue']) . ' OR `email` = ' db_escape($input['ue']) . ')
    LIMIT 1
'
);

/**
 * Get user data (if exists)
**/

if (!$data) {

    
alerts_add('User with username or email "' $input['ue'] . '" does not exist.');
    
app_redirect($relayTo$relayData);
    return;
    
}

/**
 * Check if password matches.
**/

$passwordMatch false;
if (
$data['password'] == users_encryptPassword($input['password'])) {
    
$passwordMatch true;
}

/**
 * Check if user is already locked out.
**/

$userLockoutQuery db_query('
    SELECT `timestamp`
    FROM `userLockouts`
    WHERE `user` = ' 
db_escape($data['id']) . '
    AND `timestamp` >= ' 
. (time() - $cfg['options']['userLockoutTime']) . '
    ORDER BY `timestamp` DESC
'
);

/**
 * If user is locked out, trigger an error.
**/

$userLockedOut false;
if (
db_rows($userLockoutQuery)) {

    
$userLockoutTimestamp db_fetchField('timestamp'$userLockoutQuery);
    
    
app_redirect($relayTo$relayData);
    
    
$alert 'Your account was locked at ' date('g:ia'$userLockoutTimestamp) . ' for ' . ($cfg['options']['userLockoutTime'] / 60) . ' minutes due to failed login attempts.\n';
    
$alert .= 'Please try again at ' date('g:ia'$userLockoutTimestamp $cfg['options']['userLockoutTime']) . '.';
    
    
alerts_add($alert);
    
    return;
    
}

/**
 * Check the time of their last lockout and successful login.
**/

$lastLockoutTimestamp db_quickFetchField('timestamp''
    SELECT MAX(`timestamp`) AS `timestamp`
    FROM `userLockouts`
    WHERE `user` = ' 
db_escape($data['id']) . '
'
);
$lastSuccessTimestamp db_quickFetchField('timestamp''
    SELECT MAX(`timestamp`) AS `timestamp`
    FROM `userLogins`
    WHERE `user` = ' 
db_escape($data['id']) . ' AND `success` = 1
'
);

/**
 * Log user login.
**/

$userLoginData = array(
    
'user' => $data['id'],
    
'ip' => ip2long($_SERVER['REMOTE_ADDR']),
    
'timestamp' => time(),
    
'success' => $passwordMatch
);

db_insert('userLogins'$userLoginData);

/**
 * Get number of failed logins since last lockout and successful login.
**/

$failedLoginQuery '
    SELECT COUNT(`id`) AS `num`
    FROM `userLogins` WHERE `user` = ' 
db_escape($data['id']) . '
    AND !`success` ' 
. ($lastSuccessTimestamp ' AND `timestamp` > ' $lastSuccessTimestamp '') . ($lastLockoutTimestamp ' AND `timestamp` > ' . ($lastLockoutTimestamp $cfg['options']['userLockoutTime']) : '') . '
'
;

$currentFailedLogins db_quickFetchField('num'$failedLoginQuery);

/**
 * Lock user out and display error message if appropriate.
**/

if ($currentFailedLogins >= $cfg['options']['maxFailedLogins']) {

    
app_redirect($relayTo$relayData);
    
    
$alert 'Your account is now locked for ' . ($cfg['options']['userLockoutTime'] / 60) . ' minutes.\n';
    
$alert .= 'Please try again at ' date('g:ia'time() + $cfg['options']['userLockoutTime']) . '.';
    
    
alerts_add($alert);
    
    
db_insert(
        
'userLockouts',
        array(
            
'user' => $data['id'],
            
'timestamp' => time()
        )
    );
    
    return;
}

/**
 * Compare passwords
**/

if (!$passwordMatch) {

    
app_redirect($relayTo$relayData);
    
    
alerts_add('Your password is incorrect.');
    if (
$currentFailedLogins >= $cfg['options']['warnOnFailedLogins']) {
        
alerts_add('You have ' . ($cfg['options']['maxFailedLogins'] - $currentFailedLogins) . ' login attempt(s) left until your account is locked for ' . ($cfg['options']['userLockoutTime'] / 60) . ' minutes.''warning');
    }
    
    return;
    
}

/**
 * Save user ID in session.
**/

ulog_set($data['id']);

/**
 * Get referrer and data
**/

/**
 * Redirect to referrer or account page.
**/

alerts_add('You have logged in under username "' $data['username'] . '".''success');
app_redirect($sendTo$sendData);