diff --git a/admin/language/english/admin_accounts_lang.php b/admin/language/english/admin_accounts_lang.php
index 8c10343c..737789ef 100644
--- a/admin/language/english/admin_accounts_lang.php
+++ b/admin/language/english/admin_accounts_lang.php
@@ -41,16 +41,6 @@
$lang['accounts_edit_password_legend'] = 'Password';
-$lang['accounts_edit_mfa_question_legend'] = 'Multi Factor Authentication: Questions';
-$lang['accounts_edit_mfa_question_field_reset_label'] = 'Set new qustions on next log in';
-$lang['accounts_edit_mfa_question_field_reset_yes'] = 'Yes, require user to set new security questions on next log in.';
-$lang['accounts_edit_mfa_question_field_reset_no'] = 'No, do not require user to set new security questions on next log in.';
-
-$lang['accounts_edit_mfa_device_legend'] = 'Multi Factor Authentication: Device';
-$lang['accounts_edit_mfa_device_field_reset_label'] = 'Setup a new device on next log in';
-$lang['accounts_edit_mfa_device_field_reset_yes'] = 'Yes, require user to setup a new security device on next log in.';
-$lang['accounts_edit_mfa_device_field_reset_no'] = 'No, do not require user to setup a new security device on next log in.';
-
$lang['accounts_edit_basic_legend'] = 'Basic Information';
$lang['accounts_edit_basic_field_first_placeholder'] = 'The user\'s first name';
$lang['accounts_edit_basic_field_last_placeholder'] = 'The user\'s surname';
diff --git a/admin/views/Accounts/edit/inc-mfa-device.php b/admin/views/Accounts/edit/inc-mfa-device.php
deleted file mode 100644
index b3f4974f..00000000
--- a/admin/views/Accounts/edit/inc-mfa-device.php
+++ /dev/null
@@ -1,17 +0,0 @@
- 'reset_mfa_device',
- 'label' => lang('accounts_edit_mfa_device_field_reset_label'),
- 'options' => [
- [
- 'value' => true,
- 'label' => lang('accounts_edit_mfa_device_field_reset_yes'),
- 'selected' => set_radio('reset_mfa_device') ? true : false,
- ],
- [
- 'value' => false,
- 'label' => lang('accounts_edit_mfa_device_field_reset_no'),
- 'selected' => !set_radio('reset_mfa_device') ? true : false,
- ],
- ],
-]);
diff --git a/admin/views/Accounts/edit/inc-mfa-question.php b/admin/views/Accounts/edit/inc-mfa-question.php
deleted file mode 100644
index 7d1f530c..00000000
--- a/admin/views/Accounts/edit/inc-mfa-question.php
+++ /dev/null
@@ -1,17 +0,0 @@
- 'reset_mfa_question',
- 'label' => lang('accounts_edit_mfa_question_field_reset_label'),
- 'options' => [
- [
- 'value' => true,
- 'label' => lang('accounts_edit_mfa_question_field_reset_yes'),
- 'selected' => set_radio('reset_mfa_question') ? true : false,
- ],
- [
- 'value' => false,
- 'label' => lang('accounts_edit_mfa_question_field_reset_no'),
- 'selected' => !set_radio('reset_mfa_question') ? true : false,
- ],
- ],
-]);
diff --git a/auth/config/auth.php b/auth/config/auth.php
index eff4e53d..575d9060 100644
--- a/auth/config/auth.php
+++ b/auth/config/auth.php
@@ -36,27 +36,3 @@
* On login show the last known IP of the user
*/
$config['authShowLastIpOnLogin'] = false;
-
-// --------------------------------------------------------------------------
-
-/**
- * Auth sub config files
- * Load both versions, app version overrides Nails version
- */
-$sAppPath = NAILS_APP_PATH . 'application/modules/auth/config/';
-$sNailsPath = NAILS_PATH . 'module-auth/auth/config/';
-
-$aFiles = [
- 'auth.twofactor.php',
-];
-
-foreach ($aFiles as $sFile) {
-
- if (file_exists($sNailsPath . $sFile)) {
- include $sNailsPath . $sFile;
- }
-
- if (file_exists($sAppPath . $sFile)) {
- include $sAppPath . $sFile;
- }
-}
diff --git a/auth/config/auth.twofactor.php b/auth/config/auth.twofactor.php
deleted file mode 100644
index d63f8426..00000000
--- a/auth/config/auth.twofactor.php
+++ /dev/null
@@ -1,56 +0,0 @@
- [
- // The number of system questions a user must have
- 'numQuestions' => 1,
-
- // The number of user questions a user must have
- 'numUserQuestions' => 0,
-
- // The questions the system can use
- 'questions' => [
- 'What was your childhood nickname? ',
- 'In what city did you meet your spouse/significant other?',
- 'What is the name of your favorite childhood friend? ',
- 'What is the middle name of your oldest child?',
- 'What is your oldest sibling\'s middle name?',
- 'What was your childhood phone number including area code?',
- 'What is your oldest cousin\'s first and last name?',
- 'What was the name of your first stuffed animal?',
- 'In what city or town did your mother and father meet? ',
- 'Where were you when you had your first kiss? ',
- 'What is the first name of the boy or girl that you first kissed?',
- 'In what city does your nearest sibling live? ',
- 'What is your oldest sibling\'s birthday month and year? (e.g., January 1900) ',
- 'What is your oldest brother\'s birthday month and year? (e.g., January 1900) ',
- 'What is your oldest sister\'s birthday month and year? (e.g., January 1900) ',
- 'What is your maternal grandmother\'s maiden name?',
- 'In what city or town was your first job?',
- 'What is the name of the place your wedding reception was held?',
- 'What is the name of a college or university you applied to but didn\'t attend?',
- 'Where were you when you first heard about 9/11?',
- ],
- ],
- 'DEVICE' => [],
-];
diff --git a/auth/controllers/Login.php b/auth/controllers/Login.php
index 03c1502c..bd2283b1 100644
--- a/auth/controllers/Login.php
+++ b/auth/controllers/Login.php
@@ -14,7 +14,6 @@
use Nails\Auth\Controller\Base;
use Nails\Auth\Exception\AuthException;
use Nails\Auth\Exception\Login\NoUserException;
-use Nails\Auth\Exception\Login\RequiresMfaException;
use Nails\Auth\Exception\Login\RequiresPasswordResetExpiredException;
use Nails\Auth\Exception\Login\RequiresPasswordResetTempException;
use Nails\Auth\Model\User\Password;
@@ -151,9 +150,6 @@ public function index()
} catch (NoUserException $e) {
$this->oUserFeedback->error($e->getMessage());
- } catch (RequiresMfaException $e) {
- $this->handleMfa($oUser);
-
} catch (RequiresPasswordResetTempException $e) {
$this->handlePasswordReset($oUser, $bRemember, 'TEMP');
@@ -217,8 +213,6 @@ protected function handleLogin(Resource\User $oUser, bool $bRemember = false, st
$oConfig = Factory::service('Config');
/** @var Password $oUserPasswordModel */
$oUserPasswordModel = Factory::model('UserPassword', Constants::MODULE_SLUG);
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
if (!empty($oUser->temp_pw)) {
@@ -228,10 +222,6 @@ protected function handleLogin(Resource\User $oUser, bool $bRemember = false, st
$this->handlePasswordReset($oUser, $bRemember, 'EXPIRED');
- } elseif ($oConfig->item('authTwoFactorMode')) {
-
- $this->handleMfa($oUser);
-
} else {
// Finally! Send this user on their merry way...
@@ -283,8 +273,6 @@ protected function handleLogin(Resource\User $oUser, bool $bRemember = false, st
/**
* Whether to offer this user a passkey before sending them on their way
*
- * An MFA-challenged login never returns through here.
- *
* @throws FactoryException
*/
protected function shouldNudgeForPasskey(Resource\User $oUser): bool
@@ -308,69 +296,6 @@ protected function shouldNudgeForPasskey(Resource\User $oUser): bool
// --------------------------------------------------------------------------
- /**
- * Handle MFA redirect
- *
- * @param Resource\User $oUser The user who requires MFA
- * @param bool $bRemember Whether to set the rememberMe cookie or not
- *
- * @throws AuthException
- * @throws FactoryException
- */
- protected function handleMfa(Resource\User $oUser, bool $bRemember = false): void
- {
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
- /** @var Config $oConfig */
- $oConfig = Factory::service('Config');
-
- $aTwoFactorToken = $oAuthService->mfaTokenGenerate($oUser->id);
-
- if (!$aTwoFactorToken) {
- throw new AuthException(
- 'A user tried to login and the system failed to generate a two-factor auth token.'
- );
- }
-
- // Is there any query data?
- $aQuery = array_filter([
- 'return_to' => $this->data['return_to'] ?: null,
- 'remember' => $bRemember,
- ]);
-
- $sQuery = !empty($aQuery) ? '?' . http_build_query($aQuery) : '';
-
- // Where we sending the user?
- switch ($oConfig->item('authTwoFactorMode')) {
-
- case 'QUESTION':
- $sController = 'mfa/question';
- break;
-
- case 'DEVICE':
- $sController = 'mfa/device';
- break;
-
- default:
- throw new AuthException('"' . $oConfig->item('authTwoFactorMode') . '" is not a valid MFA Mode');
- break;
- }
-
- // Compile the URL
- $aUrl = [
- 'auth',
- $sController,
- $oUser->id,
- $aTwoFactorToken['salt'],
- $aTwoFactorToken['token'],
- ];
-
- // Login was successful, redirect to the appropriate MFA page
- redirect(implode('/', $aUrl) . $sQuery);
- }
-
- // --------------------------------------------------------------------------
-
/**
* @param Resource\User $oUser The user who is resetting their password
* @param bool $bRemember Whether to set the rememberMe cookie or not
diff --git a/auth/controllers/MfaDevice.php b/auth/controllers/MfaDevice.php
deleted file mode 100644
index 68fb126d..00000000
--- a/auth/controllers/MfaDevice.php
+++ /dev/null
@@ -1,196 +0,0 @@
-authMfaMode == 'DEVICE') {
- $this->index();
- } else {
- show404();
- }
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * Remaps requests to the correct method
- *
- * @throws FactoryException
- */
- public function index()
- {
- // Validates the request token and generates a new one for the next request
- $this->validateToken();
-
- // --------------------------------------------------------------------------
-
- // Has this user already set up an MFA?
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
- $oMfaDevice = $oAuthService->mfaDeviceSecretGet($this->mfaUser->id);
-
- if ($oMfaDevice) {
- $this->requestCode();
- } else {
- $this->setupDevice();
- }
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * Sets up a new MFA device
- *
- * @throws FactoryException
- */
- protected function setupDevice()
- {
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
- /** @var Input $oInput */
- $oInput = Factory::service('Input');
-
- if ($oInput->post()) {
-
- /** @var FormValidation $oFormValidation */
- $oFormValidation = Factory::service('FormValidation');
-
- try {
-
- $oFormValidation
- ->buildValidator([
- 'mfa_secret' => [FormValidation::RULE_REQUIRED],
- 'mfa_code' => [FormValidation::RULE_REQUIRED],
- ])
- ->run();
-
- $sSecret = $oInput->post('mfa_secret');
- $sMfaCode = $oInput->post('mfa_code');
-
- // Verify the inout
- if ($oAuthService->mfaDeviceSecretValidate($this->mfaUser->id, $sSecret, $sMfaCode)) {
-
- // Codes have been validated and saved to the DB, sign the user in and move on
- $this->oUserFeedback->success(
- 'Multi Factor Authentication Enabled!
You successfully ' .
- 'associated an MFA device with your account. You will be required to use it ' .
- 'the next time you log in.'
- );
-
- $this->loginUser();
-
- } else {
- $this->oUserFeedback->error('Sorry, that code failed to validate. Please try again.');
- }
-
- } catch (ValidationException $e) {
- $this->oUserFeedback->error($e->getMessage());
- }
- }
-
- // Generate the secret
- $this->data['secret'] = $oAuthService->mfaDeviceSecretGenerate(
- $this->mfaUser->id,
- $oInput->post('mfa_secret', true)
- );
-
- if (!$this->data['secret']) {
- $this->oUserFeedback->error('Sorry, it has not been possible to get an MFA device set up for this user. ' . $oAuthService->lastError());
- redirect(loginUrl($this->returnTo ?: false));
- }
-
- // --------------------------------------------------------------------------
-
- $this->oMetaData->setTitles(['Set up a new MFA device']);
- $this->loadStyles(NAILS_APP_PATH . 'application/modules/auth/views/mfa/device/setup.php');
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/device/setup',
- 'structure/footer/blank',
- ]);
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * Requests a code from the user
- *
- * @throws FactoryException
- */
- protected function requestCode()
- {
- /** @var Input $oInput */
- $oInput = Factory::service('Input');
- if ($oInput->post()) {
-
- /** @var FormValidation $oFormValidation */
- $oFormValidation = Factory::service('FormValidation');
-
- try {
-
- $oFormValidation
- ->buildValidator([
- 'mfa_code' => [FormValidation::RULE_REQUIRED],
- ])
- ->run();
-
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
- $sMfaCode = $oInput->post('mfa_code');
-
- // Verify the inout
- if ($oAuthService->mfaDeviceCodeValidate($this->mfaUser->id, $sMfaCode)) {
- $this->loginUser();
- } else {
- $this->oUserFeedback->error(sprintf(
- 'Sorry, that code failed to validate. Please try again. %s',
- $oAuthService->lastError()
- ));
- }
-
- } catch (ValidationException $e) {
- $this->oUserFeedback->error($e->getMessage());
- }
- }
-
- // --------------------------------------------------------------------------
-
- $this->oMetaData->setTitles(['Enter your code']);
- $this->loadStyles(NAILS_APP_PATH . 'application/modules/auth/views/mfa/device/ask.php');
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/device/ask',
- 'structure/footer/blank',
- ]);
- }
-}
diff --git a/auth/controllers/MfaQuestion.php b/auth/controllers/MfaQuestion.php
deleted file mode 100644
index d827e66d..00000000
--- a/auth/controllers/MfaQuestion.php
+++ /dev/null
@@ -1,260 +0,0 @@
-authMfaMode == 'QUESTION') {
- $this->index();
- } else {
- show404();
- }
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * Sets up, or asks an MFA Question
- *
- * @throws FactoryException
- */
- public function index()
- {
- // Validates the request token and generates a new one for the next request
- $this->validateToken();
-
- // --------------------------------------------------------------------------
-
- /** @var Input $oInput */
- $oInput = Factory::service('Input');
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
-
- if ($oInput->post('answer')) {
-
- /**
- * Validate the answer, if correct then log user in and forward, if
- * not then generate a new token and show errors
- */
-
- $this->data['question'] = $oAuthService->mfaQuestionGet($this->mfaUser->id);
- $bIsValid = $oAuthService->mfaQuestionValidate(
- $this->data['question']->id,
- $this->mfaUser->id,
- $oInput->post('answer')
- );
-
- if ($bIsValid) {
- $this->loginUser();
- } else {
- $this->oUserFeedback->error(lang('auth_twofactor_answer_incorrect'));
- $this->askQuestion();
- }
-
- } else {
-
- // Determine whether the user has any security questions set
- $this->data['question'] = $oAuthService->mfaQuestionGet($this->mfaUser->id);
-
- if ($this->data['question']) {
-
- // Ask away cap'n!
- $this->askQuestion();
-
- } else {
-
- // Fetch the security questions
- $this->data['questions'] = $this->authMfaConfig['questions'];
-
- /**
- * Determine how many questions a user must have, if the number of questions
- * is smaller than the number of questions available, use the smaller.
- */
- if (count($this->data['questions']) < $this->authMfaConfig['numQuestions']) {
- $this->data['num_questions'] = count($this->data['questions']);
- } else {
- $this->data['num_questions'] = $this->authMfaConfig['numQuestions'];
- }
-
- // The number of user generated questions a user must have
- $this->data['num_custom_questions'] = $this->authMfaConfig['numUserQuestions'];
-
- if ($this->data['num_questions'] + $this->data['num_custom_questions'] <= 0) {
- throw new NailsException('Two-factor auth is enabled, but no questions available');
- }
-
- if ($oInput->post()) {
-
- /** @var FormValidation $oFormValidation */
- $oFormValidation = Factory::service('FormValidation');
-
- $aRules = [];
-
- for ($i = 0; $i < $this->data['num_questions']; $i++) {
- $aRules['question[' . $i . '][question]'] = [
- FormValidation::RULE_REQUIRED,
- FormValidation::RULE_IS_NATURAL_NO_ZERO,
- ];
- $aRules['question[' . $i . '][answer]'] = ['trim', FormValidation::RULE_REQUIRED];
- }
-
- for ($i = 0; $i < $this->data['num_custom_questions']; $i++) {
- $aRules['custom_question[' . $i . '][question]'] = ['trim', FormValidation::RULE_REQUIRED];
- $aRules['custom_question[' . $i . '][answer]'] = ['trim', FormValidation::RULE_REQUIRED];
- }
-
- try {
-
- $oValidator = $oFormValidation->buildValidator(
- $aRules,
- [FormValidation::RULE_IS_NATURAL_NO_ZERO => lang('fv_required')]
- );
- $oValidator->run();
-
- // The validated data carries the trimmed values
- $aPost = $oValidator->getValidatedData();
-
- // Make sure that we have different questions
- $aQuestionIndex = [];
- $aQuestion = array_filter((array) ($aPost['question'] ?? []));
- $bError = false;
-
- foreach ($aQuestion as $q) {
-
- if (!in_array($q['question'], $aQuestionIndex)) {
- $aQuestionIndex[] = $q['question'];
- } else {
- $bError = true;
- break;
- }
- }
-
- $aQuestionIndex = [];
- $aQuestion = array_filter((array) ($aPost['custom_question'] ?? []));
-
- foreach ($aQuestion as $q) {
- if (array_search($q['question'], $aQuestionIndex) === false) {
- $aQuestionIndex[] = $q['question'];
- } else {
- $bError = true;
- break;
- }
- }
-
- if (!$bError) {
-
- // Good arrows. Save questions
- $aData = [];
-
- if (!empty($aPost['question'])) {
-
- foreach ($aPost['question'] as $q) {
-
- $oTemp = new stdClass();
-
- if (isset($this->data['questions'][$q['question'] - 1])) {
- $oTemp->question = $this->data['questions'][$q['question'] - 1];
- } else {
- $oTemp->question = null;
- }
- $oTemp->answer = $q['answer'];
-
- $aData[] = $oTemp;
- }
- }
-
- if (!empty($aPost['custom_question'])) {
- foreach ((array) $aPost['custom_question'] as $aQuestion) {
- $aData[] = (object) [
- 'question' => trim($aQuestion['question']),
- 'answer' => $aQuestion['answer'],
- ];
- }
- }
-
- if ($oAuthService->mfaQuestionSet($this->mfaUser->id, $aData)) {
-
- $this->oUserFeedback->success(
- 'Multi Factor Authentication Enabled!
You successfully ' .
- 'set your security questions. You will be asked to answer one of them every time ' .
- 'you log in.'
- );
-
- $this->loginUser();
-
- } else {
- $oUserModel = Factory::model('User', Constants::MODULE_SLUG);
- $this->oUserFeedback->error(sprintf(
- '%s %s',
- lang('auth_twofactor_question_set_fail'),
- $oUserModel->lastError()
- ));
- }
-
- } else {
- $this->oUserFeedback->error(lang('auth_twofactor_question_unique'));
- }
-
- } catch (ValidationException $e) {
- $this->oUserFeedback->error($e->getMessage());
- }
- }
-
- // No questions, request they set them
- $this->oMetaData->setTitles([lang('auth_twofactor_question_set_title')]);
- $this->loadStyles(NAILS_APP_PATH . 'application/modules/auth/views/mfa/question/set.php');
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/question/set',
- 'structure/footer/blank',
- ]);
- }
- }
- }
-
- // --------------------------------------------------------------------------
-
- /**
- * Asks one of the user's questions
- *
- * @throws FactoryException
- */
- protected function askQuestion()
- {
- // Ask away cap'n!
- $this->oMetaData->setTitles([lang('auth_twofactor_answer_title')]);
- $this->loadStyles(NAILS_APP_PATH . 'application/modules/auth/views/mfa/question/ask.php');
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/question/ask',
- 'structure/footer/blank',
- ]);
- }
-}
diff --git a/auth/controllers/PasswordForgotten.php b/auth/controllers/PasswordForgotten.php
index e41c79a2..8705ad7a 100644
--- a/auth/controllers/PasswordForgotten.php
+++ b/auth/controllers/PasswordForgotten.php
@@ -8,7 +8,6 @@
* @category Controller
* @author Nails Dev Team
* @link
- * @todo Refactor this class so that not so much code is being duplicated, especially re: MFA
*/
use Nails\Auth\Constants;
@@ -16,10 +15,7 @@
use Nails\Auth\Factory\Email\ForgottenPassword;
use Nails\Auth\Model\User;
use Nails\Auth\Model\User\Password;
-use Nails\Auth\Service\Authentication;
use Nails\Auth\Validator\User\Identifier;
-use Nails\Common\Exception\Encrypt\DecodeException;
-use Nails\Common\Exception\EnvironmentException;
use Nails\Common\Exception\FactoryException;
use Nails\Common\Exception\NailsException;
use Nails\Common\Service\Config;
@@ -195,264 +191,50 @@ public function index()
* @param string $sCode The code to validate
*
* @throws FactoryException
- * @throws DecodeException
- * @throws EnvironmentException
*/
public function _validate($sCode)
{
- /** @var Input $oInput */
- $oInput = Factory::service('Input');
- /** @var Config $oConfig */
- $oConfig = Factory::service('Config');
- /** @var Authentication $oAuthService */
- $oAuthService = Factory::service('Authentication', Constants::MODULE_SLUG);
/** @var Password $oUserPasswordModel */
$oUserPasswordModel = Factory::model('UserPassword', Constants::MODULE_SLUG);
- /**
- * Attempt to verify code, if two factor auth is enabled then don't generate a
- * new password, we'll need the user to jump through some hoops first.
- */
- $bGenerateNewPw = !$oConfig->item('authTwoFactorMode');
- $mNewPassword = $oUserPasswordModel->validateToken($sCode, $bGenerateNewPw);
+ $mNewPassword = $oUserPasswordModel->validateToken($sCode, true);
// --------------------------------------------------------------------------
- // Determine outcome of validation
if ($mNewPassword === 'EXPIRED') {
- // Code has expired
$this->oUserFeedback->error(lang('auth_forgot_expired_code'));
} elseif ($mNewPassword === false) {
- // Code was invalid
$this->oUserFeedback->error(lang('auth_forgot_invalid_code'));
} else {
- if ($oConfig->item('authTwoFactorMode') == 'QUESTION') {
-
- // Show them a security question
- $this->data['question'] = $oAuthService->mfaQuestionGet($mNewPassword['user_id']);
-
- if ($this->data['question']) {
-
- if ($oInput->post()) {
-
- $bIsValid = $oAuthService->mfaQuestionValidate(
- $this->data['question']->id,
- $mNewPassword['user_id'],
- $oInput->post('answer')
- );
-
- if ($bIsValid) {
-
- // Correct answer, reset password and render views
- $mNewPassword = $oUserPasswordModel->validateToken($sCode, true);
-
- // @todo (Pablo - 2019-07-17) - Do failures need handled here?
-
- // --------------------------------------------------------------------------
-
- // Set some flashdata for the login page when they go to it; just a little reminder
- $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
-
- // --------------------------------------------------------------------------
-
- // Load the views
- $this->loadStyles(
- \Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php'
- );
-
- Factory::service('View')
- ->setData([
- 'new_password' => $mNewPassword['password'],
- 'user' => (object) [
- 'id' => $mNewPassword['user_id'],
- 'identity' => $mNewPassword['user_identity'],
- ],
- ])
- ->load([
- 'structure/header/blank',
- 'auth/password/forgotten_reset',
- 'structure/footer/blank',
- ]);
- return;
-
- } else {
- $this->oUserFeedback->error(lang('auth_twofactor_answer_incorrect'));
- }
- }
-
- $this->oMetaData->setTitles([lang('auth_title_forgotten_password_security_question')]);
-
- $this->loadStyles(\Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/mfa/question/ask.php');
-
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/question/ask',
- 'structure/footer/blank',
- ]);
-
- } else {
-
- // No questions, reset and load views
- $mNewPassword = $oUserPasswordModel->validateToken($sCode, true);
-
- // @todo (Pablo - 2019-07-17) - Do failures need handled here?
-
- // --------------------------------------------------------------------------
-
- // Set some flashdata for the login page when they go to it; just a little reminder
- $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
-
- // --------------------------------------------------------------------------
-
- // Load the views
- $this->loadStyles(
- \Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php'
- );
-
- Factory::service('View')
- ->setData([
- 'new_password' => $mNewPassword['password'],
- 'user' => (object) [
- 'id' => $mNewPassword['user_id'],
- 'identity' => $mNewPassword['user_identity'],
- ],
- ])
- ->load([
- 'structure/header/blank',
- 'auth/password/forgotten_reset',
- 'structure/footer/blank',
- ]);
- }
-
- } elseif ($oConfig->item('authTwoFactorMode') == 'DEVICE') {
-
- $mSecret = $oAuthService->mfaDeviceSecretGet($mNewPassword['user_id']);
-
- if ($mSecret) {
+ $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
- if ($oInput->post()) {
-
- $sMfaCode = $oInput->post('mfaCode');
-
- // Verify the inout
- if ($oAuthService->mfaDeviceCodeValidate($mNewPassword['user_id'], $sMfaCode)) {
-
- // Correct answer, reset password and render views
- $mNewPassword = $oUserPasswordModel->validateToken($sCode, true);
-
- // @todo (Pablo - 2019-07-17) - Do failures need handled here?
-
- // --------------------------------------------------------------------------
-
- // Set some flashdata for the login page when they go to it; just a little reminder
- $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
-
- // --------------------------------------------------------------------------
-
- // Load the views
- $this->loadStyles(
- \Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php'
- );
-
- Factory::service('View')
- ->setData([
- 'new_password' => $mNewPassword['password'],
- 'user' => (object) [
- 'id' => $mNewPassword['user_id'],
- 'identity' => $mNewPassword['user_identity'],
- ],
- ])
- ->load([
- 'structure/header/blank',
- 'auth/password/forgotten_reset',
- 'structure/footer/blank',
- ]);
- return;
-
- } else {
- $this->oUserFeedback->error('Sorry, that code failed to validate. Please try again. ' . $oAuthService->lastError());
- }
- }
-
- $this->oMetaData->setTitles(['Please enter the code from your device']);
-
- $this->loadStyles(\Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/mfa/device/ask.php');
-
- Factory::service('View')
- ->load([
- 'structure/header/blank',
- 'auth/mfa/device/ask',
- 'structure/footer/blank',
- ]);
-
- } else {
-
- // No devices, reset and load views
- $mNewPassword = $oUserPasswordModel->validateToken($sCode, true);
-
- // @todo (Pablo - 2019-07-17) - Do failures need handled here?
-
- // --------------------------------------------------------------------------
-
- // Set some flashdata for the login page when they go to it; just a little reminder
- $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
-
- // --------------------------------------------------------------------------
-
- // Load the views
- $this->loadStyles(\Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php');
- Factory::service('View')
- ->setData([
- 'new_password' => $mNewPassword['password'],
- 'user' => (object) [
- 'id' => $mNewPassword['user_id'],
- 'identity' => $mNewPassword['user_identity'],
- ],
- ])
- ->load([
- 'structure/header/blank',
- 'auth/password/forgotten_reset',
- 'structure/footer/blank',
- ]);
- }
-
- } else {
-
- // Everything worked!
- // Set some flashdata for the login page when they go to it; just a little reminder
- $this->oUserFeedback->warning(lang('auth_forgot_reminder', htmlentities($mNewPassword['password'])));
-
- // --------------------------------------------------------------------------
-
- // Load the views
- $this->loadStyles(\Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php');
- Factory::service('View')
- ->setData([
- 'new_password' => $mNewPassword['password'],
- 'user' => (object) [
- 'id' => $mNewPassword['user_id'],
- 'identity' => $mNewPassword['user_identity'],
- ],
- ])
- ->load([
- 'structure/header/blank',
- 'auth/password/forgotten_reset',
- 'structure/footer/blank',
- ]);
- }
+ $this->loadStyles(
+ \Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten_reset.php'
+ );
+ Factory::service('View')
+ ->setData([
+ 'new_password' => $mNewPassword['password'],
+ 'user' => (object) [
+ 'id' => $mNewPassword['user_id'],
+ 'identity' => $mNewPassword['user_identity'],
+ ],
+ ])
+ ->load([
+ 'structure/header/blank',
+ 'auth/password/forgotten_reset',
+ 'structure/footer/blank',
+ ]);
return;
}
// --------------------------------------------------------------------------
- // Load the views
$this->loadStyles(\Nails\Config::get('NAILS_APP_PATH') . 'application/modules/auth/views/password/forgotten.php');
Factory::service('View')
->load([
@@ -469,8 +251,6 @@ public function _validate($sCode)
*
* @param string $sMethod The method being called
*
- * @throws DecodeException
- * @throws EnvironmentException
* @throws FactoryException
*/
public function _remap($sMethod)
diff --git a/auth/controllers/PasswordReset.php b/auth/controllers/PasswordReset.php
index 877cae58..48b7c5d8 100644
--- a/auth/controllers/PasswordReset.php
+++ b/auth/controllers/PasswordReset.php
@@ -70,96 +70,7 @@ protected function validate($iUserId, $sHash)
if ($oUser && isset($oUser->salt) && $sHash == $oUserPasswordModel::resetHash($oUser)) {
- // Valid combination, is there MFA on the account?
- if ($oConfig->item('authTwoFactorMode')) {
-
- /**
- * This variable will stop the password resetting until we're confident
- * that MFA has been passed
- */
-
- $bMfaValid = false;
-
- /**
- * Check the user's account to see if they have MFA enabled, if so
- * require that they pass that before allowing the password to be reset
- */
-
- switch ($oConfig->item('authTwoFactorMode')) {
-
- case 'QUESTION':
- $this->data['mfaQuestion'] = $oAuthService->mfaQuestionGet($oUser->id);
-
- if ($this->data['mfaQuestion']) {
-
- if ($oInput->post()) {
-
- // Validate answer
- $isValid = $oAuthService->mfaQuestionValidate(
- $this->data['mfaQuestion']->id,
- $oUser->id,
- $oInput->post('mfaAnswer')
- );
-
- if ($isValid) {
-
- $bMfaValid = true;
-
- } else {
- $this->oUserFeedback->error('Sorry, the answer to your security question was incorrect.');
- }
- }
-
- } else {
-
- // No questions set up, allow for now
- $bMfaValid = true;
- }
-
- break;
-
- case 'DEVICE':
- $this->data['mfaDevice'] = $oAuthService->mfaDeviceSecretGet($oUser->id);
-
- if ($this->data['mfaDevice']) {
-
- if ($oInput->post()) {
-
- // Validate answer
- $isValid = $oAuthService->mfaDeviceCodeValidate(
- $oUser->id,
- $oInput->post('mfaCode')
- );
-
- if ($isValid) {
- $bMfaValid = true;
-
- } else {
- $this->oUserFeedback->error(sprintf(
- 'Sorry, that code could not be validated. %s',
- $oAuthService->lastError()
- ));
- }
- }
-
- } else {
-
- // No devices set up, allow for now
- $bMfaValid = true;
- }
- break;
- }
-
- } else {
-
- // No MFA so just set this to true
- $bMfaValid = true;
- }
-
- // --------------------------------------------------------------------------
-
- // Only run if MFA has been passed and there's POST data
- if ($bMfaValid && $oInput->post()) {
+ if ($oInput->post()) {
try {
@@ -199,8 +110,7 @@ protected function validate($iUserId, $sHash)
$oLoginUser = $oAuthService->loginWithCredentials(
$oUser,
$oInput->post('new_password'),
- $bRemember,
- false
+ $bRemember
);
if ($oLoginUser) {
@@ -244,11 +154,6 @@ protected function validate($iUserId, $sHash)
));
}
- // If MFA is setup then we'll need to set the user's session data
- if ($oConfig->item('authTwoFactorMode')) {
- $oUserModel->setLoginData($oUser->id);
- }
-
// Log user in and forward to wherever they need to go
if ($oInput->get('return_to')) {
redirect($oInput->get('return_to'));
diff --git a/auth/controllers/Register.php b/auth/controllers/Register.php
index 8fbce023..870d95d8 100644
--- a/auth/controllers/Register.php
+++ b/auth/controllers/Register.php
@@ -143,7 +143,6 @@ public function index()
// Redirect to the group homepage
// @todo (Pablo - 2017-07-11) - Setting for forced email activation
- // @todo (Pablo - 2017-07-11) - Handle setting MFA questions and/or devices
$oGroup = $oUserGroupModel->getById($oUser->group_id);
diff --git a/auth/language/english/auth_lang.php b/auth/language/english/auth_lang.php
index 3f29229e..50fc629c 100644
--- a/auth/language/english/auth_lang.php
+++ b/auth/language/english/auth_lang.php
@@ -10,9 +10,8 @@
// Page Titles
$lang['auth_title_login'] = 'Please log in';
$lang['auth_title_register'] = 'Register';
-$lang['auth_title_forgotten_password'] = 'Forgotten your password?';
-$lang['auth_title_forgotten_password_security_question'] = 'Please answer this security question';
-$lang['auth_title_reset'] = 'Reset your password';
+$lang['auth_title_forgotten_password'] = 'Forgotten your password?';
+$lang['auth_title_reset'] = 'Reset your password';
// --------------------------------------------------------------------------
@@ -63,26 +62,6 @@
$lang['auth_login_fail_blocked'] = 'This account has been temporarily blocked due to repeated failed logins. Please wait %s minutes before trying again (each failed login resets the block). ';
$lang['auth_login_fail_no_password'] = 'This account does not have a password. Click here to set a password using the Forgotten Password tool.';
-// Two-factor auth strings
-$lang['auth_twofactor_token_could_not_generate'] = 'Unable to generate two factor auth token.';
-$lang['auth_twofactor_token_invalid'] = 'Invalid token.';
-$lang['auth_twofactor_token_expired'] = 'Token has expired.';
-$lang['auth_twofactor_token_bad_ip'] = 'Invalid IP address.';
-$lang['auth_twofactor_token_unverified'] = 'Sorry, there was a problem verifying your login session. As a precaution we have logged you out.';
-
-$lang['auth_twofactor_question_set_title'] = 'Set Your Security Questions';
-$lang['auth_twofactor_question_set_body'] = 'This website offers enhanced security for your account, please specify a few security questions which we\'ll use to verify your identity when you log in to the system.';
-$lang['auth_twofactor_question_set_system_body'] = 'The following questions are generated by the system, please choose your preferred question and provide an answer.';
-$lang['auth_twofactor_question_set_system_legend'] = 'System questions';
-$lang['auth_twofactor_question_set_custom_body'] = 'Specify your own security question and answer combination. Remember to make questions hard for an attacker to guess or research (avoid information which can easily be found on public mediums, such as social networks).';
-$lang['auth_twofactor_question_set_custom_legend'] = 'Custom questions';
-$lang['auth_twofactor_question_set_fail'] = 'Sorry, there was a problem saving your security questions.';
-$lang['auth_twofactor_question_unique'] = 'Sorry, questions must be unique. Please don\'t specify the same question more than once.';
-
-$lang['auth_twofactor_answer_title'] = 'Security question';
-$lang['auth_twofactor_answer_body'] = 'Please answer the following security question.';
-$lang['auth_twofactor_answer_incorrect'] = 'Sorry, your answer was incorrect.';
-
// --------------------------------------------------------------------------
// Logout lang strings
diff --git a/auth/views/mfa/device/ask.php b/auth/views/mfa/device/ask.php
deleted file mode 100644
index 65c30c2d..00000000
--- a/auth/views/mfa/device/ask.php
+++ /dev/null
@@ -1,55 +0,0 @@
- $return_to,
- 'remember' => $remember,
-]);
-
-$sQuery = !empty($aQuery) ? '?' . http_build_query($aQuery) : '';
-$sFormUrl = null;
-
-if (isset($user_id) && isset($token)) {
- $sFormUrl = 'auth/mfa/device/' . $user_id . '/' . $token['salt'] . '/' . $token['token'] . $sQuery;
- $sFormUrl = siteUrl($sFormUrl);
-}
-
-?>
-
', '
')?> -- This site requires that you use Two Factor Authentication when logging in. To set up, please scan the QR - code with your device, then enter a valid code. -
-- =img(['src' => $secret['url'], 'class' => 'img-responsive img-thumbnail'])?> -
- -', '
')?> -- =lang('auth_twofactor_answer_body')?> -
- question; - $sFieldPlaceholder = 'Type your answer here'; - $sFieldAttr = 'id="input-' . $sFieldKey . '" autocomplete="off" placeholder="' . $sFieldPlaceholder . '" class="form__control"'; - - ?> -', '
')?> -- =lang('auth_twofactor_question_set_system_body')?> -
- -', '
')?> -', '
')?> -- =lang('auth_twofactor_question_set_custom_body')?> -
- -', '
')?> -', '
')?> -- - =$mfaQuestion->question?> - -
- =form_password($sFieldKey, set_value($sFieldKey), $sFieldAttr)?> - =form_error($sFieldKey, '', '
')?> -', '
')?> -- - Use your device to generate a single use code. - -
-- =lang('auth_twofactor_answer_body')?> -
-