elo

elo

Member Since 2 Years Ago

Experience Points
4,430
Total
Experience

570 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
7
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 1
4,430 XP
Oct
16
4 weeks ago
Activity icon

Started a new Conversation Uploading And Displaying Images Stored In Storage

Hello awesome devs. I am struggling trying to upload image files to local storage and display the same images on Nova. I have integrated Nova into a laravel API project to allow admin perform certain task like uploading a product which includes uploading product images. Currently this is a result of creating a product using postman

{
    "responseMessage": "Successful operation",
    "responseStatus": 200,
    "product": {
        "id": 17,
        "name": "AGO-0003",
        "category": "AGO",
        "description": "AGO is purpolarly called Diesel.\n\nDiesel fuel, also called diesel oil, combustible liquid used as fuel for diesel engines, ordinarily obtained from fractions of crude oil that are less volatile than the fractions used in gasoline.",
        "status": "Loading",
        "price": 100000,
        "units": "528",
        "measurement": "Units",
        "return": "46",
        "cycle": "10",
        "returnRangefrom": "30",
        "returnRangeto": "50",
        "start": "2019-10-18T23:00:00.000000Z",
        "hidden": null,
        "hoursTillStart": 72,
        "imageUrl": "http://localhost:8000/storage/images/products/pramopro_AGO-0003_17.jpeg"
    }
}

This is the store method from the controller responsible for storing new product resources

// create & store the product
if ($product = Product::create([
    'name'              => $request->name,
    'category'          => $request->category,
    'status'            => $request->status,
    // more fields here
])) {
    // store the product image
    $file               = $request->file('image');
    $destinationPath    = "public/images/products";
    $filename           = 'pramopro_' . str_replace(' ', '', $product->name) . '_' . $product->id . '.' . $file->extension();

    Storage::putFileAs($destinationPath, $file, $filename);

    ProductImage::create([
        'product_id'    => $product->id,
        'name'          => $filename
    ]);
}

The Product model has one ProductImage model, that is HasOne relationship. In my Product nova resource, I am trying to display the images for each product like this

public function fields(Request $request)
{
    return [
        Image::make('Image', function () {
            return 'images/products/' . $this->image->name;
        }),

        Text::make('Name')
            ->sortable()->rules('required'),

        // more fields here but trimmed 

        File::make('Product Image')
            ->disk('public')
            ->path('images\products')
            ->storeAs(function (Request $request) {
                'pramopro_' . str_replace(' ', '', $this->name) . '_' . $this->id . '.' . 'jpg';
            }),
    ];
}

In nova, the image is not displayed and I noticed that the url is localhost/storage/images/products/pramopro_AGO-0003_17.jpeg. This is the case on my development and staging environments.

When I try to upload an image when creating a new product, I get the error fopen(C:\home directory path\AppName\storage\app/public\images/products): failed to open stream: Permission denied

I am lost at the moment. Help

Sep
30
1 month ago
Activity icon

Started a new Conversation Assigning Roles On Nova Dashboard Using Spatie Laravel-Permissions Package

I am currently using spatie laravel permissions package in a laravel 5.8 project and using Nova for admin.

I want the super admin user to be able to assign a role to selected users from the nova dashboard. This is how I have attempted to do it, by using nova actions. I created a GrantAdminRole action and doing the role assingment inside the handle method like this

public function handle(ActionFields $fields, Collection $models)
{
    foreach ($models as $model) {

        // grant user admin role
        $model->assignRole(['admin']);
    }

    return Action::message('User has been assigned Admin role.');
}

Then in my app\Nova\User action method I am using the GrantAdminRole action

public function actions(Request $request)
{
    return [
        (new GrantAdminRole)->canSee(function ($request) {
            return $request->user()->hasRole(['super-admin']);
        })
    ];
}

Now when I try to assign the role, I get an error message

Sorry! You are not authorized to authorized to perform this action

How can I fix this? I am thinking I need a policy but can't figure out how what the policy should look like.

Activity icon

Replied to Laravel Nova Action Fields

In your nova action, add the field you want to the fields array in fields function like this

public function fields()
    {
        return [ Text::make('title') ];
    }

And remember to import the class

use Laravel\Nova\Fields\Text

Refer to the documentation here https://nova.laravel.com/docs/2.0/actions/defining-actions.html#action-fields

Activity icon

Replied to Sending Notification When Model Is Updated Via Nova

Thanks @wilburpowery for your response. Yes I am using model observer but for some reason I am yet to figure out, the notification never gets sent when I do an update on Nova.

I used Nova actions to achieve this. So in the nova handle action, I send the notification to the user after the function that updates the order

Sep
27
1 month ago
Activity icon

Started a new Conversation Sending Notification When Model Is Updated Via Nova

I have an Order model that I am observing for updates. When an update occurs on the model, I am checking if a field paymentStatus is set to paid or not. If the paymentStatus is paid, I want an email notification sent to the users.

Testing on postman sends the notification as intended but when the update is done on Nova, no notification is sent even though the update is successful and paymentStatus is set to paid.

How can I get the notification sent when update is done on Nova?

