@iamjs/next
TypeScript icon, indicating that this package has built-in type declarations

2.0.14 • Public • Published

@iamjs/next

iamjs banner

This package contains the next middleware for iamjs a library for easy role and permissions management for your next application.

Installation

npm install @iamjs/core @iamjs/next
# or
yarn add @iamjs/core @iamjs/next
# or
pnpm add @iamjs/core @iamjs/next
# or
bun add @iamjs/core @iamjs/next

Usage

Authorization

You can use the NextRoleManager to authorize a request in your express application by creating a new instance and using the check method.

Example:

import { Role, Schema } from '@iamjs/core';
import { NextRoleManager } from '@iamjs/next';
import next from 'next';

const role = new Role({
  name: 'role',
  config: {
    resource1: {
      base: 'crudl'
    },
    resource2: {
      base: 'cr-dl',
      custom: {
        'create a new user': false
      }
    }
  }
});

const schema = new Schema({
  roles : { role }
});

const roleManager = new NextRoleManager({
  schema: schema,
  onSuccess: (req, res) => {
    res.status(200).send('Hello World!');
  },
  onError: (err, req, res) => {
    console.error(err);
    res.status(403).send('Forbidden');
  }
});


const handler = roleManager.check(
    (_req, res) => {
      res.status(200).send('Hello World!');
    },
    {
      resources: 'resource2',
      actions: ['create', 'update'],
      role: 'role',
      strict: true
});

export default handler

Advanced Usage

By using the construct option you can use the data from the request to build the role from its own permissions.

Example:

import { Role, Schema } from '@iamjs/core';
import { NextRoleManager } from '@iamjs/next';
import next from 'next';

const role = new Role({
  name: 'role',
  config: {
    resource1: {
      base: 'crudl'
    },
    resource2: {
      base: 'cr-dl',
      custom: {
        'create a new user': false
      }
    }
  }
});

const schema = new Schema({
  roles : { role }
});

const roleManager = new NextRoleManager({
  schema: schema,
  onSuccess: (req, res) => {
    res.status(200).send('Hello World!');
  },
  onError: (err, req, res) => {
    console.error(err);
    res.status(403).send('Forbidden');
  }
});

const withAuth = (handler) => {
  return (req, res) => {
    req.permissions = role.toObject();
    return handler(req, res);   
  };
};

const handler = roleManager.check(
    (_req, res) => {
      res.status(200).send('Hello World!');
    },
    {
      resources: 'resource2',
      actions: ['create', 'update'],
      strict: true,
      construct: true, // to use the data from the request to build the role's permissions
      data: async (req)=>{
        return req.permissions
      }
});

export default withAuth(handler);

App Router Api Routes

The next.js 13 new api routes are using the browser's fetch api so you can't use the middleware with pages request and response interfaces but you can use the checkFn function to check if the user is authenticated inside the actual route handler.

import { getUserPermissions } from '@lib/utils/auth';
import { roleManager } from '@lib/utils/api';

export async function GET(request: Request) {
  const authorized = await roleManager.checkFn({
    resources: 'resource2',
    actions: ['read'],
    strict: true,
    construct: true,
    data: async () => {
      return await getUserPermissions(request); // handle getting user permissions
    }
  });

  if (!authorized) {
    return new Response('Unauthorized', { status: 401 });
  }
  return new Response('Authorized', { status: 200 });
}

Success and Error Handling

You can pass onSuccess and onError handlers to the NextRoleManager constructor to handle the success and error cases.

Example:

import { Role, Schema } from '@iamjs/core';
import { NextRoleManager } from '@iamjs/next';
import next from 'next';

const role = new Role({
  name: 'role',
  config: {
    resource1: {
      base: 'crudl'
    },
    resource2: {
      base: 'cr-dl',
      custom: {
        'create a new user': false
      }
    }
  }
});

const schema = new Schema({
  roles : { role }
});

