mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-14 07:02:34 +01:00
Merge pull request #8292 from turbo124/v5-develop
Add excludable permissions
This commit is contained in:
commit
57d6c13150
@ -15,6 +15,7 @@ use App\Models\Account;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Models\BankTransaction;
|
||||
use App\Models\BankTransactionRule;
|
||||
use App\Models\Client;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\Design;
|
||||
use App\Models\ExpenseCategory;
|
||||
@ -62,12 +63,41 @@ class BaseController extends Controller
|
||||
*/
|
||||
public $forced_index = 'data';
|
||||
|
||||
/**
|
||||
* The calling controller Model Type
|
||||
*/
|
||||
protected $entity_type;
|
||||
|
||||
/**
|
||||
* The calling controller Transformer type
|
||||
*
|
||||
*/
|
||||
protected $entity_transformer;
|
||||
|
||||
/**
|
||||
* The serializer in use with Fractal
|
||||
*
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/* Grouped permissions when we want to hide columns for particular permission groups*/
|
||||
|
||||
private array $client_exclusion_fields = ['balance', 'paid_to_date', 'credit_balance', 'client_hash'];
|
||||
private array $client_excludable_permissions = ['view_client'];
|
||||
private array $client_excludable_overrides = ['edit_client', 'edit_all', 'view_invoice', 'view_all', 'edit_invoice'];
|
||||
|
||||
/* Grouped permissions when we want to hide columns for particular permission groups*/
|
||||
|
||||
|
||||
/**
|
||||
* Fractal manager.
|
||||
* @var object
|
||||
* @var Manager $manager
|
||||
*/
|
||||
protected Manager $manager;
|
||||
|
||||
/**
|
||||
* An array of includes to be loaded by default.
|
||||
*/
|
||||
private $first_load = [
|
||||
'account',
|
||||
'user.company_user',
|
||||
@ -120,6 +150,10 @@ class BaseController extends Controller
|
||||
'company.task_schedulers',
|
||||
];
|
||||
|
||||
/**
|
||||
* An array of includes to be loaded by default
|
||||
* when the company is large.
|
||||
*/
|
||||
private $mini_load = [
|
||||
'account',
|
||||
'user.company_user',
|
||||
@ -140,11 +174,22 @@ class BaseController extends Controller
|
||||
'company.task_schedulers',
|
||||
];
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->manager = new Manager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Manager and transforms
|
||||
* the required includes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function buildManager()
|
||||
{
|
||||
$include = '';
|
||||
@ -172,8 +217,7 @@ class BaseController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch all fallback route
|
||||
* for non-existant route.
|
||||
* Catch all fallback route.
|
||||
*/
|
||||
public function notFound()
|
||||
{
|
||||
@ -187,7 +231,7 @@ class BaseController extends Controller
|
||||
* end user has the correct permissions to
|
||||
* view the includes
|
||||
*
|
||||
* @param array $includes The includes for the object
|
||||
* @param string $includes The includes for the object
|
||||
* @return string The filtered array of includes
|
||||
*/
|
||||
private function filterIncludes(string $includes): string
|
||||
@ -227,6 +271,7 @@ class BaseController extends Controller
|
||||
|
||||
/**
|
||||
* API Error response.
|
||||
*
|
||||
* @param string $message The return error message
|
||||
* @param int $httpErrorCode 404/401/403 etc
|
||||
* @return Response The JSON response
|
||||
@ -245,7 +290,8 @@ class BaseController extends Controller
|
||||
|
||||
/**
|
||||
* Refresh API response with latest cahnges
|
||||
* @param Builer $query
|
||||
*
|
||||
* @param Builder $query
|
||||
* @property App\Models\User auth()->user()
|
||||
* @return Builer
|
||||
*/
|
||||
@ -286,6 +332,10 @@ class BaseController extends Controller
|
||||
$query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id);
|
||||
});
|
||||
}
|
||||
|
||||
if ($user->hasExcludedPermissions($this->client_excludable_permissions, $this->client_excludable_overrides)) {
|
||||
$query->exclude($this->client_exclusion_fields);
|
||||
}
|
||||
},
|
||||
'company.company_gateways' => function ($query) use ($user) {
|
||||
$query->whereNotNull('updated_at')->with('gateway');
|
||||
@ -481,12 +531,14 @@ class BaseController extends Controller
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
//27-10-2022 - enforce unsigned integer
|
||||
$limit = $this->resolveQueryLimit();
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
|
||||
$query = $paginator->getCollection();
|
||||
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
} else {
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
@ -495,7 +547,12 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
private function resolveQueryLimit()
|
||||
/**
|
||||
* Returns the per page limit for the query.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function resolveQueryLimit(): int
|
||||
{
|
||||
if (request()->has('per_page')) {
|
||||
return abs((int)request()->input('per_page', 20));
|
||||
@ -504,6 +561,12 @@ class BaseController extends Controller
|
||||
return 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mini Load Query
|
||||
*
|
||||
* @param mixed $query
|
||||
* @return void
|
||||
*/
|
||||
protected function miniLoadResponse($query)
|
||||
{
|
||||
$user = auth()->user();
|
||||
@ -587,6 +650,7 @@ class BaseController extends Controller
|
||||
* able to access multiple companies, then we
|
||||
* need to pass back the mini load only
|
||||
*
|
||||
* @deprecated
|
||||
* @return bool
|
||||
*/
|
||||
private function complexPermissionsUser(): bool
|
||||
@ -599,6 +663,12 @@ class BaseController extends Controller
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes back the miniloaded data response
|
||||
*
|
||||
* @param mixed $query
|
||||
* @return void
|
||||
*/
|
||||
protected function timeConstrainedResponse($query)
|
||||
{
|
||||
$user = auth()->user();
|
||||
@ -637,6 +707,10 @@ class BaseController extends Controller
|
||||
$query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id);
|
||||
});
|
||||
}
|
||||
|
||||
if ($user->hasExcludedPermissions($this->client_excludable_permissions, $this->client_excludable_overrides)) {
|
||||
$query->exclude($this->client_exclusion_fields);
|
||||
}
|
||||
},
|
||||
'company.company_gateways' => function ($query) use ($user) {
|
||||
$query->whereNotNull('created_at')->with('gateway');
|
||||
@ -834,6 +908,12 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* List response
|
||||
*
|
||||
* @param mixed $query
|
||||
* @return void
|
||||
*/
|
||||
protected function listResponse($query)
|
||||
{
|
||||
$this->buildManager();
|
||||
@ -847,7 +927,6 @@ class BaseController extends Controller
|
||||
$query->with($includes);
|
||||
|
||||
if (auth()->user() && ! auth()->user()->hasPermission('view_'.Str::snake(class_basename($this->entity_type)))) {
|
||||
//06-10-2022 - some entities do not have assigned_user_id - this becomes an issue when we have a large company and low permission users
|
||||
if (in_array($this->entity_type, [User::class])) {
|
||||
$query->where('id', auth()->user()->id);
|
||||
} elseif (in_array($this->entity_type, [BankTransactionRule::class,CompanyGateway::class, TaxRate::class, BankIntegration::class, Scheduler::class, BankTransaction::class, Webhook::class, ExpenseCategory::class])) { //table without assigned_user_id
|
||||
@ -863,7 +942,10 @@ class BaseController extends Controller
|
||||
$query->where('user_id', '=', auth()->user()->id)->orWhere('assigned_user_id', auth()->user()->id);
|
||||
}
|
||||
}
|
||||
// $query->exclude(['balance','credit_balance','paid_to_date']);
|
||||
|
||||
if ($this->entity_type == Client::class && auth()->user()->hasExcludedPermissions($this->client_excludable_permissions, $this->client_excludable_overrides)) {
|
||||
$query->exclude($this->client_exclusion_fields);
|
||||
}
|
||||
|
||||
if (request()->has('updated_at') && request()->input('updated_at') > 0) {
|
||||
$query->where('updated_at', '>=', date('Y-m-d H:i:s', intval(request()->input('updated_at'))));
|
||||
@ -886,6 +968,12 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the response by keys
|
||||
*
|
||||
* @param mixed $response
|
||||
* @return void
|
||||
*/
|
||||
protected function response($response)
|
||||
{
|
||||
$index = request()->input('index') ?: $this->forced_index;
|
||||
@ -917,6 +1005,12 @@ class BaseController extends Controller
|
||||
return response()->make($response, 200, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Item Response
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return void
|
||||
*/
|
||||
protected function itemResponse($item)
|
||||
{
|
||||
$this->buildManager();
|
||||
@ -936,7 +1030,12 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
public static function getApiHeaders()
|
||||
/**
|
||||
* Returns the API headers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getApiHeaders(): array
|
||||
{
|
||||
return [
|
||||
'Content-Type' => 'application/json',
|
||||
@ -945,7 +1044,13 @@ class BaseController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRequestIncludes($data)
|
||||
/**
|
||||
* Returns the parsed relationship includes
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequestIncludes($data): array
|
||||
{
|
||||
/*
|
||||
* Thresholds for displaying large account on first load
|
||||
@ -972,6 +1077,11 @@ class BaseController extends Controller
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entrypoint for the default / route.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function flutterRoute()
|
||||
{
|
||||
if ((bool) $this->checkAppSetup() !== false && $account = Account::first()) {
|
||||
@ -1037,6 +1147,11 @@ class BaseController extends Controller
|
||||
return redirect('/setup');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Flutter build to serve
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setBuild()
|
||||
{
|
||||
$build = '';
|
||||
@ -1065,6 +1180,12 @@ class BaseController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks in a account has a required feature
|
||||
*
|
||||
* @param mixed $feature
|
||||
* @return bool
|
||||
*/
|
||||
public function checkFeature($feature)
|
||||
{
|
||||
if (auth()->user()->account->hasFeature($feature)) {
|
||||
@ -1074,6 +1195,11 @@ class BaseController extends Controller
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feature failure response
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function featureFailure()
|
||||
{
|
||||
return response()->json(['message' => 'Upgrade to a paid plan for this feature.'], 403);
|
||||
|
@ -42,9 +42,19 @@ class ContactHashLoginController extends Controller
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic error page for client portal.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function errorPage()
|
||||
{
|
||||
return render('generic.error', ['title' => session()->get('title'), 'notification' => session()->get('notification'), 'account' => auth()->guard('contact')?->user()?->user?->account, 'company' => auth()->guard('contact')?->user()?->user?->company]);
|
||||
return render('generic.error', [
|
||||
'title' => session()->get('title'),
|
||||
'notification' => session()->get('notification'),
|
||||
'account' => auth()->guard('contact')?->user()?->user?->account,
|
||||
'company' => auth()->guard('contact')?->user()?->user?->company
|
||||
]);
|
||||
}
|
||||
|
||||
private function setRedirectPath()
|
||||
|
@ -75,8 +75,8 @@ class UserController extends BaseController
|
||||
* tags={"users"},
|
||||
* summary="Gets a list of users",
|
||||
* description="Lists users, search and filters allow fine grained lists to be generated.
|
||||
|
||||
Query parameters can be added to performed more fine grained filtering of the users, these are handled by the UserFilters class which defines the methods available",
|
||||
*
|
||||
*Query parameters can be added to performed more fine grained filtering of the users, these are handled by the UserFilters class which defines the methods available",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
|
@ -30,7 +30,7 @@ class ValidCompanyQuantity implements Rule
|
||||
return auth()->user()->company()->account->companies->count() < 10;
|
||||
}
|
||||
|
||||
return auth()->user()->company()->account->companies->count() < auth()->user()->company()->account->hosted_company_count;
|
||||
return auth()->user()->account->isPaid() && auth()->user()->company()->account->companies->count() < 10 ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,14 +17,10 @@ use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\Admin\EntityFailedSendObject;
|
||||
use App\Utils\Traits\Notifications\UserNotifies;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceFailedEmailNotification
|
||||
{
|
||||
use UserNotifies, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use UserNotifies;
|
||||
|
||||
public $delay = 7;
|
||||
|
||||
|
@ -11,14 +11,12 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\Excludable;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class BankIntegration extends BaseModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
use Filterable;
|
||||
use Excludable;
|
||||
|
||||
protected $fillable = [
|
||||
'bank_account_name',
|
||||
|
@ -11,15 +11,16 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\Jobs\Util\WebhookHandler;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Jobs\Util\WebhookHandler;
|
||||
use App\Models\Traits\Excludable;
|
||||
use App\DataMapper\ClientSettings;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Utils\Traits\UserSessionAttributes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class BaseModel
|
||||
@ -33,6 +34,7 @@ class BaseModel extends Model
|
||||
use MakesHash;
|
||||
use UserSessionAttributes;
|
||||
use HasFactory;
|
||||
use Excludable;
|
||||
|
||||
protected $appends = [
|
||||
'hashed_id',
|
||||
|
@ -28,6 +28,10 @@ class CompanyGateway extends BaseModel
|
||||
'deleted_at' => 'timestamp',
|
||||
];
|
||||
|
||||
protected $with = [
|
||||
'gateway',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'gateway_key',
|
||||
'accepted_credit_cards',
|
||||
|
@ -12,12 +12,14 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\Traits\Excludable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
|
||||
|
||||
class StaticModel extends Model
|
||||
{
|
||||
use MakesHash;
|
||||
use Excludable;
|
||||
|
||||
protected $casts = [
|
||||
'updated_at' => 'timestamp',
|
||||
|
@ -392,8 +392,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
}
|
||||
}
|
||||
|
||||
return $this->isOwner() ||
|
||||
$this->isAdmin() ||
|
||||
return $this->isSuperUser() ||
|
||||
(stripos($this->token()->cu->permissions, $permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $all_permission) !== false) ||
|
||||
(stripos($this->token()->cu->permissions, $edit_all) !== false) ||
|
||||
@ -410,7 +409,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
* @param string $permission '["view_all"]'
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasExactPermission(string $permission = '___'): bool
|
||||
public function hasExactPermissionAndAll(string $permission = '___'): bool
|
||||
{
|
||||
$parts = explode('_', $permission);
|
||||
$all_permission = '__';
|
||||
@ -436,7 +435,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
public function hasIntersectPermissions(array $permissions = []): bool
|
||||
{
|
||||
foreach ($permissions as $permission) {
|
||||
if ($this->hasExactPermission($permission)) {
|
||||
if ($this->hasExactPermissionAndAll($permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -444,6 +443,22 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when we need to match exactly what permission
|
||||
* the user has, and not aggregate owner and admins.
|
||||
*
|
||||
* This method is used when we need to scope down the query
|
||||
* and display a limited subset.
|
||||
*
|
||||
* @param string $permission '["view_all"]'
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasExactPermission(string $permission = '___'): bool
|
||||
{
|
||||
return (stripos($this->token()->cu->permissions, $permission) !== false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used when we need to match a range of permissions
|
||||
* the user
|
||||
@ -461,7 +476,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
}
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
if ($this->hasExactPermission($permission)) {
|
||||
if ($this->hasExactPermissionAndAll($permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -469,6 +484,43 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when we need to filter permissions carefully.
|
||||
*
|
||||
* For instance, users that have view_client permissions should not
|
||||
* see the client balance, however if they also have
|
||||
* view_invoice or view_all etc, then they should be able to see the balance.
|
||||
*
|
||||
* First we pass over the excluded permissions and return false if we find a match.
|
||||
*
|
||||
* If those permissions are not hit, then we can iterate through the matched_permissions and search for a hit.
|
||||
*
|
||||
* Note, returning FALSE here means the user does NOT have the permission we want to exclude
|
||||
*
|
||||
* @param array $matched_permission
|
||||
* @param array $excluded_permissions
|
||||
* @return bool
|
||||
*/
|
||||
public function hasExcludedPermissions(array $matched_permission = [], array $excluded_permissions = []): bool
|
||||
{
|
||||
if ($this->isSuperUser()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($excluded_permissions as $permission) {
|
||||
if ($this->hasExactPermission($permission)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($matched_permission as $permission) {
|
||||
if ($this->hasExactPermission($permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function documents()
|
||||
{
|
||||
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Utils\CssInlinerPlugin;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class MailCssInlinerServiceProvider extends ServiceProvider
|
||||
{
|
||||
// Thanks to @fedeisas/laravel-mail-css-inliner
|
||||
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__.'/../config/css-inliner.php' => base_path('config/css-inliner.php'),
|
||||
], 'config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
// $this->app->singleton(CssInlinerPlugin::class, function ($app) {
|
||||
// return new CssInlinerPlugin([]);
|
||||
// });
|
||||
|
||||
// $this->app->singleton(CssInlinerPlugin::class, function ($app) {
|
||||
// return new CssInlinerPlugin([]);
|
||||
// });
|
||||
|
||||
// $this->app->bind(CssInlinerPlugin::class, function ($app) {
|
||||
// return new CssInlinerPlugin([]);
|
||||
// });
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
|
||||
|
||||
class CssInlinerPlugin implements \Swift_Events_SendListener
|
||||
{
|
||||
/**
|
||||
* @var CssToInlineStyles
|
||||
*/
|
||||
protected $converter;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $cssCache;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @param array $options options defined in the configuration file.
|
||||
*/
|
||||
public function __construct(array $options)
|
||||
{
|
||||
$this->converter = new CssToInlineStyles();
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Swift_Events_SendEvent $evt
|
||||
*/
|
||||
public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
|
||||
{
|
||||
$message = $evt->getMessage();
|
||||
|
||||
if ($message->getContentType() === 'text/html'
|
||||
|| ($message->getContentType() === 'multipart/alternative' && $message->getBody())
|
||||
|| ($message->getContentType() === 'multipart/mixed' && $message->getBody())
|
||||
) {
|
||||
[$body, $cssResources] = $this->messageSieve($message->getBody());
|
||||
$css = $this->concatCss($cssResources);
|
||||
$message->setBody($this->converter->convert($body, $css));
|
||||
}
|
||||
|
||||
foreach ($message->getChildren() as $part) {
|
||||
if (strpos($part->getContentType(), 'text/html') === 0) {
|
||||
[$body, $cssResources] = $this->messageSieve($part->getBody());
|
||||
$css = $this->concatCss($cssResources);
|
||||
$part->setBody($this->converter->convert($body, $css));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing
|
||||
*
|
||||
* @param \Swift_Events_SendEvent $evt
|
||||
*/
|
||||
public function sendPerformed(\Swift_Events_SendEvent $evt)
|
||||
{
|
||||
// Do Nothing
|
||||
}
|
||||
|
||||
protected function concatCss(array $cssResources): string
|
||||
{
|
||||
$output = '';
|
||||
foreach ($cssResources as $cssResource) {
|
||||
$output .= $this->fetchCss($cssResource);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function fetchCss(string $filename): string
|
||||
{
|
||||
if (isset($this->cssCache[$filename])) {
|
||||
return $this->cssCache[$filename];
|
||||
}
|
||||
|
||||
$fixedFilename = $filename;
|
||||
// Fix relative protocols on hrefs. Assume https.
|
||||
if (substr($filename, 0, 2) === '//') {
|
||||
$fixedFilename = 'https:'.$filename;
|
||||
}
|
||||
|
||||
$content = file_get_contents($fixedFilename);
|
||||
if (! $content) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$this->cssCache[$filename] = $content;
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function messageSieve(string $message): array
|
||||
{
|
||||
$cssResources = [];
|
||||
|
||||
// Initialize with config defaults, if any
|
||||
if (isset($this->options['css-files'])) {
|
||||
$cssResources = $this->options['css-files'];
|
||||
}
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
// set error level
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
|
||||
$dom->loadHTML($message);
|
||||
|
||||
// Restore error level
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
$link_tags = $dom->getElementsByTagName('link');
|
||||
|
||||
/** @var \DOMElement $link */
|
||||
foreach ($link_tags as $link) {
|
||||
if ($link->getAttribute('rel') === 'stylesheet') {
|
||||
array_push($cssResources, $link->getAttribute('href'));
|
||||
}
|
||||
}
|
||||
|
||||
$link_tags = $dom->getElementsByTagName('link');
|
||||
for ($i = $link_tags->length; --$i >= 0;) {
|
||||
$link = $link_tags->item($i);
|
||||
if ($link->getAttribute('rel') === 'stylesheet') {
|
||||
$link->parentNode->removeChild($link);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($cssResources)) {
|
||||
return [$dom->saveHTML(), $cssResources];
|
||||
}
|
||||
|
||||
return [$message, []];
|
||||
}
|
||||
}
|
@ -87,7 +87,6 @@
|
||||
"symfony/http-client": "^6.0",
|
||||
"symfony/mailgun-mailer": "^6.1",
|
||||
"symfony/postmark-mailer": "^6.1",
|
||||
"tijsverkoyen/css-to-inline-styles": "^2.2",
|
||||
"turbo124/beacon": "^1.3",
|
||||
"twilio/sdk": "^6.40",
|
||||
"webpatser/laravel-countries": "dev-master#75992ad",
|
||||
|
189
composer.lock
generated
189
composer.lock
generated
@ -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": "55a62c4290c3a07d0c38c8e4aeea61e0",
|
||||
"content-hash": "6156afb5e414466a8cd7b5903bbcbc6a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "afosto/yaac",
|
||||
@ -379,16 +379,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.258.10",
|
||||
"version": "3.259.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337"
|
||||
"reference": "096711644ebe5c956a97ef449fa2cb3b66443c25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/096711644ebe5c956a97ef449fa2cb3b66443c25",
|
||||
"reference": "096711644ebe5c956a97ef449fa2cb3b66443c25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -467,9 +467,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.258.10"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.259.0"
|
||||
},
|
||||
"time": "2023-02-14T19:21:16+00:00"
|
||||
"time": "2023-02-17T19:21:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -1504,28 +1504,27 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
"version": "2.1.0",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/lexer.git",
|
||||
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
|
||||
"reference": "84a527db05647743d50373e0ec53a152f2cde568"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
|
||||
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568",
|
||||
"reference": "84a527db05647743d50373e0ec53a152f2cde568",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/deprecations": "^1.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"doctrine/coding-standard": "^10",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psalm/plugin-phpunit": "^0.18.3",
|
||||
"vimeo/psalm": "^4.11 || ^5.0"
|
||||
"vimeo/psalm": "^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -1562,7 +1561,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/lexer/issues",
|
||||
"source": "https://github.com/doctrine/lexer/tree/2.1.0"
|
||||
"source": "https://github.com/doctrine/lexer/tree/3.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1578,7 +1577,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-14T08:49:07+00:00"
|
||||
"time": "2022-12-15T16:57:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dragonmantank/cron-expression",
|
||||
@ -2168,16 +2167,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/apiclient-services",
|
||||
"version": "v0.287.0",
|
||||
"version": "v0.288.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||
"reference": "ed58596d34272a5cd0dc2c0595d9a678b9834880"
|
||||
"reference": "de6cfa1556faf4a23d9ab5844508bb576f44fdd7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/ed58596d34272a5cd0dc2c0595d9a678b9834880",
|
||||
"reference": "ed58596d34272a5cd0dc2c0595d9a678b9834880",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/de6cfa1556faf4a23d9ab5844508bb576f44fdd7",
|
||||
"reference": "de6cfa1556faf4a23d9ab5844508bb576f44fdd7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2206,9 +2205,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.287.0"
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.288.0"
|
||||
},
|
||||
"time": "2023-02-12T01:08:11+00:00"
|
||||
"time": "2023-02-18T01:16:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "google/auth",
|
||||
@ -4232,16 +4231,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.3.8",
|
||||
"version": "2.3.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "c493585c130544c4e91d2e0e131e6d35cb0cbc47"
|
||||
"reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c493585c130544c4e91d2e0e131e6d35cb0cbc47",
|
||||
"reference": "c493585c130544c4e91d2e0e131e6d35cb0cbc47",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c1e114f74e518daca2729ea8c4bf1167038fa4b5",
|
||||
"reference": "c1e114f74e518daca2729ea8c4bf1167038fa4b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4334,7 +4333,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-10T16:02:17+00:00"
|
||||
"time": "2023-02-15T14:07:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/config",
|
||||
@ -4504,16 +4503,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.12.2",
|
||||
"version": "3.12.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "f6377c709d2275ed6feaf63e44be7a7162b0e77f"
|
||||
"reference": "81e87e74dd5213795c7846d65089712d2dda90ce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f6377c709d2275ed6feaf63e44be7a7162b0e77f",
|
||||
"reference": "f6377c709d2275ed6feaf63e44be7a7162b0e77f",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/81e87e74dd5213795c7846d65089712d2dda90ce",
|
||||
"reference": "81e87e74dd5213795c7846d65089712d2dda90ce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4575,7 +4574,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.12.2"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.12.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4591,7 +4590,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-19T12:02:19+00:00"
|
||||
"time": "2023-02-18T15:32:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-aws-s3-v3",
|
||||
@ -4928,16 +4927,16 @@
|
||||
},
|
||||
{
|
||||
"name": "livewire/livewire",
|
||||
"version": "v2.11.2",
|
||||
"version": "v2.11.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/livewire/livewire.git",
|
||||
"reference": "e92233f31dc1b88fb1ac242b32afe1ab7525ee05"
|
||||
"reference": "5ab6266a12c637f645d38a2f0f61f84182f6249d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/e92233f31dc1b88fb1ac242b32afe1ab7525ee05",
|
||||
"reference": "e92233f31dc1b88fb1ac242b32afe1ab7525ee05",
|
||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/5ab6266a12c637f645d38a2f0f61f84182f6249d",
|
||||
"reference": "5ab6266a12c637f645d38a2f0f61f84182f6249d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4989,7 +4988,7 @@
|
||||
"description": "A front-end framework for Laravel.",
|
||||
"support": {
|
||||
"issues": "https://github.com/livewire/livewire/issues",
|
||||
"source": "https://github.com/livewire/livewire/tree/v2.11.2"
|
||||
"source": "https://github.com/livewire/livewire/tree/v2.11.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4997,7 +4996,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-29T23:45:02+00:00"
|
||||
"time": "2023-02-20T03:52:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "microsoft/microsoft-graph",
|
||||
@ -13071,25 +13070,25 @@
|
||||
},
|
||||
{
|
||||
"name": "beyondcode/laravel-query-detector",
|
||||
"version": "1.6.0",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beyondcode/laravel-query-detector.git",
|
||||
"reference": "8261d80c71c97e994c1021fe5c3bd2a1c27106fc"
|
||||
"reference": "40c7e168fcf7eeb80d8e96f7922e05ab194269c8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beyondcode/laravel-query-detector/zipball/8261d80c71c97e994c1021fe5c3bd2a1c27106fc",
|
||||
"reference": "8261d80c71c97e994c1021fe5c3bd2a1c27106fc",
|
||||
"url": "https://api.github.com/repos/beyondcode/laravel-query-detector/zipball/40c7e168fcf7eeb80d8e96f7922e05ab194269c8",
|
||||
"reference": "40c7e168fcf7eeb80d8e96f7922e05ab194269c8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
|
||||
"illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/legacy-factories": "^1.0",
|
||||
"orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
@ -13125,9 +13124,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/beyondcode/laravel-query-detector/issues",
|
||||
"source": "https://github.com/beyondcode/laravel-query-detector/tree/1.6.0"
|
||||
"source": "https://github.com/beyondcode/laravel-query-detector/tree/1.7.0"
|
||||
},
|
||||
"time": "2022-02-12T16:23:40+00:00"
|
||||
"time": "2023-02-15T10:37:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brianium/paratest",
|
||||
@ -13703,30 +13702,30 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "1.14.3",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/annotations.git",
|
||||
"reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af"
|
||||
"reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
|
||||
"reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
|
||||
"url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
|
||||
"reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/lexer": "^1 || ^2",
|
||||
"doctrine/lexer": "^2 || ^3",
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"psr/cache": "^1 || ^2 || ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.11 || ^2.0",
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "~1.4.10 || ^1.8.0",
|
||||
"doctrine/cache": "^2.0",
|
||||
"doctrine/coding-standard": "^10",
|
||||
"phpstan/phpstan": "^1.8.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"symfony/cache": "^5.4 || ^6",
|
||||
"vimeo/psalm": "^4.10"
|
||||
},
|
||||
"suggest": {
|
||||
@ -13773,9 +13772,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/annotations/issues",
|
||||
"source": "https://github.com/doctrine/annotations/tree/1.14.3"
|
||||
"source": "https://github.com/doctrine/annotations/tree/2.0.1"
|
||||
},
|
||||
"time": "2023-02-01T09:20:38+00:00"
|
||||
"time": "2023-02-02T22:02:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@ -14082,27 +14081,27 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.14.2",
|
||||
"version": "v3.14.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "14f0541651841b63640e7aafad041ad55dc7aa88"
|
||||
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/14f0541651841b63640e7aafad041ad55dc7aa88",
|
||||
"reference": "14f0541651841b63640e7aafad041ad55dc7aa88",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1b3d9dba63d93b8a202c31e824748218781eae6b",
|
||||
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/semver": "^3.3",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"doctrine/annotations": "^1.14.2 || ^2",
|
||||
"doctrine/lexer": "^2",
|
||||
"doctrine/annotations": "^2",
|
||||
"doctrine/lexer": "^2 || ^3",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"sebastian/diff": "^4.0",
|
||||
"sebastian/diff": "^4.0 || ^5.0",
|
||||
"symfony/console": "^5.4 || ^6.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.0",
|
||||
@ -14160,7 +14159,7 @@
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.2"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -14168,7 +14167,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-29T23:47:01+00:00"
|
||||
"time": "2023-02-09T21:49:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
@ -14223,24 +14222,24 @@
|
||||
},
|
||||
{
|
||||
"name": "laracasts/cypress",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laracasts/cypress.git",
|
||||
"reference": "9a9e5d25a51d2cbb410393e6a0d9883aa3304bf5"
|
||||
"reference": "dd4e61188d4edaf65ffa18851a5df38d0fa0619a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laracasts/cypress/zipball/9a9e5d25a51d2cbb410393e6a0d9883aa3304bf5",
|
||||
"reference": "9a9e5d25a51d2cbb410393e6a0d9883aa3304bf5",
|
||||
"url": "https://api.github.com/repos/laracasts/cypress/zipball/dd4e61188d4edaf65ffa18851a5df38d0fa0619a",
|
||||
"reference": "dd4e61188d4edaf65ffa18851a5df38d0fa0619a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
|
||||
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0",
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^6.0|^7.0",
|
||||
"orchestra/testbench": "^6.0|^7.0|^8.0",
|
||||
"phpunit/phpunit": "^8.0|^9.5.10",
|
||||
"spatie/laravel-ray": "^1.29"
|
||||
},
|
||||
@ -14276,9 +14275,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laracasts/cypress/issues",
|
||||
"source": "https://github.com/laracasts/cypress/tree/3.0.0"
|
||||
"source": "https://github.com/laracasts/cypress/tree/3.0.1"
|
||||
},
|
||||
"time": "2022-06-27T13:49:35+00:00"
|
||||
"time": "2023-02-16T20:00:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/dusk",
|
||||
@ -15086,16 +15085,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.9.17",
|
||||
"version": "1.9.18",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2"
|
||||
"reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f2d5cf71be91172a57c649770b73c20ebcffb0bf",
|
||||
"reference": "f2d5cf71be91172a57c649770b73c20ebcffb0bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -15125,7 +15124,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.17"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.18"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -15141,7 +15140,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-08T12:25:00+00:00"
|
||||
"time": "2023-02-17T15:01:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@ -17310,30 +17309,28 @@
|
||||
},
|
||||
{
|
||||
"name": "zircote/swagger-php",
|
||||
"version": "3.3.7",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zircote/swagger-php.git",
|
||||
"reference": "e8c3bb316e385e93a0c7e8b2aa0681079244c381"
|
||||
"reference": "9d172471e56433b5c7061006b9a766f262a3edfd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/e8c3bb316e385e93a0c7e8b2aa0681079244c381",
|
||||
"reference": "e8c3bb316e385e93a0c7e8b2aa0681079244c381",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/9d172471e56433b5c7061006b9a766f262a3edfd",
|
||||
"reference": "9d172471e56433b5c7061006b9a766f262a3edfd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/annotations": "^1.7",
|
||||
"doctrine/annotations": "*",
|
||||
"ext-json": "*",
|
||||
"php": ">=7.2",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0",
|
||||
"symfony/finder": ">=2.2",
|
||||
"symfony/yaml": ">=3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/package-versions-deprecated": "1.11.99.2",
|
||||
"friendsofphp/php-cs-fixer": "^2.17 || ^3.0",
|
||||
"phpunit/phpunit": ">=8.5.14"
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpunit/phpunit": ">=8"
|
||||
},
|
||||
"bin": [
|
||||
"bin/openapi"
|
||||
@ -17377,9 +17374,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/zircote/swagger-php/issues",
|
||||
"source": "https://github.com/zircote/swagger-php/tree/3.3.7"
|
||||
"source": "https://github.com/zircote/swagger-php/tree/3.1.0"
|
||||
},
|
||||
"time": "2023-01-03T21:17:10+00:00"
|
||||
"time": "2020-09-03T20:18:43+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
@ -201,7 +201,6 @@ return [
|
||||
App\Providers\MultiDBProvider::class,
|
||||
App\Providers\ClientPortalServiceProvider::class,
|
||||
App\Providers\NinjaTranslationServiceProvider::class,
|
||||
// App\Providers\MailCssInlinerServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Css Files
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Css file of your style for your emails
|
||||
| The content of these files will be added directly into the inliner
|
||||
| Use absolute paths, ie. public_path('css/main.css')
|
||||
|
|
||||
*/
|
||||
|
||||
'css-files' => [],
|
||||
|
||||
];
|
@ -16,6 +16,7 @@ use App\Models\CompanyGateway;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -26,7 +27,8 @@ use Tests\TestCase;
|
||||
class CompanyGatewayTest extends TestCase
|
||||
{
|
||||
use MockAccountData;
|
||||
use DatabaseTransactions;
|
||||
// use DatabaseTransactions;
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function setUp() :void
|
||||
{
|
||||
|
@ -10,14 +10,17 @@
|
||||
*/
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\CompanySettings;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Company;
|
||||
use App\Models\Activity;
|
||||
use Tests\MockAccountData;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -26,8 +29,9 @@ use Tests\TestCase;
|
||||
class CompanySettingsTest extends TestCase
|
||||
{
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
// use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
use RefreshDatabase;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
@ -179,6 +183,7 @@ class CompanySettingsTest extends TestCase
|
||||
|
||||
public function testCompanyNullValueMatrixPOST()
|
||||
{
|
||||
|
||||
$settings = CompanySettings::defaults();
|
||||
$settings->reset_counter_date = null;
|
||||
|
||||
|
@ -217,8 +217,8 @@ trait MockAccountData
|
||||
$fake_email = $this->faker->email();
|
||||
|
||||
$this->account = Account::factory()->create([
|
||||
'hosted_client_count' => 1000,
|
||||
'hosted_company_count' => 1000,
|
||||
'hosted_client_count' => 1000000,
|
||||
'hosted_company_count' => 1000000,
|
||||
]);
|
||||
|
||||
$this->account->num_users = 3;
|
||||
|
@ -75,6 +75,51 @@ class PermissionsTest extends TestCase
|
||||
$company_token->save();
|
||||
}
|
||||
|
||||
public function testHasExcludedPermissions()
|
||||
{
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = '["view_client"]';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertTrue($this->user->hasExcludedPermissions(["view_client"]));
|
||||
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = 'view_client';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertTrue($this->user->hasExcludedPermissions(["view_client"]));
|
||||
|
||||
}
|
||||
|
||||
public function testHasExcludedPermissions2()
|
||||
{
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = '["view_client","edit_all"]';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertFalse($this->user->hasExcludedPermissions(["view_client"], ['edit_all']));
|
||||
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = 'view_client,edit_all';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertFalse($this->user->hasExcludedPermissions(["view_client"], ['edit_all']));
|
||||
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = 'view_client,view_all';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertFalse($this->user->hasExcludedPermissions(["view_client"], ['view_all']));
|
||||
|
||||
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
$low_cu->permissions = 'view_client,view_invoice';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertFalse($this->user->hasExcludedPermissions(["view_client"], ['view_invoice']));
|
||||
|
||||
}
|
||||
|
||||
public function testIntersectPermissions()
|
||||
{
|
||||
$low_cu = CompanyUser::where(['company_id' => $this->company->id, 'user_id' => $this->user->id])->first();
|
||||
@ -212,8 +257,8 @@ class PermissionsTest extends TestCase
|
||||
|
||||
public function testExactPermissions()
|
||||
{
|
||||
$this->assertTrue($this->user->hasExactPermission("view_client"));
|
||||
$this->assertFalse($this->user->hasExactPermission("view_all"));
|
||||
$this->assertTrue($this->user->hasExactPermissionAndAll("view_client"));
|
||||
$this->assertFalse($this->user->hasExactPermissionAndAll("view_all"));
|
||||
}
|
||||
|
||||
public function testMissingPermissions()
|
||||
@ -222,8 +267,8 @@ class PermissionsTest extends TestCase
|
||||
$low_cu->permissions = '[""]';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertFalse($this->user->hasExactPermission("view_client"));
|
||||
$this->assertFalse($this->user->hasExactPermission("view_all"));
|
||||
$this->assertFalse($this->user->hasExactPermissionAndAll("view_client"));
|
||||
$this->assertFalse($this->user->hasExactPermissionAndAll("view_all"));
|
||||
}
|
||||
|
||||
public function testViewAllValidPermissions()
|
||||
@ -232,8 +277,8 @@ class PermissionsTest extends TestCase
|
||||
$low_cu->permissions = '["view_all"]';
|
||||
$low_cu->save();
|
||||
|
||||
$this->assertTrue($this->user->hasExactPermission("view_client"));
|
||||
$this->assertTrue($this->user->hasExactPermission("view_all"));
|
||||
$this->assertTrue($this->user->hasExactPermissionAndAll("view_client"));
|
||||
$this->assertTrue($this->user->hasExactPermissionAndAll("view_all"));
|
||||
}
|
||||
|
||||
public function testReturnTypesOfStripos()
|
||||
|
Loading…
Reference in New Issue
Block a user