Yii2 - validate password (Hash is invalid error) - yii

I am trying to validate old user password, in order for him to able to change password, but at the moment I am getting Hash is invalid error.
This is validation rule:
['password_old', function($attribute){
if(!$this->validatePassword($this->{$attribute}))
$this->addError($attribute, 'Please Enter Your Old Password');
}],
validatePassword method:
public function validatePassword($password){
return Yii::$app->getSecurity()->validatePassword($this->salt . $password, $this->password);
}
Form used for changing the password:
$form = ActiveForm::begin(
[
'enableAjaxValidation' => true,
'action' => 'user/changepassword',
'id' => 'changePassword'
]
);
echo $form->field($model, 'password_old')->passwordInput( ['autocomplete' => 'off'] );
echo $form->field($model, 'password')->passwordInput(['autocomplete' => 'off'])->label('New Password');
echo $form->field($model, 'password_confirm')->passwordInput(['autocomplete' => 'off']);

Another reason the Hash is invalid error occurs if when you pass a null as the $hash to the Yii::$app->getSecurity()->validatePassword method.
I suggest you do a check like this in your code
public function validatePassword($password){
if(is_null($this->password))
return false;
return Yii::$app->getSecurity()->validatePassword($this->salt . $password, $this->password);
}

I'm solved the problem, when change value of password column in DB from varchar(128) to varchar(255) and registerd again.

"Hash is invalid error" because your password is not correct format.
Why?
When you call validatePassword in a validate rule, $this->password is not password stored in database, It is new password - recently submit from your form. To solve problems, you can refer LoginForm class in yii2-basic-app or yii-advanced-app.
Suggestions:
"Salt" is not necessary because it was included automatically in function \Yii::$app->security->generatePasswordHash (PHP 5>= 5.5.0 password_hash)

I also had this problem and resolved.
The reason is that I used to use the sha1 algorithm before, and after converting it to bcrypt (Yii::$app->security->generatePasswordHash), I encountered this problem.
My previous password was created with the sha1 algorithm and was in the database.
When I changed the code to the new algorithm and wanted to login, I was wrong.
If you reset the previous password with the new algorithm, the problem is resolved.

You will get this error when the compared password in the database cannot be a hash value!
I get this error when the field value
" $2y$13$TvlDZ5RgBL7Cr1LR9JovfOVEyMwpD6x1dy9sYlngzUIKeuEaqqiry"(first character is a space).
I delete the space character, then it worked.

Related

vee-validate Custom validation rules not working

Versions:
VueJs: 2.2.6
Vee-Validate: ^2.0.0-beta.25
Description:
I am working on a project, where I use laravel-vue-starter
as a base template.
I wants to use a custom validation for password. So I created a resources\assets\js\validators\passwordValidators.js file with code:
import { Validator } from 'vee-validate';
Validator.extend('password', {
getMessage: field => 'Insert a strong password, it should contain Uppercase letter, lowercase letter, number and special character',
validate: value => /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.[\W]).{8,}$/.test(value)
});
But when I am addingv-validate="'password'"
It produce an error[vee-validate] No such validator 'password' exists
Any help will be appreciated.
I think the answer is simple, you are now using a rule name 'password' , but your rule is password.
So try this in your markup (string notation), remove the single quotes.
v-validate = "password"
Or you can also use the object notation when you have more then 1 and complex rules.
v-validate = "{password: true}"
Regards Ben

Laravel route with variable in the url