const roleManager = new NextRoleManager({
  schema: schema,
  onSuccess: (req, res) => {
    res.status(200).send('Hello World!');
  },
  onError: (err, req, res) => {
    console.error(err);
    res.status(403).send('Forbidden');
  }
});

const withAuth = (handler) => {
  return (req, res) => {
    req.permissions = role.toObject();
    return handler(req, res);   
  };
};

const handler = roleManager.check(
    (_req, res) => {
      res.status(200).send('Hello World!');
    },
    {
      resources: 'resource2',
      actions: ['create', 'update'],
      strict: true,
      construct: true, // to use the data from the request to build the role's permissions
      data: async (req)=>{
        return req.permissions
      }
});

export default withAuth(handler);

Typescript Support

This package is written in typescript and has type definitions for all the exported types also the check method accepts a generic type which can be used to define the type of the request or response object.

Example:

interface Request extends NextApiRequest {
  role: string;
  permissions: Record<string, Record<permission, boolean>>;
}

interface Response extends NextApiResponse {}

import { Role, Schema } from '@iamjs/core';
import { NextRoleManager } from '@iamjs/next';
import next from 'next';

const role = new Role({
  name: 'role',
  config: {
    resource1: {
      base: 'crudl'
    },
    resource2: {
      base: 'cr-dl',
      custom: {
        'create a new user': false
      }
    }
  }
});

const schema = new Schema({
  roles : { role }
});

const roleManager = new NextRoleManager({
  schema: schema,
  onSuccess: <Request,Response>(req, res) => {
    res.status(200).send('Hello World!');
  },
  onError: <Request,Response>(err, req, res) => {
    console.error(err);
    res.status(403).send('Forbidden');
  }
});

const withAuth = (handler) => {
  return (req, res) => {
    req.permissions = role.toObject();
    return handler(req, res);   
  };
};

const handler = roleManager.check<Request,Response>(
    (_req, res) => {
      res.status(200).send('Hello World!');
    },
    {
      resources: 'resource2',
      actions: ['create', 'update'],
      strict: true,
      construct: true, // to use the data from the request to build the role's permissions
      data: async (req)=>{
        return req.permissions
      }
});

export default withAuth(handler);

Save users activity

You can save user activity using the onActivity method on the NextRoleManager

import { Role, Schema } from "@iamjs/core";
import { NextRoleManager } from "@iamjs/next";
import next from "next";

const role = new Role({
  name: "role",
  config: {
    resource1: {
      base: "crudl",
    },
    resource2: {
      base: "cr-dl",
      custom: {
        "create a new user": false,
      },
    },
  },
});

const schema = new Schema({
  roles: { role },
});

const roleManager = new NextRoleManager({
  schema: schema,
  onSuccess: (req, res) => {
    res.status(200).send("Hello World!");
  },
  onError: (err, req, res) => {
    console.error(err);
    res.status(403).send("Forbidden");
  },
  async onActivity(data) {
    console.log(data); // the activity object
  },
});

const withAuth = (handler) => {
  return (req, res) => {
    req.permissions = role.toObject();
    return handler(req, res);
  };
};

const handler = roleManager.check(
  (_req, res) => {
    res.status(200).send("Hello World!");
  },
  {
    resources: "resource2",
    actions: ["create", "update"],
    strict: true,
    construct: true, // to use the data from the request to build the role's permissions
    data: async (req) => {
      return req.permissions;
    },
  }
);

export default withAuth(handler);

The data object contains:

Name Description
actions? The action or actions that are authorized to be executed on the resource
resources? The resource or resources that are authorized to be accessed
role? The role that is used to authorize the request
success? The status of the request
req? The request object

Package Sidebar

Install

npm i @iamjs/next

Weekly Downloads

32

Version

2.0.14

License

MIT

Unpacked Size

32.4 kB

Total Files

9

Last publish

Collaborators

  • triyanox