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 - npm Package Compare versions

Comparing version 1.1.13 to 1.2.1

lib/model/descriptor.d.ts

20

lib/config/config.d.ts

@@ -0,1 +1,10 @@

import { IServiceDescriptor } from '../model/descriptor';
export interface ICoronerDescriptor {
name: string;
server: string;
secret: string;
resource: string;
proxy: boolean;
enabled: boolean;
}
/**

@@ -11,3 +20,14 @@ * getBackupConfig fetches a config file provided by the service itself.

export declare function getProperConfig(serviceName: string): object | undefined;
export interface IDescriptorOpts {
server?: string;
resource?: string;
proxy?: boolean;
}
/**
* getDescriptor fetches the service's integration parameters.
* @param serviceName - service name - for example: share/saml/comments
* @param defaultPort - the default port number for the service.
*/
export declare function getDescriptor(serviceName: string, defaultPort: number, opts?: IDescriptorOpts): IServiceDescriptor;
/**
* getConfig fetches from the expected place on the machine (outside the service).

@@ -14,0 +34,0 @@ * If configuration doesn't exists then getConfig method will try to fetch configuration from internal service path

@@ -12,2 +12,5 @@ "use strict";

var log = __importStar(require("../log/log"));
var crypto_1 = require("crypto");
var url = __importStar(require("url"));
;
/**

@@ -45,3 +48,57 @@ * getBackupConfig fetches a config file provided by the service itself.

exports.getProperConfig = getProperConfig;
;
/**
* getDescriptor fetches the service's integration parameters.
* @param serviceName - service name - for example: share/saml/comments
* @param defaultPort - the default port number for the service.
*/
function getDescriptor(serviceName, defaultPort, opts) {
if (opts === void 0) { opts = {}; }
var varprefix = process.env.SERVICE_DESCRIPTOR_VARPREFIX ||
'/var/run/coronerd/services.d';
var varpath = process.env.SERVICE_DESCRIPTOR_VARPATH ||
varprefix + "/" + serviceName + ".json";
var descr = {};
var paths = [];
var i = 0;
if (!process.env.SERVICE_DESCRIPTOR_PATH) {
paths.push("/etc/coronerd/services.d/" + serviceName + ".json");
paths.push(varpath);
}
else {
paths.push(process.env.SERVICE_DESCRIPTOR_PATH);
}
for (; i < paths.length; i++) {
try {
descr = JSON.parse(fs.readFileSync(paths[i], { encoding: 'utf8' }));
break;
}
catch (error) {
}
}
if (i === paths.length) {
log.info("Generating service integration for " + serviceName + " in " + varpath);
descr.name = serviceName;
descr.secret = crypto_1.randomBytes(32).toString('hex');
descr.server = opts.server || "https://0.0.0.0:" + defaultPort;
descr.resource = opts.resource || "/api/" + serviceName;
descr.proxy = opts.proxy === false ? false : true;
descr.enabled = true;
fs.writeFileSync(varpath, JSON.stringify(descr, null, 2));
}
var surl = url.parse(descr.server);
if (!surl.port && surl.protocol !== 'https:')
throw new Error("unspecified port number requires https");
var port = 443;
if (surl.port)
port = parseInt(surl.port);
return {
name: descr.name,
resource: descr.resource,
secret: descr.secret,
port: port,
};
}
exports.getDescriptor = getDescriptor;
/**
* getConfig fetches from the expected place on the machine (outside the service).

@@ -48,0 +105,0 @@ * If configuration doesn't exists then getConfig method will try to fetch configuration from internal service path

23

lib/identity/identity.d.ts
import { NextFunction, Request, Response } from 'express';
import { ICoronerRequestOption } from './model/authRequestOptions';
import { IServerConfiguration } from './model/serverConfiguration';
import { IServiceDescriptor } from '../model/descriptor';
/**

@@ -8,12 +9,8 @@ * Identity manager

export declare class IdentityManager {
name: string;
secret: string;
logger: {
log: (level: string, log: string) => void;
} | undefined;
constructor(name: string, secret: string);
private descr;
private logger;
constructor(descr: IServiceDescriptor);
setLogger(logger: {
log: (level: string, msg: string) => void;
}): void;
private log;
serviceRequest(opts: ICoronerRequestOption): ((request: Request, response: Response, next: NextFunction) => void)[];

@@ -28,2 +25,7 @@ /**

/**
* Login to a coronerd.
* @param Coronerd base URL to login to
*/
loginCoronerd(coronerdUrl: string): Promise<IServerConfiguration | undefined>;
/**
* Check if authtoken is a valid token generated by coronerd

@@ -35,7 +37,2 @@ * @param universeUrl url to coronerd universe

/**
* Login to a coronerd.
* @param Coronerd base URL to login to
*/
loginCoronerd(coronerdUrl: string): Promise<IServerConfiguration | undefined>;
/**
* Get Backtrace configuration

@@ -48,2 +45,4 @@ * @param universeUrl url to coronerd universe

private checkHmac;
private log;
private readCoronerAuthInfo;
}

@@ -49,16 +49,12 @@ "use strict";

var IdentityManager = /** @class */ (function () {
function IdentityManager(name, secret) {
this.name = name;
this.secret = secret;
function IdentityManager(descr) {
this.descr = descr;
this.logger = undefined;
}
IdentityManager.prototype.setLogger = function (logger) {
if (!logger || !logger.log)
if (!logger || !logger.log) {
throw new TypeError('unusable logger passed in');
}
this.logger = logger;
};
IdentityManager.prototype.log = function (level, msg) {
if (this.logger)
this.logger.log(level, msg);
};
/*

@@ -94,3 +90,3 @@ * Generate a middleware handler for Express.js, using options to hook the

}
if (!_this.checkHmac(_this.secret, nonce, hmac)) {
if (!_this.checkHmac(_this.descr.secret, nonce, hmac)) {
responseResult_1.ResponseResult.unauthorized(response);

@@ -123,11 +119,3 @@ return;

return function (request, response, next) {
var data = request.coronerAuth;
if (!data) {
data = {
token: request.get('X-Coroner-Token'),
url: request.get('X-Coroner-Location') || request.get('origin'),
};
request.coronerAuth = data;
}
var url = data.url, token = data.token;
var _a = _this.readCoronerAuthInfo(request), url = _a.url, token = _a.token;
if (!token || !url) {

@@ -138,3 +126,2 @@ _this.log('error', request.ip + ": missing internal params token: " + token + " || url: " + url);

}
// let result: AxiosResponse<IServerConfiguration>;
var prefix = url.endsWith('/') ? '' : '/';

@@ -144,5 +131,5 @@ axios_1.default

headers: {
'X-Service-Name': _this.name,
'X-Service-Name': _this.descr.name,
'X-Coroner-Token': token,
'X-Service-HMAC': _this.generateHmac(_this.secret, token),
'X-Service-HMAC': _this.generateHmac(_this.descr.secret, token),
},

@@ -159,3 +146,3 @@ })

if (!!coronerd_nonce && !!coronerd_hmac) {
if (!_this.checkHmac(_this.secret, coronerd_nonce, coronerd_hmac)) {
if (!_this.checkHmac(_this.descr.secret, coronerd_nonce, coronerd_hmac)) {
responseResult_1.ResponseResult.badRequest(response, 'missing parameters');

@@ -184,20 +171,2 @@ next(new Error('Invalid server generated HMAC'));

/**
* Check if authtoken is a valid token generated by coronerd
* @param universeUrl url to coronerd universe
* @param authToken user token
*/
IdentityManager.prototype.isValidToken = function (universeUrl, authToken) {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getConfiguration(universeUrl, authToken)];
case 1:
result = _a.sent();
return [2 /*return*/, result !== undefined];
}
});
});
};
/**
* Login to a coronerd.

@@ -208,12 +177,16 @@ * @param Coronerd base URL to login to

return __awaiter(this, void 0, void 0, function () {
var requestUrl, nonce, hmac, result;
var prefix, requestUrl, nonce, hmac, result, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
requestUrl = coronerdUrl + "/api/login";
prefix = coronerdUrl.endsWith('/') ? '' : '/';
requestUrl = "" + coronerdUrl + prefix + "api/login";
nonce = crypto_1.randomBytes(32).toString('hex');
hmac = this.generateHmac(this.secret, nonce);
hmac = this.generateHmac(this.descr.secret, nonce);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default.post(requestUrl, null, {
headers: {
'X-Service-Name': this.name,
'X-Service-Name': this.descr.name,
'X-Service-Nonce': nonce,

@@ -223,5 +196,10 @@ 'X-Service-HMAC': hmac,

})];
case 1:
case 2:
result = _a.sent();
return [2 /*return*/, result.status === 200 ? result.data : undefined];
case 3:
err_1 = _a.sent();
this.log('error', "Cannot login to coronerd. Reason " + JSON.stringify(err_1));
return [2 /*return*/, undefined];
case 4: return [2 /*return*/];
}