Sep
19
1 month ago
Activity icon

Replied to Nova Route Throws Authentication Exception Error

On my development server (local) I can access nova pages alright but I can only do so when I go through localhost:8000/nova/login. When I go through localhost:8000/nova it throws the error.

To restrict access to different nova pages, I am using policies and it's working fine.

The issue I am facing now is not being able to access nova through the default path /nova as this is stopping me from customizing the path to something like /admin/login. In the feature I would like to have a subdomain name for my app like this admin.app.com for nova if possible and if the path cannot be customized now, then I will not be able to use this.

Sep
18
1 month ago
Activity icon

Started a new Conversation Nova Route Throws Authentication Exception Error

I recently purchased a nova license and downloaded v2.3.0 and added it to a laravel API project.

When I try to access nova via the default route localhost:8000/nova I get an AuthenticationException error but when I go to localhost:8000/nova/login I am able to reach the login page. But when I logout I get the same error.

I tried changing the default path to admin in config/nova.php and when I visit either localhost:8000/admin or localhost:8000/admin/login I get the same error.

How can I correct this behavior? I would like to customize the path to nova when I move to a staging and production environment so I need to get this to work locally first.

Here's the changes I made in config/nova.php

'url' => env('APP_URL', '/admin'),

'path' => '/admin',
Sep
09
2 months ago
Activity icon

Replied to Downloading PDF Files

Resolved. I was able to get it to work by simply moving it from my dev server to a staging server. Looks like it doesn't work well with php artisan serve command.

Activity icon

Started a new Conversation Downloading PDF Files

Hello guys, is anyone familiar with using Barryvdh's laravel-dompdf package?

Found it fairly simply and straight forward and followed the documentation but when I call the uri to download the file, no file is downloaded. Tested on both chrome and firefox and got the error

Maximum execution time of 60 seconds exceeded

Here's what I have done so far

  1. composer require barryvdh/laravel-dompdf
  2. Added Barryvdh\DomPDF\ServiceProvider::class, to providers array in config.app and 'PDF' => Barryvdh\DomPDF\Facade::class, to the aliases array like this
'providers' => [

    /*
        * Laravel Framework Service Providers...
        */
    ...

    /*
        * Package Service Providers...
        */
    Spatie\Permission\PermissionServiceProvider::class,
    Barryvdh\DomPDF\ServiceProvider::class,

    /*
        * Application Service Providers...
        */
    ...
],

'aliases' => [

    // others
    'PDF' => Barryvdh\DomPDF\Facade::class,

],
  1. Then in my controller, I wrote the function to handle the pdf download like this
public function getReceipt(Order $order)
{
    $pdf = PDF::loadView('receipt');

    return $pdf->download('receipt.pdf');
}
  1. And finally a route in web.php for the download Route::get('orders/{order}/receipt', '[email protected]');

Have I missed step in using this package? I would appreciate help from anyone familiar with this package.

Sep
08
2 months ago
Activity icon

Started a new Conversation Displaying Logo In Email Notifications

Hi guys, I want to display a logo in email notifications, so I did the following

First, copied the components by running the following statement

php artisan vendor:publish --tag=laravel-mail

Then in the resources/views/vendor/mail/html/message.blade.php I modified this header slot like this

@slot('header')
    @component('mail::header', ['url' => 'website address'])
        <img src="{{asset('logo.png')}}" alt="{{config('app.name')}}">
    @endcomponent
@endslot

The logo.png file is just sitting inside the public folder but when an email is sent, the logo doesn't show. An empty box is displayed instead like this enter image description here

What possibly could I be doing wrong?

Aug
21
2 months ago
Activity icon

Started a new Conversation Handling Email Verification Error For APIs

In a laravel 5.8 API application, I want to pass the response message returned when a user has not verified their email address. To do this, I have added a the code below to the render method of the Handle.php like this

if (
    !$request->user() || ($request->user() instanceof MustVerifyEmail &&
        !$request->user()->hasVerifiedEmail())
) {
    return response()->json([
        'responseMessage'   => 'Your email address is not verified.',
        'responseStatus'    => 400
    ]);
}

Then I have added the middleware to the following route in api.php like this

