migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::check() && (Auth::user()->role != 'shop-owner' && Auth::user()->role != 'staff')) {
return $next($request);
}
// Redirect if the user is not an admin
return redirect('/');
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AffiliatorMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->check() && (auth()->user()->role == 'affiliator')) {
return $next($request);
}
return redirect('/login');
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*/
protected function redirectTo(Request $request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Http\Middleware;
use App\Models\Branch;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckActiveBranch
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (!moduleCheck('MultiBranchAddon')) {
return $next($request);
}
$user = auth()->user();
// If no user found, just continue
if (!$user) {
return $next($request);
}
if (in_array($user->role, ['shop-owner', 'staff']) && $user->accessToMultiBranch()) {
if ($request->routeIs([
'business.sales.create',
'business.sales.store',
'business.products.show',
'business.products.create',
'business.products.store',
'business.products.edit',
'business.products.update',
'hrm.employees.create',
'hrm.employees.store',
'business.sale-returns.create',
'business.sale-returns.store',
'business.purchase-returns.create',
'business.purchase-returns.store',
'business.purchases.create',
'business.purchases.store',
'business.expenses.store',
'business.parties.create',
'business.parties.store',
'business.parties.edit',
'business.parties.update',
])) {
$totalBranch = branch_count();
if ($totalBranch > 1) {
return $request->wantsJson()
? response()->json(
[
'redirect' => route('multibranch.branches.index'),
'message' => 'Please select a branch to continue.'
],
406
)
: redirect()->route('multibranch.branches.index')->with('warning', 'Please select a branch to continue.');
} elseif ($totalBranch == 1) {
$branch = Branch::where('business_id', $user->business_id)->first();
if ($branch) {
$user->update([
'active_branch_id' => $branch->id
]);
}
return $next($request);
}
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckDomain
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (!moduleCheck('CustomDomainAddon')) {
return $next($request);
}
$host = $request->getHost(); // Current host
$installedDomain = get_root_domain();
if (!$installedDomain) {
abort(406, 'Error: App URL not detected. Please update the APP_URL value in your .env file.');
}
// Allow the exact installed domain
if ($host === $installedDomain) {
return $next($request);
}
// Otherwise check verified addon/custom domains
$isAllowed = \Modules\CustomDomainAddon\App\Models\Domain::query()
->where('domain', $host)
->where('is_verified', 1)
->where('status', 1)
->exists();
if (!$isAllowed) {
abort(400, 'Error: this domain is not allowed. Please request for a domain/subdomain from the business panel.');
}
$publicRoutes = [
'/',
'blogs',
'blogs/*',
'about-us',
'plans',
'data-deletion',
'terms-conditions',
'privacy-policy',
'contact-us',
];
if ($request->is($publicRoutes)) {
return redirect('/login');
}
return $next($request);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CheckPermission
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle($request, Closure $next, $permission)
{
$user = Auth::user();
if ($user->role === 'shop-owner') {
return $next($request);
}
if (!$user->hasPermission($permission)) {
abort(403, 'Unauthorized');
}
return $next($request);
}
}

View File

@@ -0,0 +1,245 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\Response;
class DemoMode
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (env('DEMO_MODE', false)) {
$adminDisabledRoutes = [
'admin.business.delete-all',
'admin.business.update',
'admin.business.destroy',
'admin.business.status',
'admin.business-categories.delete-all',
'admin.business-categories.update',
'admin.business-categories.destroy',
'admin.banners.store',
'admin.banners.delete-all',
'admin.banners.status',
'admin.banners.update',
'admin.banners.destroy',
'admin.plans.store',
'admin.plans.delete-all',
'admin.plans.status',
'admin.plans.update',
'admin.plans.destroy',
'admin.users.store',
'admin.users.delete-all',
'admin.users.status',
'admin.users.update',
'admin.users.destroy',
'admin.affiliate-withdrawals.delete-all',
'admin.affiliate-withdrawals.status',
'admin.affiliates.store',
'admin.affiliates.delete-all',
'admin.affiliates.filter',
'admin.affiliates.status',
'admin.affiliates.update',
'admin.affiliates.destroy',
'admin.subscription-reports.paid',
'admin.subscription-reports.reject',
'admin.roles.update',
'admin.roles.destroy',
'admin.permissions.index',
'admin.addons.store',
'admin.addons.show',
'admin.manage-settings.store',
'admin.website-settings.update',
'admin.features.delete-all',
'admin.features.status',
'admin.features.update',
'admin.features.destroy',
'admin.blogs.delete-all',
'admin.blogs.status',
'admin.blogs.update',
'admin.blogs.destroy',
'admin.comments.delete-all',
'admin.comments.update',
'admin.comments.destroy',
'admin.testimonials.delete-all',
'admin.testimonials.status',
'admin.testimonials.update',
'admin.testimonials.destroy',
'admin.interfaces.delete-all',
'admin.interfaces.status',
'admin.interfaces.update',
'admin.interfaces.destroy',
'admin.term-conditions.store',
'admin.privacy-policy.store',
'admin.messages.delete-all',
'admin.messages.update',
'admin.messages.destroy',
'admin.currencies.delete-all',
'admin.currencies.update',
'admin.currencies.destroy',
'admin.gateways.update',
'admin.system-settings.store',
'admin.settings.update',
'admin.profiles.update',
];
$businessDisabledRoutes = [
'business.sales.store.customer',
'business.purchases.store.supplier',
'business.products.store',
'business.products.delete-all',
'business.products.update',
'business.products.destroy',
'business.barcodes.store',
'business.categories.store',
'business.categories.delete-all',
'business.categories.update',
'business.categories.destroy',
'business.units.store',
'business.units.delete-all',
'business.units.update',
'business.units.destroy',
'business.brands.store',
'business.brands.delete-all',
'business.brands.update',
'business.brands.destroy',
'business.medicine-types.store',
'business.medicine-types.delete-all',
'business.medicine-types.update',
'business.medicine-types.destroy',
'business.manufacturers.store',
'business.manufacturers.delete-all',
'business.manufacturers.update',
'business.manufacturers.destroy',
'business.product-models.store',
'business.product-models.delete-all',
'business.product-models.update',
'business.product-models.destroy',
'business.box-sizes.store',
'business.box-sizes.delete-all',
'business.box-sizes.update',
'business.box-sizes.destroy',
'business.parties.store',
'business.parties.delete-all',
'business.parties.update',
'business.parties.destroy',
'business.incomes.delete-all',
'business.incomes.update',
'business.incomes.destroy',
'business.expenses.delete-all',
'business.expenses.update',
'business.expenses.destroy',
'business.taxes.store',
'business.taxes.deleteAll',
'business.taxes.status',
'business.taxes.update',
'business.taxes.destroy',
'business.settings.update',
'business.roles.store',
'business.roles.update',
'business.roles.destroy',
'business.roles.delete-all',
'business.payment-types.store',
'business.payment-types.delete-all',
'business.payment-types.status',
'business.payment-types.update',
'business.payment-types.destroy',
'business.vats.store',
'business.vats.deleteAll',
'business.vats.update',
'business.vats.destroy',
'business.bulk-uploads.store',
'business.profiles.update',
'business.manage-settings.store',
'business.manage-settings.update',
'business.manage-settings.destroy',
'business.product.settings.update',
'business.roles.update',
'business.roles.destroy',
'brands.store',
'brands.update',
'brands.destroy',
'box-sizes.store',
'box-sizes.update',
'box-sizes.destroy',
'bulk-uploads.store',
'business.store',
'business.update',
'categories.store',
'categories.update',
'categories.destroy',
'api.change-password',
'dues.store',
'expense-categories.store',
'expense-categories.update',
'expense-categories.destroy',
'expenses.update',
'expenses.destroy',
'income-categories.store',
'income-categories.update',
'income-categories.destroy',
'incomes.update',
'incomes.destroy',
'lang.store',
'manufacturer.store',
'manufacturer.update',
'manufacturer.destroy',
'medicine-types.store',
'medicine-types.update',
'medicine-types.destroy',
'parties.store',
'parties.update',
'parties.destroy',
'password-reset',
'payment-types.store',
'payment-types.update',
'payment-types.destroy',
'products.store',
'products.update',
'products.destroy',
'profile.store',
'send-reset-code',
'stock-update',
'taxes.store',
'taxes.update',
'taxes.destroy',
'units.store',
'units.update',
'units.destroy',
'users.store',
'users.update',
'users.destroy',
'product-settings.store',
'product-models.store',
'product-models.update',
'product-models.destroy',
'vats.store',
'vats.update',
'vats.destroy',
'warehouses.store',
'warehouses.update',
'warehouses.destroy',
'multibranch.branches.store',
'multibranch.branches.update',
'multibranch.branches.status',
'multibranch.branches.destroy',
'multibranch.branches.delete-all'
];
if (in_array(Route::currentRouteName(), $adminDisabledRoutes)) {
return response()->json(['message' => 'This action is disabled in demo mode.'], 499);
} elseif (auth()->check() && auth()->user()->email == 'shopowner@acnoo.com' && in_array(Route::currentRouteName(), $businessDisabledRoutes)) {
return response()->json(['message' => 'This action is disabled in demo account. Please sign up your own account for full access.'], 499);
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

View File

@@ -0,0 +1,158 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\Response;
class ExpiredMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (!plan_data() || !plan_data()->will_expire || plan_data()->will_expire < now()) {
$message = __("You dont have any active plan. Please subscribe to a plan. Without an active plan, you can only view data.");
$disabledRoutes = [
'business.profiles.update',
'business.sales.store',
'business.sales.update',
'business.sales.destroy',
'business.sales.delete-all',
'business.sales.mail',
'business.sales.store.customer',
'business.sales.inventory',
'business.sale-returns.store',
'business.purchases.store',
'business.purchases.update',
'business.purchases.destroy',
'business.purchases.delete-all',
'business.purchases.mail',
'business.purchases.store.supplier',
'business.purchase-returns.store',
'business.products.store',
'business.products.update',
'business.products.destroy',
'business.products.delete-all',
'business.brands.store',
'business.brands.delete-all',
'business.brands.update',
'business.brands.destroy',
'business.payment-types.store',
'business.payment-types.update',
'business.payment-types.destroy',
'business.payment-types.delete-all',
'business.units.store',
'business.units.update',
'business.units.destroy',
'business.units.delete-all',
'business.categories.store',
'business.categories.update',
'business.categories.destroy',
'business.categories.delete-all',
'business.parties.store',
'business.parties.update',
'business.parties.destroy',
'business.parties.delete-all',
'business.income-categories.store',
'business.income-categories.update',
'business.income-categories.destroy',
'business.income-categories.delete-all',
'business.incomes.store',
'business.incomes.update',
'business.incomes.destroy',
'business.incomes.delete-all',
'business.expense-categories.store',
'business.expense-categories.update',
'business.expense-categories.destroy',
'business.expense-categories.delete-all',
'business.expenses.store',
'business.expenses.update',
'business.expenses.destroy',
'business.expenses.delete-all',
'business.collect.dues.store',
'business.collect.dues.mail',
'business.roles.store',
'business.roles.update',
'business.roles.destroy',
'business.settings.update',
'business.subscriptions.store',
'business.subscriptions.update',
'business.subscriptions.destroy',
'business.currencies.default',
'business.vats.store',
'business.vats.update',
'business.vats.destroy',
'business.vats.deleteAll',
'hrm.attendances.store',
'hrm.attendances.store',
'hrm.attendances.create',
'hrm.attendances.delete-all',
'hrm.attendances.update',
'hrm.attendances.destroy',
'hrm.department.store',
'hrm.department.create',
'hrm.department.delete-all',
'hrm.department.update',
'hrm.department.destroy',
'hrm.designations.store',
'hrm.designations.create',
'hrm.designations.delete-all',
'hrm.designations.update',
'hrm.designations.destroy',
'hrm.employees.store',
'hrm.employees.create',
'hrm.employees.delete-all',
'hrm.employees.update',
'hrm.employees.destroy',
'hrm.holidays.store',
'hrm.holidays.create',
'hrm.holidays.delete-all',
'hrm.holidays.update',
'hrm.holidays.destroy',
'hrm.leave-types.store',
'hrm.leave-types.create',
'hrm.leave-types.delete-all',
'hrm.leave-types.update',
'hrm.leave-types.destroy',
'hrm.leaves.store',
'hrm.leaves.create',
'hrm.leaves.delete-all',
'hrm.leaves.update',
'hrm.leaves.destroy',
'hrm.payrolls.store',
'hrm.payrolls.create',
'hrm.payrolls.delete-all',
'hrm.payrolls.update',
'hrm.payrolls.destroy',
'hrm.shifts.store',
'hrm.shifts.create',
'hrm.shifts.delete-all',
'hrm.shifts.update',
'hrm.shifts.destroy',
];
if ($request->isMethod('delete')) {
return response()->json([
'message' => $message,
], 406);
}
if (in_array(Route::currentRouteName(), $disabledRoutes)) {
return $request->wantsJson()
? response()->json([
'message' => $message,
], 406)
: redirect(route('business.subscriptions.index'))->with('error', $message);
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Nwidart\Modules\Facades\Module;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
$user = auth()->user();
if ($user->role == 'shop-owner' || $user->role == 'staff') {
$module = Module::find('Business');
if ($module) {
if ($module->isEnabled()) {
return redirect(route('business.dashboard.index'))->with('warning', 'You are already logged in!');
} else {
Auth::logout();
return redirect(route('login'))->with('warning', 'Web addon is not active.');
}
} else {
Auth::logout();
return redirect(route('login'))->with('warning', 'Web addon is not installed.');
}
} else if ($user->role == 'affiliator') {
$module = Module::find('AffiliateAddon');
if ($module) {
if ($module->isEnabled()) {
return redirect(route('affiliate.dashboard.index'))->with('warning', 'You are already logged in!');
} else {
Auth::logout();
return redirect(route('login'))->with('warning', 'Affiliate addon is not active.');
}
} else {
Auth::logout();
return redirect(route('login'))->with('warning', 'Affiliate addon is not installed.');
}
} else {
return redirect(route('admin.dashboard.index'))->with('warning', 'You are already logged in!');
}
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
{
public function handle(Request $request, Closure $next): Response
{
// Redirect to install if not installed
if (($request->is('/') || $request->is('login')) && !file_exists(storage_path('installed'))) {
return redirect('install');
}
// If DB connection fails → skip locale logic
try {
DB::connection()->getPdo();
} catch (\Throwable $e) {
app()->setLocale('en');
return $next($request);
}
// If options table does NOT exist → fallback
if (!Schema::hasTable('options')) {
app()->setLocale('en');
return $next($request);
}
// ---------- Locale Logic ----------
if (auth()->check()) {
if ($request->has('lang')) {
auth()->user()->update(['lang' => $request->lang]);
}
$lang = auth()->user()->lang
?? get_option('general')['default_lang']
?? 'en';
} elseif ($request->has('lang') || session()->has('lang')) {
if ($request->has('lang')) {
session(['lang' => $request->lang]);
}
$lang = session('lang')
?? get_option('general')['default_lang']
?? 'en';
} else {
$lang = get_option('general')['default_lang'] ?? 'en';
}
app()->setLocale($lang);
return $next($request);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class TokenExpired
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->user()->tokens ?? false) {
$token = auth()->user()->tokens->last();
if ($token && $token->expires_at <= now()) {
$token->delete();
return response()->json('Token has expired.', 401);
}
} else {
return response()->json('Token not available.', 401);
}
return $next($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
/**
* Get the host patterns that should be trusted.
*
* @return array<int, string|null>
*/
public function hosts(): array
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array<int, string>|string|null
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class UserMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->check() && (auth()->user()->role == 'shop-owner' || auth()->user()->role == 'staff')) {
return $next($request);
}
return redirect('/login');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
class ValidateSignature extends Middleware
{
/**
* The names of the query string parameters that should be ignored.
*
* @var array<int, string>
*/
protected $except = [
// 'fbclid',
// 'utm_campaign',
// 'utm_content',
// 'utm_medium',
// 'utm_source',
// 'utm_term',
];
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
'/ssl-commerz/payment/success',
'/ssl-commerz/payment/failed',
'/paytm/status',
'/cinetpay/status',
];
}