Keeping track of user activities in Strapi applications is possible with Strapi middleware. Developers can easily configure the Strapi application to log every action performed by each user, either through the admin dashboard or via API, into a custom collection type.
Audit logging is a great way to increase user trust and easily maintain your security policy. It helps with tracking the access history of all users in the system and keeps records of every action performed. It also tracks data that your API sends or receives.
An Introduction to Strapi
Strapi is the leading open-source, headless, customizable Content Management System. With Strapi, developers can easily build simple websites to complex e-commerce platforms like Shopify.
Strapi provides a rich set of features, including authentication and authorization, content management, data import/export, performance monitoring, etc.
Goals
In this tutorial, you'll learn how to:
- Log every activity that occurs within the application dashboard and via the API into a custom collection type(
AuditLog
) using the Strapi lifecycle. - Configure and use the lifecycle to automate action on your Strapi application.
- Create two collection types, Article and AuditLog, whenever a new article is created or updated.
- Store the details log of the article in the AuditLog collection type.
Prerequisites
As a prerequisite to installing Strapi, you must have the following software installed on your computer:
Node.js
v14 or v16npm
oryarn
installed
Strapi Installation
Once you have the above software installed, installing Strapi is simple. On your terminal, enter the following commands:
Yarn command:
yarn create strapi-app audit-log --quickstart
Or
npx command:
npx create-strapi-app audit-log --quickstart.
After the installation is complete, the Strapi app will automatically launch in the browser. Register your details and it will take you to your dashboard page as shown below:
Creating Collection Types
Now, you’ll create two collection types: **Article**
and **AuditLog**
.
Article Collection Type
: This is a simple publication collection type to publish content on a website, with the content details.- To create the Article Collection Type:
- From your dashboard menu, click on Content-Type Builder.
- Click on
Create New Collection Type
. - Enter the display name for the collection type (Articles) .
Click on Continue.
After that, we’ll add the necessary fields as follows:
- Content: (Text - Long Text)
- Author: (Text - Short Text)
- PublishedDate: (Text - Short Text)
- Status: (Text - Short Text)
AuditLog Collection Type
: All activities that occur within the application will be stored in this collection type. To create theauditlog
collection type, follow the same steps as the article collection type above. The AuditLog collection type will contain the following fields:- contentType: (Text - Long Text)
- action: (Text - Long Text)
- content: (JSON)
- author: (JSON)
- request: (JSON)
- method: (Text - Long Text)
- params: (JSON)
Lifecycle Hooks in Strapi
Strapi lifecycle hooks are functions that get triggered when Strapi queries are called. It is used in Strapi application to perform automated actions when managing content through the admin dashboard or via the Strapi API.
Lifecycle hooks can be configured to run before
or after
an event occurs. These two hooks takes the query event as suffix.
Before
hooks are trigger before an event get executed (beforeCreate
,beforeUpdate
,beforeDelete
, e.t.c.) and it can be use to validate or customize content.After
hooks are trigger after an event has been executed(afterCreate
,afterUpdate
,afterDelete
, e.t.c.). This hook can be use for Audit log and Newsletter.
Lifecycle Configuration (Audit Logs)
Now that we know what lifecycles are, we can configure lifecycles in our applications such that when any action is performed on the Article
collection type, we'll log it on the AuditLog collection type.
To get started with the configuration, from your Strapi project root directory, navigate to src/api/article/content-types/article/
and create a lifecycles.js
file.
AfterCreate
The AfterCreate
lifecycle hook is triggered when new content is created from the admin dashboard or via the API. To use AfterCreate, inside the lifecycles.js
file, add the following:
1 module.exports = {
2
3 afterCreate(event) {
4
5 const { result, params } = event;
6 strapi.entityService.create('api::auditlogs.auditlogs, {
7
8 data: {
9
10 contentType: 'Article',
11
12 action:'New Content Entry',
13
14 content:result.Content,
15
16 author:result.createdBy,
17
18 params:params,
19
20 request:event,
21
22
23 },
24
25 });
26
27 },
28 }
The afterCreate
hook has an event object as a parameter, which holds the payload of the request that triggers the hook.
The entityService.create
API is use to create a new entry in the auditlog collection type, this API takes two parameters. The first parameter is the collection type that we want to add a new entry into, while the second parameter is an object that contains the collection type fields and the value to add to them.
AfterUpdate
The AfterUpdate
lifecycle hook is triggered when content or entries are edited from the admin dashboard or via API. With this hook, you can easily track the user who updated the content. To do so, add afterUpdate
hook to the lifecycle hook as follows:
1 afterUpdate(event) {
2
3 const { result, params } = event;
4
5 strapi.entityService.create('api::auditlogs.auditlogs, {
6
7 data: {
8
9 contentType: 'Article',
10
11 action:'Update content',
12
13 content:result.Content,
14
15 author:result.createdBy,
16
17 params:params,
18
19 request:event,
20
21
22
23 },
24
25 });
26 },
AfterDelete
The AfterDelete
lifecycle hook is triggered when a content or entry is deleted. You can configure our Strapi application to log the user's details that delete content. Add and configure the afterDelete
hook in the lifecycle.js as follows:
1 afterDelete(event) {
2
3 const { result, params } = event;
4 strapi.entityService.create('api::auditlogs.auditlogs, {
5 data: {
6
7 contentType: 'Article',
8
9 action:'Delete Content',
10
11 content:result.Content,
12
13 params:params,
14
15 request:event,
16
17
18
19 },
20
21 });
22
23
24 },
AfterFindOne
The AfterFindOne
lifecycle hook is triggered when you search for content using an ID. afterDelete can be configured as follows:
1 afterFindOne(event) {
2
3 const { result, params } = event;
4
5 strapi.entityService.create('api::auditlogs.auditlogs, {
6
7 data: {
8
9 contentType: 'Article',
10
11 action:'sigle Content Search',
12
13 params:params,
14
15 request:event,
16
17
18
19 },
20
21 });
22
23 },
AfterFindMany
The AfterFindMany
lifecycle hook is triggered when you search for a list of content either from the dashboard or via API. afterFindMany
can be configured as follows:
1 afterFindMany(event) {
2
3 const { result, params } = event;
4
5 strapi.entityService.create('api::auditlogs.auditlogs', {
6
7 data: {
8
9 contentType: 'Article',
10
11 action:'Multiple Content Search',
12
13 params:params,
14
15 request:event,
16
17
18
19 },
20
21 });
22
23 },
Now, you have your audit log configured using Strapi lifecycles. To test whether the audit log is working as expected, perform the following actions on the article collection type:
- Create new content.
- Update the content
- Search content.
- Delete content.
After performing any of the actions above, you will see the details of those actions in the auditlog collection type.
Conclusion
In this tutorial, you learned how to use lifecycle hooks for audit logs in the Strapi application. We use the article collection type as an example. You can repeat the steps for all the collection types you want to keep track of.
With audit logs have been configured in our Strapi application, you can easily monitor user activities and trace unwanted content changes in the application. This is a feature already planned to be released, you can follow the Strapi audit logs roadmap for more details.