first commit
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
brusnitsyn
2026-04-06 00:06:00 +09:00
commit fb2e6c58e3
409 changed files with 42953 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
<?php
namespace App\Http\Middleware;
use App\Enums\TeamRole;
use App\Models\Team;
use App\Models\User;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTeamMembership
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next, ?string $minimumRole = null): Response
{
[$user, $team] = [$request->user(), $this->team($request)];
abort_if(! $user || ! $team || ! $user->belongsToTeam($team), 403);
$this->ensureTeamMemberHasRequiredRole($user, $team, $minimumRole);
if ($request->route('current_team') && ! $user->isCurrentTeam($team)) {
$user->switchTeam($team);
}
return $next($request);
}
/**
* Ensure the given user has at least the given role, if applicable.
*/
protected function ensureTeamMemberHasRequiredRole(User $user, Team $team, ?string $minimumRole): void
{
if ($minimumRole === null) {
return;
}
$role = $user->teamRole($team);
$requiredRole = TeamRole::tryFrom($minimumRole);
abort_if(
$requiredRole === null ||
$role === null ||
! $role->isAtLeast($requiredRole),
403,
);
}
/**
* Get the team associated with the request.
*/
protected function team(Request $request): ?Team
{
$team = $request->route('current_team') ?? $request->route('team');
if (is_string($team)) {
$team = Team::where('slug', $team)->first();
}
return $team;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpFoundation\Response;
class HandleAppearance
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
View::share('appearance', $request->cookie('appearance') ?? 'system');
return $next($request);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
{
/**
* The root template that's loaded on the first page visit.
*
* @see https://inertiajs.com/server-side-setup#root-template
*
* @var string
*/
protected $rootView = 'app';
/**
* Determines the current asset version.
*
* @see https://inertiajs.com/asset-versioning
*/
public function version(Request $request): ?string
{
return parent::version($request);
}
/**
* Define the props that are shared by default.
*
* @see https://inertiajs.com/shared-data
*
* @return array<string, mixed>
*/
public function share(Request $request): array
{
$user = $request->user();
return [
...parent::share($request),
'name' => config('app.name'),
'auth' => [
'user' => $user,
],
'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
'currentTeam' => fn () => $user?->currentTeam ? $user->toUserTeam($user->currentTeam) : null,
'teams' => fn () => $user?->toUserTeams(includeCurrent: true) ?? [],
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;
class SetTeamUrlDefaults
{
/**
* Set the default URL parameters for team-based routes.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($currentTeam = $request->user()?->currentTeam) {
URL::defaults([
'current_team' => $currentTeam->slug,
'team' => $currentTeam->slug,
]);
}
return $next($request);
}
}