Sending audit log events

Install the SDK

pnpm add @auditr-io/sdk-js

Configure the SDK

import Auditr from "@auditr-io/sdk-js";

const auditrSecretKey = process.env.AUDITR_SECRET_KEY ?? "";
const auditr = new Auditr(auditrSecretKey, {
  baseUrl: process.env.AUDITR_API_BASE_URL,
});

Send an event

await auditr.events.createEvent({
  org_id: "org_the-boulder-inc",
  org_name: "The Boulder, Inc",
  action: "person.get",
  action_result: "success",
  actor_type: "user",
  actor_id: "usr_jwayne-dohnson",
  actor_name: "Jwayne Dohnson",
  client_ip: req.ip ?? "",
  user_agent_raw: req.headers["user-agent"] ?? "",
  occurred_at: new Date().toISOString(),
});

Putting it all together

import Auditr from "@auditr-io/sdk-js";
import express from "express";

const PORT = process.env.PORT || 3000;

const auditrSecretKey = process.env.AUDITR_SECRET_KEY ?? "";
const auditr = new Auditr(auditrSecretKey, {
  baseUrl: process.env.AUDITR_API_BASE_URL,
});

const app = express();
app.set("trust proxy", true);
app.use(express.json());

app.get('/persons/:id', async (req, res) => {
  res.json({ id: "usr_twift-saylor", name: "Twift Saylor" });

  await auditr.events.createEvent({
    org_id: "org_the-boulder-inc",
    org_name: "The Boulder, Inc",
    action: "person.get",
    action_result: "success",
    actor_type: "user",
    actor_id: "usr_jwayne-dohnson",
    actor_name: "Jwayne Dohnson",
    client_ip: req.ip ?? "",
    user_agent_raw: req.headers["user-agent"] ?? "",
    occurred_at: new Date().toISOString(),
  });
});

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Displaying audit log events

To display audit log events securely, here are the steps:

  1. Based on the authenticated user, set the filters to restrict access to only the audit logs you allow.
  2. Obtain a token that grants access based on the filters.
  3. Use the token to fetch the audit log events for display.

Add your token API

Create a token API that grants access to audit log events based on the authenticated user.

app.post("/api/tokens", async (req, res) => {
  const tokRes = await fetch(`${process.env.AUDITR_API_BASE_URL}/tokens`, {
    method: "POST",
    headers: new Headers({
      Authorization: `Bearer ${process.env.AUDITR_SECRET_KEY}`,
      "Content-Type": "application/json",
    }),
  });

  if (!tokRes.ok) {
    console.error("error getting token", tokRes.status);
    res.status(500).json();
  }

  const token = await tokRes.json();
  res.json(token);
});

Install the SDK

pnpm add @auditr-io/sdk-react

Import css and component

import "@auditr-io/sdk-react/dist/index.css";
import AuditLogs from "@auditr-io/sdk-react";

Fetch token

async function fetchToken() {
  const res = await fetch(`/api/tokens`, {
    method: "POST",
    headers: new Headers({
      "Content-Type": "application/json",
    }),
    body: JSON.stringify({
      org_id: "org_the-boulder-inc",
      action: "person.get",
    }),
  });

  if (!res.ok) {
    console.error("error getting token", res.status);
    return undefined;
  }

  return await res.json();
}

Display log events

<AuditLogs
  className="logs"
  fetchToken={fetchToken}
  orgId="org_the-boulder-inc"
/>

Putting it all together

import React, { useState, useEffect } from "react";
import "./App.css";
import "@auditr-io/sdk-react/dist/index.css";
import AuditLogs from "@auditr-io/sdk-react";

interface Person {
  id: number;
  name: string;
}

async function fetchToken() {
  const res = await fetch(`/api/tokens`, {
    method: "POST",
    headers: new Headers({
      "Content-Type": "application/json",
    }),
    body: JSON.stringify({
      org_id: "org_the-boulder-inc",
      action: "person.get",
    }),
  });

  if (!res.ok) {
    console.error("error getting token", res.status);
    return undefined;
  }

  return await res.json();
}

function App() {
  const [person, setPerson] = useState<Person | null>(null);

  useEffect(() => {
    fetch("/api/persons/usr_twift-saylor")
      .then((response) => response.json())
      .then((data) => setPerson(data));
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        {person ? <p>Person: {person.name}</p> : <p>Loading...</p>}
      </header>
      <AuditLogs
        className="logs"
        fetchToken={fetchToken}
        orgId="org_the-boulder-inc"
      />
    </div>
  );
}

export default App;