summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrothedev <grothedev@gmail.com>2024-12-07 13:03:32 -0600
committergrothedev <grothedev@gmail.com>2024-12-07 13:03:32 -0600
commit52d4d92fb1d897ef35b22c96d9dfcbeb4b9435fb (patch)
tree0e3b120f6812f61fdfba8d7c21859d9d1019a778
parent3ce6a1423db6ff78f912ccec50850512b1eb8121 (diff)
file browser
-rw-r--r--app/Http/Controllers/SiteController.php39
-rw-r--r--public/main.js26
-rw-r--r--public/style.css11
-rw-r--r--resources/views/f.blade.php79
-rwxr-xr-xresources/views/home.blade.php1
-rwxr-xr-xroutes/web.php9
6 files changed, 151 insertions, 14 deletions
diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php
index 7bcb60f..7b83d8a 100644
--- a/app/Http/Controllers/SiteController.php
+++ b/app/Http/Controllers/SiteController.php
@@ -4,6 +4,8 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
+use Storage;
+
class SiteController extends Controller
{
/**
@@ -23,4 +25,41 @@ class SiteController extends Controller
public static function duneQuote(){
return '<b>todo</b>';
}
+
+ public function uploadFiles(Request $req){
+ $files = $req->file('f');
+ $res = [
+ 'num_files' => sizeof($files),
+ 'num_failed'=> 0,
+ 'num_uploaded' => 0,
+ 'success' => false,
+ 'files' => []
+ ];
+
+ foreach ($files as $f){
+ //validate file
+ /*$validated = $req->validate([
+ 'f' => 'required|file|max:10240', //10MB
+ ]);*/
+ $filename = $f->getClientOriginalName();
+ if (Storage::disk('public')->fileExists($filename)){
+ $filename = Carbon::now()->timestamp.'_'.$filename;
+ }
+ $path = $f->storeAs(
+ 'uploads',
+ $filename,
+ 'public'
+ );
+ if ($path){
+ $res['num_uploaded'] += 1;
+ array_push($res['files'], $path);
+ } else {
+ $res['num_failed'] += 1;
+ }
+ if (sizeof($res['num_uploaded']) == sizeof($files)){
+ $res['success'] = true;
+ }
+ }
+ return $res;
+ }
}
diff --git a/public/main.js b/public/main.js
index 8837185..c25c9d9 100644
--- a/public/main.js
+++ b/public/main.js
@@ -123,20 +123,20 @@ async function uploadFile() {
}
axios.post('/f', formData, {headers: {'Content-Type': 'multipart/form-data'}})
- .then((res)=>{
- console.log(res);
- domElems.fileUploadResult.innerHTML = 'File uploaded successfully<br>';
- res.data.files.forEach((f)=>{
- domElems.fileUploadResult.innerHTML += `<a href = "f/${f.filename}">${f.filename}</a><br>`;
+ .then((res)=>{
+ console.log(res);
+ domElems.fileUploadResult.innerHTML = 'File uploaded successfully<br>';
+ res.data.files.forEach((f)=>{
+ domElems.fileUploadResult.innerHTML += `<a href = "f/${f.filename}">${f.filename}</a><br>`;
+ });
+ domElems.inputFile.value = null;
+ domElems.buttonFileUpload.enabled = true;
+ })
+ .catch((err)=>{
+ console.log(err);
+ domElems.fileUploadResult.innerHTML = 'Error uploading file';
+ domElems.buttonFileUpload.enabled = true;
});
- domElems.inputFile.value = null;
- domElems.buttonFileUpload.enabled = true;
- })
- .catch((err)=>{
- console.log(err);
- domElems.fileUploadResult.innerHTML = 'Error uploading file';
- domElems.buttonFileUpload.enabled = true;
- });
}
async function uploadFileChunked(f){
diff --git a/public/style.css b/public/style.css
index f92d792..6c533ba 100644
--- a/public/style.css
+++ b/public/style.css
@@ -48,6 +48,17 @@ header {
min-width: 200px;
}
+footer {
+ position: relative;
+ padding: 8px 12px 12px;
+ margin: auto;
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
+ height: 100%;
+ display: block;
+ max-width: 800px;
+ min-width: 100px;
+}
+
li a {
color: #2e3f25;
text-decoration: none;
diff --git a/resources/views/f.blade.php b/resources/views/f.blade.php
new file mode 100644
index 0000000..9cad1de
--- /dev/null
+++ b/resources/views/f.blade.php
@@ -0,0 +1,79 @@
+@extends('template')
+<?php
+ $baseDir = 'storage/uploads/';
+ $currentDir = $baseDir;
+
+ //use this if want to require auth
+ /*$valid_username = 'admin'; // Set your username
+ $valid_password = 'password'; // Set your password
+ if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
+ $_SERVER['PHP_AUTH_USER'] != $valid_username || $_SERVER['PHP_AUTH_PW'] != $valid_password) {
+ header('WWW-Authenticate: Basic realm="Secure Directory"');
+ header('HTTP/1.0 401 Unauthorized');
+ echo 'Authentication required';
+ exit;
+ }*/
+
+ // check if requested file or directory
+ if (isset($_GET['file'])) {
+ $fileRequested = $_GET['file'];
+ $filePath = realpath($fileRequested);
+
+ if (file_exists($filePath) && is_file($filePath)) {
+ // Set headers to force download
+ header('Content-Description: File Transfer');
+ header('Content-Type: application/octet-stream');
+ header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate');
+ header('Pragma: public');
+ header('Content-Length: ' . filesize($filePath));
+ readfile($filePath);
+ exit;
+ } else {
+ echo "File not found.";
+ exit;
+ }
+ } else if (isset($_GET['dir'])) {
+ $dir = $_GET['dir'];
+ if (strpos($dir, '..') !== false || strpos($dir, '/') !== false || strpos($dir, '\\') !== false) {
+ echo 'Access Denied';
+ exit;
+ }
+ $dir= basename($dir); // Ensuring the folder name is isolated
+ if (!is_dir("${baseDir}/${dir}")) {
+ echo 'Directory not found';
+ exit;
+ }
+ $currentDir = "${baseDir}/${dir}";
+ }
+
+ // Extracting the name of the current directory
+ $currentDirName = basename($currentDir);
+
+ // Determine the depth of the current directory relative to the base directory
+ $depth = substr_count(str_replace($baseDir, '', $currentDir), '/');
+
+ $contents = scandir($currentDir);
+?>
+@section('body')
+<main>
+ <p><b>Contents of:</b> <em> {{ $currentDir }}</em></p>
+ <p><b>{{ htmlspecialchars(ucfirst($currentDirName)) }}</b></p>
+ <ul>
+ @foreach ($contents as $item)
+ @if ($item !== "." && $item !== "..")
+ <li>
+ @if (is_dir($currentDir . '/' . $item))
+ <strong>Directory:</strong> <a href="?dir={{ $item }}">{{ htmlspecialchars($item) }}</a>
+ @else
+ <a href="/f?file={{ $currentDir }}/{{ $item }}">{{ htmlspecialchars($item) }}</a>
+ @endif
+ </li>
+ @endif
+ @endforeach
+ @if ($currentDir != $baseDir)
+ <li><a href="/f?dir={{ $currentDirName }}">Go Up</a></li>
+ @endif
+</main>
+@endsection \ No newline at end of file
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
index 4ac84e9..863f0de 100755
--- a/resources/views/home.blade.php
+++ b/resources/views/home.blade.php
@@ -31,6 +31,7 @@
<section id = "fileupload-nojs">
<h4>File Upload (under construction)</h4>
<form action="/f" method="POST" enctype="multipart/form-data">
+ @csrf
<input multiple name="f[]" type="file">
<button type = "submit">Upload</button>
</form>
diff --git a/routes/web.php b/routes/web.php
index cdd8e4f..c450da5 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -11,4 +11,11 @@ Route::get('/env', [SiteController::class, 'env']);
Route::get('/dq', [SiteController::class, 'duneQuote']);
-Route::post('/f', [SiteController::class, 'fileUpload']); //TODO later use file resource or FPR service \ No newline at end of file
+Route::post('/f', [SiteController::class, 'uploadFiles']); //TODO later use file resource or FPR service
+Route::get('/f/{path}', function($path){
+ return response()->file(storage_path('/public/uploads/' . $path));
+});
+
+Route::get('/{v}', function($v){
+ return view($v);
+}); \ No newline at end of file