prevent duplicate file names
This commit is contained in:
1 parent
2d4c2f5aaa
commit
11e83028c5
5 files changed
+49
-16
No files matched your search
@@ -250,7 +250,6 @@ namespace Api\File {
|
||||
class GetRestrictions extends FileAPI {
|
||||
public function __construct(User $user, bool $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->csrfTokenRequired = false;
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
@@ -564,6 +563,24 @@ namespace Api\File {
|
||||
$md5Hash = @hash_file('md5', $tmpPath);
|
||||
$sha1Hash = @hash_file('sha1', $tmpPath);
|
||||
$filePath = $uploadDir . "/" . $md5Hash . $sha1Hash;
|
||||
|
||||
// check if a file with this name already exists
|
||||
$res = $sql->select($sql->count())
|
||||
->from("UserFile")
|
||||
->where(new Compare("name", $fileName))
|
||||
->where(new Compare("user_id", $userId))
|
||||
->where(new Compare("parent_id", $parentId))
|
||||
->execute();
|
||||
if ($res === false) {
|
||||
return $this->createError($sql->getLastError());
|
||||
} else {
|
||||
if ($res[0]["count"] > 0) {
|
||||
return $this->createError("Error uploading file: a file or directory with this name already exists " .
|
||||
"in the given upload directory");
|
||||
}
|
||||
}
|
||||
|
||||
// save file to disk and database
|
||||
if (file_exists($filePath) || move_uploaded_file($tmpPath, $filePath)) {
|
||||
$res = $sql->insert("UserFile", array("name", "directory", "path", "user_id", "parent_id"))
|
||||
->addRow($fileName, false, $filePath, $userId, $parentId)
|
||||
@@ -571,9 +588,7 @@ namespace Api\File {
|
||||
->execute();
|
||||
|
||||
if ($res === false) {
|
||||
$this->lastError = $sql->getLastError();
|
||||
$this->success = false;
|
||||
return false;
|
||||
return $this->createError($sql->getLastError());
|
||||
} else {
|
||||
$fileId = $sql->getLastInsertId();
|
||||
}
|
||||
@@ -581,6 +596,7 @@ namespace Api\File {
|
||||
return $this->createError("Could not create file: $fileName");
|
||||
}
|
||||
|
||||
// connect to the token, if present
|
||||
if (!is_null($token)) {
|
||||
$res = $sql->insert("UserFileTokenFile", array("file_id", "token_id"))
|
||||
->addRow($fileId, $tokenId)
|
||||
|
||||
@@ -16,6 +16,7 @@ class file_api extends DatabaseScript {
|
||||
|
||||
$queries[] = $sql->insert("ApiPermission", array("method", "groups", "description"))
|
||||
->onDuplicateKeyStrategy(new UpdateStrategy(array("method"), array("method" => new Column("method"))))
|
||||
->addRow("File/GetRestrictions", array(), "Allows users to view global upload restrictions")
|
||||
->addRow("File/Download", array(), "Allows users to download files when logged in, or using a given token")
|
||||
->addRow("File/Upload", array(), "Allows users to upload files when logged in, or using a given token")
|
||||
->addRow("File/ValidateToken", array(), "Allows users to validate a given token")
|
||||
@@ -40,9 +41,9 @@ class file_api extends DatabaseScript {
|
||||
->addString("name", 64, false)
|
||||
->addString("path", 512, true)
|
||||
->addInt("parent_id", true)
|
||||
->addInt("user_id", true)
|
||||
->addInt("user_id")
|
||||
->primaryKey("uid")
|
||||
->unique("parent_id", "name")
|
||||
->unique("user_id", "parent_id", "name")
|
||||
->foreignKey("parent_id", "UserFile", "uid", new CascadeStrategy())
|
||||
->foreignKey("user_id", "User", "uid", new CascadeStrategy());
|
||||
|
||||
|
||||
@@ -352,6 +352,15 @@ abstract class SQL {
|
||||
$column = $this->columnName($condition->getColumn());
|
||||
$value = $condition->getValue();
|
||||
$operator = $condition->getOperator();
|
||||
|
||||
if ($value === null) {
|
||||
if ($operator === "=") {
|
||||
return "$column IS NULL";
|
||||
} else if ($operator === "!=") {
|
||||
return "$column IS NOT NULL";
|
||||
}
|
||||
}
|
||||
|
||||
return $column . $operator . $this->addValue($value, $params);
|
||||
} else if ($condition instanceof CondBool) {
|
||||
return $this->columnName($condition->getValue());
|
||||
|
||||
@@ -278,12 +278,13 @@ export function FileBrowser(props) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
const cancelToken = filesToUpload[i].cancelToken;
|
||||
if (cancelToken) {
|
||||
if (cancelToken && filesToUpload[i].progress < 1) {
|
||||
cancelToken.cancel("Upload cancelled");
|
||||
let files = filesToUpload.slice();
|
||||
files.splice(i, 1);
|
||||
setFilesToUpload(files);
|
||||
}
|
||||
|
||||
let files = filesToUpload.slice();
|
||||
files.splice(i, 1);
|
||||
setFilesToUpload(files);
|
||||
}
|
||||
|
||||
if (writePermissions) {
|
||||
@@ -306,15 +307,17 @@ export function FileBrowser(props) {
|
||||
</span>
|
||||
</div> : <></>
|
||||
}
|
||||
<Icon icon={done ? "check" : "spinner"} className={"status-icon " + (done ? "text-success" : "text-secondary")} />
|
||||
<Icon icon={"times"} className={"text-danger cancel-button fa-2x"} title={"Cancel Upload"} onClick={(e) => onCancelUpload(e, i)}/>
|
||||
<Icon icon={done ? (file.success ? "check" : "times") : "spinner"}
|
||||
className={"status-icon " + (done ? (file.success ? "text-success" : "text-danger") : "text-secondary")} />
|
||||
<Icon icon={"times"} className={"text-danger cancel-button fa-2x"}
|
||||
title={"Cancel Upload"} onClick={(e) => onCancelUpload(e, i)}/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
uploadZone = <>
|
||||
<div className={"p-3"}>
|
||||
<label><b>Destination Directory:</b></label>
|
||||
<label><b>Upload Directory:</b></label>
|
||||
<select value={popup.directory} className={"form-control"}
|
||||
onChange={(e) => onPopupChange(e, "directory")}>
|
||||
{options}
|
||||
@@ -524,15 +527,19 @@ export function FileBrowser(props) {
|
||||
setFilesToUpload(newFiles);
|
||||
|
||||
api.upload(file, token, parentId, cancelToken, (e) => onUploadProgress(e, fileIndex)).then((res) => {
|
||||
|
||||
let newFiles = filesToUpload.slice();
|
||||
newFiles[fileIndex].success = res.success;
|
||||
setFilesToUpload(newFiles);
|
||||
|
||||
if (res.success) {
|
||||
// setFilesToUpload([]);
|
||||
fetchFiles();
|
||||
} else {
|
||||
pushAlert(res);
|
||||
}
|
||||
}).catch((reason) => {
|
||||
if (reason && reason.message !== "Upload cancelled") {
|
||||
pushAlert({ msg: reason}, "Error uploading files");
|
||||
pushAlert({ msg: reason }, "Error uploading files");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -299,4 +299,4 @@ e.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,w=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?w.postMessage(null):(v=!1,g=null)}catch(e){throw w.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,w.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function Y(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,O=null,H=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,Y(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=H;try{for(C(n),O=T(x);null!==O&&(!(O.expirationTime>n)||e&&!o());){var s=O.callback;if(null!==s){O.callback=null,H=O.priorityLevel;var u=s(O.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?O.callback=u:O===T(x)&&D(x),C(n)}else D(x);O=T(x)}if(null!==O)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{O=null,H=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return H},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(H){case 1:case 2:case 3:var t=3;break;default:t=H}var n=H;H=t;try{return e()}finally{H=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=H;H=e;try{return t()}finally{H=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,Y(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,Y(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==O&&null!==O&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<O.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=H;return function(){var n=H;H=t;try{return e.apply(this,arguments)}finally{H=n}}}},function(e,t,n){"use strict";(function(e){if(n(286),n(483),n(484),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,
Line truncated
|
||||
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,w=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?w.postMessage(null):(v=!1,g=null)}catch(e){throw w.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,w.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function Y(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,O=null,H=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,Y(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=H;try{for(C(n),O=T(x);null!==O&&(!(O.expirationTime>n)||e&&!o());){var s=O.callback;if(null!==s){O.callback=null,H=O.priorityLevel;var u=s(O.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?O.callback=u:O===T(x)&&D(x),C(n)}else D(x);O=T(x)}if(null!==O)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{O=null,H=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return H},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(H){case 1:case 2:case 3:var t=3;break;default:t=H}var n=H;H=t;try{return e()}finally{H=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=H;H=e;try{return t()}finally{H=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,Y(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,Y(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==O&&null!==O&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<O.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=H;return function(){var n=H;H=t;try{return e.apply(this,arguments)}finally{H=n}}}},function(e,t,n){"use strict";(function(e){if(n(286),n(483),n(484),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,
Line truncated
|
||||
Reference in new issue
Block a user