I deployed a Laravel-Livewire on Digital Ocean and now I'm having a Mixed content problem when I try to upload a file.
Here is the error:
UploadManager.js:131 Mixed Content: The page at 'https://intake.freejiji.ca/clients/3/extensions' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://intake.freejiji.ca/livewire/upload-file?expires=1625251608&signature=9d98c598db4f6fccc01c009bcfc3051c6a97b56f4058f4d9489a8d30d6d497c2'. This request has been blocked; the content must be served over HTTPS.
The error happens when after I click "Select File" and chose the .csv file I want. Since I'mdoing this on a livewire component I'm not sure how to fix this so that the request goes over HTTPS instead of HTTP.
I was able to fix similar problems on the app by changing "asset()" with "secure_asset()"
and "route()" with "secure_url()" but in this case I'm not sure what to do.
Here is the whole "Import" component:
<?php
namespace App\Http\Livewire\Modals;
use Validator;
use Livewire\Component;
use App\Http\Traits\Csv;
use App\Models\AccountUser;
use Livewire\WithFileUploads;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
class ImportExtensions extends Component
{
use WithFileUploads;
public $clientID;
public $showModal = false;
public $upload;
public $columns;
public $fieldColumnMap = [
'first_name' => '',
'last_name' => '',
'email' => '',
'password' => '',
'extension' => '',
'user_type' => '',
];
protected $rules = [
'fieldColumnMap.first_name' => 'required|max:255',
'fieldColumnMap.last_name' => 'required|max:255',
'fieldColumnMap.email' => 'required|max:255',
'fieldColumnMap.password' => 'required|max:255',
'fieldColumnMap.extension' => 'required|max:255',
'fieldColumnMap.user_type' => 'required|max:255',
];
protected $validationAttributes = [
'fieldColumnMap.first_name' => 'First Name',
'fieldColumnMap.last_name' => 'Last Name',
'fieldColumnMap.email' => 'Email',
'fieldColumnMap.password' => 'Password',
'fieldColumnMap.extension' => 'Extension',
'fieldColumnMap.user_type' => 'User Type',
];
public function updatingUpload($value)
{
Validator::make(
['upload' => $value],
['upload' => 'required|mimes:csv'],
)->validate();
}
public function updatedUpload()
{
$this->columns = Csv::from($this->upload)->columns();
$this->guessWhichColumnsMapToWhichFields();
}
public function import()
{
// Validate that you are importing any data
$this->validate();
$importCount = 0;
Csv::from($this->upload)
->eachRow( function ($row) use (&$importCount){
$eachRow = $this->extractFieldsFromRow($row);
// Validate each Row of the csv file
$validatedData = Validator::make([
'first_name' => $eachRow['first_name'],
'last_name' => $eachRow['last_name'],
'email' => $eachRow['email'],
'password' => $eachRow['password'],
'extension' => $eachRow['extension'],
'user_type' => $eachRow['user_type'],
],[
'first_name' => 'required',
'last_name' => 'required',
'password' => 'required|max:255',
'user_type' => 'required|in:user,admin',
'email' => 'required|email|unique:account_users',
'extension' => ['required', 'numeric', Rule::unique('account_users', 'extension')
->where(function($query)
{return $query->where("account_id", $this->clientID);
})],
],);
if($validatedData->fails()){
$this->notify(['error','Oops something went wrong!']);
}else{
AccountUser::create([
'user_id' => Auth::user()->id,
'account_id' => $this->clientID,
'first_name' => $eachRow['first_name'],
'last_name' => $eachRow['last_name'],
'email' => $eachRow['email'],
'password' => $eachRow['password'],
'extension' => $eachRow['extension'],
'user_type' => $eachRow['user_type'],
]);
$importCount++;
}
});
$this->reset();
$this->emit('refreshExtensions');
if($importCount!=0) $this->notify(['success','Successfully Imported '.$importCount.' Extensions']);
}
public function guessWhichColumnsMapToWhichFields()
{
$guesses = [
'first_name' => ['first_name', 'name'],
'last_name' => ['last_name'],
'email' => ['email'],
'password' => ['password', 'pass'],
'extension' => ['extension', 'ext'],
'user_type' => ['user_type', 'user', 'type'],
];
foreach ($this->columns as $column) {
$match = collect($guesses)->search(fn($options) => in_array(strtolower($column), $options));
if ($match) $this->fieldColumnMap[$match] = $column;
}
}
public function extractFieldsFromRow($row)
{
$attributes = collect($this->fieldColumnMap)
->filter()
->mapWithKeys(function($heading, $field) use ($row) {
return [$field => $row[$heading]];
})
->toArray();
return $attributes;
}
public function downloadTemplate()
{
$filename = 'extensions_template.xls';
$path = public_path('files/' . $filename);
return response()->download($path, $filename, [
'Content-Type' => 'application/vnd.ms-excel',
'Content-Disposition' => 'inline; filename="' . $filename . '"'
]);
}
}
If you get mixed content problem it is mostly about you fetching the assets or resources from different http scheme. Here you are using HTTP to fetch data in HTTPS site. Change all the links to have HTTPS link.
If you want to force all the routes to use https you can achieve this by using following code.
if(env('APP_ENV', 'production') == 'production') { // use https only if env is production
\URL::forceScheme('https')
}
The above should solve your problem as all contents now will load from https.
Related
In a Laravel/Inertia application, I try to store vinylRecords.
Therefore I created a vinylRecords resource.
Route::resource('vinylRecords', VinylRecordController::class)->only(['index', 'create','store', 'edit', 'update']);
In the frontend, the store function looks like:
methods: {
submitForm() {
this.$inertia.post(route("vinylRecords.store"), this.form, {
onSuccess: (response) => {
alert(Object.keys(response.props))
this.form.reset();
},
});
}
},
Sometimes, the routing is right and the Laravel stores the new record. But most of time, Laravel redirects to the index method without storing the data.
The store method:
public function store(StoreVinylRecordRequest $request)
{
$data = $request->validated();
$record = VinylRecord::create($data);
$record->labels()->sync($data['label_ids']);
$record->styles()->sync($data['style_ids']);
$record->specials()->sync($data['special_ids']);
return Inertia::render('vinylRecord/index', [
'records' => VinylRecordResource::collection(VinylRecord::all()),
'vinylRecordId' => $record->id
]);
}
To solve the problem, I created a new controller with a new route to store the data:
Route::post('storeVinylRecord', [StoreVinylRecordController::class, 'store'])->name('storeVinylRecord');
But the problem was the same.
How is it possible, that the routing changes from one request to the other? Is there an big error in the code from my side?
Edited: Add the StoreVinylRecordRequest
public function rules()
{
return [
'artist' => 'required|string',
'title' => 'required|string',
'barcode' => 'nullable|integer',
'genre_id' => 'nullable|integer',
'country' => 'nullable',
'year' => 'nullable|integer',
'label_ids' => 'nullable',
'style_ids' => 'nullable',
'special_ids' => 'nullable',
'thumb' => 'nullable|string',
'cover_image' => 'nullable|string',
'quantity' => 'nullable|integer',
'speed' => 'nullable|integer',
'part_type' => 'nullable|string',
'storage_location' => 'nullable|string',
'supplier_id' => 'nullable|in:suppliers,id',
'purchasing_price' => 'nullable|numeric',
'selling_price' => 'nullable|numeric',
];
}
User password changes in Laravel 8 after a period of time post logout, maybe a day or more. When I look into the database, the password hash has changed. I used the default Laravel authentication and had this issue, so I wrote the login code below, but still, I have the issue.
LoginController
public function login(Request $request)
{
$email_username = filter_var($request->username, FILTER_VALIDATE_EMAIL) ?
'email' : 'username';
$request->merge([$email_username => $request->username]);
if (Auth::attempt($request->only($email_username, 'password'))) {
return redirect()->intended($this->redirectTo);
} else {
return view('auth.login')
->with('these credetials do not match our records.');
}
$user = User::where($email_username, $request->username)->get();
if ($user && Hash::check($request->password, $user->password)) {
$request->session()->regenerate();
auth()->login($user);
return redirect()->intended($this->redirectTo);
}
return redirect()->back();
}
User Model
class User extends Authenticatable
{
use HasFactory, Notifiable;
public function partners()
{
return $this->hasMany('App\Models\partner');
}
protected $fillable = [
'username',
'profilepic',
'firstname',
'lastname',
'password',
'email',
'title',
'phone',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
and this is the method that registers user.
public function store(Request $request)
{
$request->validate([
'username' => ['required', 'string', 'max:255', 'unique:users'],
'profilepic' => ['required', 'image', 'mimes:jpeg,png,jpg,gif,svg,ico', 'max:2048'],
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'password' => ['required', 'string', 'min:8'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'title' => ['required', 'string', 'max:255'],
'phone' => ['required', 'min:10'],
]);
if ($request->profilepic != null) {
$profilepic = $request->firstname . ' ' . $request->lastname . '.' . $request->profilepic->extension();
$request->profilepic->move(public_path('/global_assets/images/users/'), $profilepic);
}
$user = new User([
'username' => $request->get('username'),
'profilepic' => $profilepic,
'firstname' => $request->get('firstname'),
'lastname' => $request->get('lastname'),
'password' => Hash::make($request->get('password')),
'email' => $request->get('email'),
'title' => $request->get('title'),
'phone' => $request->get('phone'),
'isAdmin' => $request->get('isAdmin'),
'isActive' => $request->get('isActive'),
]);
$user->save();
return redirect()->back()->with('success', 'New user has been created.');
}
I'm trying to create an register form that includes an image upload. When I submit the form, it stores an "/private/var/tmp/" path for the image on database and the image is not stored anywhere in the public folder. I don't know what I might be doing wrong. Please help.
My config/filesystems:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
My controller CreateNewUser:
class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
protected function validator(array $input)
{
return Validator::make( $input, [
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique(User::class),
],
'mobile' => ['required', 'int'],
'country' => ['required', 'string', 'max:255'],
'password' => $this->passwordRules(),
'db_upload' => ['required', 'image'] //This the image I want to upload
]);
}
public function register(Request $request)
{
$this->validator($request->all())->validate();
$imageUrl = $this->storeImage($request);
$input = $request->all();
$input['db_upload'] = $imageUrl;
$user = $this->create($input);
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
protected function storeImage(Request $request) {
$path = $request->file('db_upload')->store('public/uploads');
return substr($path, strlen('public/'));
}
public function create(array $input)
{
$user = User::create([
'firstname' => $input['firstname'],
'lastname' => $input['lastname'],
'email' => $input['email'],
'mobile' => $input['mobile'],
'country' => $input['email'],
'password' => Hash::make($input['password']),
'db_upload' => $input['db_upload'],
]);
$user->notify(new WelcomeEmailNotification());
return $user;
}
}
Try changing your storeImage function as below
protected function storeImage(Request $request) {
return $request->file('db_upload')->store('uploads', 'public');
}
Also ensure that you have created the symlink to the public disk by running php artisan storage:link and that after running the command there is a symlink visible in the <app-root>/public folder
Change the line of code that saves the file from:
$path = $request->file('db_upload')->store('public/uploads');
to
$path = $request->file('db_upload')->store('uploads', 'public');
The first argument is the path and the second argument is the disk you want to save to.
You can use the storePublicly() function to store the file in the public folder:
$file = $request->file('db_upload');
$path = $file
->storePublicly('files', ['disk' => 'public']);
I hope you can help me, I wanna customize the registercontroller from Laravel, I have this, but after the user is registered send me a JSON of data, how can I do for don't send me the JSON and redirect to the HomeController.
Thanks.
PD. Sorry for my English.
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'nombre' => ['required', 'string', 'max:255','unique:users'],
'telefono' => ['required', 'numeric', 'max:99999999', 'min:00000000'],
'direccion' => ['required', 'string', 'max:255'],
'sueldo' => ['numeric','min:0.01','max:0.99'],
//'foto' => ['string', 'max:255'],
'email' => ['string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4', 'confirmed'],
]);
if ($request->hasFile('foto')) {
$request = request();
$file = $request->file('foto');
$nom_imagen = time().".".$file->getClientOriginalExtension();
$upload_path = 'imagenes/';
$profile_image_url = $upload_path . $nom_imagen;
$success = $file->move($upload_path, $nom_imagen);
} else {
$nom_imagen = '';
}
return User::create([
'name' => $request->input('name'),
'nombre' => $request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password']),
return redirect()->action('HomeController#index'),
]);
}
Laravel 5.5: Execute a method before registration
HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('index');
}
}
You are returning the return value of User::create() which will be a User object which gets converted to json when returned as a response.
Also since your HomeController is protected by 'auth' middleware you need to login the user before redirecting to '/home'
use Illuminate\Support\Facades\Auth;
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'nombre' => ['required', 'string', 'max:255','unique:users'],
'telefono' => ['required', 'numeric', 'max:99999999', 'min:00000000'],
'direccion' => ['required', 'string', 'max:255'],
'sueldo' => ['numeric','min:0.01','max:0.99'],
//'foto' => ['string', 'max:255'],
'email' => ['string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4', 'confirmed'],
]);
if ($request->hasFile('foto')) {
$request = request();
$file = $request->file('foto');
$nom_imagen = time().".".$file->getClientOriginalExtension();
$upload_path = 'imagenes/';
$profile_image_url = $upload_path . $nom_imagen;
$success = $file->move($upload_path, $nom_imagen);
} else {
$nom_imagen = '';
}
$user = User::create([
'name' => $request->input('name'),
'nombre' => $request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password']),
]);
Auth::guard()->login($user);
return redirect('/home');
}
Move the redirect after create user , try like this
User::create([
'name' => $request->input('name'),
'nombre' =>$request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password'])
]);
return redirect()->action('HomeController#index'),
The validate() function from my sales controller seems not working, I am comparing it to my other controller, it looks like it should work but it is not. it looks like the validate() is being bypassed. here's my controller
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class SalesController extends Controller
{
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required',
'status_id' => 'required',
'currency_id' => 'required',
'company_id' => 'required',
'invoice_no' => 'nullable',
'notes' => 'nullable',
'admin_notes' => 'nullable',
'due_date' => 'nullable',
'publish' => 'nullable',
'product_id' => 'required|min:1',
'product_code' => 'required|min:1',
'product_name' => 'required|min:1',
'quantity' => 'required'
]);
$sales = $request->only(
'user_id',
'status_id',
'currency_id',
'currency_rate',
'due_date',
'company_id',
'invoice_no',
'notes',
'admin_notes',
'delivery_date',
'publish'
);
$sales['grandtotal'] = (float) str_replace(',', '', $request->grandtotal);
$sales['grandtotalcost'] = (float) str_replace(',', '', $request->grandtotalcost);
$sales = Sales::create($sales);
$input = $request->all();
for($i=0; $i<= count($input['quantity']); $i++) {
if(empty($input['quantity'][$i]) || !is_numeric($input['quantity'][$i])) continue;
$items = [
'sales_id' => $sales->id,
'product_id' => $input['product_id'][$i],
'product_code' => $input['product_code'][$i],
'product_name' => $input['product_name'][$i],
'price' => $input['price'][$i],
'cost' => $input['cost'][$i],
'quantity' => intval($input['quantity'][$i]),
'total_price' => (float) str_replace(',', '', $input['total_price'][$i]),
'total_cost' => (float) str_replace(',', '', $input['total_cost'][$i]),
];
Salesitems::create($items);
}
// $ponumbers = Ponumbers::create($request->only('purchase_no'));
$invnum = $request->all();
$invnumbers = new Invnumbers;
$invnumbers->sales_num = $invnum['invoice_no'];
$invnumbers->save();
if ($request){
Session::flash('message','Invoice was successfully added');
Session::flash('m-class','alert-success');
} else {
Session::flash('message','Data is not saved');
Session::flash('m-class','alert-danger');
return redirect()->route('sales.index');
}
return redirect()->route('sales.index');
}
}
My Blade
<input class="form-control autocomplete_txt product_name" type='text' data-type="product_name" id='product_name_1' name='product_name[]' for="1" readonly/>
#if ($errors->has('product_name')) <p class="help-block">{{ $errors->first('product_name') }}</p> #endif
if I submit my form with product name, instead of throwing error from validate,
By seeing your code, to me it seems your product_id should be an array. So the validation should be:
'product_id' => 'array|required|min:1',
'product_id.*' => 'required',
instead of
'product_id' => 'required|min:1',
Try to use $request->validate([... instead of $this->validate($request, [.... I'm not sure is there validate in your controller...