Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

backtrace-service

Package Overview
Dependencies
Maintainers
5
Versions
153
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

backtrace-service

Common tools for Backtrace Node services

  • 1.3.0-beta.0
  • npm
  • Socket score

Version published
Weekly downloads
531
increased by5.57%
Maintainers
5
Weekly downloads
 
Created
Source

Backtrace Service Layer nodejs library

Library of common functions needed for Node.js Backtrace services.

Getting started

$ npm install
$ npm run build
$ npm run test

Then in your code you can include by using

import * as backtrace-service from 'backtrace-service'

or use require instead

const backtraceService = require('backtrace-service');

Service layer integration

To start using Service Layer Integration you have to create new object of a IdentityManager class. After that you can use serviceRequest and authenticateRequest methods.

For an example service implementation, see here.

Service flow

Services are expected to configure one or more authentication tokens, which will be distributed to coronerd instances using the service. While a service is running, it may receive registration requests at ${url_prefix}/service, which enable the service to integrate new coronerd instances on the fly.

Coronerd URLs provided as the url parameter to coronerdCallback are the base URLs, for example, https://backtrace.sp.backtrace.io/. Services may expect to append the appropriate resource for their needs, e.g. /api/config, to reach that resource on the coronerd instance.

What data coronerd will send to service to register? Coronerd via HTTP POST will send in a request body:

  • action - action name (for example register),
  • url - coroner url (for example https://yolo.sp.backtrace.io/)
  • nonce - auth token
  • hmac - Hash Message Authentication Code
Quick Example

TypeScript:

import { ICoronerRequestOption, IdentityManager } from 'backtrace-service';
...

const idm = new IdentityManager(serviceName, serviceSecret);
app.post(
  '/api/{serviceName}/service',
  idm.serviceRequest({
    name: serviceName,
    secret: serviceSecret,
    coronerdCallback: (url: string) => {
      //coroner callback
    },
    logger: logger
  } as ICoronerRequestOption),
);

JavaScript:

const btservice = require('backtrace-service');
const idm = new btservice.IdentityManager(serviceName, serviceSecret);
app.post(
  '${url_prefix}/service',
  idm.serviceRequest({
    name: 'simple',
    secret: 'asdfghjk',
    coronerdCallback: (url) => {
      console.log('heard from coronerd at: ' + url);
    },
  }),
);

Options for serviceRequest

The following options are accepted as the sole argument for the call:

  • name: Name of the service (usually its type).
  • secret: The shared secret that the service will use to authenticate incoming requests and config replies from a coronerd.
  • coronerdCallback: A callback that takes a URL parameter, and performs any service specific setup associated with integrating a new coronerd instance.
  • logger (optional): An object that has a log function which can be logged to. For example, winston logger instances.

authenticateRequest usage

This function is intended as an additional middleware which may be used in application routes to validate requests that involve a session token issued by a remote coronerd. The actual call can reuse the same options argument used for serviceRequest, although it does not use coronerdCallback.

In the route middleware list, prior to authenticateRequest, the application must attach a req.coronerAuth object which contains:

  • url: The full URL to the remote coronerd instance.
  • token: The user's session token to be validated.

For example:

req.coronerAuth = {
  url: "https://backtrace.sp.backtrace.io/",
  token: "f5af46b8eb32adb860ef46a9e714cfde",
}

If req.coronerAuth object is undefined, authenticateRequest method will try to retrieve token and location information from headers. If you prefer to use headers instead of extending request object please set X-Coroner-Token and X-Coroner-Location

This normalized form is used due to the fact that different services take these parameters from clients in different ways.

Middlewares that come after authenticateRequest will have access to the validated coronerd /api/config response in req.coronerAuth.cfg.

Quick Example

Example of sample middleware

TypeScript:

import { ICoronerRequestOption, IdentityManager } from 'backtrace-service';
...

@Middleware({ type: 'before' })
export class AuthMiddleware implements ExpressMiddlewareInterface {
  private readonly _identityManager = new IdentityManager(serviceName, serviceSecret);
  public use(req: express.Request, res: express.Response, next: express.NextFunction): any {
    return this._identityManager.authenticateRequest()(req, res, next);
  }
}

In example above middleware will try to retrieve X-Coroner-Token and X-Coroner-Location from request headers.

JavaScript:

const idm = new btservice.IdentityManager();
// create express app...
// prepare utility method
function prepAuth(req, res, next) {
  const auth = {
    token: req.get('X-Coroner-Token'),
    url: req.get('X-Coroner-Location'),
  };
  req.coronerAuth = auth;
  next();
}

// create application options
const svcOpts = {
  name: 'simple',
  secret: 'asdfghjk',
  coronerdCallback: (url) => {
    log('info', 'heard: ' + url);
  },
  logger: logger,
};

app.post('/api/{name}/{action}', prepAuth, idm.authenticateRequest(svcOpts), (req, res) => {
  res.json(req.coronerAuth);
});

Utils

Backtrace-Service tools offers few utility methods. By using them we want to standarize how we read application configurations/log application messages/create custom auth methods.

Identity Manager

Service Layer Integration using IdentityManager class to provide integrations methods with coronerd. If you want to write auth method to coronerd or check if token is valid you can use methods available in aIdentityManager instance.

Quick Example:
import { IdentityManager } from 'backtrace-service';
const token = //auth token
const universeUrl = //universe url: https://yolo.sp.backtrace.io
const identityManager = new IdentityManager(serviceName, serviceSecret);
// get configuration from coronerd
const configuration = await identityManager.getConfiguration(universeUrl, token);

// validate token
const validToken = await identityManager.isValidToken(universeUrl, token)
loginCoronerd

A service may login to a coronerd via its base URL using this method. This performs a login using the service HMAC exchange, returning a configuration that includes a token usable for service purposes.

const cfg = await identityManager.loginCoronerd("https://foo.sp.backtrace.io");
GetConfiguration

IdentityManager method that allows you to prepare a request to coronerd to retrieve configuration. Please keep in mind, if you're using SL integration, configuration should be available in request.coronerAuth.cfg. GetConfiguration method using Promise API to get data from a server.

IsValidToken

IdentityManager method that allows you to validate token with coronerd. In this case IdentityManager will return boolean information - true if coronerd returns valid configuration, otherwise false. IsValidToken method using Promise API. Please keep in mind to use await or then/catch syntax to get a result from method.

Configuration

Backtrace-Service package allows you to read service configuration file. To standarize paths used in your service to configuration files we suggest to use these methods to easily integrate service with other services.

GetBackupConfig

getBackupConfig fetches a config file provided by the service itself. Path used to read configuration: ${process.cwd()}/${serviceName}.conf

GetProperConfig

getProperConfig fetches from the expected place on the machine (outside the service). Path used to read configuration: /etc/backtrace/${serviceName}/${serviceName}.conf

GetDescriptor

A service can obtain its service integration settings by using getDescriptor, which returns an IServiceDescriptor. It must specify a default port number, to be used in on-premise configurations. It may specify additional default parameters as IDescriptorOpts.

The values returned in the IServiceDescriptor must be used by the service in order to properly integrate. This function generates a descriptor file, if necessary, otherwise it uses what's provided.

const descriptor = getDescriptor('service-name', 12345);
listenDescriptor

This is a helper function that reduces boilerplate by allowing services to listen on the descriptor-specified port in the descriptor-specified manner.

The service must provide its SSL credentials (if it has any) as well as the app to process requests. It is valid for no SSL credentials to pass, although in this case, only descriptors with protocol 'http' will work.

// fill in from config file, parameter is as used by https.createServer().
const credentials = { key: "", cert: "" };
listenDescriptor(descr, app, credentials, () => {
  console.log(`Listening on ${descr.port}`);
});

GetConfig

getConfig fetches configuration from the expected place on the machine (outside the service). If configuration doesn't exists then getConfig method will try to fetch configuration from internal service path Algorithm:

  1. Try to fetch configuration from: /etc/backtrace/${serviceName}/${serviceName}.conf
  2. If configuration from #1 doesn't exists try to read configuration frile from path: ${process.cwd()}/${serviceName}.conf
  3. Return config or undefined

example:

import { getBackupConfig, getProperConfig, getConfig } from 'backtrace-service';

//read backup configuration - service internal configuration
const serviceConf = getBackupConfig('service-name');
//read production configuration - outside service
const prodConf = getProperConfig('service-name');
//get configuration - depends on preferences
const conf = getConfig('service-name');

UniverseHelper

Utility methods that allows you to get more information about Backtrace universe from a url.

getBacktraceHostName

GetBacktraceHostName method allows you to get Backtrace host name from provided urlString. For example - method will return https://yolo.sp.backtrace.io from url https://yolo.sp.backtrace.io/blah/poop/doop?query=123&anotherQuery=nbgaubakgb

getBacktaceUniverseName

GetBacktaceUniverseName method allows you to retrieve a Backtrace universe name. For example: method will return yolo from url https://yolo.sp.backtrace.io or https://submit.backtrace.io/yolo/....

example:

import { UniverseHelper } from 'backtrace-service';

const url = 'https://yolo.sp.backtrace.io/blah?a=1&b=bgj';
const url2 = 'https://submit.backtrace.io/bolo/token/json';

// method below will print a string 'https://yolo.sp.backtrace.io
console.log(UniverseHelper.getBacktraceHostName(url));

//method below will print a string 'bolo
console.log(UnvierseHelper.getBacktraceUniverseName(url2));

Keywords

FAQs

Package last updated on 03 Sep 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc