JSPM

untamper-sdk

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q73126F
  • License MIT

Official Node.js SDK for unTamper - Enterprise audit logging platform

Package Exports

  • untamper-sdk

Readme

unTamper Node.js SDK

npm version Node.js Version TypeScript

Official Node.js SDK for unTamper - Enterprise audit logging platform for secure, write-once-read-only audit logs.

Features

  • ๐Ÿš€ Fast & Reliable: Optimized for high-performance log ingestion
  • ๐Ÿ”’ Type-Safe: Full TypeScript support with comprehensive type definitions
  • ๐Ÿ”„ Auto-Retry: Built-in retry logic with exponential backoff
  • ๐Ÿ›ก๏ธ Error Handling: Comprehensive error handling with custom error classes
  • ๐Ÿ“ฆ Zero Dependencies: Minimal footprint with no external runtime dependencies
  • ๐Ÿงช Well Tested: Comprehensive test suite with 100% coverage
  • ๐Ÿ”ง Developer Friendly: Easy configuration and debugging support

Installation

npm install @untamper/sdk-node

Quick Start

import { UnTamperClient } from '@untamper/sdk-node';

// Initialize the client
const client = new UnTamperClient({
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
  // For development, you can override the base URL
  baseUrl: 'http://localhost:3000',
});

// Log an audit event
const response = await client.logs.ingestLog({
  action: 'user.login',
  actor: {
    id: 'user123',
    type: 'user',
    display_name: 'John Doe',
  },
  result: 'SUCCESS',
  context: {
    request_id: 'req_123456',
    session_id: 'sess_789012',
  },
  metadata: {
    version: '1.0.0',
    environment: 'production',
  },
});

console.log('Log ingested:', response.ingestId);

Configuration

Required Settings

  • projectId: Your project identifier
  • apiKey: Your project API key

Optional Settings

  • baseUrl: API base URL (defaults to production, allows dev override)
  • timeout: Request timeout in milliseconds (default: 30000)
  • retryAttempts: Number of retry attempts (default: 3)
  • retryDelay: Delay between retries in milliseconds (default: 1000)
const client = new UnTamperClient({
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
  baseUrl: 'http://localhost:3000', // For development
  timeout: 10000,
  retryAttempts: 5,
  retryDelay: 2000,
});

API Reference

Log Ingestion

client.logs.ingestLog(request)

Ingests a single audit log.

const response = await client.logs.ingestLog({
  action: 'document.update',
  actor: {
    id: 'user123',
    type: 'user',
    display_name: 'John Doe',
  },
  target: {
    id: 'doc456',
    type: 'document',
    display_name: 'Important Document',
  },
  result: 'SUCCESS',
  changes: [
    {
      path: 'title',
      old_value: 'Old Title',
      new_value: 'New Title',
    },
  ],
  context: {
    request_id: 'req_123',
    client: 'web-app',
  },
  metadata: {
    feature: 'document-editor',
    version: '2.1.0',
  },
});

client.logs.ingestLogs(requests)

Ingests multiple audit logs in batch.

const responses = await client.logs.ingestLogs([
  { action: 'user.login', actor: { id: 'user1', type: 'user' } },
  { action: 'user.logout', actor: { id: 'user2', type: 'user' } },
]);

client.logs.checkIngestionStatus(ingestId)

Checks the status of a previously submitted audit log.

const status = await client.logs.checkIngestionStatus('ingest_123');
console.log('Status:', status.status); // PENDING, PROCESSING, COMPLETED, FAILED, RETRYING

client.logs.waitForCompletion(ingestId, options)

Waits for an ingestion to complete with polling.

const status = await client.logs.waitForCompletion('ingest_123', {
  pollInterval: 1000, // Check every 1 second
  maxWaitTime: 30000, // Wait up to 30 seconds
});

Queue Management

client.queue.getQueueStats()

Gets queue statistics.

const stats = await client.queue.getQueueStats();
console.log('Total items:', stats.data?.total);
console.log('By status:', stats.data?.byStatus);

client.queue.triggerQueueProcessing()

Triggers manual queue processing.

const result = await client.queue.triggerQueueProcessing();
console.log('Processing triggered:', result.message);

Error Handling

The SDK provides comprehensive error handling with custom error classes:

import { 
  UnTamperError,
  AuthenticationError,
  ValidationError,
  NetworkError,
  RateLimitError,
  ServerError,
  ConfigurationError,
} from '@untamper/sdk-node';

try {
  await client.logs.ingestLog(request);
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid request:', error.message, error.details);
  } else if (error instanceof AuthenticationError) {
    console.error('Authentication failed:', error.message);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited:', error.message);
  } else if (error instanceof ServerError) {
    console.error('Server error:', error.message);
  } else if (error instanceof UnTamperError) {
    console.error('unTamper error:', error.message, error.code);
  } else {
    console.error('Unexpected error:', error);
  }
}

TypeScript Support

The SDK is built with TypeScript and provides full type safety:

import { 
  UnTamperClient,
  LogIngestionRequest,
  LogIngestionResponse,
  Actor,
  Target,
  ActionResult,
} from '@untamper/sdk-node';

const request: LogIngestionRequest = {
  action: 'user.login',
  actor: {
    id: 'user123',
    type: 'user',
    display_name: 'John Doe',
  },
  result: 'SUCCESS' as ActionResult,
};

Examples

Express.js Middleware

import express from 'express';
import { UnTamperClient } from '@untamper/sdk-node';

const client = new UnTamperClient({
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
});

function auditLogMiddleware(req: express.Request, res: express.Response, next: express.NextFunction) {
  const originalSend = res.send;
  const startTime = Date.now();

  res.send = function(body: any) {
    const duration = Date.now() - startTime;
    
    // Log the request asynchronously
    client.logs.ingestLog({
      action: `${req.method.toLowerCase()}.${req.path}`,
      actor: {
        id: (req as any).user?.id || 'anonymous',
        type: (req as any).user ? 'user' : 'system',
      },
      result: res.statusCode < 400 ? 'SUCCESS' : 'FAILURE',
      context: {
        method: req.method,
        url: req.url,
        status_code: res.statusCode,
        duration_ms: duration,
      },
    }).catch(console.error);

    return originalSend.call(this, body);
  };

  next();
}

const app = express();
app.use(auditLogMiddleware);

Batch Processing

// Process multiple events
const events = [
  { action: 'user.login', actor: { id: 'user1', type: 'user' } },
  { action: 'user.logout', actor: { id: 'user2', type: 'user' } },
  { action: 'document.create', actor: { id: 'user3', type: 'user' } },
];

const responses = await client.logs.ingestLogs(events);
console.log(`Processed ${responses.length} events`);

// Wait for all to complete
const statuses = await Promise.all(
  responses.map(response => 
    client.logs.waitForCompletion(response.ingestId!)
  )
);

Development

Prerequisites

  • Node.js 16.0.0 or higher
  • npm or yarn

Setup

git clone https://github.com/untamper/sdk-node.git
cd sdk-node
npm install

Building

npm run build

Testing

npm test
npm run test:coverage

Linting

npm run lint
npm run lint:fix

Requirements

  • Node.js: 16.0.0 or higher
  • TypeScript: 4.0 or higher (for TypeScript projects)

License

MIT License - see LICENSE file for details.

Support

Contributing

We welcome contributions! Please see our Contributing Guide for details.


Made with โค๏ธ by the unTamper team