Symfony UserPassword validation in ajax form - ajax

I have a problem validating User Password in Symfony 2.4.
I have a form created with html code inside twig and i am not using form builder because i am submitting the form via ajax.
The form is a change password form and i have a password field which must match with the user passord.
Code:
Html.twig code of the form:
<form id="changePassword" name="changePassword">
<label id="labelPassword">Write your current password </label>
<input type="password" id="CurrentPassword" name="CurrentPassword" />
<label id="labelNewPassword">Write your new password </label>
<input type="password" id="NewPassword" name ="NewPassword" />
<label id="labelNewPassword2">Repeat your new password</label>
<input type="password" id="NewPassword2" name ="NewPassword2" />
<input type="submit" class="btn-primary btn" value="Change"/>
</form>
ajax code:
var ServerData;
$(document).ready(function() {
$("form").submit(function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr("name");
var id = $(this).attr("id");
if(validates(url)){
$.ajax({
url: url+"/" ,
method: "post",
dataType: "json",
data: data,
success: function (ServerData){
successFunction();
},
error: function (){
errorFunction();
}
});
}
else{
novalidFunction();
}
});
});
function validate(url){
//Just length and matching new password with repeat new password validations
}
// succesFunction(), errorFunction() and novalidFunction() and all this code are
//working great
php code of the controller:
public function changePasswordAction ($request Request){
$user= $this->getUser();
$password = $user->getPassword();
$currentPassword = $request->get("CurrentPassword");
$newPassword = $request->get("NewPassword");
//here is where i need the code to compare $password with $currentPassword;
//the problem is that $password is encoded
//then i got the code to insert new values in Users table and its working;
}
Thanks in advance and sorry about my english

i have resolved the problem:
Since you cant decode the user password you have to encode the new password. Here is the code to complete my last code:
public function changePasswordAction(Request $request){
$user = $this->getUser();
$upassword = $user->getPassword();
$password = $request ->get("CurrentPassword");
$newPassword = $request ->get("NewPassword");
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$salt = $user->getSalt();
$passwordSecure = $encoder->encodePassword($password, $salt);
$em = $this->getDoctrine()->getManager();
if ($passwordSecure == $upassword){
if($newPassword == $newPasswordtwo){
$newsalt = md5(time() * rand(1, 9999));//just a random number
$user->setSalt($newsalt);
$user->setPassword($encoder->encodePassword($newPassword, $newsalt));
$em->persist($user);
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse(array("estado" => "success", "msg" => "Password Changed"));
}
else{
return new \Symfony\Component\HttpFoundation\JsonResponse(array("estado" => "error", "msg" => "New password doesn't match in both fields"));
}
}
else{
return new \Symfony\Component\HttpFoundation\JsonResponse(array("estado" => "error", "msg" => "User password is not correct"));
}
}
That is working great for me. I hope that could help someone. :)

Related

Laravel Controller/Ajax not saving in my database

