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

@elastic.io/object-storage-client

Package Overview
Dependencies
Maintainers
9
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@elastic.io/object-storage-client - npm Package Compare versions

Comparing version 0.0.1-dev.4 to 0.0.1-dev.5

16

dist/object-storage.d.ts
/// <reference types="node" />
import { Readable } from 'stream';
interface JWTPayload {
[index: string]: string;
}
export default class ObjectStorage {
private api;
private message;
private jwtSecret;
private static httpAgent;

@@ -10,3 +14,3 @@ private static httpsAgent;

uri: string;
token: string;
jwtSecret: string;
cipher: {

@@ -18,6 +22,8 @@ key: string;

private requestRetry;
getAsJSON(objectId: string): Promise<any>;
getAsStream(objectId: string): Promise<Readable>;
addAsStream(stream: Readable): Promise<string>;
addAsJSON(data: any): Promise<string>;
private getHeaders;
getAsJSON(objectId: string, jwtPayload: JWTPayload): Promise<any>;
getAsStream(objectId: string, jwtPayload: JWTPayload): Promise<Readable>;
addAsStream(stream: Readable, jwtPayload: JWTPayload): Promise<string>;
addAsJSON(data: any, jwtPayload: JWTPayload): Promise<string>;
}
export {};

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

const get_stream_1 = __importDefault(require("get-stream"));
const jsonwebtoken_1 = require("jsonwebtoken");
const util_1 = require("util");
;
class ObjectStorage {

@@ -21,5 +24,5 @@ constructor(config) {

httpsAgent: ObjectStorage.httpsAgent,
headers: { Authorization: `Bearer ${config.token}` },
validateStatus: null
});
this.jwtSecret = config.jwtSecret;
this.message = new message_1.default(config.cipher);

@@ -57,18 +60,22 @@ }

}
async getHeaders(jwtPayload, override) {
const token = await util_1.promisify(jsonwebtoken_1.sign)(jwtPayload, this.jwtSecret);
return Object.assign({ Authorization: `Bearer ${token}` }, override);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async getAsJSON(objectId) {
const content = await get_stream_1.default(await this.getAsStream(objectId));
async getAsJSON(objectId, jwtPayload) {
const content = await get_stream_1.default(await this.getAsStream(objectId, jwtPayload));
return JSON.parse(content);
}
async getAsStream(objectId) {
async getAsStream(objectId, jwtPayload) {
const res = await this.requestRetry({
maxAttempts: 3,
delay: 100,
request: () => this.api.get(`/objects/${objectId}`, { responseType: 'stream' })
request: async () => this.api.get(`/objects/${objectId}`, { responseType: 'stream', headers: await this.getHeaders(jwtPayload) })
});
return this.message.unpackStream(res.data);
}
async addAsStream(stream) {
async addAsStream(stream, jwtPayload) {
let objectId = uuid_1.default.v4();
const res = await this.api.put(`/objects/${objectId}`, this.message.packStream(stream), { headers: { 'content-type': 'application/octet-stream' } });
const res = await this.api.put(`/objects/${objectId}`, this.message.packStream(stream), { headers: await this.getHeaders(jwtPayload, { 'content-type': 'application/octet-stream' }) });
if (res.status >= 400) {

@@ -80,3 +87,3 @@ throw new Error(`HTTP error during object add: ${res.status} (${res.statusText})`);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
async addAsJSON(data) {
async addAsJSON(data, jwtPayload) {
let objectId = uuid_1.default.v4();

@@ -87,7 +94,7 @@ const dataString = JSON.stringify(data);

delay: 100,
request: () => {
request: async () => {
const dataStream = new stream_1.Readable();
dataStream.push(dataString);
dataStream.push(null);
return this.api.put(`/objects/${objectId}`, this.message.packStream(dataStream), { headers: { 'content-type': 'application/octet-stream' } });
return this.api.put(`/objects/${objectId}`, this.message.packStream(dataStream), { headers: await this.getHeaders(jwtPayload, { 'content-type': 'application/octet-stream' }) });
},

@@ -94,0 +101,0 @@ onResponse: (err, res) => {

{
"name": "@elastic.io/object-storage-client",
"version": "0.0.1-dev.4",
"version": "0.0.1-dev.5",
"description": "Elastic.io Message Store Client",

@@ -20,2 +20,3 @@ "main": "dist/index.js",

"get-stream": "5.1.0",
"jsonwebtoken": "8.5.1",
"uuid": "3.3.2"

@@ -27,2 +28,3 @@ },

"@types/chai": "4.1.7",
"@types/jsonwebtoken": "8.3.2",
"@types/mocha": "5.2.7",

@@ -29,0 +31,0 @@ "@types/nock": "10.0.3",

{
"extends": "../.eslintrc.js",
"rules": {
"no-unused-expressions": "off"
"no-unused-expressions": "off",
"@typescript-eslint/ban-ts-ignore": "off"
}
}

@@ -10,2 +10,3 @@ import nock from 'nock';

import { Readable } from 'stream';
import { verify } from 'jsonwebtoken';

@@ -18,3 +19,3 @@ describe('ObjectStorage', () => {

uri: 'https://ma.es.ter',
token: 'jwt',
jwtSecret: 'jwt',
cipher: {

@@ -50,2 +51,12 @@ key: process.env.ELASTICIO_MESSAGE_CRYPTO_PASSWORD,

function authHeaderMatch (jwtPayload?: { [index: string]: string }) {
return (val: string) => {
const decoded = verify(val.split(' ')[1], config.jwtSecret);
if (jwtPayload) {
expect(decoded).to.deep.include(jwtPayload);
}
return decoded;
};
}
describe('data mode', () => {

@@ -57,3 +68,4 @@ it('should fail after 3 retries', async () => {

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.get('/objects/1')

@@ -68,3 +80,3 @@ .replyWithError({ code: 'ETIMEDOUT' })

try {
await objectStorage.getAsJSON('1');
await objectStorage.getAsJSON('1', {});
} catch (e) {

@@ -84,3 +96,4 @@ err = e;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.get('/objects/1')

@@ -93,3 +106,3 @@ .reply(500)

const out = await objectStorage.getAsJSON('1');
const out = await objectStorage.getAsJSON('1', {});

@@ -104,3 +117,4 @@ expect(objectStorageCalls.isDone()).to.be.true;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.put(/^\/objects\/[0-9a-z-]+$/, putData)

@@ -113,3 +127,3 @@ .replyWithError({ code: 'ECONNREFUSED' })

await objectStorage.addAsJSON(data);
await objectStorage.addAsJSON(data, {});

@@ -124,3 +138,4 @@ expect(objectStorageCalls.isDone()).to.be.true;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.matchHeader('content-type', 'application/octet-stream')

@@ -134,7 +149,8 @@ .put(/^\/objects\/[0-9a-z-]+$/, putData)

const urls: string[] = [];
objectStorageCalls.on('request', req => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
objectStorageCalls.on('request', (req: any) => {
urls.push(req.path);
});
await objectStorage.addAsJSON(data);
await objectStorage.addAsJSON(data, {});

@@ -155,3 +171,4 @@ expect(objectStorageCalls.isDone()).to.be.true;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.get('/objects/1')

@@ -166,3 +183,3 @@ .replyWithError({ code: 'ETIMEDOUT' })

try {
await objectStorage.getAsStream('1');
await objectStorage.getAsStream('1', {});
} catch (e) {

@@ -182,3 +199,4 @@ err = e;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.get('/objects/1')

@@ -189,3 +207,3 @@ .reply(500)

const out = JSON.parse(await getStream(await objectStorage.getAsStream('1')));
const out = JSON.parse(await getStream(await objectStorage.getAsStream('1', {})));

@@ -200,3 +218,4 @@ expect(objectStorageCalls.isDone()).to.be.true;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.put(/^\/objects\/[0-9a-z-]+$/, putData)

@@ -207,3 +226,3 @@ .replyWithError({ code: 'ECONNREFUSED' });

try {
await objectStorage.addAsStream(putStream);
await objectStorage.addAsStream(putStream, {});
} catch (e) {

@@ -221,3 +240,4 @@ err = e;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.put(/^\/objects\/[0-9a-z-]+$/, putData)

@@ -228,3 +248,3 @@ .reply(409);

try {
await objectStorage.addAsStream(putStream);
await objectStorage.addAsStream(putStream, {});
} catch (e) {

@@ -242,7 +262,8 @@ err = e;

const objectStorageCalls = nock(config.uri)
.matchHeader('authorization', 'Bearer jwt')
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch())
.put(/^\/objects\/[0-9a-z-]+$/, putData)
.reply(200);
const objectId = await objectStorage.addAsStream(putStream);
const objectId = await objectStorage.addAsStream(putStream, {});

@@ -252,3 +273,19 @@ expect(objectStorageCalls.isDone()).to.be.true;

});
it('should use valid jwt token', async () => {
const objectStorage = new ObjectStorage(config);
const jwtPayload = { tenantId: '12', contractId: '1' };
const objectStorageCalls = nock(config.uri)
// @ts-ignore: Nock .d.ts are outdated.
.matchHeader('authorization', authHeaderMatch(jwtPayload))
.put(/^\/objects\/[0-9a-z-]+$/, putData)
.reply(200);
const objectId = await objectStorage.addAsStream(putStream, jwtPayload);
expect(objectStorageCalls.isDone()).to.be.true;
expect(objectId).to.match(/^[0-9a-z-]+$/);
});
});
});

@@ -9,6 +9,11 @@ import { Readable } from 'stream';

import getStream from 'get-stream';
import { sign } from 'jsonwebtoken';
import { promisify } from 'util';
interface JWTPayload { [index: string]: string };
export default class ObjectStorage {
private api: AxiosInstance;
private message: Message;
private jwtSecret: string;
// you will be able to create a lot of ObjectStorage instances and they will all use single http agent

@@ -18,3 +23,3 @@ private static httpAgent = new http.Agent({ keepAlive: true });

public constructor (config: {uri: string; token: string; cipher: {key: string; iv: string}}) {
public constructor (config: {uri: string; jwtSecret: string; cipher: {key: string; iv: string}}) {
this.api = axios.create({

@@ -24,5 +29,5 @@ baseURL: `${config.uri}/`,

httpsAgent: ObjectStorage.httpsAgent,
headers: { Authorization: `Bearer ${config.token}` },
validateStatus: null
});
this.jwtSecret = config.jwtSecret;
this.message = new Message(config.cipher);

@@ -61,5 +66,10 @@ }

private async getHeaders (jwtPayload: JWTPayload, override?: { [index: string]: string }) {
const token = await promisify(sign)(jwtPayload, this.jwtSecret);
return { Authorization: `Bearer ${token}`, ...override };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async getAsJSON (objectId: string): Promise<any> {
const content = await getStream(await this.getAsStream(objectId));
public async getAsJSON (objectId: string, jwtPayload: JWTPayload): Promise<any> {
const content = await getStream(await this.getAsStream(objectId, jwtPayload));

@@ -69,7 +79,7 @@ return JSON.parse(content);

public async getAsStream (objectId: string): Promise<Readable> {
public async getAsStream (objectId: string, jwtPayload: JWTPayload): Promise<Readable> {
const res = await this.requestRetry({
maxAttempts: 3,
delay: 100,
request: (): Promise<AxiosResponse> => this.api.get(`/objects/${objectId}`, { responseType: 'stream' })
request: async (): Promise<AxiosResponse> => this.api.get(`/objects/${objectId}`, { responseType: 'stream', headers: await this.getHeaders(jwtPayload) })
});

@@ -80,3 +90,3 @@

public async addAsStream (stream: Readable): Promise<string> {
public async addAsStream (stream: Readable, jwtPayload: JWTPayload): Promise<string> {
let objectId = uuid.v4();

@@ -87,3 +97,3 @@

this.message.packStream(stream),
{ headers: { 'content-type': 'application/octet-stream' } });
{ headers: await this.getHeaders(jwtPayload, { 'content-type': 'application/octet-stream' }) });
if (res.status >= 400) {

@@ -97,3 +107,3 @@ throw new Error(`HTTP error during object add: ${res.status} (${res.statusText})`);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async addAsJSON (data: any): Promise<string> {
public async addAsJSON (data: any, jwtPayload: JWTPayload): Promise<string> {
let objectId = uuid.v4();

@@ -105,3 +115,3 @@ const dataString = JSON.stringify(data);

delay: 100,
request: (): Promise<AxiosResponse> => {
request: async (): Promise<AxiosResponse> => {
const dataStream = new Readable();

@@ -113,3 +123,3 @@ dataStream.push(dataString);

this.message.packStream(dataStream),
{ headers: { 'content-type': 'application/octet-stream' } }
{ headers: await this.getHeaders(jwtPayload, { 'content-type': 'application/octet-stream' }) }
);

@@ -116,0 +126,0 @@ },

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