-
Notifications
You must be signed in to change notification settings - Fork 1
/
fs.js
106 lines (88 loc) · 2.7 KB
/
fs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var fs = require('fs-extra');
var pth = require('path');
var dir = require('node-dir');
var express = require('express');
var glob = require('glob');
var _err = function(status, error, error_description) {
return {
status: status,
error: error,
error_description: error_description
}
}
var ERRORS = {
illegal_path: _err(400, 'illegal_path', 'Invalid path syntax.')
}
function FSProvider(options) {
this.root = pth.resolve(options.root || require('os').tmpdir() + "/fsprovider-" + Math.random().toString().substr(2));
fs.ensureDir(this.root);
}
FSProvider.prototype.static = function() {
return express.static(this.root);
}
// ensure that the absolute resolved path is inside the root
FSProvider.prototype.securePath = function(path) {
if (path && typeof(path) === 'string') {
path = pth.join(this.root, path);
} else {
return false;
}
var resolvedPath = pth.resolve(path);
if (resolvedPath.indexOf(this.root) === 0) {
return resolvedPath;
} else {
return false;
}
}
FSProvider.prototype.fullPath = function(path) {
return '/' + pth.relative(this.root, pth.resolve(path));
}
FSProvider.prototype.list = function(path, callback) {
path = this.securePath(path || '/');
if (!path){ callback(ERRORS.illegal_path); return; }
var that = this;
fs.readdir(path, function(err, files) {
if (err){ callback(_err(500, 'unknown_error', err)); return;}
callback(null, files.map(function(file) {
var resolvedPath = pth.join(path, file);
var stat = fs.lstatSync(resolvedPath);
return {
isDirectory: stat.isDirectory(),
isFile: stat.isFile(),
name: pth.basename(file),
fullPath: that.fullPath(resolvedPath)
}
}));
});
}
FSProvider.prototype.glob = function(pattern, callback) {
glob(pattern, {
cwd: this.root,
root: this.root,
}, callback);
}
FSProvider.prototype.writePath = function(path, content, callback) {
path = this.securePath(path);
if (!path){ callback(ERRORS.illegal_path); return; }
fs.outputFile(path, content, callback);
}
FSProvider.prototype.readPath = function(path, callback) {
path = this.securePath(path);
if (!path){ callback(ERRORS.illegal_path); return; }
fs.readFile(path, {encoding: 'utf8'}, callback);
}
FSProvider.prototype.mkdir = function(path, callback) {
path = this.securePath(path);
if (!path){ callback(ERRORS.illegal_path); return; }
fs.mkdirs(path, callback);
}
FSProvider.prototype.rm = function(path, options, callback) {
path = this.securePath(path);
if (!path){ callback(ERRORS.illegal_path); return; }
if (options.recursive) {
fs.remove(path, callback);
} else {
fs.unlink(path, callback);
}
}
module.exports = FSProvider;