team invitation notification with broadcasting

This commit is contained in:
Čarodej
2022-03-10 16:23:13 +01:00
parent 64e80d387b
commit 9ae2d54a5e
50 changed files with 331 additions and 201 deletions

View File

@@ -34,11 +34,11 @@ return [
'secret' => env('PUSHER_APP_SECRET'), 'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'), 'app_id' => env('PUSHER_APP_ID'),
'options' => [ 'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'), 'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true, 'encrypted' => true,
'host' => '192.168.1.112', 'host' => '192.168.1.112',
'port' => 6001, 'port' => 6001,
'scheme' => 'http' 'scheme' => 'http',
], ],
], ],

View File

@@ -5,8 +5,8 @@ return [
'is_demo' => env('APP_DEMO', false), 'is_demo' => env('APP_DEMO', false),
'is_setup_wizard_demo' => env('IS_SETUP_WIZARD_DEMO', false), 'is_setup_wizard_demo' => env('IS_SETUP_WIZARD_DEMO', false),
'is_setup_wizard_debug' => env('IS_SETUP_WIZARD_DEBUG', false), 'is_setup_wizard_debug' => env('IS_SETUP_WIZARD_DEBUG', false),
'is_admin_vuefilemanager_bar' => env('IS_ADMIN_VUEFILEMANAGER_BAR', true), 'is_admin_vuefilemanager_bar' => env('IS_ADMIN_VUEFILEMANAGER_BAR', true),
// Define size of chunk uploaded by MB. // Define size of chunk uploaded by MB.

View File

@@ -3,7 +3,6 @@
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize; use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize;
return [ return [
/* /*
* Set a custom dashboard configuration * Set a custom dashboard configuration
*/ */
@@ -23,14 +22,14 @@ return [
*/ */
'apps' => [ 'apps' => [
[ [
'id' => env('PUSHER_APP_ID'), 'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'), 'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'), 'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'), 'secret' => env('PUSHER_APP_SECRET'),
'path' => env('PUSHER_APP_PATH'), 'path' => env('PUSHER_APP_PATH'),
'capacity' => null, 'capacity' => null,
'enable_client_messages' => false, 'enable_client_messages' => false,
'enable_statistics' => true, 'enable_statistics' => true,
], ],
], ],
@@ -48,7 +47,6 @@ return [
* Leave this empty if you want to accept requests from all hosts. * Leave this empty if you want to accept requests from all hosts.
*/ */
'allowed_origins' => [ 'allowed_origins' => [
//
], ],
/* /*

View File

@@ -15,7 +15,7 @@
"/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=92c75a6c77689046", "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=92c75a6c77689046",
"/chunks/not-found.js": "/chunks/not-found.js?id=36763aa314e00327", "/chunks/not-found.js": "/chunks/not-found.js?id=36763aa314e00327",
"/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=a3906226272982b1", "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=a3906226272982b1",
"/chunks/admin.js": "/chunks/admin.js?id=920613c2b7236639", "/chunks/admin.js": "/chunks/admin.js?id=a9cc617d7342978a",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=e7c6001687e641eb", "/chunks/dashboard.js": "/chunks/dashboard.js?id=e7c6001687e641eb",
"/chunks/invoices.js": "/chunks/invoices.js?id=85fd4514d3d85a71", "/chunks/invoices.js": "/chunks/invoices.js?id=85fd4514d3d85a71",
"/chunks/subscriptions.js": "/chunks/subscriptions.js?id=9f970bdfc7583080", "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=9f970bdfc7583080",
@@ -57,12 +57,12 @@
"/chunks/sign-up.js": "/chunks/sign-up.js?id=098d7f41b85066bf", "/chunks/sign-up.js": "/chunks/sign-up.js?id=098d7f41b85066bf",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=d6193ed0b07e7957", "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=d6193ed0b07e7957",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=d00212636148a14b", "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=d00212636148a14b",
"/chunks/settings.js": "/chunks/settings.js?id=f4a7bce3ff4c61a9", "/chunks/settings.js": "/chunks/settings.js?id=71ee8010419a7b69",
"/chunks/profile.js": "/chunks/profile.js?id=1217f457145491ec", "/chunks/profile.js": "/chunks/profile.js?id=1217f457145491ec",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=b6704f4cbf14c67d", "/chunks/settings-password.js": "/chunks/settings-password.js?id=b6704f4cbf14c67d",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=90ba712f3728443b", "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=90ba712f3728443b",
"/chunks/billing.js": "/chunks/billing.js?id=27957f2477fdd121", "/chunks/billing.js": "/chunks/billing.js?id=27957f2477fdd121",
"/chunks/platform.js": "/chunks/platform.js?id=85ee6709fe4e3b7e", "/chunks/platform.js": "/chunks/platform.js?id=4001e2c2fd8b27ce",
"/chunks/files.js": "/chunks/files.js?id=0d4e7a1330328eae", "/chunks/files.js": "/chunks/files.js?id=0d4e7a1330328eae",
"/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=2362f8fa4e3392e9", "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=2362f8fa4e3392e9",
"/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=25e9d29dd3c29338", "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=25e9d29dd3c29338",

View File

@@ -23,7 +23,7 @@
{{ notification.data.attributes.description }} {{ notification.data.attributes.description }}
</p> </p>
<div class="mb-4 flex items-center"> <div class="flex items-center">
<!--<MemberAvatar class="mr-2" :size="22" :is-border="false" :member="user" />--> <!--<MemberAvatar class="mr-2" :size="22" :is-border="false" :member="user" />-->
<time class="block text-xs text-gray-400 dark:text-gray-400"> <time class="block text-xs text-gray-400 dark:text-gray-400">
{{ notification.data.attributes.created_at }} {{ notification.data.attributes.created_at }}
@@ -31,8 +31,9 @@
</div> </div>
<!--Accept or decline team invitation--> <!--Accept or decline team invitation-->
<div v-if="notification.data.attributes.type === 'team-invitation'" class="flex items-center space-x-3"> <div v-if="action && action.type === 'invitation'" class="flex items-center space-x-3 mt-4">
<div <div
@click="acceptAction"
class="flex cursor-pointer items-center rounded-xl py-1.5 px-2 transition-colors hover:bg-green-100 dark:hover:bg-green-900" class="flex cursor-pointer items-center rounded-xl py-1.5 px-2 transition-colors hover:bg-green-100 dark:hover:bg-green-900"
> >
<check-icon size="16" class="vue-feather mr-2 text-green-600 dark:text-green-600" /> <check-icon size="16" class="vue-feather mr-2 text-green-600 dark:text-green-600" />
@@ -42,6 +43,7 @@
</div> </div>
<div <div
@click="declineAction"
class="flex cursor-pointer items-center rounded-xl py-1.5 px-2 transition-colors hover:bg-rose-100 dark:hover:bg-rose-900" class="flex cursor-pointer items-center rounded-xl py-1.5 px-2 transition-colors hover:bg-rose-100 dark:hover:bg-rose-900"
> >
<x-icon size="16" class="vue-feather mr-2 text-rose-600 dark:text-rose-600" /> <x-icon size="16" class="vue-feather mr-2 text-rose-600 dark:text-rose-600" />
@@ -69,6 +71,7 @@
<script> <script>
import { CheckIcon, XIcon, MailIcon, UserPlusIcon, UploadCloudIcon, ChevronRightIcon } from 'vue-feather-icons' import { CheckIcon, XIcon, MailIcon, UserPlusIcon, UploadCloudIcon, ChevronRightIcon } from 'vue-feather-icons'
import MemberAvatar from '../FilesView/MemberAvatar' import MemberAvatar from '../FilesView/MemberAvatar'
import {events} from "../../bus";
export default { export default {
name: 'Notification', name: 'Notification',
@@ -93,6 +96,28 @@ export default {
} }
}, },
methods: { methods: {
acceptAction() {
axios.put(`/api/teams/invitations/${this.notification.data.attributes.action.params.id}`)
.then(() => {
this.$store.commit('CLEAR_NOTIFICATION_ACTION_DATA', this.notification.data.id)
events.$emit('toaster', {
type: 'success',
message: this.$t('You successfully accepted invitation'),
})
})
},
declineAction() {
axios.delete(`/api/teams/invitations/${this.notification.data.attributes.action.params.id}`)
.then(() => {
this.$store.commit('CLEAR_NOTIFICATION_ACTION_DATA', this.notification.data.id)
events.$emit('toaster', {
type: 'success',
message: this.$t('You successfully decline invitation'),
})
})
},
closeCenter() { closeCenter() {
this.$store.commit('TOGGLE_NOTIFICATION_CENTER') this.$store.commit('TOGGLE_NOTIFICATION_CENTER')
}, },

View File

@@ -72,47 +72,6 @@ export default {
return this.user.data.relationships.unreadNotifications.data return this.user.data.relationships.unreadNotifications.data
} }
}, },
data() {
return {
laterNotifications: [
{
id: 1,
seen: 1,
type: 'remote-upload-done',
title: 'Remote Upload Finished',
description: 'Your remote uploads has been done.',
time: '09. Mar. 2022, 08:27',
action: {
id: '12-abc'
}
},
],
todayNotifications: [
{
id: 2,
seen: 0,
type: 'team-invitation',
title: 'New Team Invitation',
description: 'Jane Doe invite you to join into “Work Documents” Team Folder.',
time: '09. Mar. 2022, 08:27',
action: {
id: '12-abc'
}
},
{
id: 3,
seen: 0,
type: 'file-request',
title: 'File Request Filled',
description: 'Your file request for “Videohive” folder was filled successfully.',
time: '09. Mar. 2022, 07:12',
action: {
id: '12-abc'
}
},
]
}
},
methods: { methods: {
deleteAllNotifications() { deleteAllNotifications() {
axios.delete('/api/user/notifications') axios.delete('/api/user/notifications')

View File

@@ -180,6 +180,23 @@ const mutations = {
state.user.data.relationships.readNotifications.data = [] state.user.data.relationships.readNotifications.data = []
state.user.data.relationships.unreadNotifications.data = [] state.user.data.relationships.unreadNotifications.data = []
}, },
CLEAR_NOTIFICATION_ACTION_DATA(state, notificationId) {
if (state.user.data.relationships.readNotifications.data.length) {
state.user.data.relationships.readNotifications.data.map(notification => {
if (notification.data.id === notificationId) {
notification.data.attributes.action = undefined
}
})
}
if (state.user.data.relationships.unreadNotifications.data.length) {
state.user.data.relationships.unreadNotifications.data.map(notification => {
if (notification.data.id === notificationId) {
notification.data.attributes.action = undefined
}
})
}
},
} }
const getters = { const getters = {

View File

@@ -9,12 +9,12 @@ use Domain\Settings\Controllers\GetServerStatusController;
use Domain\Settings\Controllers\GetSettingsValueController; use Domain\Settings\Controllers\GetSettingsValueController;
use Domain\Admin\Controllers\Dashboard\GetNewbiesController; use Domain\Admin\Controllers\Dashboard\GetNewbiesController;
use Domain\Admin\Controllers\Users\ChangeUserRoleController; use Domain\Admin\Controllers\Users\ChangeUserRoleController;
use Domain\Settings\Controllers\StoreStorageCredentialsController;
use Domain\Settings\Controllers\UpdateSettingValueController; use Domain\Settings\Controllers\UpdateSettingValueController;
use Domain\Admin\Controllers\Users\ResetUserPasswordController; use Domain\Admin\Controllers\Users\ResetUserPasswordController;
use Domain\Settings\Controllers\StoreEmailCredentialsController; use Domain\Settings\Controllers\StoreEmailCredentialsController;
use Domain\Transactions\Controllers\GetAllTransactionsController; use Domain\Transactions\Controllers\GetAllTransactionsController;
use Domain\Admin\Controllers\Dashboard\GetDashboardDataController; use Domain\Admin\Controllers\Dashboard\GetDashboardDataController;
use Domain\Settings\Controllers\StoreStorageCredentialsController;
use Domain\Transactions\Controllers\GetUserTransactionsController; use Domain\Transactions\Controllers\GetUserTransactionsController;
use Domain\Localization\Controllers\UpdateLanguageStringController; use Domain\Localization\Controllers\UpdateLanguageStringController;
use Domain\Admin\Controllers\Users\ShowUserStorageCapacityController; use Domain\Admin\Controllers\Users\ShowUserStorageCapacityController;
@@ -62,4 +62,4 @@ Route::patch('/languages/{language}/strings', UpdateLanguageStringController::cl
Route::apiResource('/languages', LanguageController::class); Route::apiResource('/languages', LanguageController::class);
// Server Status // Server Status
Route::get('/status', GetServerStatusController::class); Route::get('/status', GetServerStatusController::class);

View File

@@ -4,14 +4,14 @@ use App\Users\Controllers\Account\AccountDetailsController;
use App\Users\Controllers\Account\UpdatePasswordController; use App\Users\Controllers\Account\UpdatePasswordController;
use App\Users\Controllers\Account\StorageCapacityController; use App\Users\Controllers\Account\StorageCapacityController;
use App\Users\Controllers\Verification\VerifyEmailController; use App\Users\Controllers\Verification\VerifyEmailController;
use Domain\Notifications\Controllers\FlushUserNotificationsController;
use Domain\Notifications\Controllers\GetUserNotificationsController;
use Domain\Notifications\Controllers\MarkUserNotificationsAsReadController;
use Domain\Transactions\Controllers\GetTransactionsController; use Domain\Transactions\Controllers\GetTransactionsController;
use App\Users\Controllers\Verification\ResendVerificationEmail; use App\Users\Controllers\Verification\ResendVerificationEmail;
use App\Users\Controllers\Authentication\CheckAccountController; use App\Users\Controllers\Authentication\CheckAccountController;
use App\Users\Controllers\Account\UpdateProfileSettingsController; use App\Users\Controllers\Account\UpdateProfileSettingsController;
use Domain\Notifications\Controllers\GetUserNotificationsController;
use App\Users\Controllers\Authentication\AccountAccessTokenController; use App\Users\Controllers\Authentication\AccountAccessTokenController;
use Domain\Notifications\Controllers\FlushUserNotificationsController;
use Domain\Notifications\Controllers\MarkUserNotificationsAsReadController;
Route::post('/check', CheckAccountController::class); Route::post('/check', CheckAccountController::class);

View File

@@ -3,8 +3,8 @@
use Domain\Homepage\Controllers\IndexController; use Domain\Homepage\Controllers\IndexController;
use Domain\Invoices\Controllers\GetInvoiceController; use Domain\Invoices\Controllers\GetInvoiceController;
use Domain\Settings\Controllers\DownloadLogController; use Domain\Settings\Controllers\DownloadLogController;
use Domain\Sharing\Controllers\SharePublicIndexController;
use App\Socialite\Controllers\SocialiteCallbackController; use App\Socialite\Controllers\SocialiteCallbackController;
use Domain\Sharing\Controllers\SharePublicIndexController;
use Domain\Sharing\Controllers\WebCrawlerOpenGraphController; use Domain\Sharing\Controllers\WebCrawlerOpenGraphController;
use Domain\Localization\Controllers\CurrentLocalizationController; use Domain\Localization\Controllers\CurrentLocalizationController;
@@ -20,7 +20,6 @@ Route::get('/invoices/{invoice}', GetInvoiceController::class)
Route::get('/admin/log/{log}', DownloadLogController::class) Route::get('/admin/log/{log}', DownloadLogController::class)
->middleware(['auth:sanctum', 'admin']); ->middleware(['auth:sanctum', 'admin']);
// Get og site for web crawlers // Get og site for web crawlers
if (Crawler::isCrawler()) { if (Crawler::isCrawler()) {
Route::get('/share/{share}', WebCrawlerOpenGraphController::class); Route::get('/share/{share}', WebCrawlerOpenGraphController::class);

View File

@@ -898,7 +898,7 @@ class SetupDevEnvironment extends Command
]) ])
->each(function ($file) use ($users, $financeDocumentsFolder, $otherDocuments) { ->each(function ($file) use ($users, $financeDocumentsFolder, $otherDocuments) {
$user = $users[rand(0, 2)]; $user = $users[rand(0, 2)];
$folder = [$financeDocumentsFolder, $otherDocuments][rand(0,1)]; $folder = [$financeDocumentsFolder, $otherDocuments][rand(0, 1)];
$basename = Str::random(12) . '-' . $file['basename']; $basename = Str::random(12) . '-' . $file['basename'];
@@ -1120,7 +1120,7 @@ class SetupDevEnvironment extends Command
'Smart Watch 3D Device Pack for Element 3D.mp4', 'Smart Watch 3D Device Pack for Element 3D.mp4',
]) ])
->each(function ($file) use ($users, $videos) { ->each(function ($file) use ($users, $videos) {
$user = $users[rand(0,1)]; $user = $users[rand(0, 1)];
$basename = Str::random(12) . '-' . $file; $basename = Str::random(12) . '-' . $file;
@@ -1151,7 +1151,7 @@ class SetupDevEnvironment extends Command
->each(function ($file) use ($users, $folder) { ->each(function ($file) use ($users, $folder) {
$basename = Str::random(12) . '-' . $file['basename']; $basename = Str::random(12) . '-' . $file['basename'];
$user = $users[rand(0,1)]; $user = $users[rand(0, 1)];
// Copy file into app storage // Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private'); Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private');

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace App\Http; namespace App\Http;
use Fruitcake\Cors\HandleCors; use Fruitcake\Cors\HandleCors;

View File

@@ -1,10 +1,10 @@
<?php <?php
namespace App\Providers; namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider class RouteServiceProvider extends ServiceProvider

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace App\Users\Controllers\Authentication; namespace App\Users\Controllers\Authentication;
use Illuminate\Support\Str; use Illuminate\Support\Str;

View File

@@ -1,11 +1,10 @@
<?php <?php
namespace App\Users\Resources; namespace App\Users\Resources;
use Domain\Notifications\Resources\NotificationCollection;
use Domain\Folders\Resources\FolderCollection; use Domain\Folders\Resources\FolderCollection;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
use App\Users\Actions\FormatUsageEstimatesAction; use App\Users\Actions\FormatUsageEstimatesAction;
use Domain\Notifications\Resources\NotificationCollection;
use VueFileManager\Subscription\Domain\Credits\Resources\BalanceResource; use VueFileManager\Subscription\Domain\Credits\Resources\BalanceResource;
use VueFileManager\Subscription\Domain\CreditCards\Resources\CreditCardCollection; use VueFileManager\Subscription\Domain\CreditCards\Resources\CreditCardCollection;
use VueFileManager\Subscription\Domain\BillingAlerts\Resources\BillingAlertResource; use VueFileManager\Subscription\Domain\BillingAlerts\Resources\BillingAlertResource;
@@ -49,16 +48,16 @@ class UserResource extends JsonResource
'settings' => new SettingsResource($this->settings), 'settings' => new SettingsResource($this->settings),
'favourites' => new FolderCollection($this->favouriteFolders), 'favourites' => new FolderCollection($this->favouriteFolders),
'creditCards' => new CreditCardCollection($this->creditCards), 'creditCards' => new CreditCardCollection($this->creditCards),
$this->mergeWhen($this->hasSubscription(), fn() => [ $this->mergeWhen($this->hasSubscription(), fn () => [
'subscription' => new SubscriptionResource($this->subscription), 'subscription' => new SubscriptionResource($this->subscription),
]), ]),
$this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn() => [ $this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn () => [
'balance' => new BalanceResource($this->balance), 'balance' => new BalanceResource($this->balance),
]), ]),
$this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn() => [ $this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn () => [
'alert' => new BillingAlertResource($this->billingAlert), 'alert' => new BillingAlertResource($this->billingAlert),
]), ]),
$this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn() => [ $this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn () => [
'failedPayments' => new FailedPaymentsCollection($this->failedPayments), 'failedPayments' => new FailedPaymentsCollection($this->failedPayments),
]), ]),
], ],
@@ -70,13 +69,13 @@ class UserResource extends JsonResource
'canCreateTeamFolder' => $this->canCreateTeamFolder(), 'canCreateTeamFolder' => $this->canCreateTeamFolder(),
'canInviteTeamMembers' => $this->canInviteTeamMembers(), 'canInviteTeamMembers' => $this->canInviteTeamMembers(),
], ],
$this->mergeWhen($isFixedSubscription, fn() => [ $this->mergeWhen($isFixedSubscription, fn () => [
'limitations' => $this->limitations->summary(), 'limitations' => $this->limitations->summary(),
]), ]),
$this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn() => [ $this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn () => [
'usages' => $this->getUsageEstimates(), 'usages' => $this->getUsageEstimates(),
]), ]),
$this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn() => [ $this->mergeWhen($isMeteredSubscription && $this->hasSubscription(), fn () => [
'totalDebt' => [ 'totalDebt' => [
'formatted' => format_currency($this->failedPayments->sum('amount'), $this->subscription->plan->currency), 'formatted' => format_currency($this->failedPayments->sum('amount'), $this->subscription->plan->currency),
'amount' => $this->failedPayments->sum('amount'), 'amount' => $this->failedPayments->sum('amount'),

View File

@@ -1,10 +1,7 @@
<?php <?php
namespace App\Users\Resources; namespace App\Users\Resources;
use ByteUnits\Metric; use ByteUnits\Metric;
use Carbon\CarbonPeriod;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
@@ -23,18 +20,18 @@ class UserStorageResource extends JsonResource
$totalCapacity = match (get_settings('subscription_type')) { $totalCapacity = match (get_settings('subscription_type')) {
'metered' => $this->usedCapacity / 1000000000, 'metered' => $this->usedCapacity / 1000000000,
'fixed' => $this->limitations->max_storage_amount, 'fixed' => $this->limitations->max_storage_amount,
default => $this->limitations->max_storage_amount, default => $this->limitations->max_storage_amount,
}; };
return [ return [
'data' => [ 'data' => [
'id' => (string)$this->id, 'id' => (string) $this->id,
'type' => 'storage', 'type' => 'storage',
'attributes' => [ 'attributes' => [
'used' => Metric::bytes($this->usedCapacity)->format(), 'used' => Metric::bytes($this->usedCapacity)->format(),
'capacity' => format_gigabytes($totalCapacity), 'capacity' => format_gigabytes($totalCapacity),
'percentage' => (float)get_storage_percentage($this->usedCapacity, $totalCapacity), 'percentage' => (float) get_storage_percentage($this->usedCapacity, $totalCapacity),
], ],
'meta' => [ 'meta' => [
'traffic' => [ 'traffic' => [
@@ -47,23 +44,23 @@ class UserStorageResource extends JsonResource
], ],
'images' => [ 'images' => [
'used' => Metric::bytes($images)->format(), 'used' => Metric::bytes($images)->format(),
'percentage' => (float)get_storage_percentage($images, $totalCapacity), 'percentage' => (float) get_storage_percentage($images, $totalCapacity),
], ],
'audios' => [ 'audios' => [
'used' => Metric::bytes($audios)->format(), 'used' => Metric::bytes($audios)->format(),
'percentage' => (float)get_storage_percentage($audios, $totalCapacity), 'percentage' => (float) get_storage_percentage($audios, $totalCapacity),
], ],
'videos' => [ 'videos' => [
'used' => Metric::bytes($videos)->format(), 'used' => Metric::bytes($videos)->format(),
'percentage' => (float)get_storage_percentage($videos, $totalCapacity), 'percentage' => (float) get_storage_percentage($videos, $totalCapacity),
], ],
'documents' => [ 'documents' => [
'used' => Metric::bytes($documents)->format(), 'used' => Metric::bytes($documents)->format(),
'percentage' => (float)get_storage_percentage($documents, $totalCapacity), 'percentage' => (float) get_storage_percentage($documents, $totalCapacity),
], ],
'others' => [ 'others' => [
'used' => Metric::bytes($others)->format(), 'used' => Metric::bytes($others)->format(),
'percentage' => (float)get_storage_percentage($others, $totalCapacity), 'percentage' => (float) get_storage_percentage($others, $totalCapacity),
], ],
], ],
], ],
@@ -134,12 +131,12 @@ class UserStorageResource extends JsonResource
->where('created_at', '>', $period) ->where('created_at', '>', $period)
->orderBy('created_at') ->orderBy('created_at')
->get(['upload', 'download', 'created_at']) ->get(['upload', 'download', 'created_at'])
->each(fn($record) => $record->created_at = format_date($record->created_at, 'd. M. Y')) ->each(fn ($record) => $record->created_at = format_date($record->created_at, 'd. M. Y'))
->keyBy('created_at'); ->keyBy('created_at');
$mappedTrafficRecords = mapTrafficRecords($trafficRecords); $mappedTrafficRecords = mapTrafficRecords($trafficRecords);
$upload = $mappedTrafficRecords->map(fn($record) => [ $upload = $mappedTrafficRecords->map(fn ($record) => [
'created_at' => $record->created_at, 'created_at' => $record->created_at,
'amount' => Metric::bytes($record->upload)->format(), 'amount' => Metric::bytes($record->upload)->format(),
'percentage' => intval($uploadMax) !== 0 'percentage' => intval($uploadMax) !== 0
@@ -147,7 +144,7 @@ class UserStorageResource extends JsonResource
: 0, : 0,
]); ]);
$download = $mappedTrafficRecords->map(fn($record) => [ $download = $mappedTrafficRecords->map(fn ($record) => [
'created_at' => $record->created_at, 'created_at' => $record->created_at,
'amount' => Metric::bytes($record->download)->format(), 'amount' => Metric::bytes($record->download)->format(),
'percentage' => intval($downloadMax) !== 0 'percentage' => intval($downloadMax) !== 0

View File

@@ -65,7 +65,7 @@ class GetDashboardDataController extends Controller
) )
->groupBy('created_at') ->groupBy('created_at')
->get(['upload', 'download', 'created_at']) ->get(['upload', 'download', 'created_at'])
->each(fn($record) => $record->created_at = format_date($record->created_at, 'd. M. Y')) ->each(fn ($record) => $record->created_at = format_date($record->created_at, 'd. M. Y'))
->keyBy('created_at'); ->keyBy('created_at');
$mappedTrafficRecords = mapTrafficRecords($trafficRecords); $mappedTrafficRecords = mapTrafficRecords($trafficRecords);

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\Files\Actions; namespace Domain\Files\Actions;
class StoreFileExifMetadataAction class StoreFileExifMetadataAction
@@ -9,33 +8,31 @@ class StoreFileExifMetadataAction
// Get exif metadata // Get exif metadata
$exif_data = get_image_meta_data($file); $exif_data = get_image_meta_data($file);
if($exif_data) { if ($exif_data) {
// Conver array to collection // Conver array to collection
$data = json_decode(json_encode($exif_data)) ; $data = json_decode(json_encode($exif_data));
$item->exif()->create([ $item->exif()->create([
'date_time_original' => $data->DateTimeOriginal ?? null, 'date_time_original' => $data->DateTimeOriginal ?? null,
'artist' => $data->OwnerName ?? null, 'artist' => $data->OwnerName ?? null,
'width' => $data->COMPUTED->Width ?? null, 'width' => $data->COMPUTED->Width ?? null,
'height' => $data->COMPUTED->Height ?? null, 'height' => $data->COMPUTED->Height ?? null,
'x_resolution' => $data->XResolution ?? null, 'x_resolution' => $data->XResolution ?? null,
'y_resolution' => $data->YResolution ?? null, 'y_resolution' => $data->YResolution ?? null,
'color_space' => $data->ColorSpace ?? null, 'color_space' => $data->ColorSpace ?? null,
'camera' => $data->Make ?? null, 'camera' => $data->Make ?? null,
'model' => $data->Model ?? null, 'model' => $data->Model ?? null,
'aperture_value' => $data->ApertureValue ?? null, 'aperture_value' => $data->ApertureValue ?? null,
'exposure_time' => $data->ExposureTime ?? null, 'exposure_time' => $data->ExposureTime ?? null,
'focal_length' => $data->FocalLength ?? null, 'focal_length' => $data->FocalLength ?? null,
'iso' => $data->ISOSpeedRatings ?? null, 'iso' => $data->ISOSpeedRatings ?? null,
'aperture_f_number' => $data->COMPUTED->ApertureFNumber ?? null, 'aperture_f_number' => $data->COMPUTED->ApertureFNumber ?? null,
'ccd_width' => $data->COMPUTED->CCDWidth ?? null, 'ccd_width' => $data->COMPUTED->CCDWidth ?? null,
'longitude' => $data->GPSLongitude ?? null, 'longitude' => $data->GPSLongitude ?? null,
'latitude' => $data->GPSLatitude ?? null, 'latitude' => $data->GPSLatitude ?? null,
'longitude_ref' => $data->GPSLongitudeRef ?? null, 'longitude_ref' => $data->GPSLongitudeRef ?? null,
'latitude_ref' => $data->GPSLatitudeRef ?? null 'latitude_ref' => $data->GPSLatitudeRef ?? null,
]); ]);
} }
} }
} }

View File

@@ -11,7 +11,6 @@ use Domain\Files\Models\File as UserFile;
use Domain\Traffic\Actions\RecordUploadAction; use Domain\Traffic\Actions\RecordUploadAction;
use App\Users\Exceptions\InvalidUserActionException; use App\Users\Exceptions\InvalidUserActionException;
use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Domain\Files\Actions\StoreFileExifMetadataAction;
class UploadFileAction class UploadFileAction
{ {

View File

@@ -1,12 +1,10 @@
<?php <?php
namespace Domain\Files\Models;
namespace Domain\Files\Models;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Exif extends Model class Exif extends Model
{ {
@@ -22,7 +20,7 @@ class Exif extends Model
protected $casts = [ protected $casts = [
'longitude' => 'array', 'longitude' => 'array',
'latitude' => 'array', 'latitude' => 'array',
]; ];
/** /**

View File

@@ -226,10 +226,10 @@ class File extends Model
$file->id = (string) Str::uuid(); $file->id = (string) Str::uuid();
}); });
static::deleting(function($file) { static::deleting(function ($file) {
if($file->isForceDeleting()) { if ($file->isForceDeleting()) {
$file->exif()->forceDelete(); $file->exif()->forceDelete();
}; }
}); });
} }
} }

View File

@@ -63,7 +63,7 @@ class FileResource extends JsonResource
], ],
], ],
]), ]),
$this->mergeWhen($this->exif, fn() => [ $this->mergeWhen($this->exif, fn () => [
'exif' => [ 'exif' => [
'data' => [ 'data' => [
'type' => 'exif', 'type' => 'exif',
@@ -88,8 +88,8 @@ class FileResource extends JsonResource
'latitude' => formatGPSCoordinates($this->exif->latitude, $this->exif->latitude_ref), 'latitude' => formatGPSCoordinates($this->exif->latitude, $this->exif->latitude_ref),
], ],
], ],
] ],
]) ]),
], ],
], ],
]; ];

View File

@@ -1,11 +1,10 @@
<?php <?php
namespace Domain\Notifications\Controllers; namespace Domain\Notifications\Controllers;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
class FlushUserNotificationsController extends Controller class FlushUserNotificationsController extends Controller
{ {
@@ -20,4 +19,4 @@ class FlushUserNotificationsController extends Controller
return response('Done', 204); return response('Done', 204);
} }
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\Notifications\Controllers; namespace Domain\Notifications\Controllers;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
@@ -13,4 +12,4 @@ class GetUserNotificationsController extends Controller
auth()->user()->notifications auth()->user()->notifications
); );
} }
} }

View File

@@ -1,11 +1,10 @@
<?php <?php
namespace Domain\Notifications\Controllers; namespace Domain\Notifications\Controllers;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
class MarkUserNotificationsAsReadController extends Controller class MarkUserNotificationsAsReadController extends Controller
{ {
@@ -20,4 +19,4 @@ class MarkUserNotificationsAsReadController extends Controller
return response('Done', 204); return response('Done', 204);
} }
} }

View File

@@ -2,8 +2,8 @@
namespace Domain\Notifications\Events; namespace Domain\Notifications\Events;
use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class TestUpdate implements ShouldBroadcast class TestUpdate implements ShouldBroadcast
{ {

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\Notifications\Resources; namespace Domain\Notifications\Resources;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;

View File

@@ -1,12 +1,11 @@
<?php <?php
namespace Domain\Settings\Controllers; namespace Domain\Settings\Controllers;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\File;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\File;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse;
class DownloadLogController extends Controller class DownloadLogController extends Controller
@@ -22,7 +21,9 @@ class DownloadLogController extends Controller
// Download log // Download log
return response()->download( return response()->download(
storage_path("logs/$log"), $log, [ storage_path("logs/$log"),
$log,
[
'Accept-Ranges' => 'bytes', 'Accept-Ranges' => 'bytes',
'Content-Type' => 'text/plain', 'Content-Type' => 'text/plain',
'Content-Length' => File::size($logPath), 'Content-Length' => File::size($logPath),
@@ -31,4 +32,4 @@ class DownloadLogController extends Controller
] ]
); );
} }
} }

View File

@@ -2,9 +2,8 @@
namespace Domain\Settings\Controllers; namespace Domain\Settings\Controllers;
use Artisan; use Artisan;
use Domain\Settings\Requests\StoreStorageCredentialsRequest;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Domain\Settings\Requests\StoreEmailCredentialsRequest; use Domain\Settings\Requests\StoreStorageCredentialsRequest;
class StoreStorageCredentialsController class StoreStorageCredentialsController
{ {
@@ -22,7 +21,7 @@ class StoreStorageCredentialsController
'FILESYSTEM_DISK' => 'local', 'FILESYSTEM_DISK' => 'local',
], ],
's3' => [ 's3' => [
'FILESYSTEM_DISK' => 's3', 'FILESYSTEM_DISK' => 's3',
'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null, 'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null, 'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null, 'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null,

View File

@@ -20,7 +20,7 @@ class StoreEnvironmentSettingsController extends Controller
'FILESYSTEM_DISK' => 'local', 'FILESYSTEM_DISK' => 'local',
], ],
's3' => [ 's3' => [
'FILESYSTEM_DISK' => 's3', 'FILESYSTEM_DISK' => 's3',
'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null, 'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null, 'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null, 'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null,

View File

@@ -0,0 +1,38 @@
<?php
namespace Domain\Teams\Actions;
use DB;
use App\Users\Models\User;
use Domain\Teams\Models\TeamFolderInvitation;
class ClearActionInInvitationNotificationAction
{
public function __invoke(User $user, TeamFolderInvitation $invitation): void
{
if (is_demo_account()) {
return;
}
// Get notification with invitation
$notification = DB::table('notifications')
->where('notifiable_id', $user->id)
->where('data', 'LIKE', "%{$invitation->id}%")
->first();
if ($notification) {
// Get data
$data = json_decode($notification->data);
// Clear action object
$data->action = null;
// Update notification
DB::table('notifications')
->where('notifiable_id', $user->id)
->where('data', 'LIKE', "%{$invitation->id}%")
->update([
'data' => json_encode($data),
]);
}
}
}

View File

@@ -1,6 +1,7 @@
<?php <?php
namespace Domain\Teams\Actions; namespace Domain\Teams\Actions;
use App\Users\Models\User;
use Domain\Folders\Models\Folder; use Domain\Folders\Models\Folder;
use Spatie\QueueableAction\QueueableAction; use Spatie\QueueableAction\QueueableAction;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
@@ -25,9 +26,19 @@ class InviteMembersIntoTeamFolderAction
'inviter_id' => $folder->user_id, 'inviter_id' => $folder->user_id,
]); ]);
// Invite user // Get user
Notification::route('mail', $member['email']) $user = User::where('email', $member['email'])->first();
->notify(new InvitationIntoTeamFolder($folder, $invitation));
// Invite native user
if ($user) {
$user->notify(new InvitationIntoTeamFolder($folder, $invitation));
}
// Invite guest
if (! $user) {
Notification::route('mail', $member['email'])
->notify(new InvitationIntoTeamFolder($folder, $invitation));
}
}); });
} }
} }

View File

@@ -1,7 +1,6 @@
<?php <?php
namespace Domain\Teams\Controllers; namespace Domain\Teams\Controllers;
use Domain\Folders\Resources\FolderResource;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Domain\Folders\Models\Folder; use Domain\Folders\Models\Folder;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;

View File

@@ -8,6 +8,7 @@ use Domain\Teams\Models\TeamFolderMember;
use Domain\Teams\Models\TeamFolderInvitation; use Domain\Teams\Models\TeamFolderInvitation;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Domain\Teams\Resources\TeamInvitationResource; use Domain\Teams\Resources\TeamInvitationResource;
use Domain\Teams\Actions\ClearActionInInvitationNotificationAction;
class InvitationsController extends Controller class InvitationsController extends Controller
{ {
@@ -21,22 +22,31 @@ class InvitationsController extends Controller
} }
public function update( public function update(
TeamFolderInvitation $invitation TeamFolderInvitation $invitation,
): ResponseFactory | Response { ClearActionInInvitationNotificationAction $clearActionInInvitationNotification,
$user = User::where('email', $invitation->email); ): ResponseFactory|Response {
$user = User::where('email', $invitation->email)
->first();
if ($user) {
if (is_demo_account()) {
return response('Done', 204);
}
if ($user->exists()) {
$invitation->accept(); $invitation->accept();
// Store team member // Store team member
TeamFolderMember::create([ TeamFolderMember::create([
'user_id' => $user->first()->id, 'user_id' => $user->id,
'parent_id' => $invitation->parent_id, 'parent_id' => $invitation->parent_id,
'permission' => $invitation->permission, 'permission' => $invitation->permission,
]); ]);
// Clear action in existing notification
$clearActionInInvitationNotification($user, $invitation);
} }
if ($user->doesntExist()) { if (! $user) {
$invitation->update([ $invitation->update([
'status' => 'waiting-for-registration', 'status' => 'waiting-for-registration',
]); ]);
@@ -46,10 +56,24 @@ class InvitationsController extends Controller
} }
public function destroy( public function destroy(
TeamFolderInvitation $invitation TeamFolderInvitation $invitation,
): ResponseFactory | Response { ClearActionInInvitationNotificationAction $clearActionInInvitationNotification,
): ResponseFactory|Response {
$invitation->reject(); $invitation->reject();
// Get user from invitation
$user = User::where('email', $invitation->email)
->first();
// Clear action in existing notification
if ($user) {
if (is_demo_account()) {
return response('Done', 204);
}
$clearActionInInvitationNotification($user, $invitation);
}
return response('Done', 204); return response('Done', 204);
} }
} }

View File

@@ -44,7 +44,7 @@ class TeamFoldersController extends Controller
->get(); ->get();
} }
if (!$id) { if (! $id) {
$folders = Folder::where('parent_id', null) $folders = Folder::where('parent_id', null)
->where('team_folder', true) ->where('team_folder', true)
->where('user_id', Auth::id()) ->where('user_id', Auth::id())

View File

@@ -5,10 +5,11 @@ use App\Users\Models\User;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Domain\Folders\Models\Folder; use Domain\Folders\Models\Folder;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Domain\Teams\Models\TeamFolderInvitation; use Domain\Teams\Models\TeamFolderInvitation;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
class InvitationIntoTeamFolder extends Notification class InvitationIntoTeamFolder extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
@@ -23,7 +24,7 @@ class InvitationIntoTeamFolder extends Notification
*/ */
public function via(): array public function via(): array
{ {
return ['mail']; return ['mail', 'database', 'broadcast'];
} }
/** /**
@@ -51,4 +52,22 @@ class InvitationIntoTeamFolder extends Notification
->action('Join & Create an Account', url('/team-folder-invitation', ['id' => $this->invitation->id])) ->action('Join & Create an Account', url('/team-folder-invitation', ['id' => $this->invitation->id]))
->salutation("Regards, $appTitle"); ->salutation("Regards, $appTitle");
} }
/**
* Get the array representation of the notification.
*/
public function toArray(mixed $notifiable): array
{
return [
'type' => 'team-invitation',
'title' => 'New Team Invitation',
'description' => "{$this->invitation->inviter->settings->name} invite you to join into Team Folder.",
'action' => [
'type' => 'invitation',
'params' => [
'id' => $this->invitation->id,
],
],
];
}
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\UploadRequest\Controllers; namespace Domain\UploadRequest\Controllers;
use Auth; use Auth;

View File

@@ -1,12 +1,12 @@
<?php <?php
namespace Domain\UploadRequest\Controllers; namespace Domain\UploadRequest\Controllers;
use Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Domain\UploadRequest\Models\UploadRequest; use Domain\UploadRequest\Models\UploadRequest;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Domain\UploadRequest\Resources\UploadRequestResource; use Domain\UploadRequest\Resources\UploadRequestResource;
use Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification;
class SetUploadRequestAsFilledController class SetUploadRequestAsFilledController
{ {
@@ -17,7 +17,7 @@ class SetUploadRequestAsFilledController
]); ]);
// Send user notification // Send user notification
if (!is_demo_account()) { if (! is_demo_account()) {
$uploadRequest->user->notify(new UploadRequestFulfilledNotification($uploadRequest)); $uploadRequest->user->notify(new UploadRequestFulfilledNotification($uploadRequest));
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\UploadRequest\Controllers; namespace Domain\UploadRequest\Controllers;
use DB; use DB;
@@ -14,7 +13,8 @@ class UploadFilesForUploadRequestController
{ {
public function __construct( public function __construct(
private UploadFileAction $uploadFile, private UploadFileAction $uploadFile,
) {} ) {
}
/** /**
* @throws FileNotFoundException * @throws FileNotFoundException

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\UploadRequest\Notifications; namespace Domain\UploadRequest\Notifications;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
@@ -19,7 +18,8 @@ class UploadRequestFulfilledNotification extends Notification implements ShouldQ
*/ */
public function __construct( public function __construct(
public UploadRequest $uploadRequest public UploadRequest $uploadRequest
) {} ) {
}
/** /**
* Get the notification's delivery channels. * Get the notification's delivery channels.
@@ -38,7 +38,7 @@ class UploadRequestFulfilledNotification extends Notification implements ShouldQ
return (new MailMessage) return (new MailMessage)
->subject("Your file request was fulfilled in your '{$this->uploadRequest->parent->name}' folder") ->subject("Your file request was fulfilled in your '{$this->uploadRequest->parent->name}' folder")
->greeting('Hello') ->greeting('Hello')
->line("We are emailing you because your file request was fulfilled. Please click on the link below to show uploaded files.") ->line('We are emailing you because your file request was fulfilled. Please click on the link below to show uploaded files.')
->action('Show Files', url("/platform/files/{$this->uploadRequest->id}")) ->action('Show Files', url("/platform/files/{$this->uploadRequest->id}"))
->line('Thank you for using our application!'); ->line('Thank you for using our application!');
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Domain\UploadRequest\Requests; namespace Domain\UploadRequest\Requests;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;

View File

@@ -28,9 +28,9 @@ class UploadRequestResource extends JsonResource
'id' => $this->user->id, 'id' => $this->user->id,
'type' => 'user', 'type' => 'user',
'attributes' => [ 'attributes' => [
'name' => $this->user->settings->first_name, 'name' => $this->user->settings->first_name,
'color' => $this->user->settings->color, 'color' => $this->user->settings->color,
'avatar' => $this->user->settings->avatar, 'avatar' => $this->user->settings->avatar,
], ],
], ],
], ],

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Support\Middleware; namespace Support\Middleware;
use Closure; use Closure;
@@ -16,7 +15,7 @@ class AdminCheck
public function handle($request, Closure $next) public function handle($request, Closure $next)
{ {
// Check if user have access to administration settings // Check if user have access to administration settings
if ( $request->user()->role !== 'admin') { if ($request->user()->role !== 'admin') {
abort(403, 'You don\'t have access for this operation!'); abort(403, 'You don\'t have access for this operation!');
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace Support\Middleware; namespace Support\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
class TrustProxies extends Middleware class TrustProxies extends Middleware
{ {

View File

@@ -27,9 +27,13 @@ if (! function_exists('getListOfLatestLogs')) {
return array_slice( return array_slice(
array_reverse( array_reverse(
array_filter( array_filter(
scandir(storage_path() . '/logs'), fn($fn) => !str_starts_with($fn, '.') scandir(storage_path() . '/logs'),
fn ($fn) => ! str_starts_with($fn, '.')
) )
), 0, 5, true ),
0,
5,
true
); );
} }
} }
@@ -687,6 +691,7 @@ if (! function_exists('mapTrafficRecords')) {
$records->add($record); $records->add($record);
} }
} }
return $records; return $records;
} }
} }
@@ -1126,13 +1131,13 @@ if (! function_exists('replace_occurrence')) {
} }
} }
if (!function_exists('formatGPSCoordinates')) { if (! function_exists('formatGPSCoordinates')) {
/** /**
* Format GPS coordinates * Format GPS coordinates
*/ */
function formatGPSCoordinates($coordinates, $ref): string|null function formatGPSCoordinates($coordinates, $ref): string|null
{ {
if (!$coordinates && !$ref) { if (! $coordinates && ! $ref) {
return null; return null;
} }

View File

@@ -386,12 +386,11 @@ class FileTest extends TestCase
}); });
} }
/** /**
* @test * @test
*/ */
public function it_store_file_exif_data_after_file_upload() public function it_store_file_exif_data_after_file_upload()
{ {
$file = UploadedFile::fake() $file = UploadedFile::fake()
->image('fake-image.jpg', 2000, 2000); ->image('fake-image.jpg', 2000, 2000);
@@ -417,5 +416,4 @@ class FileTest extends TestCase
'width' => 2000, 'width' => 2000,
]); ]);
} }
} }

