import type { HttpContext } from '@adonisjs/core/http'; import db from '@adonisjs/lucid/services/db'; import config from '@adonisjs/core/services/config'; import User from '#app/Models/User'; import { Exception } from '@adonisjs/core/exceptions'; // const roleTable = Config.get('rolePermission.role_table', 'roles'); const roleTable = config.get('rolePermission.role_table', 'roles'); // const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles'); const userRoleTable = config.get('rolePermission.user_role_table', 'user_roles'); // node ace make:middleware role export default class Role { // .middleware(['auth', 'role:admin,moderator']) public async handle({ auth, response }: HttpContext, next: () => Promise, userRoles: string[]) { // Check if user is logged-in or not. // let expression = ""; // if (Array.isArray(args)) { // expression = args.join(" || "); // } let user = auth.user as 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(',')}`, { status: 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 db.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; } }