Route::middleware('auth:api')->group(function () {

    Route::get('products/{product}', '[email protected]')->middleware('verified'); // #1

    Route::get('user', '[email protected]')->middleware('verified'); // #2

}

#1 returns the message I want like this

{
    "responseMessage": "Your email address is not verified.",
    "responseStatus": 400
}

#2 return something different like this

{
    "message": "Your email address is not verified.",
    "exception": "Symfony\Component\HttpKernel\Exception\HttpException",
    "file": "C:\Users\Elomena\Projects\Clients\Pramopro\vendor\laravel\framework\src\Illuminate\Foundation\Application.php",
    "line": 995,
    "trace": [
        {
            ...
}

What is it that I am doing wrong?

Activity icon

Replied to Using For Loops Inside Laravel Observer

I was able to achieve my goal by using a schedule task that checks the orders table for any order with an orderStatus of processing.

If the period between when the order was update and the current time is greater or equal to 12, then I can do what I need to do. So the cron job will keep running at every minute

$schedule->call(function () {

    // get all processing orders
    $orders = Order::where('orderStatus', 'initiated')->orWhere('orderStatus', 'processing')->get();

    // iterate over the collection
    foreach ($orders as $order) {

        // get minutes between updated_at & now
        $period = Carbon::parse($order->updated_at)->diffInMinutes();

        if ($period >= 12 && $order->paymentStatus == 'pending') {
            $order->update([
                'orderStatus'   => 'completed',
                'paymentStatus' => 'aborted'
            ]);
        }
    }
})->everyMinute();
Aug
20
2 months ago
Activity icon

Started a new Conversation Using For Loops Inside Laravel Observer

Hey guys, I want to start counting down when an update event occurs and update other fields based on certain criteria in laravel 5.8 API application.

Basically, these are the steps I want to go through

  1. When orders table orderStatus field is updated to processing, start a 12 minutes count down.

  2. During the count down if the orders table paymentStatus field gets update from pending, stop the count down and update orderStatus to completed.

  3. At the end of count down if orders paymentStatus is still pending, update orderStatus to completed and paymentStatus to aborted.

To achieve this, I made an OrderObserver that listens for an update event and tried this code

public function updated(Order $order)
{
    if ($order->paymentStatus == 'paid') {

        $order->update(['orderStatus' => 'completed']);
    }

    if ($order->paymentStatus == 'processing') {
        
        // start a timeout function
        for ($orderedAt = $order->created_at; $orderedAt <= $orderedAt->addMinutes(12); $orderedAt->addSecond()) {
            if ($order->paymentStatus !== 'pending') {
                $order->update(['orderStatus' => 'completed']);
                break;
            }

            if ($orderedAt == $orderedAt->addMinutes(12)) {
                $order->update(['orderStatus' => 'completed', 'paymentStatus' => 'aborted']);
                break;
            }
        }
    }
}

Apparently, the first if block works fine but the second does not. After 12 minutes from the created_at time, both orderStatus and paymentStatus do not get updated.

I feel like the for loop is wrong but I haven't found out the right way to do it yet.

How can I achieve the steps above using the OrderObserver update event?

Aug
12
3 months ago
Activity icon

Started a new Conversation Use Customer Email Field When Sending Password Reset Link

I have a users table that uses username as the column name for emails field in a laravel 5.8 api project.

I want to implement a password reset feature using laravel defaults but I get the error

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'email' in 'where clause' (SQL: select * from users where email = menadio1@gmail.com limit 1)

Looking at the error, it's obvious that the method responsible for creating the password_resets record is looking for email which isn't there in the users table. Where can I find the method handling the password_resets inserts? What can I change for it to use username instead of email?

Aug
09
3 months ago
Activity icon

Replied to Implementing API Email Verification

@aurawindsurfing Sure that helped. But let me explain, I am already able to verify the user email and was thinking about how the whole thing would work on the front end. For some sites, when the verify email link is clicked the user is redirected to the login page.

Should I be redirecting to the web app login page too?

I tried this code

public function verify(Request $request)
{
    $user_id = $request->id;

    $user = User::findOrFail($user_id);

    $date = date("Y-m-d g:i:s");

    $user->email_verified_at = $date;
    $user->save();

    return redirect("http://www.domain.com/login");
}

and two things should happen when the user clicks the verify link

  1. User email_verified_at is set to $date (successful)
  2. User is redirected to web app login page (failed)

Redirect fails with this message

The requested URL /login was not found on this server. Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

But if i enter the same url http://www.domain.com/login in the web browser, I can see the page. What is wrong with the redirect?

Aug
08
3 months ago
Activity icon

Started a new Conversation Implementing API Email Verification

I was following a post on medium on how to do API email verification in Laravel 5.8 here https://medium.com/@pran.81/how-to-implement-laravels-must-verify-email-feature-in-the-api-registration-b531608ecb99

I tested it and it works perfectly but I was wondering how it would work when a web or mobile application consumes the API. Here are my thoughts

  1. Web or mobile user registers a new account by calling the route Route::post('register', '[email protected]') and the controller register method is this
public function register(Request $request)
{
    // validate inputs

    // store new user & send verify email notification to user
    $user = User::create([
        'firstname' => $request->firstname,
        'lastname'  => $request->lastname,
        'username'  => $request->username,
        'password'  => bcrypt($request->password)
    ]);

    $user->sendApiEmailVerificationNotification();

    // assign access token to newly registered user
    
    // return access token & user data
    
}
  1. User get an email with a Verify Email Address button

Now what should happen next? Should the user be redirected to the web app login page? If yes, how do I customise the redirect url? At the moment when I click on the verify email address button, a browser opens up and I get all the response on the browser page like this api endpoint response

Aug
06
3 months ago
Activity icon

Replied to Checking For Null Values In A User Object

Ok so blank filled is_null can all be used to check for null values. And if I have to check multiple fields, I will simply have to check each field in a single if statement using OR condition. Got it @

Activity icon

Replied to Checking For Null Values In A User Object

What if I need to check all fields and not just 2?

Activity icon

Started a new Conversation Checking For Null Values In A User Object

is it possible to check for null values in an object in Laravel? I want to check if a user has completed their profile when they hit an api endpoint so that I can let them know they need to complete their profile if there is a field with null values.

This is how the user object will look like


    id: 8,
    name: "Jim Jam",
    username: "[email protected]",
    email_verified_at: null,
    dob: null,
    sex: null,
    nationality: null,
    address: null,
    state: null,
    country: null,
    phone: null,
    created_at: "2019-08-03 21:10:20",
    updated_at: "2019-08-03 21:10:20",
}

Tried this is_null($user->sex || $user->phone) but it returned false.

What are the possible ways to check if a field is null?

Aug
05
3 months ago
Activity icon

Replied to Passing Response From Social Provider Back To API Endpoint

I found this https://github.com/coderello/laravel-passport-social-grant and went through it but I am so confused on how it will be used. For instance, how will the user call be redirected to the provider's authentication page? How will the routing be handled?

Aug
04
3 months ago
Activity icon

Replied to Retreiving A Collection Of User Emails For Notification

Thanks @nakov @caddy for the input, I saw your solutions on stackoverflow. I realized that I was trying to send the notification to the user's email which was wrong. I should have been sending to the user entity instead.

I ended up following this solution from stack https://stackoverflow.com/questions/57348314/retrieving-a-collection-of-user-emails-for-notification Here's the code that fixed it for me incase someone comes across this post and is feeling lazy to check on stack

// get users who reserved the product
$users = User::whereHas('reservations', function (Builder $query) use ($reservation)
{
    $query->where('product_id', $reservation->product_id);
})->get();
Activity icon

Started a new Conversation Retreiving A Collection Of User Emails For Notification

I want to schedule a task that will send an email notification to selected users that have placed reservation for a particular product when a certain condition is met. Here's how the task is setup

$schedule->call(function () {

    // get reservation collection
    $reservations = Reservation::all();

    // iterate over reservation collection
    foreach ($reservations as $reservation) {

        // get difference in hours between now and product start date
        $timeDiff = Carbon::parse($reservation->product->start)->diffInHours();

        // send mail notification to reservation owners
        if ($timeDiff > 2) {

            // get users who reserved the product
            $users = Reservation::where('product_id', $reservation->product_id)->pluck($reservation->user->username);

            //notify user
            Notification::send($users, new ReservedProductPurchase($reservation));
        }
    }
})->everyMinute();

When I run the command php artisan schedule:run, it throws an error

SQLSTATE[42S22]: Column not found: 1054 Unknown column '[email protected]' in 'field list' (SQL: select [email protected].com from reservations where product_id = 2)

Of course I am not saving emails(username in this case) in my reservations table which is why the error occurs.

The relationship between a user and a reservation is One To Many which means a user hasMany reservations and a reservation belongsTo a user.

How should I go about retrieve a collection of the emails(usernames) that I want the notification sent to?

Activity icon

Replied to Passing Response From Social Provider Back To API Endpoint

You are spot on with the flow. I will see how I can work with the suggested package and hopefully I am able to make it work.

Aug
03
3 months ago
Activity icon

Started a new Conversation Passing Response From Social Provider Back To API Endpoint

I am trying to add social authentication to a laravel 5.8 API application using socialite. Following the documentation here https://laravel.com/docs/5.8/socialite#routing I created a SocialAuthController that wiill redirect the user to the provider auth page and handle the callback like this

...

use Socialite;

...

public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

public function handleProviderCallback($provider)
{
    // retrieve social user info
    $socialUser = Socialite::driver($provider)->stateless()->user();

    // check if social user provider record is stored
    $userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

    if ($userSocialAccount) {

        // retrieve the user from users store
        $user = User::find($userSocialAccount->user_id);

        // assign access token to user
        $token = $user->createToken('string')->accessToken;

        // return access token & user data
        return response()->json([
            'token' => $token,
            'user'  => (new UserResource($user))
        ]);
    } else {

        // store the new user record
        $user = User::create([...]);

        // store user social provider info
        if ($user) {

            SocialAccount::create([...]);
        }

        // assign passport token to user
        $token = $user->createToken('string')->accessToken;
        $newUser = new UserResource($user);
        $responseMessage = 'Successfully Registered.';
        $responseStatus = 201;

        // return response
        return response()->json([
            'responseMessage' => $responseMessage,
            'responseStatus'  => $responseStatus,
            'token'           => $token,
            'user'            => $newUser
        ]);
    }
}

Added the routes to web.php

Route::get('/auth/{provider}', '[email protected]');

Route::get('/auth/{provider}/callback', '[email protected]');

Then I set the GOOGLE_CALLBACK_URL=http://localhost:8000/api/v1/user in my env file.

When a user is successfully authenticated using email/password, they will be redirected to a dashboard that will consume the endpoint http://localhost:8000/api/v1/user. So in the google app, I set the URI that users will be redirected to after they are successfully authenticated to the same endpoint http://localhost:8000/api/v1/user

Now when a user tries to login with google, the app throws a 401 unauthenticated error.

// 20190803205528
// http://localhost:8000/api/v1/user?state=lCZ52RKuBQJX8EGhz1kiMWTUzB5yx4IZY2dYmHyJ&code=4/lgFLWpfJsUC51a9yQRh6mKjQhcM7eMoYbINluA58mYjs5NUm-yLLQARTDtfBn4fXgQx9MvOIlclrCeARG0NC7L8&scope=email+profile+openid+https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email&authuser=0&session_state=359516252b9d6dadaae740d0d704580aa1940f1d..10ea&prompt=none

{
  "responseMessage": "Unauthenticated",
  "responseStatus": 401
}

If I change the URI where google authenticated users should be redirect to like this GOOGLE_CALLBACK_URL=http://localhost:8000/auth/google/callback the social user information is returned.

So how should I be doing it. I have been on this for a couple of days now.

Activity icon

Replied to Adding Social Authentication To API

Now we are both on the same page but which uri have you configured as the callback uri on google developer platform? I think that is where the issue lies.

Activity icon

Replied to ArgumentCountError In Laravel 5.8

I was able to deal with the error by running php artisan route:cache command. Apparently the issue was caused as a result of the added routes not being cached.

Activity icon

Replied to ArgumentCountError In Laravel 5.8

I am following the docs https://laravel.com/docs/5.8/socialite#routing and the route for redirecting works well by doing it the same way

public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

But this method for handling the callback seems to be having a problem

public function handleProviderCallback($provider)
{
    return Socialite::driver($provider)->stateless()->user();
}
Aug
02
3 months ago
Activity icon

Replied to Auth Vs Verified Middleware

I think calling verified middleware on a route is another form of authentication, so there will be no reason to call the auth middleware again. This is not something I have tested but you can actually try it and see the result for yourself.

Activity icon

Started a new Conversation ArgumentCountError In Laravel 5.8

I am trying to add social authentication to a Laravel 5.8 API project using socialite.

When trying to handle a social provide callback, the ArgumentCountError is thrown here

Too few arguments to function App\Http\Controllers\SocialAuthController::handleProviderCallback(), 0 passed and exactly 1 expected

The error is referring to the very first line of this code block

public function handleProviderCallback($provider)
{
    // retrieve social user info
    $socialUser = Socialite::driver($provider)->stateless()->user();

    // check if social user provider record is stored
    $userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

    if ($userSocialAccount) {

        // retrieve the user from users store
        $user = User::find($userSocialAccount->user_id);

        // assign access token to user
        $token = $user->createToken('Pramopro')->accessToken;

        // return access token & user data
        return response()->json([
            'token' => $token,
            'user'  => (new UserResource($user))
        ]);
    } else {

        // store the new user record
        $user = User::create([
            'name'                  => $socialUser->name,
            'username'             => $socialUser->email,
            'email_verified_at'    => now()
        ]);

        ...

        // assign passport token to user
        $token = $user->createToken('******')->accessToken;
        

        // return response
        return response()->json(['token' => $token]);
    }
}

Below is how I have set up other code. Frist in env I added

GOOGLE_CLIENT_ID=******
GOOGLE_CLIENT_SECRET=*******
GOOGLE_CALLBACK_URL=https://staging.appdomain.com/api/v1/user

Then modified web.php

Auth::routes(['verify' => true]);

Route::get('/auth/{provider}', '[email protected]');

Route::get('/auth/{provider}/callback', '[email protected]');

Lastly in the google app, I added the uri path where users will be redirected to after successful authentication

https://staging.appdomain.com/api/v1/user 

How do I fix this?

Activity icon

Replied to Adding Social Authentication To API

Assuming I decide not to manually generate the access token which I am doing now so that it is passed in the bearer token header, please what would be the flow for social login?

Activity icon

Started a new Conversation Adding Social Authentication To API

Guys, I am working on an API application using Laravel 5.8. The API application has no web page and will only be returning json response. For instance when a user is successfully authenticated, a response is returned similar to this

{
    "responseMessage":"Successfully Registered.",
    "responseStatus":201,
    "token":"eyJ0eXAiOiJKV1...",
}

To add social authentication, I have added the socialite package and was able to log new users in using facebook and google with this code blocks below

Redirect and Callback routes in web.php file

Auth::routes(['verify' => true]);

Route::get('/auth/{provider}', '[email protected]');

Route::get('/auth/{provider}/callback', '[email protected]');

Then the controller methods are

public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

public function handleProviderCallback($provider)
{
    // retrieve social user info
    $socialUser = Socialite::driver($provider)->stateless()->user();

    // check if social user provider record is stored
    $userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

    if ($userSocialAccount) {

        // retrieve the user from users store
        $user = User::find($userSocialAccount->user_id);

        // assign access token to user
        $token = $user->createToken('string')->accessToken;

        // return access token & user data
        return response()->json([
            'token' => $token,
            'user'  => (new UserResource($user))
        ]);
    } else {

        // store the new user record
        $user = User::create([...]);

        // store user social provider info
        if ($user) {

            SocialAccount::create([...]);
        }

        // assign passport token to user
        $token = $user->createToken('string')->accessToken;
        $newUser = new UserResource($user);
        $responseMessage = 'Successfully Registered.';
        $responseStatus = 201;

        // return response
        return response()->json([
            'responseMessage'   => $responseMessage,
            'responseStatus'    => $responseStatus,
            'token' => $token,
            'user' => $newUser
        ]);
    }
}

Now when a user is authenticated, I see the expected message in the web browser window (not console). Can the the react web application or mobile application use the information that is returned this way? Or is there another way of doing it? I am not sure as this is my first implementation of implementing social auth to API only application.

Activity icon

Replied to Email Verification Redirects To Login

Yes I imported Closure I didn't at first but when it threw error, I figured I needed to which I did. But got the same error when I tested.

Aug
01
3 months ago
Activity icon

Replied to Email Verification Redirects To Login

@nakov Here's the modified code

public function __construct()
{
    // $this->middleware('auth');

    $this->middleware(function ($request, Closure $next) {
        if (auth()->check()) {
            return $next($request);
        }

        return redirect('/home');
    });

    $this->middleware('signed')->only('verify');
    $this->middleware('throttle:6,1')->only('verify', 'resend');
}
Activity icon

Replied to Passing Social Auth Response Back To Api

Now here's what I have tried to fix the issue

  1. I get the response from social provider
  2. Store the info and generate an access token for the user
  3. Redirect back to the app that made the call with the access token

Like this

return redirect('http://app.herokuapp.com')->with(['token' => $token, 'user' => $user]);

Now when I hit API app route domain/auth/google, after google login is successful, user gets redirected to http://app.herokuapp.com but I cannot see the token and user data in console.

That's one issue, secondly because the social login route domain/auth/google will be called by 2 different applications; I will have to add an if statement to check which app the authentication is being made from. Meaning more code, I don't think that's the best approach so I am still looking for one

Activity icon

Started a new Conversation Passing Social Auth Response Back To Api

I need to add social login to a laravel API application project. I have successfully implemented the social login using socialite with the set up below

web.php

Auth::routes(['verify' => true]);

Route::get('/auth/{provider}', '[email protected]');

Route::get('/auth/{provider}/callback', '[email protected]');

SocialauthController methods are

public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

public function handleProviderCallback($provider)
{
    // retrieve social user info
    $socialUser = Socialite::driver($provider)->stateless()->user();

    // check if social user provider record is stored
    $userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

    if ($userSocialAccount) {

        // retrieve the user from users store
        $user = User::find($userSocialAccount->user_id);

        // assign access token to user
        $token = $user->createToken('******')->accessToken;

        // return access token & user data
        return response()->json([...]);
    } else {

        // store the new user record
        $user = User::create([...]);

        // store user social provider info
        if ($user) {

            SocialAccount::create([...]);
        }

        // assign passport token to user
        $token = $user->createToken('******')->accessToken;
        
        return response()->json([...]);
    }
}

When the react app consuming the api makes a call to https://app-domain-name/auth/google the user is redirected to google and the user is successfully authenticated. But the response is being returned to the browser window where the user was redirected to from the app.

How do I redirect the user back to the app with the response? I need to do this so that the granted access token can be used to access app resources.

Activity icon

Started a new Conversation How To Setup A Callback API Endpoint That Recieves Payment Status From A Payment Gateway

I am trying to figure out how to setup a callback url to receive payment status from a payment gateway.

Here's a summary of the whole setup. I have built the backend (API endpoints) with Laravel 5.8 that will be consumed by a react app and a mobile app. Both apps will be using the payment gateway web and mobile sdks to initiate payment transactions.

Then the payment gateway should respond with a payment status by calling the callback api I need to set up.

This is my first attempt at doing something like this so pardon me if I am way off but here's what I have written

Callback endpoint

Route::post('order/payment/status', '[email protected]'); // receives payment status

PaymentController getstatus() method

public function getStatus(Request $request)
    {
        $paymentMethod          = $request->paymentMethod;
        $amount                 = $request->amount;
        $providerCode           = $request->provider;
        $customerName           = $request->customerName;
        $customerEmail          = $request->customerEmail;
        $paymentDescription     = $request->paymentDescription;
        $paymentStatus          = $request->paaymentStatus;
        $transactionReference   = $request->transactionReference;

        // update my record based on the paymentStatus
    }

Is this the proper way to do it? I feel like it should be a get request and not a post. Please help.

Activity icon

Replied to Email Verification Redirects To Login

@nakov Tried doing as you advised and got the error below

Argument 2 passed to App\Http\Controllers\Auth\VerificationController::App\Http\Controllers\Auth{closure}() must be an instance of App\Http\Controllers\Auth\Closure, instance of Closure given, called in C:\Users\Elomena\Projects\Clients\Pramopro\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php on line 145

What do you think? I am a novice in this area right now.

Jul
30
3 months ago
Activity icon

Started a new Conversation Consuming Payment Gateway API In Laravel Controller

Hi guys, I am doing a payment gateway integration for a Laravel 5.8 API project. So below is the logic I have come up with

  1. User confirms they want to pay for a product
  2. They hit this route Route::post('products/{product}/order', '[email protected]');
  3. In the store method, I will consume the payment gateway initiate transaction API
  4. Check the status of the transaction in the same controller method
  5. Update the order table based on response from the gateway

Here's a summary version of OrderController

<?php
...
use GuzzleHttp\Client;


class OrderController extends Controller
{
    public function store(Request $request, Product $product)
    {
        // if status is loaded, allow order
        if ($product->status == 'loaded') {

            // redirect user to payment gateway
            $payment = new Client();

            $uri = 'https://sandbox.gateway.com/api/v1/merchant/transactions/init-transaction';

            $paylaod = ["amount" => 100"];

            return $payment->post($uri, $paylaod);

            // do something with returned object
        }
    }
}

When I run my code, I get 500 internal server error

GuzzleHttp\Exception\ClientException: Client error: POST https://sandbox.gateway.com/api/v1/merchant/transactions/init-transaction resulted in a 400 Bad Request

Why am I getting this error?

Jul
29
3 months ago
Activity icon

Replied to Return JSON Response Instead Of 401 Blade File

In laravel 5.8, I was able to resolve this by handling the authentication exception in Handler.php render function like this

if ($exception instanceof AuthenticationException) {
    return response()->json(['message' => 'unauthenticated], 401);
}
Activity icon

Replied to Return JSON Response Instead Of 401 Blade File

Hi, were you able to solve this challenge? I would like to know how you did it.

Jul
27
3 months ago
Activity icon

Replied to Call To Undefined Method Laravel\Socialite\Two\User::createToken()

You are right that the user already comes with the provider token. But this token can not be used internally by the app so I need to exchange the provider token for the app's own token. To do that I am generating a token using passport.

I am following the same flow when the user logs in for the first time using the social account and an app specific token is successfully generated for the user. The issue is this same flow does not seem to be working if the same user tries to login again with the same social account.

Activity icon

Started a new Conversation Call To Undefined Method Laravel\Socialite\Two\User::createToken()

In a laravel 5.8 API project, I want to users to login via their social accounts. So far I have been able to use Socialite to to retrieve a user info from the provider and use it to create a new user record. But when I try to had the user login again, it throws up the following error

Call to undefined method Laravel\Socialite\Two\User::createToken()

Here's the code I am working with

<?php

namespace App\Http\Controllers;

use App\User;
use Socialite;
use App\SocialAccount;
use App\Http\Resources\UserResource;

class SocialAuthController extends Controller
{
    ...

    public function handleProviderCallback($provider)
    {
        $socialUser = Socialite::driver($provider)->stateless()->user();

        $userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

        /*
         if account exist, return the social account user
         else create the user account, then return the new user
        */
        if ($userSocialAccount) {

            // generate access token for use
            $token = $socialUser->createToken('********')->accessToken;

            // return access token & user data
            return response()->json([
                'token' => $token,
                'user'  => (new UserResource($userSocialAccount))
            ]);

        } else {

            $user = User::create([
                'firstname'            => $socialUser->name,
                'lastname'             => $socialUser->name,
                'username'             => $socialUser->email,
                'email_verified_at'    => now()
            ]);

            if ($user) {

                SocialAccount::create([
                    'provider_id'   => $socialUser->id,
                    'provider_name' => $provider,
                    'user_id'       => $user->id
                ]);
            }

            // assign passport token to user
            $token = $user->createToken('********')->accessToken;

            return response()->json(['token' => $token, 'user' => new UserResource($user)]);
            
        }
    }
}

I haven't been able to spot the reason why I am getting the error when the user attempts a second login but there is no error if it's the first time the user logs in with a social account.

Why does it complain about Laravel\Socialite\Two\User::createToken() method? If i try adding this line use Laravel\Socialite\Two\User vscode intelephsense flags it as a duplicate of App\User so what is really going on in my code?

Jul
26
3 months ago
Activity icon

Replied to Passport: How Can I Manually Revoke Access Token

Thanks for stating clearly that the route has to be using the auth:api middleware.

Jul
24
3 months ago
Activity icon

Started a new Conversation Unable To Authenticate User Via Social Accounts

I am having difficulty authenticating users via facebook and google in a Laravel 5.8 API application that uses passport. To achieve the social login, I did the following

  1. Added the package to app project's dependencies composer require laravel/socialite

  2. Added the configuration for both facebook and google in config services.php

  3. Added routes to handle redirect to provider and callback in web.php like so

Route::get('/auth/{provider}', '[email protected]');

Route::get('/auth/{provider}/callback', '[email protected]');
  1. Added the following methods to my AuthController
public function redirectToProvider($provider)
{
    return Socialite::driver($provider)->redirect();
}

public function handleProviderCallback($provider)
{
    // store provider callback in a variable
    $socialUser = Socialite::driver($provider)->stateless()->user();

    // check if user exist in social account table
    $socialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();

    // return user if account exist else create new user
    if ($socialAccount) {

        return response()->json(['token' => $socialUser->token, 'user' => (new UserResource($socialAccount->user))]);
    } else {
        $user = User::create([
            'firstname' => $socialUser->name,
            'lastname'  => $socialUser->name,
            'username'  => $socialUser->email
        ]);

        if ($user) {

            SocialAccount::create([
                'provider_id'   => $socialUser->id,
                'provider_name' => $provider,
                'user_id'       => $user->id
            ]);
        }

        return response()->json(['token' => $socialUser->token, 'user' => new UserResource($user)]);
    }
}

Testing both loging returns the expected data and user is created in users table while provider info is stored in socialaccounts as intended.

The real issue is that when I run a test in post man by passing in the token from provider, the app screams 401 unauthorised. What I want is to have the user authenticated when the social login is successful. How can I achieve my goal?

Jul
21
3 months ago
Activity icon

Replied to Image URL Works In Local Serve But Fails In Staging Environment

Very sorry guys. I forgot to copy the storage folder from public to public_html when I made updates and had to copy the entire app again to the staging server.

Activity icon

Replied to Image URL Works In Local Serve But Fails In Staging Environment

It returns nothing

[staging]# php artisan --version
[staging]#

Activity icon

Replied to Image URL Works In Local Serve But Fails In Staging Environment

I tried running the command via ssh but it does nothing. When I run php artisan it returns nothing but composer returns a list of the commands.

Activity icon

Started a new Conversation Working With Passport And Swagger For API Documentation

Hi guys, I am using swagger for the documentation of an API application built using Laravel 5.8. I am also using Passport for the API authentication and tried implementing it in the documentation.

When I try to authorize a user on swagger, I get the error here

auth errorTypeError: NetworkError when attempting to fetch resource.

Here's how I have set it up swagger up

In l5-swagger.php config file

/* Open API 3.0 support */
'passport' => [ // Unique name of security
    'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
    'description' => 'Laravel passport oauth2 security.',
    'in' => 'header',
    'scheme' => 'https',
    'flows' => [
        "password" => [
            "authorizationUrl" => config('app.url') . '/oauth/authorize',
            "tokenUrl" => config('app.url') . '/oauth/token',
            "refreshUrl" => config('app.url') . '/token/refresh',
            "scopes" => []
        ],
    ],
],

In the controller I have the swagger code

/**
* @OA\Get(
*      path="/products/{product}",
*      tags={"Product"},
*      description="Gets specified product",
*      operationId="getProductById",
*      summary="Fetches a product by the product Id",
*      security={{"passport": {}}},
*      @OA\Parameter(...),
*      @OA\Response(...),
* )
*/

This is the image of swagger authorization screen

https://i.stack.imgur.com/aiYjs.png

I get the client_id & client_secret from the oauth_clients table.

What am I doing wrong?

Activity icon

Started a new Conversation Image URL Works In Local Serve But Fails In Staging Environment

Hi guys, I am working on an API application using Laravel 5.8 version. When a get request is made to the products api endpoint, I return a ProductResource collection which looks like this

public function toArray($request)
{
    return [
        'id'            => $this->id,
        'name'          => $this->name,
        'category'      => $this->category,
        'description'   => $this->description,
        'status'        => $this->status,
        'price'         => $this->price,
        'barrels'       => $this->barrels,
        'interest'      => $this->interest,
        'start'         => $this->start,
        'end'           => $this->end,
        'hidden'        => $this->hidden,
        'imageUrl'      => asset('storage/images/products/' . $this->image->name)
    ];
}

The challenge I am having is that on my local server clicking the returned imageUrl displays the correct image but in the staging environment, I get the default 404 not found page.

I created a symbolic link from public/storage to storage/app/public on my local server which i am developing on to store the actual image file before uploading the app file to the staging environment. A quick check of the storage/app/public/images/products in the staging environment shows the image file but I still cannot view it from my browser. What could be the possible reason for this behavior?

Here's a sample of the resource in both my local and staging environments

Local/development server

{
    "id": 17,
    "name": "test",
    "category": "test",
    "description": "test",
    "status": "test",
    "price": 10990,
    "barrels": 207736,
    "interest": 0.2,
    "start": "2019-07-25",
    "end": "2019-08-25",
    "hidden": 0,
    "imageUrl": "http://localhost:8000/storage/images/products/pramopro_test_17.jpeg"
  }

Staging server

{
    "id": 13,
    "name": "test prod",
    "category": "test prod category",
    "description": "test prod description",
    "status": "loading",
    "price": 10000,
    "barrels": 300000,
    "interest": 0.2,
    "start": "2019-07-22",
    "end": "2019-08-28",
    "hidden": 0,
    "imageUrl": "http://staging.pramopro.com/storage/images/products/pramopro_testprod_13.jpeg"
  }
Jul
19
3 months ago
Activity icon

Replied to Email Verification Redirects To Login

My code just became cleaner. Thanks for the tip. I still don't know how to make the verificationUrl work or change it to use the login endpoint, any thoughts on that?