From 3f1a8b14cbf46d88697464c477ca25fccef82cd8 Mon Sep 17 00:00:00 2001 From: francois Date: Thu, 8 May 2025 19:19:39 +0200 Subject: [PATCH] fix file upload --- appinfo/info.xml | 9 - appinfo/routes.php | 3 +- lib/Controller/PageController.php | 102 +++++- package-lock.json | 154 ++++++++- package.json | 6 +- src/App.vue | 31 +- src/components/EditFileName.vue | 42 ++- src/components/FileExistsDialog.vue | 38 ++- src/components/FileTable.vue | 108 +++---- src/components/WebContentViewer.vue | 478 +++++++++++++++++++--------- tailwind.config.js | 2 + templates/index.php | 6 +- webpack.js | 1 - 13 files changed, 724 insertions(+), 256 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 1be8da3..a2a7fe5 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -14,13 +14,4 @@ - - - webtransfer - Web Transfer - webtransfer.page.index - app.svg - link - - diff --git a/appinfo/routes.php b/appinfo/routes.php index fc9e23a..f91f7dd 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -2,6 +2,7 @@ return [ 'routes' => [ ['name' => 'page#main', 'url' => '/', 'verb' => 'GET'], - ['name' => 'page#post', 'url' => '/post', 'verb' => 'POST'], + ['name' => 'page#zipDrop', 'url' => '/zipDrop', 'verb' => 'GET'], + ['name' => 'page#getFile', 'url' => '/getFile', 'verb' => 'GET'] ] ]; diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 7fe7930..fb64af2 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -31,17 +31,107 @@ class PageController extends Controller { ); } + // Route de la page d'extraction du zip #[NoCSRFRequired] #[NoAdminRequired] - #[FrontpageRoute(verb: 'POST', url: '/zipDeposit')] - public function post($archiveUrl, $token) { - $request = $this->request; - $parameters = array('archiveUrl' => $archiveUrl, 'token' => $token); - + #[OpenAPI(OpenAPI::SCOPE_IGNORE)] + #[FrontpageRoute(verb: 'GET', url: '/zipDrop')] + public function zipDrop() { + // Récupérer le paramètre url (compatible GET et POST) + $url = $this->request->getParam('url'); + $mode = $this->request->getParam('mode'); + + if (!$url) { + return new \OCP\AppFramework\Http\DataResponse([ + 'error' => 'Le paramètre url est manquant' + ], 400); + } + if (!$mode) { + return new \OCP\AppFramework\Http\DataResponse([ + 'error' => 'Le paramètre mode est manquant' + ], 400); + } + + // Optionnel : Validation de l'URL + if (filter_var($url, FILTER_VALIDATE_URL) === false) { + return new \OCP\AppFramework\Http\DataResponse([ + 'error' => 'url n\'est pas une URL valide' + ], 400); + } + + $parameters = array('archiveUrl' => $url, 'mode' => $mode); + + // Réponse de succès return new TemplateResponse( Application::APP_ID, 'index', $parameters ); } -} + + // Route pour download le fichier + #[NoCSRFRequired] + #[NoAdminRequired] + #[OpenAPI(OpenAPI::SCOPE_IGNORE)] + #[FrontpageRoute(verb: 'GET', url: '/getFile')] + public function getFile() { + // Récupérer les données envoyées dans la requête + $zipUrl = $this->request->getParam('url'); + + // Initialiser les paramètres de réponse + $parameters = [ + 'status' => 'error', // Par défaut, la réponse indique une erreur + 'message' => '', + 'data' => null + ]; + + // Valider l'URL + if (!$zipUrl || filter_var($zipUrl, FILTER_VALIDATE_URL) === false) { + $parameters['message'] = 'Invalid URL'; + return new JsonResponse($parameters, 400); // 400 Bad Request + } + + try { + // Initialiser cURL + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $zipUrl); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Timeout de 10 secondes + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Suivre les redirections + + // Récupérer le contenu + $response = curl_exec($ch); + + // Gérer les erreurs cURL + if (curl_errno($ch)) { + $parameters['message'] = 'cURL error: ' . curl_error($ch); + curl_close($ch); + return new JsonResponse(['parameters' => $parameters, 'status' => 500]); // 500 Internal Server Error + } + + // Vérifier le code HTTP + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($httpCode !== 200) { + $parameters['message'] = "HTTP error: $httpCode"; + return new JsonResponse(['parameters' => $parameters, 'status' => $httpCode]); + } + + // Encodage explicite en UTF-8 si nécessaire + if (!mb_detect_encoding($response, 'UTF-8', true)) { + $response = utf8_encode($response); + } + + // Si tout est OK, construire la réponse + $parameters['status'] = 'success'; + $parameters['message'] = 'File retrieved successfully'; + $parameters['data'] = $response; // Encodage Base64 pour éviter les problèmes d'encodage JSON + + return new JsonResponse(['parameters' => $parameters, 'status' => 200]); // 200 OK + } catch (\Exception $e) { + $parameters['message'] = 'Exception: ' . $e->getMessage(); + return new JsonResponse(['parameters' => $parameters, 'status' => 500]); // 500 Internal Server Error + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 80fe678..7696e87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@nextcloud/files": "^3.10.0", "@nextcloud/initial-state": "^2.2.0", "@nextcloud/vue": "^8.20.0", + "file-type": "^19.6.0", + "i18next": "^24.0.2", "jszip": "^3.10.1", "vue": "^2.7.16", "vue-material-design-icons": "^5.3.1" @@ -1818,6 +1820,12 @@ "license": "MIT", "peer": true }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, "node_modules/@shikijs/core": { "version": "1.23.1", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.23.1.tgz", @@ -1881,6 +1889,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -6711,6 +6725,24 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-type": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz", + "integrity": "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==", + "license": "MIT", + "dependencies": { + "get-stream": "^9.0.1", + "strtok3": "^9.0.1", + "token-types": "^6.0.0", + "uint8array-extras": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -7063,6 +7095,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -7782,6 +7830,37 @@ "node": ">=10.18" } }, + "node_modules/i18next": { + "version": "24.0.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.0.2.tgz", + "integrity": "sha512-D88xyIGcWAKwBTAs4RSqASi8NXR/NhCVSTM4LDbdoU8qb/5dcEZjNCLDhtQBB7Epw/Cp1w2vH/3ujoTbqLSs5g==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/ical.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.1.0.tgz", @@ -7820,7 +7899,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -7835,8 +7913,7 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.2", @@ -8523,6 +8600,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -11011,6 +11100,19 @@ "node": ">=0.12" } }, + "node_modules/peek-readable": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz", + "integrity": "sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -13486,6 +13588,23 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", "license": "MIT" }, + "node_modules/strtok3": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.1.1.tgz", + "integrity": "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.3.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/style-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", @@ -14213,6 +14332,23 @@ "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz", + "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/tree-dump": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", @@ -14555,6 +14691,18 @@ "license": "MIT", "peer": true }, + "node_modules/uint8array-extras": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", + "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", diff --git a/package.json b/package.json index 21e0260..2a0e26c 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "dev": "NODE_ENV=development webpack --config webpack.js --progress", "watch": "NODE_ENV=development webpack --config webpack.js --progress --watch", "lint": "eslint src", - "stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css" + "stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css", + "tailwind": "npx tailwindcss -i ./src/input.css -o ./src/output.css", + "buildAll": "npm i && npm run tailwind && npm run build" }, "browserslist": [ "extends @nextcloud/browserslist-config" @@ -21,6 +23,8 @@ "@nextcloud/files": "^3.10.0", "@nextcloud/initial-state": "^2.2.0", "@nextcloud/vue": "^8.20.0", + "file-type": "^19.6.0", + "i18next": "^24.0.2", "jszip": "^3.10.1", "vue": "^2.7.16", "vue-material-design-icons": "^5.3.1" diff --git a/src/App.vue b/src/App.vue index a647972..85519f5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,16 +1,16 @@