var destinationPath = (destination ? '/' + destination : '') + '/' + relativeFilePath;
console.log('Uploading file %s -> %s', relativeFilePath.cyan, destinationPath.cyan);
- superagent.put(config.server() + API + destinationPath).query(gQuery).attach('file', file).end(function (error, result) {
+ superagent.post(config.server() + API + destinationPath).query(gQuery).attach('file', file).end(function (error, result) {
if (result && result.statusCode === 403) return callback(new Error('Upload destination ' + destinationPath + ' not allowed'));
if (result && result.statusCode !== 201) return callback(new Error('Error uploading file: ' + result.statusCode));
if (error) return callback(error);
</div>
<div class="modal-body">
<h5 v-show="deleteData.isFile">Really delete <span style="font-weight: bold;">{{ deleteData.filePath }}</span>?</h5>
- <h5 v-show="deleteData.isDirectory">Really delete directory <span style="font-weight: bold;">{{ deleteData.filePath }}</span> and all its content?</h5>
+ <h5 v-show="deleteData.isDirectory">Really delete folder <span style="font-weight: bold;">{{ deleteData.filePath }}</span> and all its content?</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
</div>
</div>
+ <div class="modal fade" tabindex="-1" role="dialog" id="modalRename" v-cloak>
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+ <h4 class="modal-title">Rename {{ renameData.entry.filePath }}</h4>
+ </div>
+ <div class="modal-body">
+ <form v-on:submit.prevent="rename(renameData)">
+ <div class="form-group" v-bind:class="{ 'has-error': renameData.error }">
+ <input type="text" class="form-control" v-model="renameData.newFilePath" placeholder="Name" autofocus="true">
+ <label class="control-label">{{ renameData.error }}</label>
+ </div>
+ <button type="submit" style="display: none;"></button>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
+ <button type="button" class="btn btn-success" v-on:click="rename(renameData)">Yes</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
<div class="modal fade" tabindex="-1" role="dialog" id="modalcreateDirectory" v-cloak>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
- <h4 class="modal-title">New Directory Name</h4>
+ <h4 class="modal-title">New directory name</h4>
</div>
<div class="modal-body">
<form v-on:submit.prevent="createDirectory(createDirectoryData)">
<a href="{{ part.link }}">{{ part.name }}</a>
</li>
<li>{{ pathParts.slice(-1)[0].name }}</li>
- <button class="btn btn-default btn-sm pull-right" v-on:click="createDirectoryAsk()">Create Directory</button>
+ <button class="btn btn-default btn-sm pull-right" v-on:click="createDirectoryAsk()">Create Folder</button>
</ol>
</div>
<div class="col-lg-12">
</tr>
</thead>
<tbody>
+ <tr v-show="entries.length === 0">
+ <th><i>Empty folder</i></th>
+ </tr>
<tr v-for="entry in entries" v-on:click="open(entry)" class="hand">
<th>
<img v-bind:src="entry.previewUrl" height="48px" width="48px"/>
<th><span v-my-tooltip="foobar" data-toggle="tooltip" title="{{ entry.mtime }}">{{ entry.mtime | prettyDate }}</span></th>
<th style="text-align: right;">
<span class="entry-toolbar">
- <!-- <button class="btn btn-sm btn-default" v-on:click.stop="renameAsk(entry)" title="Rename"><i class="fa fa-pencil"></i></button> -->
+ <button class="btn btn-sm btn-default" v-on:click.stop="renameAsk(entry)" title="Rename"><i class="fa fa-pencil"></i></button>
<button class="btn btn-sm btn-danger" v-on:click.stop="delAsk(entry)" title="Delete"><i class="fa fa-trash"></i></button>
</span>
</th>
var formData = new FormData();
formData.append('file', file);
- superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send(formData).end(function (error, result) {
+ superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send(formData).end(function (error, result) {
if (result && result.statusCode === 401) return logout();
if (result && result.statusCode !== 201) console.error('Error uploading file: ', result.statusCode);
if (error) console.error(error);
app.uploadStatus.done += 1;
app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100);
- console.log(Math.round(app.uploadStatus.done / app.uploadStatus.count * 100))
-
if (app.uploadStatus.done >= app.uploadStatus.count) {
app.uploadStatus = {
busy: false,
});
}
+function renameAsk(entry) {
+ app.renameData.entry = entry;
+ app.renameData.error = null;
+ app.renameData.newFilePath = entry.filePath;
+
+ $('#modalRename').modal('show');
+}
+
+function rename(data) {
+ app.busy = true;
+
+ var path = encode(sanitize(app.path + '/' + data.entry.filePath));
+ var newFilePath = sanitize(app.path + '/' + data.newFilePath);
+
+ superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send({ newFilePath: newFilePath }).end(function (error, result) {
+ app.busy = false;
+
+ if (result && result.statusCode === 401) return logout();
+ if (result && result.statusCode !== 200) return console.error('Error renaming file: ', result.statusCode);
+ if (error) return console.error(error);
+
+ refresh();
+
+ $('#modalRename').modal('hide');
+ });
+}
+
function createDirectoryAsk() {
$('#modalcreateDirectory').modal('show');
app.createDirectoryData = '';
var path = encode(sanitize(app.path + '/' + name));
- superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
+ superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
app.busy = false;
if (result && result.statusCode === 401) return logout();
},
loginData: {},
deleteData: {},
+ renameData: {
+ entry: {},
+ error: null,
+ newFilePath: ''
+ },
createDirectoryData: '',
createDirectoryError: null,
entries: []
upload: upload,
delAsk: delAsk,
del: del,
+ renameAsk: renameAsk,
+ rename: rename,
createDirectoryAsk: createDirectoryAsk,
createDirectory: createDirectory
}
var multipart = multipart({ maxFieldsSize: 2 * 1024, limit: '512mb', timeout: 3 * 60 * 1000 });
router.get ('/api/files/*', auth.verify, files.get);
-router.put ('/api/files/*', auth.verify, multipart, files.put);
+router.post ('/api/files/*', auth.verify, multipart, files.post);
+router.put ('/api/files/*', auth.verify, files.put);
router.delete('/api/files/*', auth.verify, files.del);
router.get ('/api/healthcheck', function (req, res) { res.status(200).send(); });
return {
get: get,
put: put,
+ post: post,
del: del
};
};
});
}
-function put(req, res, next) {
+function post(req, res, next) {
var filePath = decodeURIComponent(req.params[0]);
if (!(req.files && req.files.file) && !req.query.directory) return next(new HttpError(400, 'missing file or directory'));
if ((req.files && req.files.file) && req.query.directory) return next(new HttpError(400, 'either file or directory'));
+ debug('post:', filePath);
+
var absoluteFilePath = getAbsolutePath(filePath);
if (!absoluteFilePath || isProtected(absoluteFilePath)) return next(new HttpError(403, 'Path not allowed'));
fs.stat(absoluteFilePath, function (error, result) {
if (error && error.code !== 'ENOENT') return next(new HttpError(500, error));
- debug('put', absoluteFilePath);
-
if (result && req.query.directory) return next(new HttpError(409, 'name already exists'));
- if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories'));
+ if (result && result.isDirectory()) return next(new HttpError(409, 'cannot post on directories'));
if (req.query.directory) {
return createDirectory(absoluteFilePath, function (error) {
});
}
+function put(req, res, next) {
+ var oldFilePath = decodeURIComponent(req.params[0]);
+
+ if (!req.body || !req.body.newFilePath) return next(new HttpError(400, 'missing newFilePath'));
+
+ var newFilePath = decodeURIComponent(req.body.newFilePath);
+
+ debug('put: %s -> %s', oldFilePath, newFilePath);
+
+ var absoluteOldFilePath = getAbsolutePath(oldFilePath);
+ if (!absoluteOldFilePath || isProtected(absoluteOldFilePath)) return next(new HttpError(403, 'Path not allowed'));
+
+ var absoluteNewFilePath = getAbsolutePath(newFilePath);
+ if (!absoluteNewFilePath || isProtected(absoluteNewFilePath)) return next(new HttpError(403, 'Path not allowed'));
+
+ fs.rename(absoluteOldFilePath, absoluteNewFilePath, function (error) {
+ if (error) return next (new HttpError(500, error));
+
+ debug('put: successful');
+
+ return next(new HttpSuccess(200, {}));
+ });
+}
+
function del(req, res, next) {
var filePath = decodeURIComponent(req.params[0]);
var recursive = !!req.query.recursive;