The "admin" app provides middleware to restrict routes to admin account only, a way to add admin-only routes, and an AdminBro instance.
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.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.
The "admin" app defines the following named middleware which you can add to routes and access via the "middleware" app.
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" 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>
/".
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 };
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.