aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--app/index.html25
-rw-r--r--app/js/app.js33
-rw-r--r--src/files.js21
-rw-r--r--src/multipart.js2
4 files changed, 74 insertions, 7 deletions
diff --git a/app/index.html b/app/index.html
index cf1f399..ea14bc1 100644
--- a/app/index.html
+++ b/app/index.html
@@ -49,6 +49,29 @@
49 </div> 49 </div>
50 </div> 50 </div>
51 51
52 <div class="modal fade" tabindex="-1" role="dialog" id="modalcreateDirectory">
53 <div class="modal-dialog">
54 <div class="modal-content">
55 <div class="modal-header">
56 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
57 <h4 class="modal-title">New Directory Name</h4>
58 </div>
59 <div class="modal-body">
60 <form v-on:submit.prevent="createDirectory(createDirectoryData)">
61 <div class="form-group">
62 <input type="text" class="form-control" v-model="createDirectoryData" placeholder="Name">
63 </div>
64 <button type="submit" style="display: none;"></button>
65 </form>
66 </div>
67 <div class="modal-footer">
68 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
69 <button type="button" class="btn btn-primary" v-on:click="createDirectory(createDirectoryData)">Create</button>
70 </div>
71 </div>
72 </div>
73 </div>
74
52 <div class="container" v-show="busy" v-cloak> 75 <div class="container" v-show="busy" v-cloak>
53 <div class="row"> 76 <div class="row">
54 <div class="col-lg-12"> 77 <div class="col-lg-12">
@@ -126,7 +149,7 @@
126 </table> 149 </table>
127 </div> 150 </div>
128 <div class="col-lg-12" style="text-align: right;"> 151 <div class="col-lg-12" style="text-align: right;">
129 <button class="btn btn-default btn-sm" v-on:click="">Create Directory</button> 152 <button class="btn btn-default btn-sm" v-on:click="createDirectoryAsk()">Create Directory</button>
130 </div> 153 </div>
131 </div> 154 </div>
132 </div> 155 </div>
diff --git a/app/js/app.js b/app/js/app.js
index 823e4f7..c0ed616 100644
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -79,9 +79,12 @@ function up() {
79} 79}
80 80
81function upload() { 81function upload() {
82 $(app.$els.upload).change(function () { 82 $(app.$els.upload).on('change', function () {
83 app.busy = true; 83 app.busy = true;
84 84
85 // detach event handler
86 $(app.$els.upload).off('change');
87
85 var file = app.$els.upload.files[0]; 88 var file = app.$els.upload.files[0];
86 var path = encode(sanitize(app.path + '/' + file.name)); 89 var path = encode(sanitize(app.path + '/' + file.name));
87 90
@@ -123,6 +126,29 @@ function del(entry) {
123 }); 126 });
124} 127}
125 128
129function createDirectoryAsk() {
130 $('#modalcreateDirectory').modal('show');
131 app.createDirectoryData = '';
132}
133
134function createDirectory(name) {
135 app.busy = true;
136
137 var path = encode(sanitize(app.path + '/' + name));
138
139 superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
140 app.busy = false;
141
142 if (error) return console.error(error);
143 if (result.statusCode !== 201) return console.error('Error creating directory: ', result.statusCode);
144
145 app.createDirectoryData = '';
146 refresh();
147
148 $('#modalcreateDirectory').modal('hide');
149 });
150}
151
126var app = new Vue({ 152var app = new Vue({
127 el: '#app', 153 el: '#app',
128 data: { 154 data: {
@@ -134,6 +160,7 @@ var app = new Vue({
134 }, 160 },
135 loginData: {}, 161 loginData: {},
136 deleteData: {}, 162 deleteData: {},
163 createDirectoryData: '',
137 entries: [] 164 entries: []
138 }, 165 },
139 methods: { 166 methods: {
@@ -144,7 +171,9 @@ var app = new Vue({
144 up: up, 171 up: up,
145 upload: upload, 172 upload: upload,
146 delAsk: delAsk, 173 delAsk: delAsk,
147 del: del 174 del: del,
175 createDirectoryAsk: createDirectoryAsk,
176 createDirectory: createDirectory
148 } 177 }
149}); 178});
150 179
diff --git a/src/files.js b/src/files.js
index 520127d..68dfea3 100644
--- a/src/files.js
+++ b/src/files.js
@@ -54,6 +54,13 @@ function copyFile(source, target, cb) {
54 }); 54 });
55} 55}
56 56
57function createDirectory(targetPath, callback) {
58 mkdirp(targetPath, function (error) {
59 if (error) return callback(error);
60 callback(null);
61 });
62}
63
57function getAbsolutePath(filePath) { 64function getAbsolutePath(filePath) {
58 var absoluteFilePath = path.resolve(path.join(gBasePath, filePath)); 65 var absoluteFilePath = path.resolve(path.join(gBasePath, filePath));
59 66
@@ -103,7 +110,8 @@ function get(req, res, next) {
103function put(req, res, next) { 110function put(req, res, next) {
104 var filePath = req.params[0]; 111 var filePath = req.params[0];
105 112
106 if (!req.files.file) return next(new HttpError(400, 'missing file')); 113 if (!(req.files && req.files.file) && !req.query.directory) return next(new HttpError(400, 'missing file or directory'));
114 if ((req.files && req.files.file) && req.query.directory) return next(new HttpError(400, 'either file or directory'));
107 115
108 var absoluteFilePath = getAbsolutePath(filePath); 116 var absoluteFilePath = getAbsolutePath(filePath);
109 if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); 117 if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed'));
@@ -111,10 +119,17 @@ function put(req, res, next) {
111 fs.stat(absoluteFilePath, function (error, result) { 119 fs.stat(absoluteFilePath, function (error, result) {
112 if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); 120 if (error && error.code !== 'ENOENT') return next(new HttpError(500, error));
113 121
114 debug('put', absoluteFilePath, req.files.file); 122 debug('put', absoluteFilePath);
115 123
124 if (result && req.query.directory) return next(new HttpError(409, 'name already exists'));
116 if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); 125 if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories'));
117 if (!result || result.isFile()) { 126
127 if (req.query.directory) {
128 return createDirectory(absoluteFilePath, function (error) {
129 if (error) return next(new HttpError(500, error));
130 next(new HttpSuccess(201, {}));
131 });
132 } else if (!result || result.isFile()) {
118 return copyFile(req.files.file.path, absoluteFilePath, function (error) { 133 return copyFile(req.files.file.path, absoluteFilePath, function (error) {
119 if (error) return next(new HttpError(500, error)); 134 if (error) return next(new HttpError(500, error));
120 next(new HttpSuccess(201, {})); 135 next(new HttpSuccess(201, {}));
diff --git a/src/multipart.js b/src/multipart.js
index 7b994cc..ec72506 100644
--- a/src/multipart.js
+++ b/src/multipart.js
@@ -12,7 +12,7 @@ function _mime(req) {
12 12
13module.exports = function multipart(options) { 13module.exports = function multipart(options) {
14 return function (req, res, next) { 14 return function (req, res, next) {
15 if (_mime(req) !== 'multipart/form-data') return res.status(400).send('Invalid content-type. Expecting multipart'); 15 if (_mime(req) !== 'multipart/form-data') return next(null);
16 16
17 var form = new multiparty.Form({ 17 var form = new multiparty.Form({
18 uploadDir: '/tmp', 18 uploadDir: '/tmp',