View File

@@ -1,11 +1,10 @@
<?php <?php
namespace Tests\Domain\Notifications; namespace Tests\Domain\Notifications;
use App\Users\Models\User;
use Tests\TestCase;
use Str;
use DB; use DB;
use Str;
use Tests\TestCase;
use App\Users\Models\User;
class NotificationsTest extends TestCase class NotificationsTest extends TestCase
{ {
@@ -131,4 +130,4 @@ class NotificationsTest extends TestCase
$this->assertDatabaseCount('notifications', 0); $this->assertDatabaseCount('notifications', 0);
} }
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace Tests\Domain\Settings; namespace Tests\Domain\Settings;
use Storage; use Storage;

View File

@@ -62,11 +62,41 @@ class TeamManagementTest extends TestCase
'permission' => 'can-view', 'permission' => 'can-view',
]); ]);
DB::table('notifications')
->insert([
'id' => Str::uuid(),
'type' => 'Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification',
'notifiable_type' => 'App\Users\Models\User',
'notifiable_id' => $member->id,
'data' => json_encode([
'type' => 'team-invitation',
'title' => 'New Team Invitation',
'description' => 'Jane Doe invite you to join into Team Folder..',
'action' => [
'type' => 'invitation',
'params' => [
'type' => 'invitation',
'params' => [
'id' => $invitation->id,
],
],
],
]),
'created_at' => now(),
'updated_at' => now(),
]);
$this $this
->actingAs($member) ->actingAs($member)
->putJson("/api/teams/invitations/{$invitation->id}") ->putJson("/api/teams/invitations/{$invitation->id}")
->assertNoContent(); ->assertNoContent();
// Get notification
$notification = json_decode(DB::table('notifications')->first()->data);
// Check if action is null
$this->assertEquals(null, $notification->action);
$this $this
->assertDatabaseHas('team_folder_invitations', [ ->assertDatabaseHas('team_folder_invitations', [
'parent_id' => $folder->id, 'parent_id' => $folder->id,
@@ -174,11 +204,41 @@ class TeamManagementTest extends TestCase
'permission' => 'can-edit', 'permission' => 'can-edit',
]); ]);
DB::table('notifications')
->insert([
'id' => Str::uuid(),
'type' => 'Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification',
'notifiable_type' => 'App\Users\Models\User',
'notifiable_id' => $member->id,
'data' => json_encode([
'type' => 'team-invitation',
'title' => 'New Team Invitation',
'description' => 'Jane Doe invite you to join into Team Folder..',
'action' => [
'type' => 'invitation',
'params' => [
'type' => 'invitation',
'params' => [
'id' => $invitation->id,
],
],
],
]),
'created_at' => now(),
'updated_at' => now(),
]);
$this $this
->actingAs($member) ->actingAs($member)
->deleteJson("/api/teams/invitations/{$invitation->id}") ->deleteJson("/api/teams/invitations/{$invitation->id}")
->assertNoContent(); ->assertNoContent();
// Get notification
$notification = json_decode(DB::table('notifications')->first()->data);
// Check if action is null
$this->assertEquals(null, $notification->action);
$this $this
->assertDatabaseHas('team_folder_invitations', [ ->assertDatabaseHas('team_folder_invitations', [
'parent_id' => $folder->id, 'parent_id' => $folder->id,

View File

@@ -1,8 +1,6 @@
<?php <?php
namespace Tests\Domain\UploadRequest; namespace Tests\Domain\UploadRequest;
use Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification;
use Storage; use Storage;
use Notification; use Notification;
use Tests\TestCase; use Tests\TestCase;
@@ -12,6 +10,7 @@ use Illuminate\Http\UploadedFile;
use Domain\UploadRequest\Models\UploadRequest; use Domain\UploadRequest\Models\UploadRequest;
use Support\Scheduler\Actions\ExpireUnfilledUploadRequestAction; use Support\Scheduler\Actions\ExpireUnfilledUploadRequestAction;
use Domain\UploadRequest\Notifications\UploadRequestNotification; use Domain\UploadRequest\Notifications\UploadRequestNotification;
use Domain\UploadRequest\Notifications\UploadRequestFulfilledNotification;
class UploadRequestTest extends TestCase class UploadRequestTest extends TestCase
{ {