Skip to main content
👀 Interested in the latest enterprise backend features of refine? 👉 Join now and get early access!
Version: 4.xx.xx

Audit Log Provider

Overview​

refine allows you to track changes and who made them in your data by sending a new log event record whenever a new record is created, updated or deleted. Mutations made with data hooks are automatically sent to the auditLogProvider as an event. You can also manually send events to the auditLogProvider via hooks.

To use auditLogProvider, you just need to pass it to <Refine>:

App.tsx
import { Refine } from "@refinedev/core";

import auditLogProvider from "./auditLogProvider";

const App: React.FC = () => {
return <Refine auditLogProvider={auditLogProvider} />;
};

An auditLogProvider must have the following methods:

  • create: Logs an event to the audit log.
  • get: Returns a list of events.
  • update: Updates an event in the audit log.

Below are the corresponding interfaces for each of these methods:

const auditLogProvider = {
create: (params: {
resource: string;
action: string;
data?: any;
author?: {
name?: string;
[key: string]: any;
};
previousData?: any;
meta?: Record<string, any>;
}) => void;
get: (params: {
resource: string;
action?: string;
meta?: Record<string, any>;
author?: Record<string, any>;
metaData?: MetaDataQuery;
}) => Promise<any>;
update: (params: {
id: BaseKey;
name: string;
}) => Promise<any>;
}
NOTE

refine provides the useLog and useLogList hooks that can be used to access your auditLogProvider methods from anywhere in your application.

Creating an Audit Log Provider​

Let's create an auditLogProvider to understand how it works better. Though we will be using dataProvider to handle events, you can do it however you want thanks to refine providing an agnostic API.

get​

This method is used to get a list of audit log events.

For example, using the useLogList hook to list all resource activities by a specific record id creates an event like this:

{
"resource": "posts",
"meta": {
"id": "1"
}
}
INFORMATION

The event is created with parameters that were passed to the useLogList hook.

Now let's see how we can handle these events in our audit log provider.

auditLogProvider.ts
import refineSimpleRestDataProvider from "@refinedev/simple-rest";

const API_URL = "https://api.fake-rest.refine.dev";

const dataProvider = refineSimpleRestDataProvider(API_URL);

const auditLogProvider: AuditLogProvider = {
get: async ({ resource, meta }) => {
const { data } = await dataProvider(API_URL).getList({
resource: "logs",
filters: [
{
field: "resource",
operator: "eq",
value: resource,
},
{
field: "meta.id",
operator: "eq",
value: meta?.id,
},
],
});

return data;
},
};

Parameter Types​

This method can take the following parameters via hooks. You can use these parameters to filter the events.

NameType
resourcestring
action"create" | "update" | "delete" | "createMany" | "updateMany" | "deleteMany" | string
metaRecord<string, any>
authorRecord<string, any>

create​

This method is used to create an audit log event. It is triggered when a new successful mutation is made or when you use useLog's log method. The incoming parameters show the values of the new record to be created.

CAUTION

We recommend you create audit logs on the API side for security concerns since the data can be changed on the client side.

When the mutations is successful, the create method is called with the following parameters, depending on the mutation type:

When a record is created, refine automatically sends an event to create method like this:

{
"action": "create",
"resource": "posts",
"data": {
"title": "Hello World",
"content": "Hello World"
},
"meta": {
"dataProviderName": "simple-rest",
// If request response has a `id` field, it will be add in the `meta` field.
"id": 1
}
}
INFORMATION

The id of the created record is added to the meta object and can be used for filtering purposes.

TIP

If getUserIdentity is defined in your auth provider, the author object will be added to the event with the value returned by getUserIdentity.


And here is how we can handle these events in our audit log provider:

auditLogProvider.ts
import refineSimpleRestDataProvider from "@refinedev/simple-rest";

const API_URL = "https://api.fake-rest.refine.dev";

const dataProvider = refineSimpleRestDataProvider(API_URL);

const auditLogProvider: AuditLogProvider = {
create: (params) => {
return dataProvider(API_URL).create({
resource: "logs",
variables: params,
});
},
};

Parameter Types​

This method can take the following parameters.

