CAROLINA DOCS


Admin

The "admin" app provides middleware to restrict routes to admin account only, a way to add admin-only routes, and an AdminBro instance.

The Admin Service

When the "admin" service is loaded, it looks for an admin.js file in any installed apps.

It looks for the following exported properties:

  • resources: An array of resources, which will be added to the adminbro instance. You must create them with the reference to the model class from "db" service.
  • labels: An object mapping model classes to the names you want shown in the admin panel.
  • router: An express router which will be mounted at /<admin_app_mount>/<app_name>/ and accessible only to logged-in admin users.
  • adminLinks: A list of objects with link and text properties to be added to the admin landing page menu.

Publishable Template Files

The "admin" app uses 1 template file, which should be published to your project directory using the following command:

node . publish --templates admin

That file (templates/admin/admin_home.pug) is served when visiting the admin page.

Middleware

The "admin" app defines the following named middleware which you can add to routes and access via the "middleware" app.

  • requireAdmin: Depends on "extractUser" and "requireLogin" from the "auth" app. If req.user is not an admin user, a redirect response is set to the login page with the next parameter set to the original destination.

The Admin Routes

The "admin" app provides a router and can be mounted to a route in config/routes.js, preferrably at "/admin".

The admin landing page will be at "/<mount_point>". The adminbro instance will be running at "/<mount_point>/adminbro". Any other apps that have admin routers will be at "/<mount_point>/<app_name>/".

Configuring Admin Bro

AdminBro allows you to specify some details about resources to be managed by the AdminBro interface. To add resources, expose resources from your app's admin.js file. You can expose labels to set their names. You have to use references to the actual model classes.

As an example, here is the admin.js file from the "auth" app, which adds user management to the admin panel and an admin-only router with a handler for changing passwords:


const path = require('path');

const express = require('express');
const asyncHandler = require('express-async-handler');

const AdminBro = require('admin-bro');

const App = require('@carolina/core');

const User = App.$('db').model('User');

// router

const router = express.Router();

router.post('/api/change-password', asyncHandler(async (req, res) => {

const { username, password } = req.body;

let { success, message } = await App.$auth.setPassword(username, password);
return res.json({ success, message });
}));

// admin bro

function changePasswordHandler(req, res, ctx) {

let record = ctx.record;
return {
record: {
...record.toJSON(ctx.currentAdmin),
actionUrl: App.$admin.getAppAdminRoute('auth', '/api/change-password')
}
};
}

let resources = [
{
resource: User,
options: {
listProperties: ['username', 'emailAddress', 'isAdmin', 'isVerified'],
actions: {
changePassword: {
actionType: 'record',
icon: 'Password',
isVisible: true,
handler: changePasswordHandler,
component: AdminBro.bundle(
path.resolve(process.cwd(), 'src', 'auth', 'adminbro', 'user-change-password')
)
}
}
}
}
];

let labels = {
User: "User"
};

module.exports = { router, resources, labels };

Adding Extra Routers

You can expose an express router as router from admin.js. It will be entirely separate from the app's main router from router.js. It will instead be mounted as a subrouter on the "admin" app router.


CAROLINA DOCS