@mamoorali295/rbac
Version:
Complete RBAC (Role-Based Access Control) system for Node.js with Express middleware, NestJS integration, GraphQL support, MongoDB & PostgreSQL support, modern admin dashboard, TypeScript support, and dynamic permission management
121 lines (120 loc) • 6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerUserDirectiveTransformer = registerUserDirectiveTransformer;
const utils_1 = require("@graphql-tools/utils");
const graphql_1 = require("graphql");
const RBAC_1 = require("../../RBAC");
/**
* GraphQL directive transformer for automatically registering users in the RBAC system.
* Automatically assigns default role if configured and calls registration hooks.
*
* @example
* ```graphql
* type Mutation {
* # Default field mapping (id -> user_id, name -> name, email -> email)
* createUser(input: CreateUserInput): User @registerUser
*
* # Custom field mapping
* signUp(data: SignUpInput): User @registerUser(
* userIdField: "userId",
* nameField: "fullName",
* emailField: "emailAddress"
* )
* }
*
* input CreateUserInput {
* id: ID!
* name: String
* email: String
* }
*
* input SignUpInput {
* userId: ID!
* fullName: String
* emailAddress: String
* }
* ```
*/
function registerUserDirectiveTransformer(schema, directiveName = 'registerUser') {
return (0, utils_1.mapSchema)(schema, {
[utils_1.MapperKind.OBJECT_FIELD]: (fieldConfig) => {
var _a;
const registerUserDirective = (_a = (0, utils_1.getDirective)(schema, fieldConfig, directiveName)) === null || _a === void 0 ? void 0 : _a[0];
if (registerUserDirective) {
const { resolve = graphql_1.defaultFieldResolver } = fieldConfig;
const { userIdField = 'id', nameField = 'name', emailField = 'email' } = registerUserDirective;
fieldConfig.resolve = function (source, args, context, info) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (!RBAC_1.RBAC['config'] || !RBAC_1.RBAC['initialized'] || !RBAC_1.RBAC['dbAdapter']) {
throw new graphql_1.GraphQLError('RBAC system not initialized', {
extensions: { code: 'INTERNAL_SERVER_ERROR' }
});
}
// Extract user data from arguments
const input = args.input || args.data || args;
const userData = {
user_id: input[userIdField],
name: input[nameField] || '',
email: input[emailField] || '',
};
if (!userData.user_id) {
throw new graphql_1.GraphQLError(`${userIdField} is required`, {
extensions: { code: 'BAD_USER_INPUT' }
});
}
// Check if user already exists
const existingUser = yield RBAC_1.RBAC['dbAdapter'].findUserByUserId(userData.user_id);
if (existingUser) {
throw new graphql_1.GraphQLError('User already registered in RBAC system', {
extensions: { code: 'BAD_USER_INPUT' }
});
}
// Get default role if configured
let defaultRoleId = undefined;
if (RBAC_1.RBAC['config'].defaultRole) {
const role = yield RBAC_1.RBAC['dbAdapter'].findRoleByName(RBAC_1.RBAC['config'].defaultRole);
if (role) {
defaultRoleId = role.id;
}
}
// Create user in RBAC system
yield RBAC_1.RBAC['dbAdapter'].createUser({
user_id: userData.user_id,
name: userData.name,
email: userData.email,
role_id: defaultRoleId,
});
// Call registration hook if configured
if (RBAC_1.RBAC['config'].onUserRegister) {
yield RBAC_1.RBAC['config'].onUserRegister(userData);
}
// Attach user info to context for downstream use
context.rbacUser = userData;
// Continue with original resolver
return resolve.call(this, source, args, context, info);
}
catch (error) {
if (error instanceof graphql_1.GraphQLError) {
throw error;
}
throw new graphql_1.GraphQLError('Internal server error during user registration', {
extensions: { code: 'INTERNAL_SERVER_ERROR' }
});
}
});
};
}
return fieldConfig;
}
});
}