I am trying to implement the password reset logic. The user gets the link to reset the password in the email. The url looks like
http://example.com/reset/resetcode
I have the route defined for it:
Route::get('reset/{resetcode}', function(){
return View::make('users.reset_password');
});
The form is rendered in the view to submit the email, new password etc. For the post of the form I have route defined as:
Route::post('reset/{resetcode}', array( 'as' => 'reset', 'uses' => 'UserController#passwordReset'));
I grab the resetcode from post route inside the passwordReset controller below
public function passwordReset($resetcode)
{
$validation = Validator::make(Input::all(), UserModel::$rulesPasswordReset);
if ($validation->passes())
{
try
{
// Find the user using the user email address
$user = Sentry::findUserByLogin(Input::get('email'));
// Check if the reset password code is valid
if ($user->checkResetPasswordCode($resetcode))
{
// Attempt to reset the user password
if ($user->attemptResetPassword($resetcode, 'new_password'))
{
// Password reset passed
}
else
{
// Password reset failed
}
}
else
{
// The provided password reset code is Invalid
}
}
catch (Cartalyst\Sentry\Users\UserNotFoundException $e)
{
echo 'User was not found.';
}
}
else return Redirect::route('reset')->withInput()
->withErrors($validation)
->with('title', 'resetrequestfailure')
->with('message', 'Seems like you made some errors.');
}
The problem I am having is when I do Redirect::route after the validation fails. I am getting the resetcode from the route defined for post. When validation fails, the redirect route messes up and I cannot get the resetcode the second time. The supposed url of format
http://example.com/reset/8f1Z7wA4uVt7VemBpGSfaoI9mcjdEwtK8elCnQOb
becomes
http://bcnet.org/reset/%7Bcode%7D
It has to do with /{resetcode} part of the route and this is variable, so how can I get the correct resetcode even after the validation fails meaning that the url remains intact. Or how can I fix it to the appropriate Redirect::route after the validation failure.
You need to include the $resetcode on your return
else return Redirect::route('reset', $resetcode)->withInput()
->withErrors($validation)

Inserting new password by overriding old password

