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

fpark

Package Overview
Dependencies
Maintainers
2
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fpark - npm Package Compare versions

Comparing version 0.2.5 to 0.3.0

2

package.json
{
"name": "fpark",
"version": "0.2.5",
"version": "0.3.0",
"main": "index.js",

@@ -5,0 +5,0 @@ "scripts": {

@@ -62,2 +62,11 @@ # Fpark

### Systemd
- Install
```
cd /tmp
curl https://raw.githubusercontent.com/Ideolys/fpark/master/install.sh | sudo bash
```
## Usage

@@ -100,3 +109,3 @@

#### GET /file/:container/:filename
#### GET /file/:filename/container/:container

@@ -110,5 +119,6 @@ The url is **public**.

Query options for the url are:
- `access_key` : access key to get a file for a container. It is mandatory. The key is given at the creation of the container (see Container creation).
- `size` : a valid size in `config.SIZES` to resize on the fly a file of type image.
#### PUT /file/:container/:filename
#### PUT /file/:filename/container/:container

@@ -119,3 +129,3 @@ Put a file with id `filename` to a container `container`.

#### DELETE /file/:container/:filename
#### DELETE /file/:filename/container/:container

@@ -135,3 +145,4 @@ Delete a file given by `filename` from a container `container`.

"container" : "a unique key",
"key" : "public key"
"key" : "public key",
"accessKey" : "a key to access GET /file/:filename"
}

@@ -146,3 +157,3 @@ ```

1. Register a container by calling the API `POST /node/register` **or** put the public key of the container in the keys directory as `container.pub` where `container` is the name of the container to create.
1. Register a container by calling the API `POST /node/register` **or** put the public key of the container in the keys directory as `container.pub` where `container` is the name of the container to create and set an access key for the container in a file as `contaiener.access_key`.
1. Create a JsonWebToken token with the field `aud` equals to the registered `container`.

@@ -149,0 +160,0 @@ 1. Add the token in the header `authorization` as `Authorization: Bearer <token>`.

@@ -19,2 +19,5 @@ const fs = require('fs');

const kittenLogger = require('kitten-logger');
const logger = kittenLogger.createPersistentLogger('del_file');
/**

@@ -34,2 +37,3 @@ * DEL API

if (getHeaderNthNode(req.headers) === 3) {
logger.warn({ msg : 'Depth reached', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
return respond(res, 500);

@@ -44,2 +48,3 @@ }

let proxy = proxyFactory(() => {
logger.warn({ msg : 'cannot proxy' }, { idKittenLogger : req.log_id });
return respond(res, 500);

@@ -58,2 +63,3 @@ });

}, () => {
logger.warn({ msg : 'Cannot proxy' }, { idKittenLogger : req.log_id });
respond(res, 500);

@@ -67,2 +73,3 @@ });

if (err) {
logger.warn({ msg : 'cannot delete', err }, { idKittenLogger : req.log_id });
return respond(res, 404);

@@ -69,0 +76,0 @@ }

@@ -26,2 +26,6 @@

const kittenLogger = require('kitten-logger');
const auth = require('../commons/auth');
const logger = kittenLogger.createPersistentLogger('get_file');
/**

@@ -33,2 +37,3 @@ * Get a file (initialize streams)

* @param {Object} params request's params
* @param {Object} queryParams query parameters
* @param {String} keyNodes path 'node1-node2-node3'

@@ -38,5 +43,6 @@ * @param {Array} streams

*/
function getFile (CONFIG, req, res, params, keyNodes, streams, handler) {
function getFile (CONFIG, req, res, params, queryParams, keyNodes, streams, handler) {
function handlerError (err) {
if (getHeaderNthNode(req.headers) === 3 || getHeaderFromNode(req.headers)) {
logger.warn({ msg : 'Depth reached', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
return respond(res, 404);

@@ -52,11 +58,7 @@ }

if (isImage(extensionWithoutDot) && req.url) {
let query = url.parse(req.url).search;
let sizeId = queryParams.get('size');
let size = getSize(CONFIG, sizeId);
if (query) {
let sizeId = new URLSearchParams(url.parse(req.url).search).get('size');
let size = getSize(CONFIG, sizeId);
if (size) {
streams.unshift(resize(CONFIG, sizeId));
}
if (size) {
streams.unshift(resize(CONFIG, sizeId));
}

@@ -80,85 +82,90 @@ }

exports.getApi = function getApi (req, res, params, store) {
let nodes = repartition.getNodesToPersistTo(params.id, store.CONFIG.NODES, store.CONFIG.REPLICATION_NB_REPLICAS);
let isAllowedToWrite = repartition.isCurrentNodeInPersistentNodes(nodes, store.CONFIG.ID);
auth.verifyAccessKey(req, res, params, queryParams => {
let nodes = repartition.getNodesToPersistTo(params.id, store.CONFIG.NODES, store.CONFIG.REPLICATION_NB_REPLICAS);
let isAllowedToWrite = repartition.isCurrentNodeInPersistentNodes(nodes, store.CONFIG.ID);
if (!isAllowedToWrite && nodes.length) {
if (getHeaderNthNode(req.headers) === 3) {
return respond(res, 404);
}
return queue(nodes, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
if (!isAllowedToWrite && nodes.length) {
if (getHeaderNthNode(req.headers) === 3) {
logger.warn({ msg : 'Depth reached', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
return respond(res, 404);
}
let proxy = proxyFactory(() => {
return respond(res, 404);
});
return queue(nodes, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
}
let headers = {};
setHeaderNthNode(headers, req.headers);
setHeaderCurrentNode(headers, store.CONFIG.ID);
let proxy = proxyFactory(() => {
return respond(res, 404);
});
proxy(req, res, {
selfHandleResponse : true,
target : node.host,
headers
let headers = {};
setHeaderNthNode(headers, req.headers);
setHeaderCurrentNode(headers, store.CONFIG.ID);
proxy(req, res, {
selfHandleResponse : true,
target : node.host,
headers
});
}, () => {
logger.warn({ msg : 'Cannot proxy', }, { idKittenLogger : req.log_id });
respond(res, 500);
});
}, () => {
respond(res, 500);
});
}
}
let keyNodes = repartition.flattenNodes(nodes);
let keyNodes = repartition.flattenNodes(nodes);
res.setHeader('Cache-Control', 'max-age=' + store.CONFIG.CACHE_CONTROL_MAX_AGE + ',immutable');
res.setHeader('Content-Encoding', 'gzip');
res.setHeader('Cache-Control', 'max-age=' + store.CONFIG.CACHE_CONTROL_MAX_AGE + ',immutable');
res.setHeader('Content-Encoding', 'gzip');
getFile(store.CONFIG, req, res, params, keyNodes, [zlib.createGzip()], () => {
if (!nodes.length) {
return respond(res, 404);
}
let headers = {
'accept-encoding' : 'gzip'
};
setHeaderCurrentNode(headers, store.CONFIG.ID);
// Try to get file from another node
// Save it
// Serve it
queue(nodes, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
getFile(store.CONFIG, req, res, params, queryParams, keyNodes, [zlib.createGzip()], () => {
if (!nodes.length) {
return respond(res, 404);
}
setHeaderNthNode(headers);
let _req = {
method : 'GET',
headers,
let headers = {
'accept-encoding' : 'gzip'
};
setHeaderCurrentNode(headers, store.CONFIG.ID);
fetch(node.host + req.url, _req).then((resRequest) => {
if (resRequest.status !== 200) {
// Try to get file from another node
// Save it
// Serve it
queue(nodes, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
}
putFile(resRequest.body, params, store, keyNodes, null, err => {
if (err) {
return respond(res, 500);
setHeaderNthNode(headers);
let _req = {
method : 'GET',
headers,
};
fetch(node.host + req.url, _req).then((resRequest) => {
if (resRequest.status !== 200) {
return next();
}
getFile(store.CONFIG, _req, res, params, keyNodes, [], () => {
respond(res, 404);
putFile(resRequest.body, params, store, keyNodes, null, err => {
if (err) {
logger.warn({ msg : 'Cannot get file', err }, { idKittenLogger : req.log_id });
return respond(res, 500);
}
getFile(store.CONFIG, _req, res, params, queryParams, keyNodes, [], () => {
respond(res, 404);
});
});
}).catch(() => {
next();
});
}).catch(() => {
next();
}, () => {
// No file has been found
respond(res, 404);
});
}, () => {
// No file has been found
respond(res, 404);
});
});
}

@@ -12,5 +12,5 @@ const { putApi } = require('./put');

function load (router, store) {
router.on('GET' , '/file/container/:containerId/:id', getApi, store);
router.on('PUT' , '/file/container/:containerId/:id', putApi, store);
router.on('DELETE', '/file/container/:containerId/:id', delApi, store);
router.on('GET' , '/file/:id/container/:containerId', getApi, store);
router.on('PUT' , '/file/:id/container/:containerId', putApi, store);
router.on('DELETE', '/file/:id/container/:containerId', delApi, store);

@@ -17,0 +17,0 @@ if (store.CONFIG.IS_REGISTRATION_ENABLED) {

@@ -25,3 +25,3 @@ const fs = require('fs');

if (!_body.container || !_body.key) {
if (!_body.container || !_body.key || !_body.accessKey) {
return respond(res, 400);

@@ -39,36 +39,42 @@ }

setKey(_body.container, _body.key);
fs.writeFile(path.join(store.CONFIG.KEYS_DIRECTORY, _body.container + '.access_key'), _body.accessKey, { flag : 'wx' }, (err) => {
if (err) {
return respond(res, 500);
}
if (getHeaderFromNode(req.headers)) {
return respond(res, 200);
}
setKey(_body.container, _body.key);
queue(store.CONFIG.NODES, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
if (getHeaderFromNode(req.headers)) {
return respond(res, 200);
}
let headers = {
'Content-Type' : 'application/json'
};
setHeaderCurrentNode(headers);
queue(store.CONFIG.NODES, (node, next) => {
if (node.id === store.CONFIG.ID) {
return next();
}
let _req = {
method : 'POST',
headers,
body
};
let headers = {
'Content-Type' : 'application/json'
};
setHeaderCurrentNode(headers);
fetch(node.host + req.url, _req).then((resRequest) => {
if (resRequest.status !== 200) {
let _req = {
method : 'POST',
headers,
body
};
fetch(node.host + req.url, _req).then((resRequest) => {
if (resRequest.status !== 200) {
return respond(res, 500);
}
next();
}).catch(() => {
return respond(res, 500);
}
next();
}).catch(() => {
return respond(res, 500);
});
}, () => {
// No file has been found
respond(res, 200);
});
}, () => {
// No file has been found
respond(res, 200);
});

@@ -75,0 +81,0 @@ });

@@ -32,2 +32,5 @@ const fs = require('fs');

const kittenLogger = require('kitten-logger');
const logger = kittenLogger.createPersistentLogger('put_file');
/**

@@ -112,2 +115,3 @@ * PUT a file

if (getHeaderNthNode(req.headers) === 3) {
logger.warn({ msg : 'Depth reached', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
return respond(res, 500);

@@ -122,2 +126,3 @@ }

let proxy = proxyFactory(() => {
logger.warn({ msg : 'Cannot proxy', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
return respond(res, 500);

@@ -136,2 +141,3 @@ });

}, () => {
logger.warn({ msg : 'Cannot proxy', from : getHeaderFromNode(req.headers) }, { idKittenLogger : req.log_id });
respond(res, 500);

@@ -171,2 +177,3 @@ });

if (err) {
logger.warn({ msg : 'Cannot put file', err }, { idKittenLogger : req.log_id });
return respond(res, 500);

@@ -217,2 +224,3 @@ }

busboy.on('error' , err => {
logger.warn({ msg : 'Cannot put file', err }, { idKittenLogger : req.log_id });
respond(res, 500);

@@ -219,0 +227,0 @@ });

const path = require('path');
const fs = require('fs');
const cluster = require('cluster');
const url = require('url');
const jwt = require('jsonwebtoken');

@@ -12,3 +13,5 @@ const cache = require('kitten-cache');

const PUBLIC_KEY_FILE_EXTENSION = '.pub';
const ACCESS_KEY_FILE_EXTENSION = '.access_key';
const keys = {};
const accessKeys = {};

@@ -111,2 +114,34 @@ if (cluster.isMaster) {

/**
* Verify accessKey
* @param {Object} req
* @param {Object} res
* @param {Object} params request parameters
* @param {Function} callback
*/
verifyAccessKey (req, res, params, callback) {
let query = url.parse(req.url).search;
if (!query) {
return respond(res, 401);
}
let queryParams = new URLSearchParams(query);
if (!queryParams.has('access_key')) {
return respond(res, 401);
}
let containerAccessKey = queryParams.get('access_key');
if (!accessKeys[params.containerId]) {
return respond(res, 401);
}
if (accessKeys[params.containerId] !== containerAccessKey) {
return respond(res, 401);
}
callback(queryParams);
},
/**
* Load ECDH keys

@@ -126,3 +161,3 @@ * @param {String} directory path to ECDH keys directory

let _filename = path.basename(file, PUBLIC_KEY_FILE_EXTENSION);
let _filename = path.basename(file, PUBLIC_KEY_FILE_EXTENSION);
fs.readFile(path.join(directory, file), (err, file) => {

@@ -138,4 +173,32 @@ if (err) {

});
}
},
/**
* Load Access keys
* @param {String} directory path to access keys directory (sameas keys)
*/
loadAccessKeys : function (directory, callback) {
fs.readdir(directory, (err, files) => {
if (err) {
return callback(err);
}
queue(files, (file, next) => {
if (path.extname(file) !== ACCESS_KEY_FILE_EXTENSION) {
return next();
}
let _filename = path.basename(file, ACCESS_KEY_FILE_EXTENSION);
fs.readFile(path.join(directory, file), (err, file) => {
if (err) {
return next();
}
accessKeys[_filename] = file.toString().trim();
next();
});
}, callback);
});
},
}

@@ -79,8 +79,3 @@ const http = require('http');

server = http.createServer((req, res) => {
logger(req, res);
router.lookup(req, res);
});
server.listen(CONFIG.SERVER_PORT, err => {
auth.loadAccessKeys(path.join(process.cwd(), CONFIG.KEYS_DIRECTORY), err => {
if (err) {

@@ -90,3 +85,14 @@ throw err;

console.log('Server listening on: http://localhost:' + CONFIG.SERVER_PORT);
server = http.createServer((req, res) => {
logger(req, res);
router.lookup(req, res);
});
server.listen(CONFIG.SERVER_PORT, err => {
if (err) {
throw err;
}
console.log('Server listening on: http://localhost:' + CONFIG.SERVER_PORT);
});
});

@@ -93,0 +99,0 @@ });

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