diff --git a/app/Http/Controllers/Sharing/BrowseShareController.php b/app/Http/Controllers/Sharing/BrowseShareController.php
index 70beef7d..8861b6b4 100644
--- a/app/Http/Controllers/Sharing/BrowseShareController.php
+++ b/app/Http/Controllers/Sharing/BrowseShareController.php
@@ -27,12 +27,10 @@ class BrowseShareController extends Controller
* @param Share $shared
* @return Collection
*/
- public function get_public_folders($id, Share $shared)
+ public function browse_folder($id, Share $shared)
{
- // Abort if folder is protected
- if ($shared->is_protected) {
- abort(403, "Sorry, you don't have permission");
- }
+ // Check ability to access protected share record
+ $this->helper->check_protected_share_record($shared);
// Check if user can get directory
$this->helper->check_item_access($id, $shared);
@@ -57,12 +55,10 @@ class BrowseShareController extends Controller
* @param Share $shared
* @return Collection
*/
- public function search_public(Request $request, Share $shared)
+ public function search(Request $request, Share $shared)
{
- // Abort if folder is protected
- if ($shared->is_protected) {
- abort(403, "Sorry, you don't have permission");
- }
+ // Check ability to access protected share record
+ $this->helper->check_protected_share_record($shared);
// Search files id db
$searched_files = File::search($request->input('query'))
@@ -108,8 +104,11 @@ class BrowseShareController extends Controller
* @param Share $shared
* @return array
*/
- public function get_public_navigation_tree(Share $shared)
+ public function navigation_tree(Share $shared)
{
+ // Check ability to access protected share record
+ $this->helper->check_protected_share_record($shared);
+
// Check if user can get directory
$this->helper->check_item_access($shared->item_id, $shared);
diff --git a/app/Http/Controllers/Sharing/FileSharedAccessController.php b/app/Http/Controllers/Sharing/FileSharedAccessController.php
index 596c3b5e..3a4dde6f 100644
--- a/app/Http/Controllers/Sharing/FileSharedAccessController.php
+++ b/app/Http/Controllers/Sharing/FileSharedAccessController.php
@@ -54,15 +54,14 @@ class FileSharedAccessController extends Controller
* Get file public
*
* @param $filename
+ * @param $permission
* @param Share $shared
* @return mixed
*/
- public function get_file_public($filename, Share $shared)
+ public function get_file_public($filename, $permission, Share $shared)
{
- // Abort if shared is protected
- if ($shared->is_protected) {
- abort(403, "Sorry, you don't have permission");
- }
+ // Check ability to access protected share files
+ $this->helper->check_protected_share_record($shared, $permission);
// Get file record
$file = UserFile::where('user_id', $shared->user_id)
@@ -86,15 +85,14 @@ class FileSharedAccessController extends Controller
* Get public image thumbnail
*
* @param $filename
+ * @param $permission
* @param Share $shared
* @return mixed
*/
- public function get_thumbnail_public($filename, Share $shared)
+ public function get_thumbnail_public($filename, $permission, Share $shared)
{
- // Abort if thumbnail is protected
- if ($shared->is_protected) {
- abort(403, "Sorry, you don't have permission");
- }
+ // Check ability to access protected share files
+ $this->helper->check_protected_share_record($shared, $permission);
// Get file record
$file = UserFile::where('user_id', $shared->user_id)
diff --git a/app/Http/Controllers/Sharing/ServeSharedController.php b/app/Http/Controllers/Sharing/ServeSharedController.php
index af1843ef..0e9869e9 100644
--- a/app/Http/Controllers/Sharing/ServeSharedController.php
+++ b/app/Http/Controllers/Sharing/ServeSharedController.php
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Sharing;
use App\Http\Controllers\Controller;
use App\Http\Requests\Share\AuthenticateShareRequest;
+use App\Http\Resources\FileResource;
use App\Http\Resources\ShareResource;
use App\Models\Share;
use App\Models\Setting;
@@ -118,20 +119,17 @@ class ServeSharedController extends Controller
*/
public function file_public(Share $shared)
{
- // Abort if file is protected
- if ($shared->is_protected) {
- abort(403, "Sorry, you don't have permission");
- }
+ // Check ability to access protected share files
+ $this->helper->check_protected_share_record($shared);
// Get file
$file = File::where('user_id', $shared->user_id)
->where('id', $shared->item_id)
- ->firstOrFail(['name', 'basename', 'thumbnail', 'type', 'filesize', 'mimetype']);
+ ->firstOrFail();
- // Set urls
+ // Set access urls
$file->setPublicUrl($shared->token);
- // Return record
- return $file;
+ return response(new FileResource($file), 200);
}
}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 61e128aa..41f9652d 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -15,6 +15,7 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
+ // \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
diff --git a/app/Http/Middleware/SharedAuth.php b/app/Http/Middleware/SharedAuth.php
deleted file mode 100644
index 27457a3e..00000000
--- a/app/Http/Middleware/SharedAuth.php
+++ /dev/null
@@ -1,29 +0,0 @@
-bearerToken()) {
- if ($request->hasCookie('shared_access_token')) {
-
- $shared_access_token = $request->cookie('shared_access_token');
-
- $request->headers->add(['Authorization' => 'Bearer ' . $shared_access_token]);
-
- }
- }
- return $next($request);
- }
-}
diff --git a/app/Http/Resources/FileResource.php b/app/Http/Resources/FileResource.php
new file mode 100644
index 00000000..a0973320
--- /dev/null
+++ b/app/Http/Resources/FileResource.php
@@ -0,0 +1,35 @@
+ [
+ 'id' => $this->id,
+ 'type' => 'file',
+ 'attributes' => [
+ 'name' => $this->name,
+ 'basename' => $this->basename,
+ 'mimetype' => $this->mimetype,
+ 'filesize' => $this->filesize,
+ 'type' => $this->type,
+ 'file_url' => $this->file_url,
+ 'thumbnail' => $this->thumbnail,
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->created_at,
+ ]
+ ],
+ ];
+ }
+}
diff --git a/app/Http/Resources/GatewayCollection.php b/app/Http/Resources/GatewayCollection.php
deleted file mode 100644
index 7944bcf1..00000000
--- a/app/Http/Resources/GatewayCollection.php
+++ /dev/null
@@ -1,23 +0,0 @@
- $this->collection,
- ];
- }
-}
diff --git a/app/Http/Resources/GatewayResource.php b/app/Http/Resources/GatewayResource.php
deleted file mode 100644
index 8c7a02fc..00000000
--- a/app/Http/Resources/GatewayResource.php
+++ /dev/null
@@ -1,36 +0,0 @@
- [
- 'id' => (string)$this->id,
- 'type' => 'gateways',
- 'attributes' => [
- 'status' => $this->status,
- 'sandbox' => $this->sandbox,
- 'name' => $this->name,
- 'slug' => $this->slug,
- 'logo' => $this->logo,
- 'client_id' => $this->client_id,
- 'secret' => $this->secret,
- 'webhook' => $this->webhook,
- 'payment_processed' => $this->payment_processed,
- 'optional' => $this->optional,
- ]
- ]
- ];
- }
-}
diff --git a/app/Models/File.php b/app/Models/File.php
index 56ba806b..0db56450 100644
--- a/app/Models/File.php
+++ b/app/Models/File.php
@@ -94,9 +94,9 @@ class File extends Model
public function getThumbnailAttribute()
{
// Get thumbnail from external storage
- if ($this->attributes['thumbnail'] && is_storage_driver(['s3', 'spaces', 'wasabi', 'backblaze'])) {
+ if ($this->attributes['thumbnail'] && ! is_storage_driver(['local'])) {
- return Storage::temporaryUrl('file-manager/' . $this->attributes['thumbnail'], now()->addHour());
+ return Storage::temporaryUrl('files/' . $this->attributes['thumbnail'], now()->addHour());
}
// Get thumbnail from local storage
@@ -106,7 +106,7 @@ class File extends Model
$route = route('thumbnail', ['name' => $this->attributes['thumbnail']]);
if ($this->public_access) {
- return $route . '/public/' . $this->public_access;
+ return "$route/$this->public_access";
}
return $route;
@@ -123,7 +123,7 @@ class File extends Model
public function getFileUrlAttribute()
{
// Get file from external storage
- if (is_storage_driver(['s3', 'spaces', 'wasabi', 'backblaze'])) {
+ if (! is_storage_driver(['local'])) {
$file_pretty_name = is_storage_driver('backblaze')
? Str::snake(mb_strtolower($this->attributes['name']))
@@ -144,7 +144,7 @@ class File extends Model
$route = route('file', ['name' => $this->attributes['basename']]);
if ($this->public_access) {
- return $route . '/public/' . $this->public_access;
+ return "$route/$this->public_access";
}
return $route;
@@ -198,8 +198,8 @@ class File extends Model
{
parent::boot();
- static::creating(function ($model) {
- $model->id = (string)Str::uuid();
+ static::creating(function ($file) {
+ $file->id = (string)Str::uuid();
});
}
}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index bf6e052e..56e5611b 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -25,8 +25,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
- Schema::defaultStringLength(191);
-
$get_time_locale = App::getLocale() . '_' . mb_strtoupper(App::getLocale());
// Set locale for carbon dates
diff --git a/app/Services/HelperService.php b/app/Services/HelperService.php
index 3d618c8a..42d8d9ba 100644
--- a/app/Services/HelperService.php
+++ b/app/Services/HelperService.php
@@ -4,9 +4,11 @@ namespace App\Services;
use App\Models\File;
use App\Models\Folder;
+use App\Models\Share;
use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use DB;
+use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
@@ -291,4 +293,34 @@ class HelperService
return [$folders, $files];
}
+
+ /**
+ * @param Share $shared
+ */
+ function check_protected_share_record(Share $shared): void
+ {
+ if ($shared->is_protected) {
+
+ $abort_message = "Sorry, you don't have permission";
+
+ if (!request()->hasCookie('share_session')) {
+ abort(403, $abort_message);
+ }
+
+ // Get shared session
+ $share_session = json_decode(
+ request()->cookie('share_session')
+ );
+
+ // Check if is requested same share record
+ if ($share_session->token !== $shared->token) {
+ abort(403, $abort_message);
+ }
+
+ // Check if share record was authenticated previously via ServeSharedController@authenticate
+ if (!$share_session->authenticated) {
+ abort(403, $abort_message);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/database/migrations/2019_08_15_171328_create_file_manager_folders.php b/database/migrations/2019_08_15_171328_create_file_manager_folders.php
index 8294aea0..6b8234de 100644
--- a/database/migrations/2019_08_15_171328_create_file_manager_folders.php
+++ b/database/migrations/2019_08_15_171328_create_file_manager_folders.php
@@ -20,6 +20,8 @@ class CreateFileManagerFolders extends Migration
$table->text('name');
$table->string('color')->nullable();
$table->longText('emoji')->nullable();
+
+ // TODO: upravit user scope
$table->enum('user_scope', ['master', 'editor', 'visitor'])->default('master');
$table->softDeletes();
$table->timestamps();
diff --git a/database/migrations/2019_08_15_171345_create_file_manager_files.php b/database/migrations/2019_08_15_171345_create_file_manager_files.php
index 989d8cc8..722cdc8c 100644
--- a/database/migrations/2019_08_15_171345_create_file_manager_files.php
+++ b/database/migrations/2019_08_15_171345_create_file_manager_files.php
@@ -27,6 +27,8 @@ class CreateFileManagerFiles extends Migration
$table->text('type')->nullable();
$table->longText('metadata')->nullable();
+
+ // TODO: upravit user scope
$table->enum('user_scope', ['master', 'editor', 'visitor'])->default('master');
$table->softDeletes();
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..1ab5110b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/public/mix-manifest.json b/public/mix-manifest.json
index f8a09113..1964ef38 100644
--- a/public/mix-manifest.json
+++ b/public/mix-manifest.json
@@ -66,7 +66,7 @@
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=c6b88005b133268ed88f",
"/chunks/shared.js": "/chunks/shared.js?id=2c38f535d52e0e448846",
"/chunks/shared-files.js": "/chunks/shared-files.js?id=e6f7de2910d85a2dd3e4",
- "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=9024f3b0b3bed191fe8d",
+ "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=f6155ac74f9bb460cf65",
"/chunks/shared/file-browser.js": "/chunks/shared/file-browser.js?id=3127fab4cfd3d5f00a72",
"/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=298e41c1c453bf1fde9b",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=af61663f3e69eae3e5ee",
@@ -88,5 +88,13 @@
"/chunks/users.js": "/chunks/users.js?id=9085e0306eafce8f9fce",
"/vendors~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-i~68e3c6cf.js": "/vendors~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-i~68e3c6cf.js?id=b490efdc8470a6c2f625",
"/vendors~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-i~a4a4a595.js": "/vendors~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-i~a4a4a595.js?id=be99c10088b00578891b",
- "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/file-browser~ch~52c14f2e.js": "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/file-browser~ch~52c14f2e.js?id=66afa0e341251a68c3d3"
+ "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/file-browser~ch~52c14f2e.js": "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared-files~chunks/shared/file-browser~ch~52c14f2e.js?id=66afa0e341251a68c3d3",
+ "/js/main.723fdf599ac2ecb35271.hot-update.js": "/js/main.723fdf599ac2ecb35271.hot-update.js",
+ "/js/main.4a8fc01e2ff5a4e6ad28.hot-update.js": "/js/main.4a8fc01e2ff5a4e6ad28.hot-update.js",
+ "/js/main.83e4a1fba24fb3ed581d.hot-update.js": "/js/main.83e4a1fba24fb3ed581d.hot-update.js",
+ "/js/main.4cd1727b0d5ad436dba4.hot-update.js": "/js/main.4cd1727b0d5ad436dba4.hot-update.js",
+ "/js/main.7e6541d1cbf9901a3e5a.hot-update.js": "/js/main.7e6541d1cbf9901a3e5a.hot-update.js",
+ "/js/main.51418924870a080afea3.hot-update.js": "/js/main.51418924870a080afea3.hot-update.js",
+ "/js/main.869d3fad73dd6fe243f9.hot-update.js": "/js/main.869d3fad73dd6fe243f9.hot-update.js",
+ "/js/main.d7f2bec845fc64b7d5e4.hot-update.js": "/js/main.d7f2bec845fc64b7d5e4.hot-update.js"
}
diff --git a/resources/js/store/modules/fileBrowser.js b/resources/js/store/modules/fileBrowser.js
index 77d5595d..8ee33f3f 100644
--- a/resources/js/store/modules/fileBrowser.js
+++ b/resources/js/store/modules/fileBrowser.js
@@ -154,12 +154,16 @@ const actions = {
// Get route
let route = undefined
- if (getters.sharedDetail && getters.sharedDetail.is_protected)
- route = '/api/browse/search/private'
- else if (getters.sharedDetail && !getters.sharedDetail.is_protected)
- route = '/api/browse/search/public/' + router.currentRoute.params.token
- else
+ if (getters.sharedDetail) {
+ let permission = getters.sharedDetail.is_protected
+ ? 'private'
+ : 'public'
+
+ route = `/api/browse/search/${permission}/${router.currentRoute.params.token}`
+
+ } else {
route = '/api/browse/search'
+ }
axios
.get(route, {
@@ -177,12 +181,11 @@ const actions = {
// Get route
let route = undefined
- if (getters.sharedDetail && getters.sharedDetail.is_protected)
- route = '/api/browse/navigation/private'
- else if (getters.sharedDetail && !getters.sharedDetail.is_protected)
- route = '/api/browse/navigation/public/' + router.currentRoute.params.token
- else
+ if (getters.sharedDetail) {
+ route = `/api/browse/navigation/${router.currentRoute.params.token}`
+ } else {
route = '/api/browse/navigation'
+ }
axios
.get(route + getters.sorting.URI)
diff --git a/resources/js/store/modules/fileFunctions.js b/resources/js/store/modules/fileFunctions.js
index 65e6c7e5..1f396d2e 100644
--- a/resources/js/store/modules/fileFunctions.js
+++ b/resources/js/store/modules/fileFunctions.js
@@ -22,10 +22,9 @@ const actions = {
message: i18n.t('popup_zipping.message')
})
- // Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/zip/folder/' + folder.id + '/public/' + router.currentRoute.params.token
- : '/api/zip/folder/' + folder.id
+ let route = getters.sharedDetail
+ ? `/api/zip/folder/${folder.id}/${router.currentRoute.params.token}`
+ : `/api/zip/folder/${folder.id}`
axios.get(route)
.then(response => {
@@ -37,7 +36,6 @@ const actions = {
.finally(() => {
commit('PROCESSING_POPUP', undefined)
})
-
},
downloadFiles: ({commit, getters}) => {
let files = []
@@ -46,8 +44,8 @@ const actions = {
getters.fileInfoDetail.forEach(file => files.push(file.id))
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/zip/files/public/' + router.currentRoute.params.token
+ let route = getters.sharedDetail
+ ? `/api/zip/files/${router.currentRoute.params.token}`
: '/api/zip/files'
commit('PROCESSING_POPUP', {
@@ -87,8 +85,8 @@ const actions = {
commit('CLEAR_FILEINFO_DETAIL')
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/editor/move/public/' + router.currentRoute.params.token
+ let route = getters.sharedDetail
+ ? `/api/editor/move/${router.currentRoute.params.token}`
: '/api/move'
console.log(to_item);
@@ -114,8 +112,8 @@ const actions = {
createFolder: ({commit, getters, dispatch}, folder) => {
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/editor/create-folder/public/' + router.currentRoute.params.token
+ let route = getters.sharedDetail
+ ? `/api/editor/create-folder/${router.currentRoute.params.token}`
: '/api/create-folder'
axios
@@ -149,9 +147,9 @@ const actions = {
commit('UPDATE_NAME_IN_FAVOURITES', data)
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/editor/rename/' + data.id + '/public/' + router.currentRoute.params.token
- : '/api/rename/' + data.id
+ let route = getters.sharedDetail
+ ? `/api/editor/rename/${data.id}/${router.currentRoute.params.token}`
+ : `/api/rename/${data.id}`
axios
.post(route, {
@@ -172,8 +170,8 @@ const actions = {
return new Promise((resolve, reject) => {
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/editor/upload/public/' + router.currentRoute.params.token
+ let route = getters.sharedDetail
+ ? `/api/editor/upload/${router.currentRoute.params.token}`
: '/api/upload'
// Create cancel token for axios cancellation
@@ -341,8 +339,8 @@ const actions = {
}
// Get route
- let route = getters.sharedDetail && !getters.sharedDetail.is_protected
- ? '/api/editor/remove/public/' + router.currentRoute.params.token
+ let route = getters.sharedDetail
+ ? `/api/editor/remove/${router.currentRoute.params.token}`
: '/api/remove'
axios
diff --git a/resources/js/store/modules/sharing.js b/resources/js/store/modules/sharing.js
index d0611db2..821d30f7 100644
--- a/resources/js/store/modules/sharing.js
+++ b/resources/js/store/modules/sharing.js
@@ -38,13 +38,9 @@ const actions = {
payload.folder.location = 'public'
- let route = getters.sharedDetail.is_protected
- ? '/api/browse/folders/' + payload.folder.id + '/private'
- : '/api/browse/folders/' + payload.folder.id + '/public/' + router.currentRoute.params.token
-
return new Promise((resolve, reject) => {
axios
- .get(route + getters.sorting.URI)
+ .get(`/api/browse/folders/${payload.folder.id}/${router.currentRoute.params.token}${getters.sorting.URI}`)
.then(response => {
commit('LOADING_STATE', {loading: false, data: response.data})
commit('STORE_CURRENT_FOLDER', payload.folder)
@@ -66,6 +62,32 @@ const actions = {
})
})
},
+ getSingleFile: ({commit}) => {
+
+ axios.get(`/api/browse/file/${router.currentRoute.params.token}`)
+ .then(response => {
+ commit('STORE_SHARED_FILE', response.data)
+ })
+ },
+ getShareDetail: ({commit, state}, token) => {
+ return new Promise((resolve, reject) => {
+ axios
+ .get(`/api/browse/share/${token}`)
+ .then(response => {
+ resolve(response)
+
+ // Commit shared item options
+ commit('SET_SHARED_DETAIL', response.data.data.attributes)
+ commit('SET_PERMISSION', response.data.data.attributes.permission)
+ })
+ .catch(error => {
+ reject(error)
+
+ if (error.response.status == 404)
+ router.push({name: 'NotFound'})
+ })
+ })
+ },
shareCancel: ({commit, getters}, singleItem) => {
return new Promise((resolve, reject) => {
@@ -109,37 +131,6 @@ const actions = {
})
})
},
- getSingleFile: ({commit, state}) => {
-
- let route = state.sharedDetail.is_protected
- ? '/api/browse/files/private'
- : '/api/browse/files/' + router.currentRoute.params.token + '/public'
-
- axios.get(route)
- .then(response => {
- commit('STORE_SHARED_FILE', response.data)
- })
- },
- getShareDetail: ({commit, state}, token) => {
- return new Promise((resolve, reject) => {
- axios
- .get(`/api/browse/shared/${token}`)
- .then(response => {
- resolve(response)
-
- // Commit shared item options
- commit('SET_SHARED_DETAIL', response.data.data.attributes)
- commit('SET_PERMISSION', response.data.data.attributes.permission)
- })
- .catch(error => {
- reject(error)
-
- if (error.response.status == 404) {
- router.push({name: 'NotFound'})
- }
- })
- })
- },
}
const mutations = {
SET_SHARED_DETAIL(state, data) {
diff --git a/resources/js/store/modules/userAuth.js b/resources/js/store/modules/userAuth.js
index 75979fe1..0b2e10ca 100644
--- a/resources/js/store/modules/userAuth.js
+++ b/resources/js/store/modules/userAuth.js
@@ -35,7 +35,7 @@ const actions = {
)
})
},
- logOut: ({getters, commit}) => {
+ logOut: ({commit}) => {
let popup = setTimeout(() => {
commit('PROCESSING_POPUP', {
diff --git a/resources/js/views/Shared/SharedAuthentication.vue b/resources/js/views/Shared/SharedAuthentication.vue
index e666920c..47e43b57 100644
--- a/resources/js/views/Shared/SharedAuthentication.vue
+++ b/resources/js/views/Shared/SharedAuthentication.vue
@@ -42,7 +42,7 @@
},
data() {
return {
- password: undefined,
+ password: 'secret',
isLoading: false,
}
},
@@ -61,9 +61,18 @@
axios
.post('/api/browse/authenticate/' + this.$route.params.token, {
password: this.password
- }).then(() => {
+ })
+ .then(response => {
- // todo: Redirect to file browser page
+ // Show file browser
+ if (response.data.data.attributes.type === 'folder' && this.$router.currentRoute.name !== 'SharedFileBrowser') {
+ this.$router.push({name: 'SharedFileBrowser'})
+ }
+
+ // Show single file
+ if (response.data.data.attributes.type !== 'folder' && this.$router.currentRoute.name !== 'SharedSingleFile') {
+ this.$router.push({name: 'SharedSingleFile'})
+ }
})
.catch(error => {
diff --git a/routes/file.php b/routes/file.php
index bcc011c1..09068ffb 100644
--- a/routes/file.php
+++ b/routes/file.php
@@ -8,8 +8,8 @@ Route::get('/avatars/{avatar}', [FileAccessController::class, 'get_avatar'])->na
Route::get('/system/{image}', [FileAccessController::class, 'get_system_image']);
// Get public thumbnails and files
-Route::get('/thumbnail/{name}/public/{shared}', [FileSharedAccessController::class, 'get_thumbnail_public']);
-Route::get('/file/{name}/public/{shared}', [FileSharedAccessController::class, 'get_file_public']);
+Route::get('/thumbnail/{name}/{shared}', [FileSharedAccessController::class, 'get_thumbnail_public']);
+Route::get('/file/{name}/{shared}', [FileSharedAccessController::class, 'get_file_public']);
Route::get('/zip/{id}/public/{token}', [FileSharedAccessController::class, 'get_zip_public'])->name('zip_public');
// User master,editor,visitor access to image thumbnails and file downloads
diff --git a/routes/share.php b/routes/share.php
index 76864197..76f8175c 100644
--- a/routes/share.php
+++ b/routes/share.php
@@ -6,39 +6,30 @@ use App\Http\Controllers\Sharing\EditShareItemsController;
use App\Http\Controllers\FileManager\ShareController;
use App\Http\Controllers\Sharing\ServeSharedController;
-// Editor functions
+// Browse functions
Route::group(['prefix' => 'editor'], function () {
- Route::post('/create-folder/public/{shared}', [EditShareItemsController::class, 'create_folder']);
- Route::patch('/rename/{id}/public/{shared}', [EditShareItemsController::class, 'rename_item']);
- Route::post('/remove/public/{shared}', [EditShareItemsController::class, 'delete_item']);
- Route::post('/upload/public/{shared}', [EditShareItemsController::class, 'upload']);
- Route::post('/move/public/{shared}', [EditShareItemsController::class, 'move']);
+ Route::post('/create-folder/{shared}', [EditShareItemsController::class, 'create_folder']);
+ Route::patch('/rename/{id}/{shared}', [EditShareItemsController::class, 'rename_item']);
+ Route::post('/remove/{shared}', [EditShareItemsController::class, 'delete_item']);
+ Route::post('/upload/{shared}', [EditShareItemsController::class, 'upload']);
+ Route::post('/move/{shared}', [EditShareItemsController::class, 'move']);
});
-// Editor/Visitor zip functions
+// Zip shared items
Route::group(['prefix' => 'zip'], function () {
- Route::post('/files/public/{shared}', [EditShareItemsController::class, 'zip_multiple_files']);
- Route::get('/folder/{id}/public/{shared}', [EditShareItemsController::class, 'zip_folder']);
+ Route::post('/files/{shared}', [EditShareItemsController::class, 'zip_multiple_files']);
+ Route::get('/folder/{id}/{shared}', [EditShareItemsController::class, 'zip_folder']);
});
// Browse share content
Route::group(['prefix' => 'browse'], function () {
- Route::get('/navigation/public/{shared}', [BrowseShareController::class, 'get_public_navigation_tree']);
- Route::get('/folders/{id}/public/{shared}', [BrowseShareController::class, 'get_public_folders']);
- Route::get('/search/public/{shared}', [BrowseShareController::class, 'search_public']);
+ Route::get('/navigation/{shared}', [BrowseShareController::class, 'navigation_tree']);
+ Route::get('/folders/{id}/{shared}', [BrowseShareController::class, 'browse_folder']);
+ Route::get('/search/{shared}', [BrowseShareController::class, 'search']);
Route::post('/authenticate/{shared}', [ServeSharedController::class, 'authenticate']);
- Route::get('/files/{shared}/public', [ServeSharedController::class, 'file_public']);
- Route::get('/shared/{shared}', [ShareController::class, 'show']);
-});
-
-// Private sharing secured by password
-// TODO: tests
-Route::group(['middleware' => ['auth:api', 'auth.shared', 'scope:visitor,editor']], function () {
- Route::get('/folders/{id}/private', [ServeSharedController::class, 'get_private_folders']);
- Route::get('/navigation/private', [ServeSharedController::class, 'get_private_navigation_tree']);
- Route::get('/search/private', [ServeSharedController::class, 'search_private']);
- Route::get('/files/private', [ServeSharedController::class, 'file_private']);
+ Route::get('/file/{shared}', [ServeSharedController::class, 'file_public']);
+ Route::get('/share/{shared}', [ShareController::class, 'show']);
});
Route::get('/og-site/{shared}', [AppFunctionsController::class, 'og_site']);
\ No newline at end of file
diff --git a/tests/Feature/Share/PrivateShareContentAccessTest.php b/tests/Feature/Share/PrivateFilesAccessTest.php
similarity index 97%
rename from tests/Feature/Share/PrivateShareContentAccessTest.php
rename to tests/Feature/Share/PrivateFilesAccessTest.php
index 6c1df057..5ab9e67e 100644
--- a/tests/Feature/Share/PrivateShareContentAccessTest.php
+++ b/tests/Feature/Share/PrivateFilesAccessTest.php
@@ -8,7 +8,7 @@ use App\Services\SetupService;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
-class PrivateShareContentAccessTest extends TestCase
+class PrivateFilesAccessTest extends TestCase
{
use DatabaseMigrations;
diff --git a/tests/Feature/Share/PrivateVisitorTest.php b/tests/Feature/Share/PrivateVisitorTest.php
new file mode 100644
index 00000000..0b6a7a9c
--- /dev/null
+++ b/tests/Feature/Share/PrivateVisitorTest.php
@@ -0,0 +1,106 @@
+setup = app()->make(SetupService::class);
+ }
+
+ /**
+ * @test
+ */
+ public function authenticated_visitor_get_folder_content()
+ {
+ $user = User::factory(User::class)
+ ->create();
+
+ $root = Folder::factory(Folder::class)
+ ->create([
+ 'name' => 'root',
+ 'user_id' => $user->id,
+ ]);
+
+ $share = Share::factory(Share::class)
+ ->create([
+ 'item_id' => $root->id,
+ 'user_id' => $user->id,
+ 'type' => 'folder',
+ 'is_protected' => true,
+ 'permission' => 'editor',
+ ]);
+
+ $folder = Folder::factory(Folder::class)
+ ->create([
+ 'parent_id' => $root->id,
+ 'name' => 'Documents',
+ "user_scope" => "master",
+ 'user_id' => $user->id,
+ ]);
+
+ $file = File::factory(File::class)
+ ->create([
+ 'folder_id' => $root->id,
+ 'name' => 'Document',
+ 'basename' => 'document.pdf',
+ "mimetype" => "application/pdf",
+ "user_scope" => "master",
+ "type" => "file",
+ 'user_id' => $user->id,
+ ]);
+
+ $this->withUnencryptedCookie('share_session', json_encode([
+ 'token' => $share->token,
+ 'authenticated' => true,
+ ]))
+ ->get("/api/browse/folders/$root->id/private/$share->token")
+ ->assertStatus(200)
+ ->assertExactJson([
+ [
+ "id" => $folder->id,
+ "user_id" => $user->id,
+ "parent_id" => $root->id,
+ "name" => "Documents",
+ "color" => null,
+ "emoji" => null,
+ "user_scope" => "master",
+ "deleted_at" => null,
+ "created_at" => $folder->created_at,
+ "updated_at" => $folder->updated_at->toJson(),
+ "items" => 0,
+ "trashed_items" => 0,
+ "type" => "folder",
+ ],
+ [
+ "id" => $file->id,
+ "user_id" => $user->id,
+ "folder_id" => $root->id,
+ "thumbnail" => null,
+ "name" => "Document",
+ "basename" => "document.pdf",
+ "mimetype" => "application/pdf",
+ "filesize" => $file->filesize,
+ "type" => "file",
+ "metadata" => null,
+ "user_scope" => "master",
+ "deleted_at" => null,
+ "created_at" => $file->created_at,
+ "updated_at" => $file->updated_at->toJson(),
+ "file_url" => "http://localhost/file/document.pdf/private/$share->token",
+ ]
+ ]);
+ }
+}
diff --git a/tests/Feature/Share/PublicFilesAccessTest.php b/tests/Feature/Share/PublicFilesAccessTest.php
new file mode 100644
index 00000000..22cafed3
--- /dev/null
+++ b/tests/Feature/Share/PublicFilesAccessTest.php
@@ -0,0 +1,254 @@
+setup = app()->make(SetupService::class);
+ }
+
+ /**
+ * @test
+ */
+ public function it_get_public_file_record_and_download_file_within()
+ {
+ Storage::fake('local');
+
+ $this->setup->create_directories();
+
+ collect(['private', 'public'])
+ ->each(function ($permission) {
+
+ $user = User::factory(User::class)
+ ->create();
+
+ $document = UploadedFile::fake()
+ ->create(Str::random() . '-fake-file.pdf', 1000, 'application/pdf');
+
+ Storage::putFileAs("files/$user->id", $document, $document->name);
+
+ $file = File::factory(File::class)
+ ->create([
+ 'filesize' => $document->getSize(),
+ 'user_id' => $user->id,
+ 'basename' => $document->name,
+ 'name' => 'fake-file.pdf',
+ ]);
+
+ $share = Share::factory(Share::class)
+ ->create([
+ 'item_id' => $file->id,
+ 'user_id' => $user->id,
+ 'type' => 'file',
+ 'is_protected' => $permission === 'private',
+ 'password' => \Hash::make('secret'),
+ ]);
+
+ if ($permission === 'private') {
+
+ $cookie = ['share_session' => json_encode([
+ 'token' => $share->token,
+ 'authenticated' => true,
+ ])];
+
+ $this->disableCookieEncryption();
+ $this->defaultCookies = $cookie;
+
+ $this->get("/api/browse/file/$share->token/private")
+ ->assertStatus(200)
+ ->assertJsonFragment([
+ 'basename' => $document->name
+ ]);
+
+ $this->get("/file/$document->name/private/$share->token")
+ ->assertStatus(200);
+ }
+
+ if ($permission === 'public') {
+
+ $this->get("/api/browse/file/$share->token/public")
+ ->assertStatus(200)
+ ->assertJsonFragment([
+ 'basename' => $document->name
+ ]);
+
+ // Get shared file
+ $this->get("/file/$document->name/public/$share->token")
+ ->assertStatus(200);
+ }
+
+ /*$this->assertDatabaseHas('traffic', [
+ 'user_id' => $user->id,
+ ]);*/
+ });
+ }
+
+ /**
+ * @test
+ */
+ public function it_try_to_get_protected_file_record()
+ {
+ $share = Share::factory(Share::class)
+ ->create([
+ 'type' => 'file',
+ 'is_protected' => true,
+ ]);
+
+ // Get share record
+ $this->get("/api/browse/file/$share->token/public")
+ ->assertStatus(403);
+ }
+
+ /**
+ * @test
+ */
+ public function it_get_shared_image()
+ {
+ Storage::fake('local');
+
+ $this->setup->create_directories();
+
+ $user = User::factory(User::class)
+ ->create();
+
+ $thumbnail = UploadedFile::fake()
+ ->image(Str::random() . '-fake-image.jpg');
+
+ Storage::putFileAs("files/$user->id", $thumbnail, $thumbnail->name);
+
+ $file = File::factory(File::class)
+ ->create([
+ 'user_id' => $user->id,
+ 'thumbnail' => $thumbnail->name,
+ 'basename' => $thumbnail->name,
+ 'name' => 'fake-thumbnail.jpg',
+ 'type' => 'image',
+ 'mimetype' => 'jpg',
+ ]);
+
+ $share = Share::factory(Share::class)
+ ->create([
+ 'item_id' => $file->id,
+ 'user_id' => $user->id,
+ 'type' => 'file',
+ 'is_protected' => false,
+ ]);
+
+ $this->get("/shared/$share->token")
+ ->assertStatus(200);
+ }
+
+ /**
+ * @test
+ */
+ public function it_get_public_thumbnail()
+ {
+ Storage::fake('local');
+
+ $this->setup->create_directories();
+
+ collect(['private', 'public'])
+ ->each(function ($permission) {
+
+ $user = User::factory(User::class)
+ ->create();
+
+ $thumbnail = UploadedFile::fake()
+ ->image(Str::random() . '-fake-thumbnail.jpg');
+
+ Storage::putFileAs("files/$user->id", $thumbnail, $thumbnail->name);
+
+ $file = File::factory(File::class)
+ ->create([
+ 'user_id' => $user->id,
+ 'thumbnail' => $thumbnail->name,
+ 'name' => 'fake-thumbnail.jpg',
+ ]);
+
+ $share = Share::factory(Share::class)
+ ->create([
+ 'item_id' => $file->id,
+ 'user_id' => $user->id,
+ 'type' => 'file',
+ 'is_protected' => $permission === 'private',
+ 'password' => \Hash::make('secret'),
+ ]);
+
+ // Get thumbnail file
+ if ($permission === 'private') {
+ $this->withCookie('share_session', json_encode([
+ 'token' => $share->token,
+ 'authenticated' => true,
+ ]))
+ ->get("/thumbnail/$thumbnail->name/private/$share->token")
+ ->assertStatus(200);
+ }
+
+ if ($permission === 'public') {
+ $this->get("/thumbnail/$thumbnail->name/public/$share->token")
+ ->assertStatus(200);
+ }
+
+ $this->assertDatabaseMissing('traffic', [
+ 'user_id' => $user->id,
+ 'download' => null,
+ ]);
+ });
+ }
+
+ /**
+ * @test
+ */
+ public function it_download_publicly_zipped_files()
+ {
+ Storage::fake('local');
+
+ $this->setup->create_directories();
+
+ $user = User::factory(User::class)
+ ->create();
+
+ $share = Share::factory(Share::class)
+ ->create([
+ 'user_id' => $user->id,
+ 'type' => 'folder',
+ 'is_protected' => false,
+ ]);
+
+ $zip = Zip::factory(Zip::class)->create([
+ 'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
+ 'user_id' => $user->id,
+ 'shared_token' => $share->token,
+ ]);
+
+ $file = UploadedFile::fake()
+ ->create($zip->basename, 1000, 'application/zip');
+
+ Storage::putFileAs("zip", $file, $file->name);
+
+ $this->get("/zip/$zip->id/public/$share->token")
+ ->assertStatus(200);
+
+ $this->assertDatabaseMissing('traffic', [
+ 'user_id' => $user->id,
+ 'download' => null,
+ ]);
+ }
+}
diff --git a/tests/Feature/Share/PublicShareContentAccessTest.php b/tests/Feature/Share/PublicShareContentAccessTest.php
deleted file mode 100644
index f90e443e..00000000
--- a/tests/Feature/Share/PublicShareContentAccessTest.php
+++ /dev/null
@@ -1,211 +0,0 @@
-setup = app()->make(SetupService::class);
- }
-
- /**
- * @test
- */
- public function it_get_public_file_record_and_download_file_within()
- {
- Storage::fake('local');
-
- $this->setup->create_directories();
-
- $user = User::factory(User::class)
- ->create();
-
- $document = UploadedFile::fake()
- ->create(Str::random() . '-fake-file.pdf', 1000, 'application/pdf');
-
- Storage::putFileAs("files/$user->id", $document, $document->name);
-
- $file = File::factory(File::class)
- ->create([
- 'filesize' => $document->getSize(),
- 'user_id' => $user->id,
- 'basename' => $document->name,
- 'name' => 'fake-file.pdf',
- ]);
-
- $share = Share::factory(Share::class)
- ->create([
- 'item_id' => $file->id,
- 'user_id' => $user->id,
- 'type' => 'file',
- 'is_protected' => false,
- ]);
-
- // Get share record
- $this->get("/api/browse/files/$share->token/public")
- ->assertStatus(200)
- ->assertJsonFragment([
- 'basename' => $document->name
- ]);
-
- // Get shared file
- $this->get("/file/$document->name/public/$share->token")
- ->assertStatus(200);
-
- $this->assertDatabaseHas('traffic', [
- 'user_id' => $user->id,
- 'download' => '1024000',
- ]);
- }
-
- /**
- * @test
- */
- public function it_try_to_get_protected_file_record()
- {
- $share = Share::factory(Share::class)
- ->create([
- 'type' => 'file',
- 'is_protected' => true,
- ]);
-
- // Get share record
- $this->get("/api/browse/files/$share->token/public")
- ->assertStatus(403);
- }
-
- /**
- * @test
- */
- public function it_get_shared_image()
- {
- Storage::fake('local');
-
- $this->setup->create_directories();
-
- $user = User::factory(User::class)
- ->create();
-
- $thumbnail = UploadedFile::fake()
- ->image(Str::random() . '-fake-image.jpg');
-
- Storage::putFileAs("files/$user->id", $thumbnail, $thumbnail->name);
-
- $file = File::factory(File::class)
- ->create([
- 'user_id' => $user->id,
- 'thumbnail' => $thumbnail->name,
- 'basename' => $thumbnail->name,
- 'name' => 'fake-thumbnail.jpg',
- 'type' => 'image',
- 'mimetype' => 'jpg',
- ]);
-
- $share = Share::factory(Share::class)
- ->create([
- 'item_id' => $file->id,
- 'user_id' => $user->id,
- 'type' => 'file',
- 'is_protected' => false,
- ]);
-
- $this->get("/shared/$share->token")
- ->assertStatus(200);
- }
-
- /**
- * @test
- */
- public function it_download_public_thumbnail()
- {
- Storage::fake('local');
-
- $this->setup->create_directories();
-
- $user = User::factory(User::class)
- ->create();
-
- $thumbnail = UploadedFile::fake()
- ->image(Str::random() . '-fake-thumbnail.jpg');
-
- Storage::putFileAs("files/$user->id", $thumbnail, $thumbnail->name);
-
- $file = File::factory(File::class)
- ->create([
- 'user_id' => $user->id,
- 'thumbnail' => $thumbnail->name,
- 'name' => 'fake-thumbnail.jpg',
- ]);
-
- $share = Share::factory(Share::class)
- ->create([
- 'item_id' => $file->id,
- 'user_id' => $user->id,
- 'type' => 'file',
- 'is_protected' => false,
- ]);
-
- // Get thumbnail file
- $this->get("/thumbnail/$thumbnail->name/public/$share->token")
- ->assertStatus(200);
-
- $this->assertDatabaseMissing('traffic', [
- 'user_id' => $user->id,
- 'download' => null,
- ]);
- }
-
- /**
- * @test
- */
- public function it_download_publicly_zipped_files()
- {
- Storage::fake('local');
-
- $this->setup->create_directories();
-
- $user = User::factory(User::class)
- ->create();
-
- $share = Share::factory(Share::class)
- ->create([
- 'user_id' => $user->id,
- 'type' => 'folder',
- 'is_protected' => false,
- ]);
-
- $zip = Zip::factory(Zip::class)->create([
- 'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
- 'user_id' => $user->id,
- 'shared_token' => $share->token,
- ]);
-
- $file = UploadedFile::fake()
- ->create($zip->basename, 1000, 'application/zip');
-
- Storage::putFileAs("zip", $file, $file->name);
-
- $this->get("/zip/$zip->id/public/$share->token")
- ->assertStatus(200);
-
- $this->assertDatabaseMissing('traffic', [
- 'user_id' => $user->id,
- 'download' => null,
- ]);
- }
-}
diff --git a/tests/Feature/Share/ShareEditorTest.php b/tests/Feature/Share/PublicVisitorTest.php
similarity index 99%
rename from tests/Feature/Share/ShareEditorTest.php
rename to tests/Feature/Share/PublicVisitorTest.php
index c7e151ab..b26dde67 100644
--- a/tests/Feature/Share/ShareEditorTest.php
+++ b/tests/Feature/Share/PublicVisitorTest.php
@@ -15,7 +15,7 @@ use Laravel\Sanctum\Sanctum;
use Storage;
use Tests\TestCase;
-class ShareEditorTest extends TestCase
+class PrivateVisitorTest extends TestCase
{
use DatabaseMigrations;
@@ -775,7 +775,7 @@ class ShareEditorTest extends TestCase
]);
- $this->getJson("/api/browse/files/$share->token/public")
+ $this->getJson("/api/browse/file/$share->token/public")
->assertStatus(200)
->assertJsonFragment([
'name' => 'Document'