skip to Main Content

First of all, I’d like to comment on this that I’m working on a project based on Laravel VueJs with tenancy for laravel v3 package.

To get into context, I can perfectly log in on my [email protected] account registered at any created tenant on local development but after logging in, I’m struggling mainly with TypeError: Cannot read properties of undefined (reading ‘xxxxx’) in console with all the api-related and VueJs routes. I have been digging deeper over the problem and got into a conclusion.

TypeError: Cannot read properties of undefined (reading ‘xxxxx’)

And with that, I figured out my GET route with GetUserAuth as uri at ‘api’ middleware on tenant.php is recognized but isn’t calling the method associated to it but throwing as a status code 200 OK. Instead, the response is a blade as in the following picture.

Where Respuesta is Response

It’s also important to mention I’ve set up Laravel Passport according to the stancl/tenancy v3 documentation, specifically using Passport in the tenant application only with shared passport encryption keys.

The following code refers to my tenant.php

<?php

declare(strict_types=1);

use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;
use StanclTenancyMiddlewareInitializeTenancyByDomain;
use StanclTenancyMiddlewarePreventAccessFromCentralDomains;
use AppHttpControllersUserController;

/*
|--------------------------------------------------------------------------
| Tenant Routes
|--------------------------------------------------------------------------
|
| Here you can register the tenant routes for your application.
| These routes are loaded by the TenantRouteServiceProvider.
|
| Feel free to customize them however you want. Good luck!
|
*/

Route::middleware(['api', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class])->group(
    function ()
    {
        /*auth middleware api passport token*/
        Route::middleware('auth:api')->get('/user', function (Request $request) {
            return $request->user();
        });
        
        // Other routes

        Route::middleware(['auth:api', 'Is_Active'])->group(function ()
        {
            //Other routes

            //------------------------------- Users --------------------------\

            Route::get('GetUserRole', [UserController::class, "GetUserRole"]);
            Route::get('GetUserAuth', [UserController::class, "GetUserAuth"]);
            Route::get("/GetPermissions", [UserController::class, "GetPermissions"]);
            Route::resource('users', UserController::class);
            Route::put('users/Activated/{id}', [UserController::class, "IsActivated"]);
            Route::get('users/export/Excel', [UserController::class, "exportExcel"]);
            Route::get('users/Get_Info/Profile', [UserController::class, "GetInfoProfile"]);
            Route::put('updateProfile/{id}', [UserController::class, "updateProfile"]);
        });
    });

Route::middleware(['web', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class])->group(
     function ()
     {
          // Web routes   
     });

The following one is referring to the code located at C:/project-root/resources/src/store/modules/auth.js

import Vue from 'vue'
import Vuex from 'vuex'
// import VueCookie from 'vue-cookie'
import axios from 'axios'
import router from "./../../router";
Vue.use(Vuex)
// Vue.use(VueCookie)


const state = {
    // token: Vue.cookie.get('Stocky_token'),
    isAuthenticated:false,
    Permissions: null,
    user: {},
    loading: false,
    error: null,
    notifs:0,
};


const getters = {
    isAuthenticated: state => state.isAuthenticated,
    currentUser: state => state.user,
    currentUserPermissions: state => state.Permissions,
    loading: state => state.loading,
    notifs_alert: state => state.notifs,
    error: state => state.error
};

const mutations = {
    setLoading(state, data) {
        state.loading = data;
        state.error = null;
    },
    setError(state, data) {
        state.error = data;
        state.loggedInUser = null;
        state.loading = false;
    },
    clearError(state) {
        state.error = null;
    },
    // setLoginCred(state, payload) {
    //     state.token = payload.token;
    //     // state.isAuthenticated = true;
    // },

    setPermissions(state, Permissions) {
        state.Permissions = Permissions;
        // state.user = user;
    },


    setUser(state, user) {
        state.user = user;
    },

    // SET_AUTHENTICATED(state, isAuthenticated) {
    //     state.isAuthenticated = isAuthenticated;
    // },

    Notifs_alert(state, notifs) {
        state.notifs = notifs;
    },

    logout(state) {
        // state.token = null;
        state.user = null;
        state.Permissions = null;
        // state.isAuthenticated = false;
        // Vue.cookie.delete('Stocky_token');
        state.loggedInUser = null;
        state.loading = false;
        state.error = null;
    },
};

const actions = {

    // setLoginCred(context, payload) {
    //     context.commit('setLoading', true)
    //     context.commit('setLoginCred', payload)
    // },

    async refreshUserPermissions(context) {

        await axios.get("GetUserAuth").then((userAuth) => {
            let Permissions = userAuth.data.permissions
            let user = userAuth.data.user
            let notifs = userAuth.data.notifs

            // context.commit('SET_AUTHENTICATED', true)
            context.commit('setPermissions', Permissions)
            context.commit('setUser', user)
            context.commit('Notifs_alert', notifs)
        }).catch(() => {
            // context.commit('SET_AUTHENTICATED', false)
            context.commit('setPermissions', null)
            context.commit('setUser', null)
            context.commit('Notifs_alert', null)
        });
    },

    logout({ commit }) {

        axios({method:'post',  url: '/logout', baseURL: '' })
          .then((userData) => {
            window.location.href='/login';
        })
    },
};

