izmjs

IAM

IAM (Identity Access Management) plays the role of a wrapper around express middlewares, IAM is a declarative way to make application routes, they also make it easy to make role-based privileges in your app.

In the /todo folder create a new folder called iam and under /iam create a new file called main.server.iam.js

The folder structure so far should be looking like this:

modules
└── todo
├── bootstraps
│ └── main.server.bootstrap.js
└── iam
└── main.server.iam.js

To declare a new route, you can use the provided snippet to automatically generate it, in your text editor on the main.server.iam.js if you're using vscode text editor type iam and then press TAB.

What IAM does is export an object with some properties:

  • Prefix: the API endpoint routes prefix

  • Routes: an array where we declare our API routes each route is an object where we can specify the path and the http methods to execute on that route

Our first route will have a GET request to list out our todos.

modules/todo/iam/main.server.iam.js
1/**
2 * @type { IAM.default }
3 */
4module.exports = {
5 prefix: "/todo",
6 routes: [
7 {
8 path: "/",
9 methods: {
10 get: {
11 iam: "modules:todo:main:list",
12 title: "List todo",
13 groups: [],
14 parents: ["modules:todo", "modules:todo:main"],
15 description: "List available todo",
16 middlewares: [(req, res) => res.json({ message: "Hello, world" })],
17 },
18 },
19 },
20 ],
21};

To test out our app so far we will be using a popular http client called Postman

Open up postman and make a GET request to http://localhost:<port-number>/api/v1/todo

api get request

at First we'd get a response with a message saying "User is not signed in", Because by default to call our API we must be logged in but to make it simple for this tutorial, all we need to do now is to make the API public by simply going to /config/lib/acl.js and add the iam string to the guest array like the following:

config/lib/acl.js
1/**
2 * Guest role
3 * @type {Array}
4 */
5const guest = ["vendor:users:public", "modules:todo:main"];
6
7/**
8 * User role
9 * @type {Array}
10 */
11
12const user = [
13 /**
14 * Users IAMs
15 */
16 "vendor:users:user",
17 "vendor:users:auth",
18];
19/**
20 * Admin role
21 * @type {Array}
22 */
23const admin = [
24 ...user,
25 /**
26 * Admin IAMs
27 */
28 "vendor:users:admin",
29 "vendor:users:roles",
30];
31/**
32 * All roles
33 */
34module.exports = [
35 {
36 name: "guest",
37 protected: true,
38 title: "Guest role",
39 description:
40 "Role given for any unauthenticated user, or users who don't have any role.",
41 iams: guest,
42 },
43 {
44 name: "user",
45 protected: true,
46 iams: user,
47 title: "User role",
48 description: "The default role.",
49 },
50 {
51 name: "admin",
52 protected: true,
53 iams: admin,
54 title: "Admin role",
55 description: "Given to advanced users.",
56 },
57];

Now let's save and test our app again, it should work as intended now

api get request

We will discuss Roles and IAM in details the next section

Now let's make the rest of the routes necessary for our CRUD

modules/todo/iam/main.server.iam.js
1/**
2 * @type { IAM.default }
3 */
4module.exports = {
5 prefix: '/todo',
6 routes: [
7 {
8 path: '/',
9 methods: {
10 get: {
11 iam: 'modules:todo:main:list',
12 title: 'List todo',
13 groups: [],
14 parents: ['modules:todo', 'modules:todo:main'],
15 description: 'List available todo',
16 middlewares: [(req, res) => res.json({ message: 'Hello, world' })],
17 },
18
19 post: {
20 iam: 'modules:todo:main:create',
21 title: 'Create new task',
22 groups: [],
23 parents: ['modules:todo', 'modules:todo:main'],
24 description: 'Create new task',
25 middlewares: [(req, res) => res.status(201).json({ message: 'Todo Created' })],
26 },
27 },
28 },
29 {
30 path: '/:taskId',
31 methods: {
32 get: {
33 iam: 'modules:todo:main:one:get',
34 title: 'Get task',
35 groups: [],
36 parents: ['modules:todo', 'modules:todo:main'],
37 description: 'Get specific task',
38 middlewares: [(req, res) => res.json({ message: 'got one task' })],
39 },
40 put: {
41 iam: 'modules:todo:main:one:update',
42 title: 'Update task',
43 groups: [],
44 parents: ['modules:todo', 'modules:todo:main'],
45 description: 'Modify task',
46 middlewares: [(req, res) => res.json({ message: 'Updated one task' })],
47 },
48 delete: {
49 iam: 'modules:todo:main:one:remove',
50 title: 'Remove task',
51 groups: [],
52 parents: ['modules:todo', 'modules:todo:main'],
53 description: 'Remove an existing task',
54 middlewares: [(req, res) => res.json({ message: 'deleted one task' })],
55 },
56 },
57 },
58 ],
59};
Edit this page on GitHub