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

unifile

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unifile - npm Package Compare versions

Comparing version 0.0.52 to 0.0.53

lib/services/open-pages.js

44

lib/default-config.js

@@ -21,3 +21,4 @@ /**

'www',
'ftp'
'ftp',
'open-pages'
];

@@ -40,3 +41,3 @@

{
ROOT : __dirname + '../../www',
ROOT : __dirname + '/../www',
LOGIN_TEMPLATE_PATH: __dirname + '/templates/login-www.jade',

@@ -46,4 +47,4 @@ LOGIN_CSS_PATH: __dirname + '/templates/login.css',

AUTH_FORM_SUBMIT_ROUTE: '/api/v1.0/www-auth-submit',
USERS: {
}
USERS: {
}
}

@@ -57,6 +58,20 @@ /**

LOGIN_CSS_PATH: __dirname + '/templates/login.css',
AUTH_FORM_ROUTE: '/api/v1.0/ftp-auth',
AUTH_FORM_SUBMIT_ROUTE: '/api/v1.0/ftp-auth-submit'
AUTH_FORM_ROUTE: '/api/v1.0/ftp-auth',
AUTH_FORM_SUBMIT_ROUTE: '/api/v1.0/ftp-auth-submit'
}
/**
* Open pages
*/
exports.openPages =
{
ENABLED: false,
LOGIN_TEMPLATE_PATH: __dirname + '/templates/login-open-pages.jade',
LOGIN_CSS_PATH: __dirname + '/templates/login.css',
AUTH_FORM_ROUTE: '/api/v1.0/open-pages-auth',
ROOT : __dirname + '/../open-pages',
AUTH_FORM_SUBMIT_ROUTE: '/api/v1.0/open-pages-auth-submit',
SQLLITE_FILE: __dirname + '/../open-pages/db.sql',
OPEN_PAGES_WEB_ROUTE: '/og', // means that /og/{name}/ is serves the user's folder 'name'
}
/**
* dropbox app config

@@ -108,4 +123,19 @@ */

}
},
'ftp/':{
'connect/':{},
'login/':{},
'logout/':{},
'account/':{},
'exec/':{
'ls/':{},
'rm/':{},
'mkdir/':{},
'cp/':{},
'mv/':{},
'get/':{},
'put/':{}
}
},
'ftp/':{
'open-pages/':{
'connect/':{},

@@ -112,0 +142,0 @@ 'login/':{},

320

lib/services/www.js

@@ -75,2 +75,18 @@ /**

}
exports.getRootPath = function(request, path) {
var resolvedPath = pathModule.resolve(exports.config.ROOT + '/' + path);
return resolvedPath;
}
exports.getSessionObject = function(request) {
return request.session.www_user;
}
exports.setSessionObject = function(request, value) {
request.session.www_user = value;
}
/**

@@ -80,5 +96,5 @@ * @return true if the user is logged in (and connected)

exports.isLoggedIn = function (request) {
if (request.session.www_user)
return true;
return false;
if (exports.getSessionObject(request))
return true;
return false;
}

@@ -89,5 +105,5 @@ /**

exports.isConnected = function (request) {
if (request.session.www_user)
return true;
return false;
if (exports.getSessionObject(request))
return true;
return false;
}

@@ -100,23 +116,23 @@

* Call the provided callback with these parameters
* @return {"success": true, authorize_url: "https://www.dropbox.com/1/oauth/authorize?oauth_token=NMCS862sIG1m6P"}
* @return {"success": false, message: Oups!"}
* @return {'success': true, authorize_url: "https://www.dropbox.com/1/oauth/authorize?oauth_token=NMCS862sIG1m6P"}
* @return {'success': false, message: Oups!"}
*/
exports.connect = function (request, response, next, cbk) {
if (exports.isConnected(request)){
cbk(
{
success:true
, message:'Was already connected. You might want to <a href="../logout/">logout</a> before connecting again.'
}
);
}
else{
cbk(
{
success:true
, message:'Now connected. You probably want to <a href="'+exports.config.AUTH_FORM_ROUTE+'">authenticate</a> now.'
, authorize_url: exports.config.AUTH_FORM_ROUTE
}
);
}
if (exports.isConnected(request)){
cbk(
{
success:true
, message:'Was already connected. You might want to <a href="../logout/">logout</a> before connecting again.'
}
);
}
else{
cbk(
{
success:true
, message:'Now connected. You probably want to <a href="'+exports.config.AUTH_FORM_ROUTE+'">authenticate</a> now.'
, authorize_url: exports.config.AUTH_FORM_ROUTE
}
);
}
}

@@ -127,11 +143,11 @@ /**

* Call the provided callback with this data
* status : {"success": true},
* status : {'success': true},
*/
exports.login = function (request, response, next, cbk) {
if (exports.isLoggedIn(request)){
cbk({success:true});
}
else{
cbk({success:false, code: 401, message: 'User not authorized.'});
}
if (exports.isLoggedIn(request)){
cbk({success:true});
}
else{
cbk({success:false, code: 401, message: 'User not authorized.'});
}
}

@@ -141,19 +157,19 @@ /**

* Call the provided callback with this data
* status : {"success": true},
* status : {'success': true},
*/
exports.logout = function (request, response, next, cbk) {
if (request.session.www_user){
request.session.www_user = undefined;
cbk({success:true, message:"Now logged out."});
}
else{
cbk({success:true, message:"Was not logged in."});
}
if (exports.getSessionObject(request)){
exports.setSessionObject(request, undefined);
cbk({success:true, message:"Now logged out."});
}
else{
cbk({success:true, message:"Was not logged in."});
}
}
exports.errNotLoggedIn = function (cbk) {
cbk({
success:false,
message:"User not connected yet. You need to call the 'login' service first.",
code: 401
});
cbk({
success:false,
message:"User not connected yet. You need to call the 'login' service first.",
code: 401
});
}

@@ -163,18 +179,18 @@ /**

* Call the provided callback with this data
* status : {"success": true},
* data {
* display_name: "Alexandre Hoyau",
* quota_info: {
* available: 5368709120,
* used: 144201723
* }
* status : {'success': true},
* data {
* display_name: "Alexandre Hoyau",
* quota_info: {
* available: 5368709120,
* used: 144201723
* }
*/
exports.getAccountInfo = function (request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
cbk({"success": true},
{
display_name: request.session.www_user.name
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
cbk({'success': true},
{
'display_name': exports.getSessionObject(request).name
});

@@ -188,6 +204,6 @@ }

* List the files of a given folder
* @result an object like this one:
* @result an object like this one:
* {
* "status": {
* "success": true
* 'success': true
* },

@@ -208,3 +224,3 @@ * "data": [

exports.ls = function (path, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
if (!exports.isLoggedIn(request)) {
exports.errNotLoggedIn(cbk);

@@ -214,15 +230,33 @@ return;

var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT+path) + '/';
var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT + path) + '/';
try{
try {
var now = Date.now();
response._headers['etag'] = now;
response._headerNames['etag'] = 'ETag';
// implement weak ETag support based on directory modification times
var etag = request.headers['if-none-match'];
if (etag) {
var dir_mtime = fs.statSync(resolvedPath).mtime.getTime();
var browser_mtime = Number(etag);
if (browser_mtime > dir_mtime && browser_mtime < now) { // cache hit
response._headers['etag'] = etag;
response.statusCode = 304;
response.end("", 'utf-8');
return;
}
}
var filesArray = fs.readdirSync(resolvedPath);
var filesData = [];
for(var idx=0; idx<filesArray.length; idx++){
var file = fs.statSync(resolvedPath+filesArray[idx]);
filesData.push({
bytes: file.size,
modified: file.mtime,
name: filesArray[idx].normalize(),
is_dir: file.isDirectory(),
});
for (var idx = 0; idx < filesArray.length; idx++) {
try {
var file = fs.statSync(resolvedPath + filesArray[idx]);
file.name = filesArray[idx].normalize();
file.is_dir = file.isDirectory();
filesData.push(file);
} catch (e) {
var ignorableErrors = ["EPERM", "ENOENT", "EAGAIN", "EACCES"];
if (ignorableErrors.indexOf(e.code) < 0) throw e;
}
}

@@ -237,69 +271,69 @@ cbk({success:true}, filesData);

* delete a file or folder
* @return an object with this attribute
* @return an object with this attribute
* {
* "status": {"success": true}
* "status": {'success': true}
* }
*/
exports.rm = function (path, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT+path);
fs.unlink(resolvedPath, function (err) {
if (err){
console.error(err);
cbk({success:false, message: err});
}
else
cbk({success:true});
});
var resolvedPath = exports.getRootPath(request, path);
fs.unlink(resolvedPath, function (err) {
if (err){
console.error(err);
cbk({success:false, message: err});
}
else
cbk({success:true});
});
}
/**
* create a folder
* @return an object with this attribute
* @return an object with this attribute
* {
* "status": {"success": true}
* "status": {'success': true}
* }
*/
exports.mkdir = function (path, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT+path);
fs.exists(resolvedPath, function (exists) {
if (!exists){
fs.mkdir(resolvedPath, null, function (error) {
if (error){
cbk({success:false, message: error.code});
}
else{
cbk({success:true});
}
});
}
else{
console.error('mkdir error: folder already exists', resolvedPath);
cbk({success:false, message: 'folder already exists'});
}
});
var resolvedPath = exports.getRootPath(request, path);
fs.exists(resolvedPath, function (exists) {
if (!exists){
fs.mkdir(resolvedPath, null, function (error) {
if (error){
cbk({success:false, message: error.code});
}
else{
cbk({success:true});
}
});
}
else{
console.error('mkdir error: folder already exists', resolvedPath);
cbk({success:false, message: 'folder already exists'});
}
});
}
/**
* Create the give file
* @return an object with this attribute
* @return an object with this attribute
* {
* "status": {"success": true}
* "status": {'success': true}
* }
*/
exports.cp = function (src, dst, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
var resolvedSrc = pathModule.resolve(__dirname, exports.config.ROOT + src);
var resolvedDst = pathModule.resolve(__dirname, exports.config.ROOT + dst);
var resolvedSrc = exports.getRootPath(request, src);
var resolvedDst = exports.getRootPath(request, dst);
// Check that the file exists

@@ -332,12 +366,12 @@ fs.exists(resolvedSrc, function (exists) {

* Move or rename a file or folder
* @return an object with this attribute
* @return an object with this attribute
* {
* "status": {"success": true}
* "status": {'success': true}
* }
*/
exports.mv = function (src, dst, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
exports.cp(src, dst, request, response, next, function(res){

@@ -355,36 +389,36 @@ if (res.success === false){

* Create the give file
* @return an object with this attribute
* @return an object with this attribute
* {
* "status": {"success": true}
* "status": {'success': true}
* }
*/
exports.put = function (path, data, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT+path);
var resolvedPath = exports.getRootPath(request, path);
var file = fs.createWriteStream(resolvedPath);
file.write(data);
var file = fs.createWriteStream(resolvedPath);
file.write(data);
cbk({success:true});
cbk({success:true});
}
/**
* Get the give file, output its content
* @return the content of the file if there is no error
* @return an object with this attribute
* @return the content of the file if there is no error
* @return an object with this attribute
* {
* "status": {"success": false}
* "status": {'success': false}
* }
*/
exports.get = function (path, request, response, next, cbk) {
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
if (!exports.isLoggedIn(request)){
exports.errNotLoggedIn(cbk);
return;
}
var resolvedPath = pathModule.resolve(__dirname, exports.config.ROOT+path);
cbk(undefined, undefined, undefined, resolvedPath);
var resolvedPath = exports.getRootPath(request, path);
cbk(undefined, undefined, undefined, resolvedPath);
}
{
"name": "unifile",
"description": "Express middleware to provide a common API for cloud storage services. ",
"version": "0.0.52",
"version": "0.0.53",
"author": {

@@ -14,2 +14,3 @@ "name": "Alex Hoyau aka lexoyo"

"dependencies": {
"crypto": "0.0.3",
"dbox": "~0.6.3",

@@ -21,2 +22,4 @@ "express": "~4.8.5",

"path": "~0.4.9",
"request": "^2.53.0",
"sqlite3": "^3.1.0",
"unorm": "~1.3.3"

@@ -23,0 +26,0 @@ },

@@ -13,4 +13,5 @@ #Unifile, unified access to cloud storage services.

* Dropbox
* local web server
* see instructions bellow to add a service
* local web server: auth and browse a given folder on the server where unifile is running
* self hosting mode: auth with [Mozilla persona](https://www.mozilla.org/en-US/persona/), choose a name and brose a folder on the server where unifile is installed and which is served as `http(s)://the-unifile-server.com/chosen-name/` - this is an experimental feature which still has to be fine tuned
* extend unifile: see instructions bellow to add a service

@@ -190,2 +191,3 @@ Example

* app keys and sensitive info in env vars
* unit tests for get/put/cat

@@ -192,0 +194,0 @@ * pagination for ls commands?

@@ -23,2 +23,9 @@ /**

// enable open pages
// this is the ""self hosting mode"
// auth with Mozilla persona, choose a name and brose a folder on the server where unifile is installed and which is served as http(s)://the-unifile-server.com/chosen-name/ - this is an experimental feature which still has to be fine tuned
// here you can set all open pages config, see default-config.js
options.openPages.ENABLED = true;
// parse data for file upload

@@ -25,0 +32,0 @@ app.use(options.apiRoot, multipart());

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