export default {
    state,
    getters,
    actions,
    mutations
};

And the following one refers to the mentioned before method on UserCon related with the GET route throwing status code 200 OK with a blade as a response

   //------------- GET USER Auth ---------\

    public function GetUserAuth(Request $request)
    {
        $helpers = new helpers();
        $user['avatar'] = Auth::user()->avatar;
        $user['username'] = Auth::user()->username;
        $user['currency'] = $helpers->Get_Currency();
        $user['logo'] = Setting::first()->logo;
        $user['footer'] = Setting::first()->footer;
        $user['developed_by'] = Setting::first()->developed_by;
        $user['initCCF'] = Auth::user()->initCCF;
        $user['currentCCF'] = Auth::user()->currentCCF;
        $user['finalCCF'] = Auth::user()->finalCCF;
        $user['initCF'] = Auth::user()->initCF;
        $user['currentCF'] = Auth::user()->currentCF;
        $user['finalCF'] = Auth::user()->finalCF;
        $user['warehouse_id'] = Auth::user()->warehouse_id;
        $permissions = Auth::user()->roles()->first()->permissions->pluck('name');
        $products_alerts = product_warehouse::join('products', 'product_warehouse.product_id', '=', 'products.id')
            ->whereRaw('qte <= stock_alert')
            ->where('product_warehouse.deleted_at', null)
            ->count();

        return response()->json([
            'success' => true,
            'user' => $user,
            'notifs' => $products_alerts,
            'permissions' => $permissions,
        ]);
    }

Finally, I’d like to mention that my application with central domain only and a single database was working perfectly but I don’t know what could be the problem even debugging, checking all the documentation related and other answered questions but none of those fixed my issue and I need help as soon as possible. Any suggestions or help are welcomed and if you need extra information, please let me know. Thanks in advance for taking your time.

2

Answers


  1. Chosen as BEST ANSWER

    First of all, sorry for my delayed solution.

    For those who are struggling with the same issue I went through the past year using stancl/tenancy v3 package, and as I mentioned in this comment, I'll leave over here my passport.php settings:

    <?php
    
    return [
    
        /*
        |--------------------------------------------------------------------------
        | Encryption Keys
        |--------------------------------------------------------------------------
        |
        | Passport uses encryption keys while generating secure access tokens for
        | your application. By default, the keys are stored as local files but
        | can be set via environment variables when that is more convenient.
        |
        */
    
        'private_key' => env('PASSPORT_PRIVATE_KEY', storage_path('oauth-private.key')),
    
        'public_key' => env('PASSPORT_PUBLIC_KEY', storage_path('oauth-public.key')),
    
        /*
        |--------------------------------------------------------------------------
        | Client UUIDs
        |--------------------------------------------------------------------------
        |
        | By default, Passport uses auto-incrementing primary keys when assigning
        | IDs to clients. However, if Passport is installed using the provided
        | --uuids switch, this will be set to "true" and UUIDs will be used.
        |
        */
    
        'client_uuids' => false,
    
        /*
        |--------------------------------------------------------------------------
        | Personal Access Client
        |--------------------------------------------------------------------------
        |
        | If you enable client hashing, you should set the personal access client
        | ID and unhashed secret within your environment file. The values will
        | get used while issuing fresh personal access tokens to your users.
        |
        */
    
        'personal_access_client' => [
            'id' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_ID'),
            'secret' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET'),
        ],
    
        /*
        |--------------------------------------------------------------------------
        | Passport Storage Driver
        |--------------------------------------------------------------------------
        |
        | This configuration value allows you to customize the storage options
        | for Passport, such as the database connection that should be used
        | by Passport's internal database models which store tokens, etc.
        |
        */
    
        'storage' => [
            'database' => [
                'connection' => null,
            ],
        ],
    
        'key_path' => env('OAUTH_KEY_PATH', storage_path(''))
    ];
    

    Hopefully this will help other developers solve the problem detailed above.

    Best regards,

    Ignacio Y. C.


  2. A common thing I faced when using tenancy for laravel is the default Authenticate middleware included with the SaaS boilderplate you can purchase. It extends the default laravel Authenticate and adds this code:

    if (! $request->expectsJson()) {
      // return a blade view
      return route('tenant.login');
    }
    

    This redirects all requests to the tenant.login view if the Accept: application/json header is missing.

    I can’t really see the headers of the request you’re seding to GetUserAuth, but this could be the reason.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search