mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-18 08:12:15 +00:00
qr code generator
This commit is contained in:
@@ -64,7 +64,7 @@
|
|||||||
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=7f623c8a4002f17eecef",
|
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=7f623c8a4002f17eecef",
|
||||||
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=7eff560fea52770a642f",
|
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=7eff560fea52770a642f",
|
||||||
"/chunks/plans.js": "/chunks/plans.js?id=293e7e8d59da542a9710",
|
"/chunks/plans.js": "/chunks/plans.js?id=293e7e8d59da542a9710",
|
||||||
"/chunks/platform.js": "/chunks/platform.js?id=1cd6e357b28006f2c0d0",
|
"/chunks/platform.js": "/chunks/platform.js?id=995d87d771ab3755300d",
|
||||||
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=eb52b5029ab2132cc7a8",
|
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=eb52b5029ab2132cc7a8",
|
||||||
"/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js": "/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js?id=ca9ca67afd5839597647",
|
"/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js": "/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js?id=ca9ca67afd5839597647",
|
||||||
"/chunks/profile.js": "/chunks/profile.js?id=8688d9c7ff850e6989e6",
|
"/chunks/profile.js": "/chunks/profile.js?id=8688d9c7ff850e6989e6",
|
||||||
@@ -1031,5 +1031,24 @@
|
|||||||
"/chunks/platform~chunks/shared.ea85f5cfae919a076286.hot-update.js": "/chunks/platform~chunks/shared.ea85f5cfae919a076286.hot-update.js",
|
"/chunks/platform~chunks/shared.ea85f5cfae919a076286.hot-update.js": "/chunks/platform~chunks/shared.ea85f5cfae919a076286.hot-update.js",
|
||||||
"/chunks/platform~chunks/shared.84634b8388c060112c1b.hot-update.js": "/chunks/platform~chunks/shared.84634b8388c060112c1b.hot-update.js",
|
"/chunks/platform~chunks/shared.84634b8388c060112c1b.hot-update.js": "/chunks/platform~chunks/shared.84634b8388c060112c1b.hot-update.js",
|
||||||
"/chunks/platform~chunks/shared.bad4a30908dd6677cf57.hot-update.js": "/chunks/platform~chunks/shared.bad4a30908dd6677cf57.hot-update.js",
|
"/chunks/platform~chunks/shared.bad4a30908dd6677cf57.hot-update.js": "/chunks/platform~chunks/shared.bad4a30908dd6677cf57.hot-update.js",
|
||||||
"/chunks/platform~chunks/shared.7344fdb67d1d2c382527.hot-update.js": "/chunks/platform~chunks/shared.7344fdb67d1d2c382527.hot-update.js"
|
"/chunks/platform~chunks/shared.7344fdb67d1d2c382527.hot-update.js": "/chunks/platform~chunks/shared.7344fdb67d1d2c382527.hot-update.js",
|
||||||
|
"/chunks/platform.9935a3fb40cb1a6c789a.hot-update.js": "/chunks/platform.9935a3fb40cb1a6c789a.hot-update.js",
|
||||||
|
"/chunks/platform.5b66195d24b17de302b0.hot-update.js": "/chunks/platform.5b66195d24b17de302b0.hot-update.js",
|
||||||
|
"/chunks/platform.79d4290d27451ea79ccb.hot-update.js": "/chunks/platform.79d4290d27451ea79ccb.hot-update.js",
|
||||||
|
"/chunks/platform.7a437caaafe827fe07cc.hot-update.js": "/chunks/platform.7a437caaafe827fe07cc.hot-update.js",
|
||||||
|
"/chunks/platform.7187684ae9b0faa2a7f1.hot-update.js": "/chunks/platform.7187684ae9b0faa2a7f1.hot-update.js",
|
||||||
|
"/chunks/platform.bb37cb7d93d79c9e6a5a.hot-update.js": "/chunks/platform.bb37cb7d93d79c9e6a5a.hot-update.js",
|
||||||
|
"/chunks/platform.74e0ff5ead757ff49708.hot-update.js": "/chunks/platform.74e0ff5ead757ff49708.hot-update.js",
|
||||||
|
"/chunks/platform.ea1c3e65c26938bba387.hot-update.js": "/chunks/platform.ea1c3e65c26938bba387.hot-update.js",
|
||||||
|
"/chunks/platform.54c9d7a94fbee65e2da7.hot-update.js": "/chunks/platform.54c9d7a94fbee65e2da7.hot-update.js",
|
||||||
|
"/chunks/platform.1c70eca57aee433b8aa9.hot-update.js": "/chunks/platform.1c70eca57aee433b8aa9.hot-update.js",
|
||||||
|
"/chunks/platform.42f9d03cdae6611c56cd.hot-update.js": "/chunks/platform.42f9d03cdae6611c56cd.hot-update.js",
|
||||||
|
"/chunks/platform.ff639c6b90300df114a8.hot-update.js": "/chunks/platform.ff639c6b90300df114a8.hot-update.js",
|
||||||
|
"/chunks/platform.67a4de439a33f4a20333.hot-update.js": "/chunks/platform.67a4de439a33f4a20333.hot-update.js",
|
||||||
|
"/chunks/platform.a266c10be8a18abd0620.hot-update.js": "/chunks/platform.a266c10be8a18abd0620.hot-update.js",
|
||||||
|
"/chunks/platform.1cdf2801a1dc08744bfb.hot-update.js": "/chunks/platform.1cdf2801a1dc08744bfb.hot-update.js",
|
||||||
|
"/chunks/platform.59a13c955f76e3699f76.hot-update.js": "/chunks/platform.59a13c955f76e3699f76.hot-update.js",
|
||||||
|
"/chunks/platform.7a1f473c56b980ad30a0.hot-update.js": "/chunks/platform.7a1f473c56b980ad30a0.hot-update.js",
|
||||||
|
"/chunks/platform.2dff6a153cfe9e102eea.hot-update.js": "/chunks/platform.2dff6a153cfe9e102eea.hot-update.js",
|
||||||
|
"/chunks/platform.9fc0238e5466745ede6c.hot-update.js": "/chunks/platform.9fc0238e5466745ede6c.hot-update.js"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
public/qr.png
BIN
public/qr.png
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
@@ -59,7 +59,7 @@
|
|||||||
</ValidationObserver>
|
</ValidationObserver>
|
||||||
|
|
||||||
<!--Copy generated link-->
|
<!--Copy generated link-->
|
||||||
<AppInputText v-if="isGeneratedShared" :title="$t('shared_form.label_share_vie_email')" class="px-6" :is-last="true">
|
<AppInputText v-if="isGeneratedShared" :title="$t('shared_form.label_share_vie_email')" :is-last="true">
|
||||||
<CopyShareLink :item="pickedItem" />
|
<CopyShareLink :item="pickedItem" />
|
||||||
</AppInputText>
|
</AppInputText>
|
||||||
</PopupContent>
|
</PopupContent>
|
||||||
|
|||||||
@@ -5,8 +5,11 @@
|
|||||||
|
|
||||||
<!--Qr Code-->
|
<!--Qr Code-->
|
||||||
<div v-if="pickedItem && activeSection === 'qr-code'">
|
<div v-if="pickedItem && activeSection === 'qr-code'">
|
||||||
<PopupContent>
|
<PopupContent class="flex justify-center items-center">
|
||||||
<img src="/qr.png" alt="qr code" class="w-36 mx-auto">
|
<div v-if="! qrCode" class="relative my-8">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
<div v-if="qrCode" v-html="qrCode" class="my-5 overflow-hidden rounded-xl"></div>
|
||||||
</PopupContent>
|
</PopupContent>
|
||||||
|
|
||||||
<PopupActions>
|
<PopupActions>
|
||||||
@@ -155,6 +158,7 @@
|
|||||||
import AppInputSwitch from "../Admin/AppInputSwitch"
|
import AppInputSwitch from "../Admin/AppInputSwitch"
|
||||||
import AppInputText from "../Admin/AppInputText"
|
import AppInputText from "../Admin/AppInputText"
|
||||||
import {required} from 'vee-validate/dist/rules'
|
import {required} from 'vee-validate/dist/rules'
|
||||||
|
import Spinner from "../FilesView/Spinner"
|
||||||
import {events} from '/resources/js/bus'
|
import {events} from '/resources/js/bus'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
@@ -179,6 +183,7 @@
|
|||||||
SwitchInput,
|
SwitchInput,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
required,
|
required,
|
||||||
|
Spinner,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
@@ -215,6 +220,7 @@
|
|||||||
shareOptions: undefined,
|
shareOptions: undefined,
|
||||||
pickedItem: undefined,
|
pickedItem: undefined,
|
||||||
emails: undefined,
|
emails: undefined,
|
||||||
|
qrCode: undefined,
|
||||||
isConfirmedDestroy: false,
|
isConfirmedDestroy: false,
|
||||||
canChangePassword: false,
|
canChangePassword: false,
|
||||||
isMoreOptions: false,
|
isMoreOptions: false,
|
||||||
@@ -223,6 +229,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getQrCode() {
|
||||||
|
axios.get(`/api/share/${this.shareOptions.token}/qr`)
|
||||||
|
.then(response => {
|
||||||
|
this.qrCode = response.data
|
||||||
|
})
|
||||||
|
.catch(() => this.$isSomethingWrong())
|
||||||
|
},
|
||||||
showSection(section = undefined) {
|
showSection(section = undefined) {
|
||||||
this.activeSection = section
|
this.activeSection = section
|
||||||
},
|
},
|
||||||
@@ -321,6 +334,9 @@
|
|||||||
if (args.section)
|
if (args.section)
|
||||||
this.activeSection = args.section
|
this.activeSection = args.section
|
||||||
|
|
||||||
|
if (args.section === 'qr-code')
|
||||||
|
this.getQrCode()
|
||||||
|
|
||||||
this.canChangePassword = args.item.data.relationships.shared.data.attributes.protected
|
this.canChangePassword = args.item.data.relationships.shared.data.attributes.protected
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use Domain\Browsing\Controllers\BrowseLatestFilesController;
|
|||||||
use Domain\Browsing\Controllers\BrowseSharedItemsController;
|
use Domain\Browsing\Controllers\BrowseSharedItemsController;
|
||||||
use Domain\Browsing\Controllers\BrowseTrashContentController;
|
use Domain\Browsing\Controllers\BrowseTrashContentController;
|
||||||
use Domain\Homepage\Controllers\SendContactMessageController;
|
use Domain\Homepage\Controllers\SendContactMessageController;
|
||||||
|
use Domain\Sharing\Controllers\GetShareLinkViaQrCodeController;
|
||||||
use App\Users\Controllers\Authentication\RegisterUserController;
|
use App\Users\Controllers\Authentication\RegisterUserController;
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
@@ -67,6 +68,7 @@ Route::group(['middleware' => ['auth:sanctum']], function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Share
|
// Share
|
||||||
|
Route::get('/share/{token}/qr', GetShareLinkViaQrCodeController::class);
|
||||||
Route::post('/share/{token}/email', ShareViaEmailController::class);
|
Route::post('/share/{token}/email', ShareViaEmailController::class);
|
||||||
Route::apiResource('/share', ShareController::class);
|
Route::apiResource('/share', ShareController::class);
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Domain\Invoices\Controllers;
|
namespace Domain\Invoices\Controllers;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Users\Actions\FormatUsageEstimatesAction;
|
|
||||||
use Domain\Settings\Models\Setting;
|
use Domain\Settings\Models\Setting;
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
use App\Users\Actions\FormatUsageEstimatesAction;
|
||||||
use VueFileManager\Subscription\Domain\Transactions\Models\Transaction;
|
use VueFileManager\Subscription\Domain\Transactions\Models\Transaction;
|
||||||
|
|
||||||
class GetInvoiceController extends Controller
|
class GetInvoiceController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public FormatUsageEstimatesAction $formatUsageEstimates,
|
public FormatUsageEstimatesAction $formatUsageEstimates,
|
||||||
) {}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public function __invoke(Transaction $invoice): View|Factory|Application
|
public function __invoke(Transaction $invoice): View|Factory|Application
|
||||||
{
|
{
|
||||||
@@ -34,4 +34,4 @@ class GetInvoiceController extends Controller
|
|||||||
->with('settings', $settings)
|
->with('settings', $settings)
|
||||||
->with('invoice', $invoice);
|
->with('invoice', $invoice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
namespace Domain\Sharing\Controllers;
|
||||||
|
|
||||||
|
use BaconQrCode\Writer;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use BaconQrCode\Renderer\Color\Rgb;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use BaconQrCode\Renderer\ImageRenderer;
|
||||||
|
use BaconQrCode\Renderer\RendererStyle\Fill;
|
||||||
|
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
|
||||||
|
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||||
|
|
||||||
|
class GetShareLinkViaQrCodeController extends Controller
|
||||||
|
{
|
||||||
|
public function __invoke($token): Response
|
||||||
|
{
|
||||||
|
// Get share url
|
||||||
|
$url = url('/share', ['token' => $token]);
|
||||||
|
|
||||||
|
// Generate qr code
|
||||||
|
$svg = (new Writer(
|
||||||
|
new ImageRenderer(
|
||||||
|
new RendererStyle(192, 2, null, null, Fill::uniformColor(new Rgb(255, 255, 255), new Rgb(0, 0, 0))),
|
||||||
|
new SvgImageBackEnd
|
||||||
|
)
|
||||||
|
))->writeString($url);
|
||||||
|
|
||||||
|
$qrCode = trim(substr($svg, strpos($svg, "\n") + 1));
|
||||||
|
|
||||||
|
// Return qr code
|
||||||
|
return response($qrCode, 201);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Tests\App\Users;
|
namespace Tests\App\Users;
|
||||||
|
|
||||||
use Storage;
|
use Storage;
|
||||||
@@ -121,7 +122,7 @@ class UserAccountTest extends TestCase
|
|||||||
|
|
||||||
collect(config('vuefilemanager.avatar_sizes'))
|
collect(config('vuefilemanager.avatar_sizes'))
|
||||||
->each(
|
->each(
|
||||||
fn ($size) => Storage::disk('local')
|
fn($size) => Storage::disk('local')
|
||||||
->assertExists("avatars/{$size['name']}-{$user->settings->getRawOriginal('avatar')}")
|
->assertExists("avatars/{$size['name']}-{$user->settings->getRawOriginal('avatar')}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ class UserAccountTest extends TestCase
|
|||||||
->assertStatus(200)
|
->assertStatus(200)
|
||||||
->assertExactJson([
|
->assertExactJson([
|
||||||
'data' => [
|
'data' => [
|
||||||
'id' => (string) $user->id,
|
'id' => (string)$user->id,
|
||||||
'type' => 'user',
|
'type' => 'user',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'avatar' => [
|
'avatar' => [
|
||||||
@@ -163,7 +164,7 @@ class UserAccountTest extends TestCase
|
|||||||
'created_at' => format_date($user->created_at, '%d. %b. %Y'),
|
'created_at' => format_date($user->created_at, '%d. %b. %Y'),
|
||||||
'updated_at' => format_date($user->updated_at, '%d. %B. %Y'),
|
'updated_at' => format_date($user->updated_at, '%d. %B. %Y'),
|
||||||
],
|
],
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'restrictions' => [
|
'restrictions' => [
|
||||||
'canCreateFolder' => true,
|
'canCreateFolder' => true,
|
||||||
'canCreateTeamFolder' => true,
|
'canCreateTeamFolder' => true,
|
||||||
@@ -178,7 +179,7 @@ class UserAccountTest extends TestCase
|
|||||||
],
|
],
|
||||||
'settings' => [
|
'settings' => [
|
||||||
'data' => [
|
'data' => [
|
||||||
'id' => (string) $user->id,
|
'id' => (string)$user->id,
|
||||||
'type' => 'settings',
|
'type' => 'settings',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'avatar' => $user->settings->avatar,
|
'avatar' => $user->settings->avatar,
|
||||||
@@ -188,6 +189,8 @@ class UserAccountTest extends TestCase
|
|||||||
'city' => $user->settings->city,
|
'city' => $user->settings->city,
|
||||||
'postal_code' => $user->settings->postal_code,
|
'postal_code' => $user->settings->postal_code,
|
||||||
'country' => $user->settings->country,
|
'country' => $user->settings->country,
|
||||||
|
'first_name' => $user->settings->first_name,
|
||||||
|
'last_name' => $user->settings->last_name,
|
||||||
'phone_number' => $user->settings->phone_number,
|
'phone_number' => $user->settings->phone_number,
|
||||||
'timezone' => $user->settings->timezone,
|
'timezone' => $user->settings->timezone,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -11,6 +11,21 @@ use Domain\Sharing\Notifications\SharedSendViaEmail;
|
|||||||
|
|
||||||
class UserShareTest extends TestCase
|
class UserShareTest extends TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_generate_qr_code()
|
||||||
|
{
|
||||||
|
$user = User::factory()
|
||||||
|
->hasSettings()
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$this
|
||||||
|
->actingAs($user)
|
||||||
|
->get('/api/share/123456789/qr')
|
||||||
|
->assertCreated();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user