Compare commits

...

12 Commits

Author SHA1 Message Date
Peter Papp
7f6f60227a Ability to set expiration for shared link
If user is logged in, after visit SignIn page will be redirected to files page
2020-08-26 08:17:49 +02:00
Peter Papp
ab6ff5dbfd force migration
added maintenance mode
2020-08-26 07:51:16 +02:00
Peter Papp
0d272bc9b7 version change 2020-08-26 07:30:48 +02:00
Peter Papp
2b08d7801b Shared link expiration backend
Redirect from sign in page when user is logged
Updated README.md
2020-08-26 07:29:28 +02:00
Peter Papp
cec4ff6cda shared link title fix 2020-08-25 15:33:16 +02:00
Peter Papp
6f300ba1d5 Link expiration frontend 2020-08-25 15:25:18 +02:00
Peter Papp
86813629ed updated readme 2020-08-25 12:53:46 +02:00
Peter Papp
73a728e606 change vuefilemanager version 2020-08-25 12:37:09 +02:00
Peter Papp
af1228e363 reading metadata in shared link RC 2020-08-25 12:36:21 +02:00
Peter Papp
f3a2758bcc reading metadata in shared link v0.1 2020-08-25 12:04:13 +02:00
Peter Papp
6f9f2f2d34 reading metadata in shared link 2020-08-25 11:03:53 +02:00
Peter Papp
9f4c21a1b1 UserSubscription page fix
PaymentMethods page fix
2020-08-24 09:30:38 +02:00
108 changed files with 4756 additions and 4686 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,8 @@ But, it can't be done without you, development is more and more complicated and
- [Recover Failed Installation](#installation-failed)
- [Update Guide](#update-guide)
- [Instructions](#instructions)
- [Update from 1.7.x to 1.7.7](#update-from-17x-to-177)
- [Update from 1.7.8 to 1.7.9](#update-from-178-to-179)
- [Update from 1.7.x to 1.7.8](#update-from-17x-to-178)
- [Update from 1.6.x to 1.7](#update-from-16x-to-17)
- [Payments](#payments)
- [Get your active plans](#get-your-active-plans)
@@ -104,6 +105,13 @@ At first step you have to verify your purchase code. **Subscription service with
That was the hardest part of installation proces. Please follow instructions in every step of Setup Wizard to successfully install VueFileManager.
#### 7. Set up Cron
Add the following Cron entry to your server
```
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```
## PHP Configuration
There are several PHP settings good to know to setup before you try upload any file. Please set these values in your php.ini, we provide minimal setup for you. When you set `-1` then you set infinity limits.
@@ -203,7 +211,17 @@ Follow this steps:
- Upload and replace all the files on your server with what's inside the app folder.
- Restore your `.env` config file on your server.
## Update from 1.7.x to 1.7.7
## Update from 1.7.8 to 1.7.9
After uploaded new files, log in as admin to the app and go to `your-domain.com/service/upgrade-database`. This will upgrade your database on the background.
After that, **update path to your project in command below** and add the following **Cron** entry to your server:
```
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```
That's all.
## Update from 1.7.x to 1.7.8
If you are upgrading app to 1.7.7 from 1.7.x, make sure you have copied new /vendor folder or if you are using terminal or git, run `composer update` command to update your vendors.
## Update from 1.6.x to 1.7

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,8 @@ use App\Console\Commands\Deploy;
use App\Console\Commands\SetupDevEnvironment;
use App\Console\Commands\SetupProductionEnvironment;
use App\Console\Commands\UpgradeApp;
use App\Share;
use Carbon\Carbon;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -23,13 +25,14 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->call(function () {
$this->delete_expired_shared_links();
})->hourly();
}
/**
@@ -39,8 +42,28 @@ class Kernel extends ConsoleKernel
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
/**
* Get and delete expired shared links
*/
protected function delete_expired_shared_links(): void
{
// Get all shares with expiration time
$shares = Share::whereNotNull('expire_in')->get();
$shares->each(function ($share) {
// Get dates
$created_at = Carbon::parse($share->created_at);
// If time was over, then delete share record
if ($created_at->diffInHours(Carbon::now()) >= $share->expire_in) {
$share->delete();
}
});
}
}

View File

@@ -85,8 +85,8 @@ class UserController extends Controller
{
$user = User::find($id);
if (! $user->stripeId()) {
return response('User is not stripe customer', 404);
if (! $user->stripeId() || ! $user->subscription('main')) {
return response('User doesn\'t have any subscription.', 404);
}
return new UserSubscription(

View File

@@ -3,12 +3,15 @@
namespace App\Http\Controllers;
use App\Content;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\PublicPages\SendMessageRequest;
use App\Http\Resources\PageResource;
use App\Http\Tools\Demo;
use App\Mail\SendSupportForm;
use App\Page;
use App\Setting;
use App\User;
use Artisan;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Http\Request;
@@ -96,6 +99,68 @@ class AppFunctionsController extends Controller
->with('installation', $connection);
}
/**
* Get og site for web crawlers
*
* @param $token
*/
public function og_site($token)
{
// Get all settings
$settings = Setting::all();
// Get shared token
$shared = get_shared($token);
// Get user
$user = User::findOrFail($shared->user_id);
// Handle single file
if ($shared->type === 'file') {
// Get file record
$file = FileManagerFile::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->first();
if ($file->thumbnail) {
$file->setPublicUrl($token);
}
$metadata = [
'is_protected' => $shared->protected,
'url' => url('/shared', ['token' => $token]),
'user' => $user->name,
'name' => $file->name,
'size' => $file->filesize,
'thumbnail' => $file->thumbnail ? $file->thumbnail : null,
];
}
// Handle single file
if ($shared->type === 'folder') {
// Get file record
$folder = FileManagerFolder::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->first();
$metadata = [
'is_protected' => $shared->protected,
'url' => url('/shared', ['token' => $token]),
'user' => $user->name,
'name' => $folder->name,
'size' => $folder->items,
'thumbnail' => null,
];
}
// Return view
return view("og-view")
->with('settings', json_decode($settings->pluck('value', 'name')->toJson()))
->with('metadata', $metadata);
}
/**
* Check if setup wizard was passed
*

View File

@@ -69,12 +69,12 @@ class BrowseController extends Controller
->pluck('item_id');
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $folder_ids)
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $file_ids)
->get();
@@ -145,13 +145,13 @@ class BrowseController extends Controller
}
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->orderBy('created_at', 'DESC')
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->orderBy('created_at', 'DESC')
@@ -217,7 +217,7 @@ class BrowseController extends Controller
// Get user id
$user_id = Auth::id();
return FileManagerFile::with(['shared:token,id,item_id,permission,protected'])
return FileManagerFile::with(['shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();

View File

@@ -51,6 +51,7 @@ class ShareController extends Controller
'protected' => $request->isPassword,
'permission' => $request->permission,
'item_id' => $request->unique_id,
'expire_in' => $request->expiration,
'user_id' => Auth::id(),
'token' => $token,
];
@@ -77,6 +78,7 @@ class ShareController extends Controller
$shared->update([
'permission' => $request->permission,
'protected' => $request->protected,
'expire_in' => $request->expiration,
'password' => $request->password ? Hash::make($request->password) : $shared->password,
]);

View File

@@ -7,6 +7,7 @@ use App\Page;
use App\Setting;
use Artisan;
use Illuminate\Http\Request;
use Schema;
class UpgradeAppController extends Controller
{
@@ -123,4 +124,52 @@ class UpgradeAppController extends Controller
return response('Done', 200);
}
/**
* Start maintenance mode
*/
public function up() {
$command = Artisan::call('up');
if ($command === 0) {
echo 'System is in production mode';
}
}
/**
* End maintenance mode
*/
public function down() {
$command = Artisan::call('down');
if ($command === 0) {
echo 'System is in maintenance mode';
}
}
/**
* Upgrade database
*/
public function upgrade_database()
{
/*
* Upgrade expire_in in shares table
*
* @since v1.7.9
*/
if (! Schema::hasColumn('shares', 'expire_in')) {
$command = Artisan::call('migrate', [
'--force' => true
]);
if ($command === 0) {
echo 'Operation was successful.';
}
if ($command === 1) {
echo 'Operation failed.';
}
}
}
}

View File

@@ -12,6 +12,8 @@ class CheckForMaintenanceMode extends Middleware
* @var array
*/
protected $except = [
//
'/service/upgrade-database',
'/service/down',
'/service/up',
];
}

View File

@@ -28,6 +28,7 @@ class CreateShareRequest extends FormRequest
'isPassword' => 'required|boolean',
'unique_id' => 'required|integer',
'type' => 'required|string',
'expiration' => 'integer|nullable',
'permission' => 'string',
'password' => 'string',
];

View File

@@ -27,6 +27,7 @@ class UpdateShareRequest extends FormRequest
return [
'protected' => 'required|boolean',
'permission' => 'nullable|string',
'expiration' => 'integer|nullable',
'password' => 'string',
];
}

View File

@@ -22,6 +22,7 @@ class ShareResource extends JsonResource
'permission' => $this->permission,
'protected' => (int) $this->protected,
'item_id' => (int) $this->item_id,
'expire_in' => (int) $this->expire_in,
'token' => $this->token,
'link' => $this->link,
'type' => $this->type,

View File

@@ -5,6 +5,25 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
use Kyslik\ColumnSortable\Sortable;
/**
* App\Page
*
* @property int $id
* @property int $visibility
* @property string $title
* @property string $slug
* @property string $content
* @method static \Illuminate\Database\Eloquent\Builder|Page newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Page newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Page query()
* @method static \Illuminate\Database\Eloquent\Builder|Page sortable($defaultParameters = null)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereContent($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereVisibility($value)
* @mixin \Eloquent
*/
class Page extends Model
{
use Sortable;

View File

@@ -4,6 +4,20 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\Setting
*
* @property int $id
* @property string $name
* @property string|null $value
* @method static \Illuminate\Database\Eloquent\Builder|Setting newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Setting newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Setting query()
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereValue($value)
* @mixin \Eloquent
*/
class Setting extends Model
{
public $timestamps = false;

View File

@@ -73,6 +73,7 @@ use Rinvex\Subscriptions\Traits\HasSubscriptions;
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereRole($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereStripeId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereTrialEndsAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User sortable($defaultParameters = null)
*/
class User extends Authenticatable
{
@@ -193,7 +194,7 @@ class User extends Authenticatable
*/
public function getFolderTreeAttribute()
{
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('parent_id', 0)
->where('user_id', $this->id)
->get();
@@ -258,7 +259,7 @@ class User extends Authenticatable
*/
public function favourite_folders()
{
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected,expire_in');
}
/**

View File

@@ -4,6 +4,34 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\UserSettings
*
* @property int $id
* @property int $user_id
* @property int $storage_capacity
* @property string|null $billing_name
* @property string|null $billing_address
* @property string|null $billing_state
* @property string|null $billing_city
* @property string|null $billing_postal_code
* @property string|null $billing_country
* @property string|null $billing_phone_number
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings query()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingAddress($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCity($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCountry($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingName($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPhoneNumber($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPostalCode($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingState($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereStorageCapacity($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereUserId($value)
* @mixin \Eloquent
*/
class UserSettings extends Model
{
public $timestamps = false;

View File

@@ -15,6 +15,7 @@
"fruitcake/laravel-cors": "^1.0",
"gabrielelana/byte-units": "^0.5.0",
"intervention/image": "^2.5",
"jaybizzle/laravel-crawler-detect": "^1.2",
"kyslik/column-sortable": "^6.3",
"laravel/cashier": "^12.0",
"laravel/framework": "^7.0",

115
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0d1b10acc2a996969b828cc7f51cdee6",
"content-hash": "aadbe31a952d26aab5730369e2bf4089",
"packages": [
{
"name": "asm89/stack-cors",
@@ -1467,6 +1467,119 @@
],
"time": "2019-11-02T09:15:47+00:00"
},
{
"name": "jaybizzle/crawler-detect",
"version": "v1.2.98",
"source": {
"type": "git",
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
"reference": "02b24e5d4dc347737577f48c688ee14c3b5dfd4f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/02b24e5d4dc347737577f48c688ee14c3b5dfd4f",
"reference": "02b24e5d4dc347737577f48c688ee14c3b5dfd4f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.5|^6.5",
"satooshi/php-coveralls": "1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"Jaybizzle\\CrawlerDetect\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Beech",
"email": "m@rkbee.ch",
"role": "Developer"
}
],
"description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent",
"homepage": "https://github.com/JayBizzle/Crawler-Detect/",
"keywords": [
"crawler",
"crawler detect",
"crawler detector",
"crawlerdetect",
"php crawler detect"
],
"time": "2020-08-20T18:36:15+00:00"
},
{
"name": "jaybizzle/laravel-crawler-detect",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/JayBizzle/Laravel-Crawler-Detect.git",
"reference": "e39b536fb5e4f21a49328e83a2ab26f0b64b06f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/JayBizzle/Laravel-Crawler-Detect/zipball/e39b536fb5e4f21a49328e83a2ab26f0b64b06f7",
"reference": "e39b536fb5e4f21a49328e83a2ab26f0b64b06f7",
"shasum": ""
},
"require": {
"jaybizzle/crawler-detect": "1.*",
"php": ">=5.4.0"
},
"require-dev": {
"orchestra/testbench": "3.1.*",
"phpunit/phpunit": "4.*"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Jaybizzle\\LaravelCrawlerDetect\\LaravelCrawlerDetectServiceProvider"
],
"aliases": {
"Crawler": "Jaybizzle\\LaravelCrawlerDetect\\Facades\\LaravelCrawlerDetect"
}
}
},
"autoload": {
"psr-4": {
"Jaybizzle\\LaravelCrawlerDetect\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Beech",
"email": "mbeech@mark-beech.co.uk"
}
],
"description": "A Laravel package to detect web crawlers via the user agent",
"homepage": "http://github.com/JayBizzle/Laravel-Crawler-Detect",
"keywords": [
"bot",
"crawler",
"crawler detect",
"crawler detector",
"crawlerdetect",
"detect",
"laravel",
"php crawler detect",
"spider",
"user-agent"
],
"time": "2017-06-01T20:29:30+00:00"
},
{
"name": "kyslik/column-sortable",
"version": "6.3.0",

View File

@@ -231,6 +231,7 @@ return [
'View' => Illuminate\Support\Facades\View::class,
'Image' => Intervention\Image\Facades\Image::class,
'Stripe' => Cartalyst\Stripe\Laravel\Facades\Stripe::class,
'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class,
],
'deploy_secret' => env('APP_DEPLOY_SECRET'),

View File

@@ -2,7 +2,7 @@
return [
'version' => '1.7.7',
'version' => '1.7.9',
// Define size of chunk uploaded by MB. E.g. integer 128 means chunk size will be 128MB.
'chunk_size' => env('CHUNK_SIZE', '128'),

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddExpirationAtAttributeToSharesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('shares', function (Blueprint $table) {
$table->integer('expire_in')->after('password')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('shares', function (Blueprint $table) {
//
});
}
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{584:function(e,t,r){"use strict";r.r(t);var n=r(7);function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var c={name:"SetupWizard",computed:function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},Object(n.b)(["config"])),mounted:function(){"setup-done"!==this.config.installation&&"quiet-update"!==this.config.installation||this.$router.push({name:"SignIn"})}},u=r(0),a=Object(u.a)(c,(function(){var e=this.$createElement;return(this._self._c||e)("router-view")}),[],!1,null,null,null);t.default=a.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{556:function(e,t,r){"use strict";r.r(t);var n=r(7);function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var c={name:"SetupWizard",computed:function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},Object(n.b)(["config"])),mounted:function(){"setup-done"!==this.config.installation&&"quiet-update"!==this.config.installation||this.$router.push({name:"SignIn"})}},u=r(0),a=Object(u.a)(c,(function(){var e=this.$createElement;return(this._self._c||e)("router-view")}),[],!1,null,null,null);t.default=a.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
*/
/*!
* vue-i18n v8.21.0
* vue-i18n v8.18.2
* (c) 2020 kazuya kawaguchi
* Released under the MIT License.
*/
@@ -17,7 +17,7 @@
*/
/**
* vee-validate v3.3.9
* vee-validate v3.3.7
* (c) 2020 Abdelrahman Awad
* @license MIT
*/

View File

@@ -1,6 +1,7 @@
<template>
<div class="action-button">
<FontAwesomeIcon class="icon" :icon="icon" />
<x-icon size="12" class="icon" v-if="icon === 'x'"></x-icon>
<edit-2-icon size="12" class="icon" v-if="icon === 'pencil-alt'"></edit-2-icon>
<span class="label">
<slot></slot>
</span>
@@ -8,9 +9,15 @@
</template>
<script>
import { Edit2Icon, XIcon } from 'vue-feather-icons'
export default {
name: 'ActionButton',
props: ['icon'],
components: {
Edit2Icon,
XIcon,
}
}
</script>
@@ -23,18 +30,17 @@
.label {
@include font-size(12);
color: $theme;
font-weight: 600;
text-decoration: underline;
}
.icon {
@include font-size(10);
vertical-align: middle;
display: inline-block;
margin-right: 2px;
path {
fill: $theme;
path, circle, line {
stroke: $theme;
}
}
}

View File

@@ -0,0 +1,95 @@
<template>
<div class="select-box">
<div class="box-item"
:class="{'selected': item.value === input}"
@click="getSelectedValue(item)"
v-for="(item, i) in data" :key="i"
>
<span class="box-value">{{ item.label }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'SelectBoxInput',
props: [
'data',
'value',
],
data() {
return {
input: undefined,
}
},
methods: {
getSelectedValue(item) {
if (! this.input || this.input !== item.value)
this.input = item.value
else
this.input = undefined
this.$emit('input', this.input)
}
},
created() {
if (this.value)
this.input = this.value
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import "@assets/vue-file-manager/_forms.scss";
.select-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
flex-direction: row;
margin-bottom: 10px;
.box-item {
margin-bottom: 10px;
padding: 12px 4px;
text-align: center;
background: $light_background;
border-radius: 8px;
font-weight: 700;
border: 2px solid $light_background;
cursor: pointer;
flex-direction: column;
flex-basis: 55px;
.box-value {
@include font-size(15);
}
&.selected {
background: rgba($theme, .1);
border-color: $theme;
.box-value {
color: $theme;
}
}
}
}
@media only screen and (max-width: 960px) {
.select-box {
.box-item {
flex-basis: calc(34% - 10px);
}
}
}
@media (prefers-color-scheme: dark) {
}
</style>

View File

@@ -32,6 +32,18 @@
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" :placeholder="$t('page_sign_in.placeholder_password')">
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<!--More options-->
<div class="more-options" v-if="isMoreOptions">
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" class="box"/>
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
</ValidationObserver>
<!--Copy generated link-->
@@ -66,6 +78,7 @@
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import SelectBoxInput from '@/components/Others/Forms/SelectBoxInput'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
import PopupContent from '@/components/Others/Popup/PopupContent'
@@ -73,6 +86,7 @@
import SwitchInput from '@/components/Others/Forms/SwitchInput'
import SelectInput from '@/components/Others/Forms/SelectInput'
import ThumbnailItem from '@/components/Others/ThumbnailItem'
import ActionButton from '@/components/Others/ActionButton'
import CopyInput from '@/components/Others/Forms/CopyInput'
import ButtonBase from '@/components/FilesView/ButtonBase'
import {required} from 'vee-validate/dist/rules'
@@ -85,7 +99,9 @@
components: {
ValidationProvider,
ValidationObserver,
SelectBoxInput,
ThumbnailItem,
ActionButton,
PopupWrapper,
PopupActions,
PopupContent,
@@ -97,7 +113,10 @@
required,
},
computed: {
...mapGetters(['permissionOptions']),
...mapGetters([
'permissionOptions',
'expirationList',
]),
itemTypeTitle() {
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
},
@@ -106,12 +125,16 @@
},
submitButtonText() {
return this.isGeneratedShared ? this.$t('shared_form.button_done') : this.$t('shared_form.button_generate')
},
moreOptionsTitle() {
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
}
},
data() {
return {
shareOptions: {
isPassword: false,
expiration: undefined,
password: undefined,
permission: undefined,
type: undefined,
@@ -121,9 +144,16 @@
shareLink: undefined,
isGeneratedShared: false,
isLoading: false,
isMoreOptions: false,
}
},
methods: {
moreOptions() {
this.isMoreOptions = ! this.isMoreOptions
if (! this.isMoreOptions)
this.shareOptions.expiration = undefined
},
async submitShareOptions() {
// If shared was generated, then close popup
@@ -185,10 +215,12 @@
permission: undefined,
password: undefined,
isPassword: false,
expiration: undefined,
type: undefined,
unique_id: undefined,
}
this.isGeneratedShared = false
this.isMoreOptions = false
this.shareLink = undefined
}, 150)
})
@@ -200,6 +232,10 @@
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
.more-options {
margin-bottom: 10px;
}
.input-wrapper {
&.password {

View File

@@ -31,7 +31,7 @@
<label class="input-label">{{ $t('shared_form.label_password_protection') }}:</label>
<SwitchInput v-model="shareOptions.isProtected" :state="shareOptions.isProtected" class="switch"/>
</div>
<ActionButton v-if="(pickedItem.shared.protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" icon="pencil-alt">{{ $t('popup_share_edit.change_pass') }}</ActionButton>
<ActionButton v-if="(pickedItem.shared.protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" class="change-password">{{ $t('popup_share_edit.change_pass') }}</ActionButton>
</div>
<!--Set password-->
@@ -40,6 +40,18 @@
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<!--More options-->
<div class="more-options" v-if="isMoreOptions">
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" :value="shareOptions.expiration" class="box"/>
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions || shareOptions.expiration ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
</ValidationObserver>
</PopupContent>
@@ -68,6 +80,7 @@
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import SelectBoxInput from '@/components/Others/Forms/SelectBoxInput'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
import PopupContent from '@/components/Others/Popup/PopupContent'
@@ -88,6 +101,7 @@
components: {
ValidationProvider,
ValidationObserver,
SelectBoxInput,
ThumbnailItem,
ActionButton,
PopupWrapper,
@@ -101,7 +115,12 @@
required,
},
computed: {
...mapGetters(['user', 'permissionOptions', 'currentFolder']),
...mapGetters([
'permissionOptions',
'expirationList',
'currentFolder',
'user',
]),
isFolder() {
return this.pickedItem && this.pickedItem.type === 'folder'
},
@@ -114,18 +133,28 @@
isSharedLocation() {
return this.currentFolder && this.currentFolder.location === 'shared'
},
moreOptionsTitle() {
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
}
},
data() {
return {
isConfirmedDestroy: false,
canChangePassword: false,
shareOptions: undefined,
pickedItem: undefined,
isLoading: false,
isMoreOptions: false,
isDeleting: false,
canChangePassword: false,
isConfirmedDestroy: false,
isLoading: false,
}
},
methods: {
moreOptions() {
this.isMoreOptions = ! this.isMoreOptions
if (! this.isMoreOptions)
this.shareOptions.expiration = undefined
},
changePassword() {
this.canChangePassword = false
},
@@ -187,22 +216,22 @@
.post('/api/share/' + this.shareOptions.token, {
permission: this.shareOptions.permission,
protected: this.shareOptions.isProtected,
expiration: this.shareOptions.expiration,
password: this.shareOptions.password ? this.shareOptions.password : undefined,
_method: 'patch'
})
.then(response => {
// End loading
this.isLoading = false
// Update shared data
this.$store.commit('UPDATE_SHARED_ITEM', response.data.data.attributes)
events.$emit('popup:close')
})
.catch(error => {
.catch(() => {
// todo: catch errors
this.$isSomethingWrong()
})
.finally(() => {
// End loading
this.isLoading = false
@@ -222,11 +251,15 @@
// Store shared options
this.shareOptions = {
token: args.item.shared.token,
expiration: args.item.shared.expire_in,
isProtected: args.item.shared.protected,
permission: args.item.shared.permission,
password: undefined,
}
if (args.item.shared.expire_in)
this.isMoreOptions = true
this.canChangePassword = args.item.shared.protected
})
@@ -256,6 +289,11 @@
}
}
.change-password {
opacity: 0.7;
text-decoration: underline;
}
.item-thumbnail {
margin-bottom: 20px;
}

View File

@@ -52,7 +52,7 @@ const Helpers = {
}
Vue.prototype.$getImage = function (source) {
return source ? '/' + source : ''
return source ? this.$store.getters.config.host + '/' + source : ''
}
Vue.prototype.$getCreditCardBrand = function (brand) {

View File

@@ -626,11 +626,16 @@
"visitor": "仅可以查看或下载文件"
},
"shared_form": {
"button_more_options": "More Options",
"button_close_options": "Close Options",
"button_done": "太好了!",
"button_generate": "生成分享链接",
"label_password_protection": "密码保护",
"label_permission": "权限",
"label_shared_url": "分享链接",
"label_expiration": "Link Expiration",
"expiration_hour": "{value}h.",
"expiration_day": "{value}d.",
"placeholder_permission": "请设置权限"
},
"sidebar": {

View File

@@ -626,11 +626,16 @@
"visitor": "Can only view and download"
},
"shared_form": {
"button_more_options": "More Options",
"button_close_options": "Close Options",
"button_done": "Awesome, Im done!",
"button_generate": "Generate Link",
"label_password_protection": "Password Protected",
"label_permission": "Permission",
"label_shared_url": "Share url",
"label_expiration": "Link Expiration",
"expiration_hour": "{value}h.",
"expiration_day": "{value}d.",
"placeholder_permission": "Select your permission"
},
"sidebar": {

View File

@@ -626,11 +626,16 @@
"visitor": "Môže len vidieť a sťahovať súbory"
},
"shared_form": {
"button_more_options": "Viac nastavení",
"button_close_options": "Zavrieť viac možností",
"button_done": "Super, som hotový!",
"button_generate": "Vygenerovať link",
"label_password_protection": "Chrániť heslom",
"label_permission": "Oprávnenie",
"label_shared_url": "Zdieľací odkaz",
"label_expiration": "Expirácia Linku",
"expiration_hour": "{value}h.",
"expiration_day": "{value}d.",
"placeholder_permission": "Zvoľte oprávnenia"
},
"sidebar": {

View File

@@ -263,9 +263,39 @@ const defaultState = {
{label: 'Zambia', value: 'ZM'},
{label: 'Zimbabwe', value: 'ZW'}
],
expirationList: [
{
label: i18n.t('shared_form.expiration_hour', {value: 1}),
value: 1,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 2}),
value: 2,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 6}),
value: 6,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 12}),
value: 12,
},
{
label: i18n.t('shared_form.expiration_day', {value: 1}),
value: 24,
},
{
label: i18n.t('shared_form.expiration_day', {value: 2}),
value: 48,
},
{
label: i18n.t('shared_form.expiration_day', {value: 7}),
value: 168,
},
],
}
const actions = {
changePreviewType: ({commit, dispatch, state, getters}) => {
changePreviewType: ({commit, state}) => {
// Get preview type
let previewType = state.FilePreviewType == 'grid' ? 'list' : 'grid'
@@ -320,6 +350,7 @@ const mutations = {
const getters = {
fileInfoVisible: state => state.fileInfoPanelVisible,
FilePreviewType: state => state.FilePreviewType,
expirationList: state => state.expirationList,
homeDirectory: state => state.homeDirectory,
requestedPlan: state => state.requestedPlan,
countries: state => state.countries,

View File

@@ -17,6 +17,10 @@ const actions = {
.then((response) => {
resolve(response)
// Redirect user if is logged
if (router.currentRoute.name === 'SignIn')
router.push({ name: 'Files' })
commit('RETRIEVE_USER', response.data)
}).catch((error) => {

View File

@@ -2,7 +2,7 @@
<PageTab :is-loading="isLoading" class="form-fixed-width">
<!--Personal Information-->
<PageTabGroup>
<PageTabGroup v-if="! isLoading">
<div class="form block-form">
<FormLabel>{{ $t('admin_settings.appearance.section_general') }}</FormLabel>

View File

@@ -15,7 +15,7 @@
</div>
<!--Payment methods table-->
<DatatableWrapper :table-data="{data: PaymentMethods}" :paginator="false" :columns="columns" class="table">
<DatatableWrapper v-if="PaymentMethods" :table-data="{data: PaymentMethods}" :paginator="false" :columns="columns" class="table">
<!--Table data content-->
<template slot-scope="{ row }">

Some files were not shown because too many files have changed in this diff Show More