NameType
resourcestring
action"create" | "update" | "delete" | "createMany" | "updateMany" | "deleteMany" | string
metaRecord<string, any>
dataRecord<string, any>
authorRecord<string, any>

INFORMATION

For more information, refer to the useLog documentation→

update​

This method is used to update an audit log event.

For example, using useLog's log method creates an event like below:

{
"id": "1",
"name": "event name"
}
auditLogProvider.ts
import refineSimpleRestDataProvider from "@refinedev/simple-rest";

const API_URL = "https://api.fake-rest.refine.dev";

const dataProvider = refineSimpleRestDataProvider(API_URL);

const auditLogProvider: AuditLogProvider = {
update: async ({ id, name }) => {
const { data } = await dataProvider(API_URL).update({
resource: "logs",
id,
variables: { name },
});
return data;
},
};
INFORMATION

For more information, refer to the useLog documentation→

Parameter Types​

This method can take the following parameters.

NameType
idBaseKey
namestring

TIP

You can use this hook to name an event and create a milestone.

Supported Hooks​

refine will send specific parameters to the audit log provider's create method when a mutation is successful.

Here are the parameters each hook send to create:

useCreate​

const { mutate } = useCreate();

mutate({
resource: "posts",
values: {
title: "New Post",
status: "published",
content: "New Post Content",
},
metaData: {
foo: "bar",
},
});
Create event
{
"action": "create",
"resource": "posts",
"data": {
"title": "Title",
"status": "published",
"content": "New Post Content"
},
"meta": {
"id": "1",
// `metaData` is included in `meta`.
"foo": "bar"
}
}

useCreateMany​

const { mutate } = useCreateMany();

mutate({
resource: "posts",
values: [
{
title: "Title1",
status: "published",
content: "New Post Content1",
},
{
title: "Title2",
status: "published",
content: "New Post Content2",
},
],
metaData: {
foo: "bar",
},
});
CreateMany event
{
"action": "createMany",
"resource": "posts",
"data": [
{
"title": "Title1",
"status": "published",
"content": "New Post Content1"
},
{
"title": "Title2",
"status": "published",
"content": "New Post Content2"
}
],
"meta": {
"ids": [1, 2],
// `metaData` is included in `meta`.
"foo": "bar"
}
}

useUpdate​

const { mutate } = useUpdate();

mutate({
id: 1,
resource: "posts",
values: {
title: "Updated New Title",
},
});
Update event
{
"action": "update",
"resource": "posts",
"data": {
"title": "Updated New Title",
"status": "published",
"content": "New Post Content"
},
"previousData": {
"title": "Title",
"status": "published",
"content": "New Post Content"
},
"meta": {
"id": 1
}
}

useUpdateMany​

const { mutate } = useUpdateMany();

mutate({
ids: [1, 2],
resource: "posts",
values: {
title: "Updated New Title",
},
});
UpdateMany event
{
"action": "updateMany",
"resource": "posts",
"data": {
"title": "Updated New Title"
},
"previousData": [
{
"title": "Title1"
},
{
"title": "Title2"
}
],
"meta": {
"ids": [1, 2]
}
}

useDelete​

const { mutate } = useDelete();

mutate({
id: 1,
resource: "posts",
});
Delete event
{
"action": "delete",
"resource": "posts",
"meta": {
"id": 1
}
}

useDeleteMany​

const { mutate } = useDeleteMany();

mutate({
ids: [1, 2],
resource: "posts",
});
DeleteMany event
{
"action": "deleteMany",
"resource": "posts",
"meta": {
"ids": [1, 2]
}
}

Enable/Disable to Audit Log by Mutation Type for a Resource​

With meta.audit, you can specify which mutations trigger audit logs; otherwise, all create, update, and delete actions will be logged by default.

For example, if you have the code below, only events will be created for the create mutation.

App.tsx
<Refine
dataProvider={dataProvider(API_URL)}
resources={[
{
name: "posts",
list: PostList,
create: PostCreate,
edit: PostEdit,
show: PostShow,
canDelete: true,
meta: {
audit: ["create"],
},
},
]}
/>

Example​

Run on your local
npm create refine-app@latest -- --example audit-log-provider
Last updated on Jul 19, 2023 by Yıldıray Ünlü