@@ -232,2 +210,20 @@ });

/**
* Check if authtoken is a valid token generated by coronerd
* @param universeUrl url to coronerd universe
* @param authToken user token
*/
IdentityManager.prototype.isValidToken = function (universeUrl, authToken) {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getConfiguration(universeUrl, authToken)];
case 1:
result = _a.sent();
return [2 /*return*/, result !== undefined];
}
});
});
};
/**
* Get Backtrace configuration

@@ -239,3 +235,3 @@ * @param universeUrl url to coronerd universe

return __awaiter(this, void 0, void 0, function () {
var prefix, requestUrl, result, err_1;
var prefix, requestUrl, result, err_2;
return __generator(this, function (_a) {

@@ -261,3 +257,3 @@ switch (_a.label) {

case 3:
err_1 = _a.sent();
err_2 = _a.sent();
return [2 /*return*/, undefined];

@@ -277,2 +273,18 @@ case 4: return [2 /*return*/];

};
IdentityManager.prototype.log = function (level, msg) {
if (this.logger) {
this.logger.log(level, msg);
}
};
IdentityManager.prototype.readCoronerAuthInfo = function (request) {
var data = request.coronerAuth;
if (!data) {
data = {
token: request.get('X-Coroner-Token'),
url: request.get('X-Coroner-Location') || request.get('origin'),
};
request.coronerAuth = data;
}
return data;
};
return IdentityManager;

