| #0 | PDO->__construct(mysql:charset=utf8;host=localhost;dbname=factorial_laberit_local, root, , Array([20] => , [17] => , [3] => 2)) |
| #1 | Phalcon\Db\Adapter\Pdo\AbstractPdo->connect(Array([host] => localhost, [username] => root, [password] => (empty string), [dbname] => factorial_laberit_local, [charset] => utf8, [options] => Array([20] => , [17] => ))) |
| #2 | Phalcon\Db\Adapter\Pdo\AbstractPdo->__construct(Array([host] => localhost, [username] => root, [password] => (empty string), [dbname] => factorial_laberit_local, [charset] => utf8, [options] => Array([20] => , [17] => )))
/home/laberitillusions/public_html/apps/config/services.php (91) <?php
namespace illusion;
use Common\Libraries\Translate\DbAdapter;
use illusion\Common\Acl\Acl;
use illusion\Common\Auth\Auth;
use illusion\Common\Models\Info;
use illusion\Common\Models\Languages;
use illusion\Common\Plugins\ForwardPlugin;
use illusion\Common\Plugins\NotFoundPlugin;
use illusion\Common\Plugins\SecurityHeadersPlugin;
use illusion\Common\Plugins\SecurityPlugin;
use illusion\Common\Utils\Utils;
use illusion\Mail\Mail;
use Phalcon\Encryption\Crypt;
use Phalcon\Db\Adapter\Pdo\Mysql as Connection;
use Phalcon\DI\Di;
use Phalcon\DI\FactoryDefault;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Html\Escaper;
use Phalcon\Http\Request;
use Phalcon\Http\Response\Cookies;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Model\Metadata\Files as MetaDataAdapter;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;
use Phalcon\Session\Adapter\Stream as SessionAdapter;
use Phalcon\Session\Manager as SessionManager;
use ReflectionClass;
use ReflectionMethod;
//use Phalcon\Flash\Direct as Flash;
/**
* The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
*/
$di = new FactoryDefault();
/**
* Register the global configuration as config
*/
$di->set('config', $config);
/**
* Loading routes from the routes.php file
*/
$di->set('router', function () use ($config) {
return require APPS_DIR . '/config/routes.php';
});
/**
* The URL component is used to generate all kind of urls in the application
*/
$di->set('url', function () use ($config) {
$url = new UrlResolver();
$url->setBaseUri($config->application->publicUrl . $config->application->baseUri);
return $url;
}, true);
/**
* Setting up the view component
*/
$di->set('view', function () use ($config) {
$view = new View();
$view->setViewsDir(CACHE_DIR . '/volt/');
$view->registerEngines(['.volt' => function ($view) use ($config) {
$volt = new Volt($view, $this);
$volt->setOptions([
'path' => CACHE_DIR . '/volt/',
'separator' => '_',
'always' => false
]); #options
return $volt;
}
]); #engines
return $view;
}, true);
/**
* Database connection is created based in the parameters defined in the configuration file
*/
$di->set('db', function () use ($config) {
$connection = new Connection(
array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->dbname,
"charset" => $config->database->charset,
'options' => [
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_STRINGIFY_FETCHES => false,
],
)
);
return $connection;
});
if (APPLICATION_ENV == 'pro') {
$di->set('modelsMetadata', function () use ($config) {
return new MetaDataAdapter([
'metaDataDir' => CACHE_DIR . '/metaData/'
]);
});
}
/**
* Start the session the first time some component request the session service
*/
$di->set('session', function () {
$adapter = new SessionAdapter();
$session = new SessionManager();
$session->setAdapter($adapter);
// $session = new SessionAdapter();
$session->start();
return $session;
});
$di->set('cookies', function () {
$cookies = new Cookies();
// Requiere el servicio 'crypt' (ya registrado abajo). Cifra valor de cookies a nivel app.
$cookies->useEncryption(true);
return $cookies;
});
/**
* Crypt service
*/
$di->set('crypt', function () use ($config) {
$crypt = new Crypt();
$crypt->setKey($config->application->cryptSalt);
return $crypt;
});
$di->set('dispatcher', function () use ($di) {
$evManager = $di->getShared('eventsManager');
$evManager->attach('dispatch:beforeDispatch', new SecurityPlugin);
$evManager->attach('dispatch:afterDispatchLoop', new SecurityHeadersPlugin);
$evManager->attach('dispatch:beforeException', new NotFoundPlugin);
$evManager->attach('dispatch:beforeForward', new ForwardPlugin);
$dispatcher = new Dispatcher();
$dispatcher->setEventsManager($evManager);
return $dispatcher;
}, true);
/**
* Flash service with custom CSS classes
*/
$di->set('flash', function () {
$flash = new FlashSession();
$flash->setCssClasses([
'success' => 'alert alert-success alert-dismissable fade in',
'notice' => 'alert alert-info alert-dismissable fade in',
'warning' => 'alert alert-warning alert-dismissable fade in',
'error' => 'alert alert-danger alert-dismissable fade in'
]);
return $flash;
});
/**
* Custom authentication component
*/
$di->setShared('auth', function () {
return new Auth();
});
$di->setShared('utils', function () {
return new Utils();
});
/**
* Access Control List
*/
$di->set('acl', function () {
return new Acl();
});
/**
* Access Control List
*/
$di->setShared('mobiledetect', function () {
return new \Mobile_Detect();
});
$di->setShared('t', function ($lang = false) use ($config, $di) {
global $lang;
$request = new Request();
$language = DI::getDefault()->getShared('auth')->getActiveLanguage();
if (!$language) {
$lang = $request->getBestLanguage();
if (!$lang) {
$lang = 'es';
}
$language = Languages::findFirstByLang($lang);
if (!$language) {
$lang = 'es';
} else {
$lang = $language->lang;
}
} else {
$lang = $language->lang;
}
$db = $di->getDefault()->getDb();
return new DbAdapter([
'db' => $db,
'table' => 'translations',
'language' => 'language',
'key' => 'key_name',
'value' => 'value',
'locale' => $lang,
]);
});
$di->setShared('request', function () {
return new Request();
});
/*
* Marcando como shared el modulo al cargalo esto deja disponibles las "cosicas"
*/
foreach ($config->modules as $module) {
$dir = preg_replace("/\/Module.php$/", "", $module['path']);
// Register Namespace for Shared Module (will not be called by dispatch)
if (isset($module['shared'])) {
$namespace = preg_replace('/\\\Module$/', "", $module['className']);
$loader->setNamespaces(array($namespace => $dir), true);
// Loading Module class bootloader Reflection Instance
$reflexion = new ReflectionClass($module['className']);
$instance = $reflexion->newInstanceWithoutConstructor();
// Execute every 'register' methods
foreach ($reflexion->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if (preg_match('/^register/', $method->name)) {
$instance->{$method->name}($di);
}
}
}
} |
| #3 | Closure->illusion\{closure}() |
| #4 | Phalcon\Di\Service->resolve(null, Object(Phalcon\Di\FactoryDefault)) |
| #5 | Phalcon\Di\Di->get(db, null) |
| #6 | Phalcon\Di\Di->getShared(db) |
| #7 | Phalcon\Mvc\Model\Manager->getConnection(Object(illusion\Common\Models\Languages: 30), Array()) |
| #8 | Phalcon\Mvc\Model\Manager->getReadConnection(Object(illusion\Common\Models\Languages: 30)) |
| #9 | Phalcon\Mvc\Model->getReadConnection() |
| #10 | Phalcon\Mvc\Model\MetaData\Strategy\Introspection->getMetaData(Object(illusion\Common\Models\Languages: 30), Object(Phalcon\Di\FactoryDefault)) |
| #11 | Phalcon\Mvc\Model\MetaData->initializeMetaData(Object(illusion\Common\Models\Languages: 30), illusion\common\models\languages) |
| #12 | Phalcon\Mvc\Model\MetaData->getMetaDataUniqueKey(Object(illusion\Common\Models\Languages: 30)) |
| #13 | Phalcon\Mvc\Model\MetaData->readMetaDataIndex(Object(illusion\Common\Models\Languages: 30), 4) |
| #14 | Phalcon\Mvc\Model\MetaData->getDataTypes(Object(illusion\Common\Models\Languages: 30)) |
| #15 | Phalcon\Mvc\Model::invokeFinder(findFirstByLang, Array([0] => es)) |
| #16 | Phalcon\Mvc\Model::__callStatic(findFirstByLang, Array([0] => es))
/home/laberitillusions/public_html/apps/config/services.php (208) <?php
namespace illusion;
use Common\Libraries\Translate\DbAdapter;
use illusion\Common\Acl\Acl;
use illusion\Common\Auth\Auth;
use illusion\Common\Models\Info;
use illusion\Common\Models\Languages;
use illusion\Common\Plugins\ForwardPlugin;
use illusion\Common\Plugins\NotFoundPlugin;
use illusion\Common\Plugins\SecurityHeadersPlugin;
use illusion\Common\Plugins\SecurityPlugin;
use illusion\Common\Utils\Utils;
use illusion\Mail\Mail;
use Phalcon\Encryption\Crypt;
use Phalcon\Db\Adapter\Pdo\Mysql as Connection;
use Phalcon\DI\Di;
use Phalcon\DI\FactoryDefault;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Html\Escaper;
use Phalcon\Http\Request;
use Phalcon\Http\Response\Cookies;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Model\Metadata\Files as MetaDataAdapter;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;
use Phalcon\Session\Adapter\Stream as SessionAdapter;
use Phalcon\Session\Manager as SessionManager;
use ReflectionClass;
use ReflectionMethod;
//use Phalcon\Flash\Direct as Flash;
/**
* The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
*/
$di = new FactoryDefault();
/**
* Register the global configuration as config
*/
$di->set('config', $config);
/**
* Loading routes from the routes.php file
*/
$di->set('router', function () use ($config) {
return require APPS_DIR . '/config/routes.php';
});
/**
* The URL component is used to generate all kind of urls in the application
*/
$di->set('url', function () use ($config) {
$url = new UrlResolver();
$url->setBaseUri($config->application->publicUrl . $config->application->baseUri);
return $url;
}, true);
/**
* Setting up the view component
*/
$di->set('view', function () use ($config) {
$view = new View();
$view->setViewsDir(CACHE_DIR . '/volt/');
$view->registerEngines(['.volt' => function ($view) use ($config) {
$volt = new Volt($view, $this);
$volt->setOptions([
'path' => CACHE_DIR . '/volt/',
'separator' => '_',
'always' => false
]); #options
return $volt;
}
]); #engines
return $view;
}, true);
/**
* Database connection is created based in the parameters defined in the configuration file
*/
$di->set('db', function () use ($config) {
$connection = new Connection(
array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->dbname,
"charset" => $config->database->charset,
'options' => [
\PDO::ATTR_EMULATE_PREPARES => false,
\PDO::ATTR_STRINGIFY_FETCHES => false,
],
)
);
return $connection;
});
if (APPLICATION_ENV == 'pro') {
$di->set('modelsMetadata', function () use ($config) {
return new MetaDataAdapter([
'metaDataDir' => CACHE_DIR . '/metaData/'
]);
});
}
/**
* Start the session the first time some component request the session service
*/
$di->set('session', function () {
$adapter = new SessionAdapter();
$session = new SessionManager();
$session->setAdapter($adapter);
// $session = new SessionAdapter();
$session->start();
return $session;
});
$di->set('cookies', function () {
$cookies = new Cookies();
// Requiere el servicio 'crypt' (ya registrado abajo). Cifra valor de cookies a nivel app.
$cookies->useEncryption(true);
return $cookies;
});
/**
* Crypt service
*/
$di->set('crypt', function () use ($config) {
$crypt = new Crypt();
$crypt->setKey($config->application->cryptSalt);
return $crypt;
});
$di->set('dispatcher', function () use ($di) {
$evManager = $di->getShared('eventsManager');
$evManager->attach('dispatch:beforeDispatch', new SecurityPlugin);
$evManager->attach('dispatch:afterDispatchLoop', new SecurityHeadersPlugin);
$evManager->attach('dispatch:beforeException', new NotFoundPlugin);
$evManager->attach('dispatch:beforeForward', new ForwardPlugin);
$dispatcher = new Dispatcher();
$dispatcher->setEventsManager($evManager);
return $dispatcher;
}, true);
/**
* Flash service with custom CSS classes
*/
$di->set('flash', function () {
$flash = new FlashSession();
$flash->setCssClasses([
'success' => 'alert alert-success alert-dismissable fade in',
'notice' => 'alert alert-info alert-dismissable fade in',
'warning' => 'alert alert-warning alert-dismissable fade in',
'error' => 'alert alert-danger alert-dismissable fade in'
]);
return $flash;
});
/**
* Custom authentication component
*/
$di->setShared('auth', function () {
return new Auth();
});
$di->setShared('utils', function () {
return new Utils();
});
/**
* Access Control List
*/
$di->set('acl', function () {
return new Acl();
});
/**
* Access Control List
*/
$di->setShared('mobiledetect', function () {
return new \Mobile_Detect();
});
$di->setShared('t', function ($lang = false) use ($config, $di) {
global $lang;
$request = new Request();
$language = DI::getDefault()->getShared('auth')->getActiveLanguage();
if (!$language) {
$lang = $request->getBestLanguage();
if (!$lang) {
$lang = 'es';
}
$language = Languages::findFirstByLang($lang);
if (!$language) {
$lang = 'es';
} else {
$lang = $language->lang;
}
} else {
$lang = $language->lang;
}
$db = $di->getDefault()->getDb();
return new DbAdapter([
'db' => $db,
'table' => 'translations',
'language' => 'language',
'key' => 'key_name',
'value' => 'value',
'locale' => $lang,
]);
});
$di->setShared('request', function () {
return new Request();
});
/*
* Marcando como shared el modulo al cargalo esto deja disponibles las "cosicas"
*/
foreach ($config->modules as $module) {
$dir = preg_replace("/\/Module.php$/", "", $module['path']);
// Register Namespace for Shared Module (will not be called by dispatch)
if (isset($module['shared'])) {
$namespace = preg_replace('/\\\Module$/', "", $module['className']);
$loader->setNamespaces(array($namespace => $dir), true);
// Loading Module class bootloader Reflection Instance
$reflexion = new ReflectionClass($module['className']);
$instance = $reflexion->newInstanceWithoutConstructor();
// Execute every 'register' methods
foreach ($reflexion->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if (preg_match('/^register/', $method->name)) {
$instance->{$method->name}($di);
}
}
}
} |
| #17 | Closure->illusion\{closure}() |
| #18 | Phalcon\Di\Service->resolve(null, Object(Phalcon\Di\FactoryDefault)) |
| #19 | Phalcon\Di\Di->get(t, null) |
| #20 | Phalcon\Di\Di->getShared(t) |
| #21 | Phalcon\Di\Injectable->__get(t)
/home/laberitillusions/public_html/apps/modules/users/controllers/AuthController.php (36) <?php
namespace illusion\Modules\Users\Controllers;
use illusion\Common\Auth\Exception;
use illusion\Common\TwoFactor\TwoFactorService;
use illusion\Modules\Users\Forms\ConfirmaccountForm;
use illusion\Modules\Users\Forms\ForgotPasswordForm;
use illusion\Modules\Users\Forms\LoginForm;
use illusion\Modules\Users\Forms\PasswordForm;
use illusion\Modules\Users\Models\FailedLoginsData;
use illusion\Modules\Users\Models\PasswordChanges;
use illusion\Modules\Users\Models\ResetPasswords;
use illusion\Modules\Users\Models\Users;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;
class AuthController extends Controller
{
/**
* Acceso usuario
*/
public function loginAction()
{
$this->moduleName = $this->dispatcher->getModuleName();
$this->controllerName = $this->dispatcher->getControllerName();
$this->actionName = $this->dispatcher->getActionName();
$this->utils->addPageLevelAssets($this->moduleName, $this->controllerName, $this->actionName);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVars(
array(
'pageTitle' => $this->t->_('Iniciar sesión'),
'pageTitleSmall' => ''
)
);
// Si el usuario vuelve al login con un 2FA pendiente, cancelarlo
if ($this->session->has('pending_2fa')) {
$this->session->remove('pending_2fa');
}
$form = new LoginForm();
if (!$this->request->isPost()) {
if ($this->auth->hasRememberMe()) {
return $this->auth->loginWithRememberMe();
}
} else {
if ($form->isValid($this->request->getPost()) == false) {
foreach ($form->getMessages() as $message) {
$this->flash->error($message);
}
} else {
$email = $this->request->getPost('email', 'striptags');
$password = $this->request->getPost('password', 'striptags');
$remember = $this->request->getPost('remember');
try {
$user = $this->auth->validateCredentials($email, $password);
$is2faEnabled = filter_var(
function_exists('env') ? env('APP_2FA_ENABLED', 'true') : 'true',
FILTER_VALIDATE_BOOLEAN
);
if ($is2faEnabled) {
$twoFactor = new TwoFactorService();
$codeId = $twoFactor->generate($user);
$this->session->set('pending_2fa', [
'usersId' => $user->id,
'twoFactorCodeId' => $codeId,
'email' => $this->crypt->encrypt($email),
'password' => $this->crypt->encrypt($password),
'remember' => !empty($remember),
]);
return $this->response->redirect('users/auth/verify2fa');
}
// 2FA deshabilitado: login directo
$this->auth->createSession($user, !empty($remember));
$this->session->remove('lock');
$this->session->remove('referer');
$url = 'dashboard';
if ($this->session->has('returnTo')) {
$returnTo = $this->session->get('returnTo');
if (!strpos($returnTo, 'users/login')) {
$url = $returnTo;
}
$this->session->remove('returnTo');
}
return $this->response->redirect($url);
} catch (Exception $e) {
$this->flash->error($e->getMessage());
}
}
}
$this->view->setVar('loginForm', new LoginForm());
$this->view->setVar('forgotForm', new ForgotPasswordForm());
}
/**
* Activar cuenta de usuario despues del registro
*/
public function confirmaccountAction($code)
{
// El $code por URL es plano; BD guarda sólo hash SHA-256.
$user = Users::findFirst([
'conditions' => 'code = :h:',
'bind' => ['h' => hash('sha256', (string)$code)],
]);
if (!$user) {
$this->flash->warning($this->t->_('El enlace ha caducado, puede solicitar una recuperación de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
// if ($user->used == 'Y') {
// $this->flash->warning($this->t->_('El enlace ya ha sido utilizado, puede solicitar una recuperación de contraseña.'));
// return $this->dispatcher->forward(array(
// 'module' => 'users',
// 'controller' => 'auth',
// 'action' => 'login'
// ));
// }
$dateLimit = \DateTime::createFromFormat('Y-m-d H:i:s', $user->codeCreatedAt);
$dateLimit->modify('+24 hours');
$dateNow = \DateTime::createFromFormat('Y-m-d H:i:s', date("Y-m-d H:i:s"));
if ($dateNow > $dateLimit) {
$this->flash->warning($this->t->_('El enlace ha caducado, puede solicitar una recuperación de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$form = new ConfirmaccountForm($user);
if ($this->request->isPost()) {
if ($form->isValid($this->request->getPost()) == false) {
foreach ($form->getMessages() as $message) {
$this->flash->error($message);
}
} else {
$user = Users::findFirstByHash($this->request->getPost('hash'));
if (!$user) {
$this->flash->warning($this->t->_('El enlace ha caducado, puede solicitar una recuperación de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
$password = $this->request->getPost('passwordNew');
$user->password = $this->security->hash($password);
$passwordChange = new PasswordChanges();
$passwordChange->usersId = $user->id;
$passwordChange->ipAddress = $this->request->getClientAddress();
$passwordChange->userAgent = $this->request->getUserAgent();
$passwordChange->createdAt = date('Y-m-d H:i:s');
$user->code = '';
$user->codeUsedAt = date('Y-m-d H:i:s');
$user->tmpPassword = $password;
$user->update();
$this->auth->authUserById($user->id);
$this->flash->success($this->t->_('Contraseña guardada correctamente, ya puede acceder a %siteName%.', ['siteName' => $this->config->info->siteName]));
return $this->response->redirect('');
}
}
$this->view->form = $form;
$this->view->code = $code;
}
/**
* Formulario solicitar restablecer contraseña
*/
public function rememberPasswordAction()
{
$this->moduleName = $this->dispatcher->getModuleName();
$this->controllerName = $this->dispatcher->getControllerName();
$this->actionName = $this->dispatcher->getActionName();
$this->utils->addPageLevelAssets($this->moduleName, $this->controllerName, $this->actionName);
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVars(
array(
'pageTitle' => $this->t->_('Recuperar contraseña'),
'pageTitleSmall' => ''
)
);
$form = new ForgotPasswordForm();
if ($this->request->isPost()) {
if ($form->isValid($this->request->getPost()) == false) {
foreach ($form->getMessages() as $message) {
$this->flash->error($this->t->_($message));
}
} else {
$user = Users::findFirst("email = '" . $this->request->getPost('email') . "'");
if (!$user) {
$this->flash->error($this->t->_('Esta acción no se puede realizar, datos incorrectos.'));
} else {
if ($user->active == 'N' or $user->deleted == 'Y') {
$this->flash->error($this->t->_('Esta acción no se puede realizar, datos incorrectos.'));
} else {
$user->used = 'N';
$user->update();
$resetPassword = new ResetPasswords();
$resetPassword->usersId = $user->id;
$resetPassword->ipAddress = $this->request->getClientAddress();
$resetPassword->userAgent = $this->request->getUserAgent();
if ($resetPassword->save()) {
$this->flash->success($this->t->_('Le hemos enviado instrucciones al correo electrónico indicado.'));
return $this->response->redirect('users/auth/login');
} else {
foreach ($resetPassword->getMessages() as $message) {
$this->flash->error($this->t->_($message));
}
}
}
}
}
}
$this->view->forgotForm = $form;
}
/**
* Formulario cambio contraseña
*/
public function resetPasswordAction($code)
{
$this->moduleName = $this->dispatcher->getModuleName();
$this->controllerName = $this->dispatcher->getControllerName();
$this->actionName = $this->dispatcher->getActionName();
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVars(
array(
'pageTitle' => $this->t->_('Cambiar contraseña'),
'pageTitleSmall' => ''
)
);
// El $code que llega por URL es el plano. En BD guardamos sólo el
// hash SHA-256 — comparamos hasheando lo recibido.
$resetPassword = ResetPasswords::findFirst([
'conditions' => 'code = :h:',
'bind' => ['h' => hash('sha256', (string)$code)],
]);
if (!$resetPassword) {
$this->flash->warning($this->t->_('El enlace ha caducado, deberá solicitar de nuevo un reinicio de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
if ($resetPassword->reset != 'N') {
$this->flash->warning($this->t->_('El enlace ya ha sido utilizado, deberá solicitar de nuevo un reinicio de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
$dateLimit = \DateTime::createFromFormat('Y-m-d H:i:s', $resetPassword->createdAt);
$dateLimit->modify('+24 hours');
$dateNow = \DateTime::createFromFormat('Y-m-d H:i:s', date("Y-m-d H:i:s"));
if ($dateNow > $dateLimit) {
$this->flash->warning($this->t->_('El enlace ha caducado, deberá solicitar de nuevo un reinicio de contraseña.'));
return $this->dispatcher->forward(array(
'module' => 'users',
'controller' => 'auth',
'action' => 'login'
));
}
$tempPassword = preg_replace('/[^a-zA-Z0-9]/', '', base64_encode(openssl_random_pseudo_bytes(12)));
$resetPassword->User->tmpPassword = $tempPassword;
$resetPassword->User->password = $this->security->hash($tempPassword);
$resetPassword->User->save();
$passwordForm = new PasswordForm(null, array(
'edit' => true
));
$this->view->form = $passwordForm;
if ($this->request->isPost()) {
if (!$passwordForm->isValid($this->request->getPost())) {
foreach ($passwordForm->getMessages() as $message) {
$this->flash->error($message);
}
return $this->response->redirect($this->request->getHTTPReferer());
} else {
$password = $this->request->getPost('passwordNew', 'striptags');
$confirmPassword = $this->request->getPost('confirmPassword', 'striptags');
if (strlen($password) > 0 && strlen($confirmPassword) > 0) {
$user2 = $resetPassword->User;
$user2->password = $this->security->hash($password);
$passwordChange = new PasswordChanges();
$passwordChange->usersId = $user2->id;
$passwordChange->ipAddress = $this->request->getClientAddress();
$passwordChange->userAgent = $this->request->getUserAgent();
$passwordChange->createdAt = date('Y-m-d H:i:s');
$passwordChange->save();
$user2->save();
$this->flash->success($this->t->_('Contraseña establecida correctamente.'));
$this->session->set('credentials', array(
'email' => $this->crypt->encrypt($user2->email, $this->config->application->cryptSalt),
'password' => $this->crypt->encrypt($password, $this->config->application->cryptSalt)
));
return $this->response->redirect('users/auth/login');
}
}
}
$this->view->code = $code;
}
/**
* Verificación del código OTP de segundo factor.
*/
public function verify2faAction()
{
$pending = $this->session->get('pending_2fa');
if (!$pending || !isset($pending['usersId'], $pending['twoFactorCodeId'])) {
return $this->response->redirect('users/auth/login');
}
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVars([
'pageTitle' => $this->t->_('Verificación en dos pasos'),
'pageTitleSmall' => '',
]);
if ($this->request->isPost()) {
$inputCode = trim((string)$this->request->getPost('otp_code', 'striptags'));
$twoFactor = new TwoFactorService();
$result = $twoFactor->verify(
(int)$pending['twoFactorCodeId'],
(int)$pending['usersId'],
$inputCode
);
switch ($result) {
case 'ok':
$user = Users::findFirstById((int)$pending['usersId']);
if (!$user) {
$this->session->remove('pending_2fa');
return $this->response->redirect('users/auth/login');
}
$this->auth->createSession($user, (bool)($pending['remember'] ?? false));
$this->session->remove('pending_2fa');
$this->session->remove('lock');
$this->session->remove('referer');
$url = 'dashboard';
if ($this->session->has('returnTo')) {
$returnTo = $this->session->get('returnTo');
if (!strpos($returnTo, 'users/login')) {
$url = $returnTo;
}
$this->session->remove('returnTo');
}
return $this->response->redirect($url);
case 'exhausted':
case 'invalid':
$this->session->remove('pending_2fa');
$this->flash->error($this->t->_('Código inválido o expirado. Inicia sesión de nuevo.'));
return $this->response->redirect('users/auth/login');
case 'wrong':
default:
$this->flash->error($this->t->_('Código incorrecto. Inténtalo de nuevo.'));
break;
}
}
}
}
|
| #22 | illusion\Modules\Users\Controllers\AuthController->loginAction() |
| #23 | Phalcon\Dispatcher\AbstractDispatcher->callActionMethod(Object(illusion\Modules\Users\Controllers\AuthController), loginAction, Array()) |
| #24 | Phalcon\Dispatcher\AbstractDispatcher->dispatch() |
| #25 | Phalcon\Mvc\Application->handle(/users/auth/login)
/home/laberitillusions/public_html/public/index.php (102) <?php
// Cargamos el helper env() antes de cualquier cosa (no depende de nada)
require_once dirname(__DIR__) . '/apps/config/env_variable_loader.php';
ini_set("session.cookie_lifetime", "14400");
ini_set("session.gc_maxlifetime", "14000");
// Endurecimiento de la cookie de sesión (aplicar ANTES de session_start).
// JS no puede leer la cookie:
ini_set('session.cookie_httponly', '1');
// Bloquea envío cross-site en POST/navegación top-level sospechosa (protección CSRF básica):
ini_set('session.cookie_samesite', 'Lax');
// Rechaza session_id no emitido por PHP (mitiga session fixation a bajo nivel):
ini_set('session.use_strict_mode', '1');
// Secure solo tiene sentido sobre HTTPS; en local WAMP romperíamos el login.
if ((!defined('APPLICATION_ENV') || getenv('APPLICATION_ENV') !== 'local') && !empty($_SERVER['HTTPS'])) {
ini_set('session.cookie_secure', '1');
}
use Phalcon\Mvc\Application;
date_default_timezone_set('Europe/Madrid');
setlocale(LC_ALL, array("es_ES"));
setlocale(LC_MONETARY, 'es_ES');
if (!defined('APPLICATION_ENV')) {
define('APPLICATION_ENV', 'local');
}
if (!defined('BASE_DIR')) {
define('BASE_DIR', dirname(__DIR__));
}
// Composer autoloader necesario para que class_exists(Dotenv\Dotenv) funcione
// (loader.php lo cargará de nuevo pero require_once lo omite si ya está cargado)
if (is_file(BASE_DIR . '/vendor/autoload.php')) {
require_once BASE_DIR . '/vendor/autoload.php';
}
// Dotenv: carga .env.{env} o .env si el paquete vlucas/phpdotenv está instalado.
// En local, APPLICATION_ENV puede no estar definido aún — fallback a 'local' para
// que .env.local se cargue automáticamente sin configurar Apache.
if (class_exists(\Dotenv\Dotenv::class)) {
$appEnv = $_ENV['APPLICATION_ENV'] ?? $_SERVER['APPLICATION_ENV'] ?? getenv('APPLICATION_ENV');
if (!is_string($appEnv) || $appEnv === '') {
$appEnv = 'local';
}
foreach (['.env.' . $appEnv, '.env'] as $_envCandidate) {
if (is_file(BASE_DIR . '/' . $_envCandidate)) {
\Dotenv\Dotenv::createImmutable(BASE_DIR, $_envCandidate)->safeLoad();
break;
}
}
unset($appEnv, $_envCandidate);
}
// Fail-secure: solo 'local' expone errores por pantalla. Cualquier otro env (pre/pro/…) los oculta y loguea.
if (APPLICATION_ENV === 'local') {
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
} else {
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_STRICT);
ini_set('display_errors', '0');
ini_set('display_startup_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', BASE_DIR . '/apps/logs/php_errors.log');
}
include BASE_DIR . '/apps/config/constants.php';
include BASE_DIR . '/apps/config/c_modules.php';
$config = include APPS_DIR . '/config/environment/' . APPLICATION_ENV . '/base-config.php';
$ini_file = BASE_DIR . '/private/config/environment/' . APPLICATION_ENV . '/base-config.ini';
$config2 = new \Phalcon\Config\Adapter\Ini($ini_file);
$config->merge($config2);
include APPS_DIR . '/config/loader.php';
include APPS_DIR . '/config/services.php';
$application = new Application();
$application->setDI($di);
require APPS_DIR . '/config/modules.php';
//$baseUri = str_replace('/public/index.php', '', $_SERVER['PHP_SELF']);
//$uri = str_replace($baseUri, '', $_SERVER['REQUEST_URI']);
//echo $application->handle($uri)->getContent();
//$path = str_replace($_SERVER["DOCUMENT_ROOT"], '', str_replace("\\", "/", BASE_DIR));
//$uri = str_replace($path, '', $_SERVER['REQUEST_URI']);
//echo $application->handle($uri)->getContent();
//echo $application->handle($_SERVER['REQUEST_URI'])->getContent();
$request = $di->getShared('request');
echo $application->handle($request->getURI())->getContent(); |