It seems like my save(); in my categories does not function as intended below. I will show the necessary codes first:
my table name is hms_bbr_category which is also connectec to my .env locally:
DB_CONNECTION=pgsql
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=jhs
DB_USERNAME=postgres
DB_PASSWORD=pa55wor0
my model: HmsBbrCategory
class HmsBbrCategory extends Model
{
protected $table = 'hms_bbr_category';
protected $fillable = [
"category_name", "category_description"
];
}
my controller: BBRCategoryConfigurationController
class BBRCategoryConfigurationController extends Controller
{
public function index(){
return view('frontend.bbr-settings.bbr-category-configuration');
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'category_name'=>'required|max:191',
'category_description'=>'required|max:191',
]);
if($validator->fails())
{
return response()->json([
'status'=>400,
'errors'=>$validator->messages(),
]);
}
else {
$category = new HmsBbrCategory;
$category->category_name = $request->input('category_name');
$category->category_description = $request->input('category_description');
$category->save();
return response()->json([
'status'=>200,
'message'=>'Category Added!',
]);
}
}
The ajax and modal fields
<div class="form-group">
<input type="text" class="form-control form-group w-100 category_name" placeholder="Category Name">
</div>
<div class="form-group">
<textarea class="form-control w-100 category_description" placeholder="Category Description" cols="50" rows="10"></textarea>
</div>
<script>
$(document).ready(function (){
$(document).on('click', '.add_category', function(e){
e.preventDefault();
var category_data = {
'category_name': $('.category_name').val(),
'category_description': $('.category_description').val(),
}
//token taken from laravel documentation
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
console.log(category_data);
$.ajax({
type: "POST",
url: "/clinical/bbr-category-configuration",
data: "category_data",
dataType: "json",
success: function (response){
// console.log(response);
if(response.status == 400)
{
$('#saveform_errList').html("");
$('#saveform_errList').addClass('alert alert-danger');
$.each(response.errors, function (key, err_values) {
$('#saveform_errList').append('<li>'+err_values+'</li>');
});
}
else
{
$('#saveform_errList').html("");
$('#success_message').addClass('alert alert-success');
$('#success_message').text(response.message);
$.('#createCategory').modal('hide');
$.('#createCategory').find('input').val("");
console.log(category_data);
}
}
});
});
});
</script>
my routes at web.php
Route::get('/bbr-category-configuration', [BBRCategoryConfigurationController::class,'index']);
Route::post('/bbr-category-configuration', [BBRCategoryConfigurationController::class,'store']);
Things to note:
my hunch is that my store function does not connect properly at $category = new HmsBbrCategory; However I have checked that my table name and the fields taken are the same, as seen at $category->category_name = $request->input('category_name');
I have also tested in ajax with the values by simply adding console.log(response) as seen in the screenshot, I cannot get past my validator to get to the save(). I am not sure how but There should not be an error since my text fields are filled.
I can elaborate more if needed, I am asking what can I change to fix my validation/save. thanks for any help.
As the error shows, The validation is failing (empty value i guess) and returning the code you programmed (400).
i'm guessing it is because you are using a string instead of the variable at the attribute data: "category_data",
update the code to send the variable instead
$.ajax({
type: "POST",
url: "/clinical/bbr-category-configuration",
data: category_data, //change here
dataType: "json",
success: function (response){
//...

Creating default object from empty value using laravel 6 and ajax

i have in an annonces table a multiple images, i want to update multiple images, but it gives me error:
Creating default object from empty value knowing that i tried to transform multipleimage to a given json.in the console it gives me the name of the images to select.
AnnoncesController.php
public function filesUpdate(Request $request,$id)
{
$Annonce=Annonce::find($id);
$data = array();
if($request->hasFile('images'))
{
foreach($request->file('images') as $file)
{
$path = $request->images->store('annonces');
$Annonce->images = $path;
array_push($data,$path);
}
}
$Annonce->images = json_encode($data);
$Annonce->save();
return Redirect::to("annonces")
->withSuccess('Great! file has been successfully uploaded.');
}
web.php
Route::post('annonces/filesUpdate','AnnoncesController#filesUpdate');
details.blade.php
<form method="post" action="{{url('annonces/filesUpdate')}}" enctype="multipart/form-data"
class="dropzone" id="dropzone">
<input type="hidden" name="_method" value="PUT">
{{ csrf_field() }}
</form>
<script type="text/javascript">
Dropzone.options.dropzone =
{
maxFilesize: 12,
renameFile: function(file) {
var dt = new Date();
var time = dt.getTime();
var images = time+file.name
console.log(time+file.name);
return images;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
success: function(file, response)
{
console.log(response);
},
error: function(file, response)
{
return false;
}
};
</script>
You are not passing the id as route parameter in the form action so the $id value received in filesUptate method in controller will be null. You have to pass the $Annonce->id as route parameter via form action
//When you send this view as response from edit method you need to pass
//either $Annonce object or at least the $Annonce->id as $AnnonceId to the view
//If you pass the entire $Annonce object then append $Annonce->id as below
//to the form action or replace it with $AnnonceId if you are passing only
//$AnnonceId from the edit method of the controller
<form
method="post"
action="{{url('annonces/filesUpdate/' . $Annonce->id)}}"
enctype="multipart/form-data"
class="dropzone" id="dropzone"
>
<input type="hidden" name="_method" value="PUT">
{{ csrf_field() }}
</form>
The error probably arises as you are trying to call store method on array.
Try the below
public function filesUpdate(Request $request,$id)
{
$Annonce=Annonce::findOrFail($id);
$data = array();
if($request->hasFile('images'))
{
foreach($request->file('images') as $file)
{
//Trying to call store on an array here
//$request->images is not an instance of UploadedFile
//$path = $request->images->store('annonces');
//$file is an instance of UploadedFile
//so you can call store method on it
$data[] = $file->store('annonces');
}
}
$Annonce->images = json_encode($data);
$Annonce->save();
return Redirect::to("annonces")
->withSuccess('Great! file has been successfully uploaded.');
}
You can also use $casts property to let Laravel handle the casting of images attribute automatically
class Annonce extends Model
{
protected $casts = [ 'images' => 'array'];
}

stripe payment method is returning null when I submit form

when I try to create a new subscription I get this error (This customer has no attached payment source or default payment method. ) so I checked the PaymentController with dd($paymentMethod) which returned null
so I don't know why the variable $paymentMethod in store method is returning NULL from the $request but the request, for the price is returning the price_id. Please any help is appreciated
but when console.log() setupIntent.payment_method it returned the payment_method in the console
Here is my PaymentController
public function index()
{
$availablePlans = [
'price_1HnIiLLzAo4pwMcyh2aGaznB' => 'Monthly',
'price_1HnJ2vLzAo4pwMcygQT66juk' => 'Yearly',
'price_1HnIhILzAo4pwMcy9iH3j30L' => 'Free Membership'
];
$user = auth()->user();
$data = [
'intent' => $user->createSetupIntent(),
'plans' => $availablePlans
];
return view('payments.checkout')->with($data);
}
public function store(Request $request)
{
$user = auth()->user();
$paymentMethod = $request->payment_method;
// dd($paymentMethod);
$planId = $request->plan;
$user->newSubscription('premium', $planId)->create($paymentMethod);
return response(['status' => 'success']);
}
This is the Javascript
window.addEventListener('load', function (){
// Create a Stripe client.
const stripe = Stripe('pk_test_51H2OqqLzAo4pwMcyT4h405wpFRAn3FWhvByfvmVnW6tabrIsDoU1dBXJ0UaWexUJeacCJ9uKpb5OBmmA2KaCg4sd00ZZ5tj2q8');
// Create an instance of Elements.
const elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
// const cardElement = elements.create('card', {style: style});
// Create an instance of the card Element.
const cardElement = elements.create('card');
// Add an instance of the card Element into the `card-element` <div>.
cardElement.mount('#card-element');
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
const plan = document.getElementById('subscription-plan').value;
cardButton.addEventListener('click', async (e) => {
const { setupIntent, error } = await stripe.handleCardSetup(
clientSecret, cardElement, {
payment_method_data: {
billing_details: { name: cardHolderName.value }
}
}
);
if (error) {
// Display "error.message" to the user...
} else {
// The card has been verified successfully...
// console.log('handling success', setupIntent.payment_method);
axios.post('/subscribe', {
payment_method: setupIntent.payment_method,
plan: plan
})
}
});
});
Here is the form
<form action="{{ route('subscribe')}}" method="POST" id="">
#csrf
<div class="form-content">
<div class="field">
<select class="form-control" name="plan" id="subscription-plan">
#foreach ($plans as $key=>$plan )
<option value="{{$key}}">{{$plan}}</option>
#endforeach
</select>
</div>
<div class="field">
<input type="text" autocorrect="off" spellcheck="false" id="card-holder-name" maxlength="25" />
<span class="focus-bar"></span>
<label for="cardholder">Card holder (Name on card)</label>
</div>
<div class="field mb-5" id="card-element">
<!-- Stripe Elements Placeholder -->
</div>
<button id="card-button" data-secret="{{ $intent->client_secret }}"><span>Pay</span></button>
</div>
</form>
The Route
Route::resource('payments', 'PaymentsController', [
'names'=> [
'index' => 'checkout',
'store' => 'subscribe',
]
]);
Looks like there is something wrong with how you're using axios. Have you tried taking a look at laravel simple axios with argument
Adding a hidden input field in the form and setting the value to setupIntent.payment_method passed the payment_method id to the controller which is used to create the subscription so the problem is solved.
A few modifications and adding a hidden input field to the JS
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
//cardButton.addEventListener('click', async (e) => {
//e.preventDefault()
const { setupIntent, error } = await stripe.handleCardSetup(
clientSecret, cardElement, {
payment_method_data: {
billing_details: { name: cardHolderName.value }
}
}
);
if (error) {
// Display "error.message" to the user...
} else {
// The card has been verified successfully...
//console.log('handling success', setupIntent.payment_method);
axios.post('/subscribe',{
plan : plan
})
var paymentMethod = setupIntent.payment_method;
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'payment_method');
hiddenInput.setAttribute('value', paymentMethod);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}

codeigniter session with ajax input is not working

view
<input type="text" class="form-control" placeholder="Username" name="username" id="username">
<input type="password" class="form-control" placeholder="Password" name="password" id="password">
<button type="button" class="btn btn-primary btn-block btn-flat" id="login">Sign In</button>
here i pass the values to the controller using ajax
<script>
$(function()
{
$('#login').click(function()
{
var username=$("#username").val();
var password=$("#password").val();
$.ajax({
url:"<?php echo base_url();?>home/check_login",
type:"POST",
async:false,
data:{username:username,password:password},
success:function(data)
{
var obj = JSON.parse(data);
var count = Object.keys(obj).length;
console.log(obj);
console.log(count);
if(obj.length==1)
{
window.location.href = "<?php echo base_url();?>home/show_dashboard";
}
else if(obj.length==0)
{
$('#modal_warning').modal('show');
}
}
});
});
});
</script>
and my controller is
public function check_login()
{
$username= $this->input->post('username');
$password= $this->input->post('password');
$newdata = array(
'username' => $username,
);
$this->session->set_userdata('ci_session',$newdata);
$details=$this->user_model->check_username($username,$password);
echo json_encode($details);
}
when click log out button
public function log_out()
{
if($this->session->unset_userdata('ci_session'))
{
$this->load->view('login');
}
else
{
echo "nooo";
exit;
}
}
when i click the logout button it gives me "noo" which i placed in else part.
When i try to print the session data, it prints nothing. How can I set session which data is passing by ajax.
I also loaded session library
You are doing $this->set_userdata('ci_session',$newdata); without the session. Do it like so to set session variables. $this->session->set_userdata('ci_session',$newdata);
Also make sure the session driver is loaded. To access the session variable you can do print_r($this->session->ci_session)
Further:
Unset userdata doesn't actually return anything:
/**
* Unset userdata
*
* Legacy CI_Session compatibility method
*
* #param mixed $key Session data key(s)
* #return void
*/
public function unset_userdata($key)
{
if (is_array($key))
{
foreach ($key as $k)
{
unset($_SESSION[$k]);
}
return;
}
unset($_SESSION[$key]);
}
hence its always evaluating to false. The function itself is just an alias for unset($_SESSION[$key]) you can view the function in the session core file. There is no need for the conditional statement; just $this->session->unset_userdata('ci_session'); redirect(...); is sufficient.

Is updating codeigniter db-session data clientside via ajax possible?

I'm using codeigniter with encrypted sessions in the database and I'm using a twitter bootstrap modal to update some user details in a form.
I use jquery validation on the form and in the submitHandler I post the data via ajax and close the modal.
submitHandler: function (form) {
document.getElementById("edit-profile-submit-button").disabled = true;
$('.modal-ajax-loader').show();
$.ajax({
type: $(form).attr('method'), // 'Post'
url: $(form).attr('action'), // 'profile/edit_basic_details'
data: $(form).serialize(),
success: function(data, status){
$(form).html(data);
$('.modal-ajax-loader').hide();
setTimeout(function() { $('#edit-profile-details').modal('hide'); }, 2000);
},
error: function(data, status) {
$(form).html(data);
}
});
return false;
}
and here is the model function called from the controller with the same name,
function edit_basic_profile() {
$screenname = $this->security->xss_clean($this->input->post('screenname'));
$firstname = $this->security->xss_clean($this->input->post('firstname'));
$lastname = $this->security->xss_clean($this->input->post('lastname'));
$email = $this->security->xss_clean($this->input->post('email'));
$bio = $this->security->xss_clean($this->input->post('bio'));
$data = array(
'screen_name' => $screenname,
'first_name' => $firstname,
'last_name' => $lastname,
'email' => $email,
'bio' => $bio,
);
try{
// Run the update query
$this->db->where('profile_id', $this->session->userdata('profile_id'));
$this->db->update('profiles', $data);
// Let's check if there are any results
if($this->db->affected_rows() == 1)
{
// Setup the session information for the user
$this->session->set_userdata($data);
return true;
}
// If the previous process did not update rows then return false.
error_log("profile_model, edit_basic_profile(): There were no affected rows");
return false;
} catch(PDOExceprion $e) {
error_log("profile_model, edit_basic_profile(): ".$e);
return false;
}
}
I can update the values that changed on the page in the submitHandler also and of course the session on the server is updated in the model.
$("#profile-screenname").html($(screenname).val());
$("#profile-bio").html($(bio).val());
The problem is when I open the modal again it grabs the user details from the session data in the browser cookie and grabs the original data unless the page has been refreshed after the first update.
(form data is loaded like this);
<input type="text" class="input-large" id="firstname" name="firstname" placeholder="First Name" value="<?php echo $this->session->userdata('first_name'); ?>">
"<?php echo $this->session->userdata('first_name'); ?>" on the second time i open the modal before any page refresh loads the old data.
Sure, you just need to call an ajax url which updates/sets new session data:
HTML+JS
---> Ajax call
----> $this->session->set_userdata('key','new-value');
----> session and db updated.
Done.
Also notice and change all these:
$screenname = $this->security->xss_clean($this->input->post('screenname'));
to this:
$screenname = $this->input->post('screenname',true);
which is exactly the same result

Resources