@@ -279,0 +291,0 @@ }());

@@ -14,2 +14,2 @@ /**

export { UniverseHelper } from './universe/backtraceUniverseHelper';
export { getBackupConfig, getConfig, getProperConfig } from './config/config';
export { getBackupConfig, getConfig, getDescriptor, getProperConfig } from './config/config';

@@ -23,3 +23,4 @@ "use strict";

exports.getConfig = config_1.getConfig;
exports.getDescriptor = config_1.getDescriptor;
exports.getProperConfig = config_1.getProperConfig;
//# sourceMappingURL=index.js.map

@@ -8,4 +8,4 @@ import { Response } from 'express';

static ok(response: Response): void;
static internalError(response: Response, msg?: string): void;
static internalError(response: Response, msg: string): void;
constructor(msg: string, status?: string);
}

@@ -20,3 +20,5 @@ "use strict";

};
ResponseResult.internalError = function (response, msg) { };
ResponseResult.internalError = function (response, msg) {
response.status(500).send(new ResponseResult(msg, 'error'));
};
return ResponseResult;

@@ -23,0 +25,0 @@ }());

{
"name": "backtrace-service",
"version": "1.1.13",
"version": "1.2.1",
"description": "Common tools for Backtrace Node services",

@@ -52,8 +52,5 @@ "author": "Backtrace",

"nock": "^10.0.6",
"prettier": "^1.17.0",
"ts-jest": "^24.0.2",
"ts-node": "^8.0.3",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.4.4"
}
}

@@ -248,2 +248,17 @@ # Backtrace Service Layer nodejs library

#### 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.
```javascript
const descriptor = getDescriptor('service-name', 12345);
```
### GetConfig

@@ -250,0 +265,0 @@

import * as fs from 'fs';
import * as log from '../log/log';
import { randomBytes } from 'crypto';
import * as url from 'url';
import { IServiceDescriptor } from '../model/descriptor';
/* What coronerd sees; not intended for service consumption. */
export interface ICoronerDescriptor {
name: string,
server: string,
secret: string,
resource: string,
proxy: boolean,
enabled: boolean,
};
/**

@@ -37,4 +50,68 @@ * getBackupConfig fetches a config file provided by the service itself.

export interface IDescriptorOpts {
server?: string,
resource?: string,
proxy?: boolean,
};
/**
* getDescriptor fetches the service's integration parameters.
* @param serviceName - service name - for example: share/saml/comments
* @param defaultPort - the default port number for the service.
*/
export function getDescriptor(serviceName: string, defaultPort: number,
opts: IDescriptorOpts = {}): IServiceDescriptor {
const varprefix = process.env.SERVICE_DESCRIPTOR_VARPREFIX ||
'/var/run/coronerd/services.d';
const varpath = process.env.SERVICE_DESCRIPTOR_VARPATH ||
`${varprefix}/${serviceName}.json`;
let descr: ICoronerDescriptor = <ICoronerDescriptor> {};
let paths = [];
let i = 0;
if (!process.env.SERVICE_DESCRIPTOR_PATH) {
paths.push(`/etc/coronerd/services.d/${serviceName}.json`);
paths.push(varpath);
} else {
paths.push(process.env.SERVICE_DESCRIPTOR_PATH);
}
for (; i < paths.length; i++) {
try {
descr = JSON.parse(fs.readFileSync(paths[i], { encoding: 'utf8' }));
break;
} catch (error) {
}
}
if (i === paths.length) {
log.info(`Generating service integration for ${serviceName} in ${varpath}`);
descr.name = serviceName;
descr.secret = randomBytes(32).toString('hex');
descr.server = opts.server || `https://0.0.0.0:${defaultPort}`;
descr.resource = opts.resource || `/api/${serviceName}`;
descr.proxy = opts.proxy === false ? false : true;
descr.enabled = true;
fs.writeFileSync(varpath, JSON.stringify(descr, null, 2));
}
const surl = url.parse(descr.server);
if (!surl.port && surl.protocol !== 'https:')
throw new Error("unspecified port number requires https");
let port: number = 443;
if (surl.port)
port = parseInt(surl.port);
return {
name: descr.name,
resource: descr.resource,
secret: descr.secret,
port: port,
};
}
/**
* getConfig fetches from the expected place on the machine (outside the service).

@@ -51,2 +128,2 @@ * If configuration doesn't exists then getConfig method will try to fetch configuration from internal service path

return config;
}
}

@@ -12,2 +12,3 @@ import axios from 'axios';

import { IServerConfiguration } from './model/serverConfiguration';
import { IServiceDescriptor } from '../model/descriptor';

@@ -18,23 +19,13 @@ /**

export class IdentityManager {
name: string;
secret: string;
logger: { log: (level: string, log: string) => void } | undefined;
private logger: { log: (level: string, log: string) => void } | undefined = undefined;
constructor(name: string, secret: string) {
this.name = name;
this.secret = secret;
this.logger = undefined;
}
constructor(private descr: IServiceDescriptor) {}
public setLogger(logger: { log: (level: string, msg: string) => void }) {
if (!logger || !logger.log)
if (!logger || !logger.log) {
throw new TypeError('unusable logger passed in');
}
this.logger = logger;
}
private log(level: string, msg: string) {
if (this.logger)
this.logger.log(level, msg);
}
/*

@@ -78,3 +69,3 @@ * Generate a middleware handler for Express.js, using options to hook the

if (!this.checkHmac(this.secret, nonce, hmac)) {
if (!this.checkHmac(this.descr.secret, nonce, hmac)) {
ResponseResult.unauthorized(response);

@@ -110,11 +101,3 @@ return;

return (request: Request, response: Response, next: NextFunction) => {
let data = (request as any).coronerAuth as ICoronerAuth;
if (!data) {
data = {
token: request.get('X-Coroner-Token') as string,
url: (request.get('X-Coroner-Location') as string) || (request.get('origin') as string),
};
(request as any).coronerAuth = data;
}
const { url, token } = data;
const { url, token } = this.readCoronerAuthInfo(request);
if (!token || !url) {

@@ -126,3 +109,2 @@ this.log('error', `${request.ip}: missing internal params token: ${token} || url: ${url}`);

// let result: AxiosResponse<IServerConfiguration>;
const prefix = url.endsWith('/') ? '' : '/';

@@ -132,5 +114,5 @@ axios

headers: {
'X-Service-Name': this.name,
'X-Service-Name': this.descr.name,
'X-Coroner-Token': token,
'X-Service-HMAC': this.generateHmac(this.secret, token),
'X-Service-HMAC': this.generateHmac(this.descr.secret, token),
},

@@ -148,3 +130,3 @@ })

if (!!coronerd_nonce && !!coronerd_hmac) {
if (!this.checkHmac(this.secret, coronerd_nonce, coronerd_hmac)) {
if (!this.checkHmac(this.descr.secret, coronerd_nonce, coronerd_hmac)) {
ResponseResult.badRequest(response, 'missing parameters');

@@ -174,2 +156,26 @@ next(new Error('Invalid server generated HMAC'));

/**
* Login to a coronerd.
* @param Coronerd base URL to login to
*/
public async loginCoronerd(coronerdUrl: string): Promise<IServerConfiguration | undefined> {
const prefix = coronerdUrl.endsWith('/') ? '' : '/';
const requestUrl = `${coronerdUrl}${prefix}api/login`;
const nonce = randomBytes(32).toString('hex');
const hmac = this.generateHmac(this.descr.secret, nonce);
try {
const result = await axios.post<IServerConfiguration>(requestUrl, null, {
headers: {
'X-Service-Name': this.descr.name,
'X-Service-Nonce': nonce,
'X-Service-HMAC': hmac,
},
});
return result.status === 200 ? result.data : undefined;
} catch (err) {
this.log('error', `Cannot login to coronerd. Reason ${JSON.stringify(err)}`);
return undefined;
}
}
/**
* Check if authtoken is a valid token generated by coronerd

@@ -185,22 +191,2 @@ * @param universeUrl url to coronerd universe

/**
* Login to a coronerd.
* @param Coronerd base URL to login to
*/
public async loginCoronerd(
coronerdUrl: string
): Promise<IServerConfiguration | undefined> {
const requestUrl = `${coronerdUrl}/api/login`;
const nonce = randomBytes(32).toString('hex');
const hmac = this.generateHmac(this.secret, nonce);
const result = await axios.post<IServerConfiguration>(requestUrl, null, {
headers: {
'X-Service-Name': this.name,
'X-Service-Nonce': nonce,
'X-Service-HMAC': hmac,
},
});
return result.status === 200 ? result.data : undefined;
}
/**
* Get Backtrace configuration

@@ -240,2 +226,19 @@ * @param universeUrl url to coronerd universe

}
private log(level: string, msg: string) {
if (this.logger) {
this.logger.log(level, msg);
}
}
private readCoronerAuthInfo(request: Request) {
let data = (request as any).coronerAuth as ICoronerAuth;
if (!data) {
data = {
token: request.get('X-Coroner-Token') as string,
url: (request.get('X-Coroner-Location') as string) || (request.get('origin') as string),
};
(request as any).coronerAuth = data;
}
return data;
}
}

@@ -16,2 +16,2 @@ /**

export { UniverseHelper } from './universe/backtraceUniverseHelper';
export { getBackupConfig, getConfig, getProperConfig } from './config/config';
export { getBackupConfig, getConfig, getDescriptor, getProperConfig } from './config/config';

@@ -16,5 +16,7 @@ import { Response } from 'express';

public static internalError(response: Response, msg?: string): void {}
public static internalError(response: Response, msg: string): void {
response.status(500).send(new ResponseResult(msg, 'error'));
}
constructor(public readonly msg: string, public status: string = 'error') {}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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