Middleware to check for company

Hi.

I have users and companies. a user can have many companies but only one active. The user also cannot have any company at all.

User.js

  async activeCompany(){

    const company = await this.company()
                            .wherePivot('active',1)
                            .first()
    return company
  }

  company(){
    return this.belongsToMany(
      'App/Models/Company',
      'user_id',
      'company_id'
    )
    .pivotTable('users_companies')
    .withTimestamps()
    .withPivot('active')
  }

I want to restrict the access of some routes only for users that have an active Company and send the Company to the Controller. For that I created the Middleware UserCompany.js

  async handle ({ request }, next) {

    await next()
  }

How can I do that?

Try the following code snippet

async handle ({ request, response, auth }, next) {
	const company = await auth.user.activeCompany()
	if (!company) {
		response.status(401).send('Not allowed')
		return
	}

	await next()
}
2 Likes

Hi Virk.
I worked perfect, thanks!.

can I send the company to the Controller ? For example, if the user has a Company and wants to create a product:

ProductController.js

async store({request, response, auth, company}){
....
}

You have access to the auth object in the controller, you can get the company there the same way:

const company = await auth.user.activeCompany()

Or, if you want to avoid another db query, you could inject it into the request object in the middleware, thusly:

async handle ({ request, response, auth }, next) {
	const company = await auth.user.activeCompany()
	if (!company) {
		response.status(401).send('Not allowed')
		return
	}

    request.company = company

	await next()
}

Then in your controller:

const company = request.company

I have a similar thing where users belong to an organization, and organizations are defined in a hierarchy, so a user of a particular org can access anything in their organization, or any descendent of their organzation, but not in the parents/grandparents/etc…

So I have a middleware that fetches a list of all the accessible organization IDs for the current user, and shoves that into the request object, so that anywhere it’s relevant I can just check if the organization they’re attempting to do something against is in that list, or I can restrict query results by that list, etc.

'use strict'

const Organization = use('App/Models/Organization')

class LimitByOrg {
  async handle ({ auth, request }, next) {
    const user = await auth.user
    const orgIds = await Organization.query().whereRaw('ancestor_tree like ?', [`%-${ user.organization_id }-%`]).pluck('id')
    orgIds.push(user.organization_id)

    request.accessible_orgs = orgIds
    // call next to advance the request
    await next()
  }
}

module.exports = LimitByOrg

Organizations have a column called ‘ancestor_tree’ that list each org id that is an ancestor that organization, ie: -1-2-5-18-22-

So I find any org id where the user’s orgid appears in the ancestor tree, and push those, along with the user’s org id itself into the request object as accessible_orgs for reference within whatever controller is being called. This works incredibly well. :smiley:

3 Likes