import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import Database from '@ioc:Adonis/Lucid/Database'; import Config from '@ioc:Adonis/Core/Config'; import User from 'app/Models/User'; import { Exception } from '@adonisjs/core/build/standalone'; const roleTable = Config.get('rolePermission.role_table', 'roles'); const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles'); // node ace make:middleware role export default class Role { // .middleware(['auth', 'role:admin,moderator']) public async handle( { auth, response }: HttpContextContract, next: () => Promise, userRoles: string[] ) { // Check if user is logged-in or not. // let expression = ""; // if (Array.isArray(args)) { // expression = args.join(" || "); // } let user = await auth.user; if (!user) { return response.unauthorized({ error: 'Must be logged in' }); } let hasRole = await this.checkHasRoles(user, userRoles); if (!hasRole) { // return response.unauthorized({ // error: `Doesn't have required role(s): ${userRoles.join(',')}`, // // error: `Doesn't have required role(s)`, // }); throw new Exception(`Doesn't have required role(s): ${userRoles.join(',')}`, 401); } // code for middleware goes here. ABOVE THE NEXT CALL await next(); } private async checkHasRoles(user: User, userRoles: string[]): Promise { // await user.load("roles"); // const ok = user.roles.map((role) => role.name); // const roles = await user.getRoles(); let rolePlaceHolder = '('; let placeholders = new Array(userRoles.length).fill('?'); rolePlaceHolder += placeholders.join(','); rolePlaceHolder += ')'; // const roles = await user // .related('roles') // .query() // .count('*') // .select('name') // .whereIn('name', userRoles); // // .groupBy('name'); // select count(*) as roleCount // from gba.roles // inner join gba.link_accounts_roles // on "roles"."id" = "link_accounts_roles"."role_id" // where ("name" in ('administrator', 'editor')) and ("link_accounts_roles"."account_id" = 1) let { rows: { 0: { rolecount }, }, } = await Database.rawQuery( 'SELECT count("r"."id") as roleCount FROM ' + roleTable + ' r INNER JOIN ' + userRoleTable + ' ur ON r.id=ur.role_id WHERE "ur"."account_id"=? AND "r"."name" in ' + rolePlaceHolder + ' LIMIT 1', [user.id, ...userRoles] ); return rolecount > 0; } }