In yii i am creating project. After validation of user's entered email, i am displaying password.php file which is having textfield for entering new password.
Password.php=
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'email-form',
'enableClientValidation'=>true,
));
echo CHtml::textField('Enter new password');
echo CHtml::textField('Repeat password');
echo CHtml::submitButton('Submit');
$this->endWidget();
When user will enter new password and click on submit button i want to insert this new password into User table's password field, in such a way that it overright old password.
In controller i had created method as-
public function actionCreate(){
if(isset($_POST['email']))
{
$record=User2::model()->find(array(
'select'=>'userId, securityQuestionId, primaryEmail',
'condition'=>'primaryEmail=:email',
'params'=>array(':email'=>$_POST['email']))
);
if($record===null) {
echo "Email invalid";
}
else {
echo "email exists";
$this->render('Password');
if(isset($_POST['Password']))
{
$command = Yii::app()->db->createCommand();
$command->insert('User', array(
'password'=>$_POST['password'] ,
//'params'=>array(':password'=>$_POST['password'])
}
}
}
else{
$this->render('emailForm'); //show the view with the password field
}
But its not inserting new password. So How can i implement this...Please help me
First of all the way you are handling the form is certainly not Yii-ish which means it's not really the way to go.
The way you should handle this is by creating an object which extends from the CFormModel and put all your logic code in there instead of in the controller.
Now, if you want to continue working with your piece of code, then it would be best to place the following piece of code
$this->render('Password');
BELOW the if isset password stuff.
For your problem, the reason why your password isn't being updated is because the query you created is not being executed. If we take a look here then we can see that the following piece of code should be added:
$command->execute();
Which will execute your piece of sql.
Something like this...
$user = User::find('email = :email', ':email' => $_POST['email']);
if( empty($user) )
return;
$user->password = $_POST['password'];
$user->save();
You can't get password like this $_POST['Password'], because you haven't set this post variable.
You had to use:
echo CHtml::textField('password');
echo CHtml::textField('repeatPassword');
echo CHtml::hiddenField('email', $email);
'password' and 'repeatPassword' are names of POST vars
And in your controller you have too many mistakes, try this (check for typos):
if(isset($_POST['email']))
{
$record=User2::model()->find(array(
'select'=>'userId, securityQuestionId, primaryEmail',
'condition'=>'primaryEmail=:email',
'params'=>array(':email'=>$_POST['email']))
);
if($record===null) {
echo "Email invalid";
}
else {
if(isset($_POST['password']) && isset($_POST['repeatPassword']) && ($_POST['password'] === $_POST['repeatPassword']))
{
$record->password = $_POST['password'];
if ($record->save()) {
$this->render('saved');
}
}
$this->render('Password' array('email'=>$_POST['email']));
}
}
}
else{
$this->render('emailForm'); //show the view with the password field
}
In your code if(isset($_POST['Password'])) won't ever execute, because after sending password you haven't set email variable. So you just $this->render('emailForm');. Thus we set it by CHtml::hiddenField('email', $email);
Upd. I strongly recommend you to read this guide. It will save a lot of time for you.

Accessing content of textarea in Drupal-7-Theme-Form

in my custom theme-settings.php (zen-subtheme) i put following code to get a new textarea with textformat in my theme-settings:
<?php
function paper_form_system_theme_settings_alter(&$form, &$form_state) {
$form['paper_data'] = array(
'#type' => 'text_format',
'#title' => 'Put Text in here:',
'#rows' => 5,
'#resizable' => FALSE,
'#default_value' => 'xyz..',
'#format' => 'full_html'
);
}
the form is working perfektly, but when i want to access the variable by writing
<?php
$pdata = theme_get_setting('paper_data');
echo $pdata;
?>
in my page.tpl.php, the content of the variable is not rendered - instead the word "Array" is printed ...
What's wrong and why? (If i use 'textarea' as type instead of 'text_format', all is rendered well.)
You will understand when you use something like the Devel module's dpm() function to check the variable rather than echo(). Coding Drupal without the Devel module is, IMHO, folly.
The issue very likely stems from your use of the text_format type. As you can see, it saves both the textarea value as well as an associated text format. When this is used Drupal returns the data in structured form which varies depending on the type of format.
dpm() is your friend :)

Zend Form getValue. Need someone to explain?

I'm just working with the Zend_Form in Zend Framework and came across something pretty weird.
I have the following inside my loginAction
$form = new Application_Model_FormLogin();
if ($this->getRequest()->isPost()) {
$email = $form->getValue('email');
$pswd = $form->getValue('pswd');
echo "<p>Your e-mail is {$email}, and password is {$pswd}</p>";
}
Which when submitted only outputs
Your e-mail is, and password is
So I checked to see what's going on with print_r ,
print_r($form->getValues());
print_r($_POST);
Which displayed the following,
Array ( [email] => [pswd] => ) Array ( [email] => asd [pswd] => asd [submit] => Login )
So the forms values array has both values as null and the global post array had the correct values. Now I can't work out the problem?
Now I did manage to fix the problem, but I need help understanding why this works? All I did was change the loginAction to this.
$form = new Application_Model_FormLogin();
if ($this->getRequest()->isPost()) {
//Added this in
if ($form->isValid($this->_request->getPost())) {
$email = $form->getValue('email');
$pswd = $form->getValue('pswd');
echo "<p>Your e-mail is {$email}, and password is {$pswd}</p>";
}
}
I don't get how this made it work? Considering there is no validation on the fields?
Any thoughts? All I can think is maybe I have something setup weird in my server configuration?
Thanks
You didnt load the Values in your form object.
Normaly you check if the form is valid and for this load it with the post data, in the next step you can use getValue() to get the (filtered) value from the form.
if($this->getRequest()->isPost()) {
$form = new My_Form();
if($form->isValid($this->getRequest()->getPost())){
echo $form->getValue('fieldname');
}
}
isValid() is what actually populates the fields in your form object, until you do that the values do not exist in your form object yet.
modifying your original code would be as simple as this
if ($this->getRequest()->isPost()) {
//your $form object has none of your POSTed values
$form->isValid($this->getRequest()->getPost())
//now your form object has the POSTed values and you can access them
$email = $form->getValue('email');
$pswd = $form->getValue('pswd');
echo "<p>Your e-mail is {$email}, and password is {$pswd}</p>";
}
This skims over it extremely lightly http://framework.zend.com/manual/1.11/en/zend.form.quickstart.html#zend.form.quickstart.validate
Consider this example also and it might make more sense. Here you just grab the values from the POST.
if ($this->getRequest()->isPost()) {
$email = $this->getRequest()->getPost('email');
$password = $this->getRequest()->getPost('password');
echo "<p> Your email is $email and your password is $password </p>";
}