mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
Removed Laravel Jetstream
This commit is contained in:
committed by
Constantin Graf
parent
bffd0773be
commit
89a9341d91
@@ -63,7 +63,7 @@ class InvitationController extends Controller
|
||||
$email = $request->getEmail();
|
||||
$role = $request->getRole();
|
||||
|
||||
$invitationService->inviteUser($organization, $email, $role);
|
||||
$invitationService->inviteUser($organization, $email, $role, $this->user());
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ class MemberController extends Controller
|
||||
throw new ThisPlaceholderCanNotBeInvitedUseTheMergeToolInsteadException;
|
||||
}
|
||||
|
||||
$invitationService->inviteUser($organization, $user->email, Role::Employee);
|
||||
$invitationService->inviteUser($organization, $user->email, Role::Employee, $this->user());
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
||||
33
app/Http/Controllers/Api/V1/TimeZoneController.php
Normal file
33
app/Http/Controllers/Api/V1/TimeZoneController.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Service\TimezoneService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class TimeZoneController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get all timezones
|
||||
*
|
||||
* @response object{key: string}[]
|
||||
*
|
||||
* @operationId getTimezones
|
||||
*/
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$timezones = app(TimezoneService::class)->getTimezones();
|
||||
|
||||
$response = [];
|
||||
|
||||
foreach ($timezones as $timezone) {
|
||||
$response[] = (object) [
|
||||
'key' => $timezone,
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class UserController extends Controller
|
||||
}
|
||||
|
||||
if ($request->hasPhotoKey()) {
|
||||
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
||||
$photoDisk = (string) config('filesystems.public');
|
||||
$previousPhotoPath = $user->profile_photo_path;
|
||||
$newPhoto = $request->getPhoto();
|
||||
|
||||
|
||||
@@ -4,4 +4,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
abstract class Controller extends \App\Http\Controllers\Controller {}
|
||||
use App\Models\Organization;
|
||||
use App\Service\PermissionStore;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
abstract class Controller extends \App\Http\Controllers\Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected PermissionStore $permissionStore,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws AuthorizationException
|
||||
*/
|
||||
protected function hasPermission(Organization $organization, string $permission): bool
|
||||
{
|
||||
return $this->permissionStore->has($organization, $permission);
|
||||
}
|
||||
}
|
||||
|
||||
69
app/Http/Controllers/Web/OrganizationController.php
Normal file
69
app/Http/Controllers/Web/OrganizationController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Models\Organization;
|
||||
use Brick\Money\Currency;
|
||||
use Brick\Money\ISOCurrencyProvider;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class OrganizationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the team creation screen.
|
||||
*/
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
return Inertia::render('Teams/Create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the organizatio details screen.
|
||||
*
|
||||
* @param string $organizationId The organization ID
|
||||
*/
|
||||
public function show(string $organizationId): Response|RedirectResponse
|
||||
{
|
||||
$organization = Str::isUuid($organizationId) ? Organization::find($organizationId) : null;
|
||||
if ($organization === null) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
if (! $this->hasPermission($organization, 'organizations:view')) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
|
||||
$owner = $organization->owner;
|
||||
|
||||
return Inertia::render('Teams/Show', [
|
||||
'team' => [
|
||||
'id' => $organization->getKey(),
|
||||
'name' => $organization->name,
|
||||
'currency' => $organization->currency,
|
||||
'owner' => [
|
||||
'id' => $owner->getKey(),
|
||||
'name' => $owner->name,
|
||||
'profile_photo_url' => $owner->profile_photo_url,
|
||||
],
|
||||
],
|
||||
'currencies' => array_map(function (Currency $currency): string {
|
||||
return $currency->getName();
|
||||
}, ISOCurrencyProvider::getInstance()->getAvailableCurrencies()),
|
||||
'availableRoles' => [],
|
||||
'availablePermissions' => [],
|
||||
'defaultPermissions' => [],
|
||||
'permissions' => [
|
||||
'canAddTeamMembers' => true,
|
||||
'canDeleteTeam' => true,
|
||||
'canRemoveTeamMembers' => true,
|
||||
'canUpdateTeam' => true,
|
||||
'canUpdateTeamMembers' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
142
app/Http/Controllers/Web/UserProfileController.php
Normal file
142
app/Http/Controllers/Web/UserProfileController.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Enums\Weekday;
|
||||
use App\Service\Dto\UserAgentDto;
|
||||
use App\Service\TimezoneService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
use Laravel\Fortify\Actions\DisableTwoFactorAuthentication;
|
||||
use Laravel\Fortify\Features;
|
||||
|
||||
class UserProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Validate the two-factor authentication state for the request.
|
||||
*/
|
||||
protected function validateTwoFactorAuthenticationState(Request $request): void
|
||||
{
|
||||
if (! Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currentTime = time();
|
||||
|
||||
// Notate totally disabled state in session...
|
||||
if ($this->twoFactorAuthenticationDisabled($request)) {
|
||||
$request->session()->put('two_factor_empty_at', $currentTime);
|
||||
}
|
||||
|
||||
// If was previously totally disabled this session but is now confirming, notate time...
|
||||
if ($this->hasJustBegunConfirmingTwoFactorAuthentication($request)) {
|
||||
$request->session()->put('two_factor_confirming_at', $currentTime);
|
||||
}
|
||||
|
||||
// If the profile is reloaded and is not confirmed but was previously in confirming state, disable...
|
||||
if ($this->neverFinishedConfirmingTwoFactorAuthentication($request, $currentTime)) {
|
||||
app(DisableTwoFactorAuthentication::class)(Auth::user());
|
||||
|
||||
$request->session()->put('two_factor_empty_at', $currentTime);
|
||||
$request->session()->remove('two_factor_confirming_at');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if two-factor authentication is totally disabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function twoFactorAuthenticationDisabled(Request $request)
|
||||
{
|
||||
return is_null($request->user()->two_factor_secret) &&
|
||||
is_null($request->user()->two_factor_confirmed_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if two-factor authentication is just now being confirmed within the last request cycle.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasJustBegunConfirmingTwoFactorAuthentication(Request $request)
|
||||
{
|
||||
return ! is_null($request->user()->two_factor_secret) &&
|
||||
is_null($request->user()->two_factor_confirmed_at) &&
|
||||
$request->session()->has('two_factor_empty_at') &&
|
||||
is_null($request->session()->get('two_factor_confirming_at'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if two-factor authentication was never totally confirmed once confirmation started.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function neverFinishedConfirmingTwoFactorAuthentication(Request $request, int $currentTime)
|
||||
{
|
||||
return ! array_key_exists('code', $request->session()->getOldInput()) &&
|
||||
is_null($request->user()->two_factor_confirmed_at) &&
|
||||
$request->session()->get('two_factor_confirming_at', 0) !== $currentTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the general profile settings screen.
|
||||
*/
|
||||
public function show(Request $request): Response
|
||||
{
|
||||
$this->validateTwoFactorAuthenticationState($request);
|
||||
|
||||
return Inertia::render('Profile/Show', [
|
||||
'timezones' => app(TimezoneService::class)->getSelectOptions(),
|
||||
'weekdays' => Weekday::toSelectArray(),
|
||||
'confirmsTwoFactorAuthentication' => Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm'),
|
||||
'sessions' => $this->sessions($request),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current sessions.
|
||||
*
|
||||
* @return array<int, object{agent: array{is_desktop: bool, platform: string|null, browser: string|null}, ip_address: string, is_current_device: bool, last_active: string}&\stdClass>
|
||||
*/
|
||||
public function sessions(Request $request): array
|
||||
{
|
||||
if (config('session.driver') !== 'database') {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect(
|
||||
DB::connection(config('session.connection'))->table(config('session.table', 'sessions'))
|
||||
->where('user_id', $request->user()->getAuthIdentifier())
|
||||
->orderBy('last_activity', 'desc')
|
||||
->get()
|
||||
)->map(function (object $session) use ($request): object {
|
||||
$agent = $this->createAgent(is_string($session->user_agent) ? $session->user_agent : '');
|
||||
|
||||
return (object) [
|
||||
'agent' => [
|
||||
'is_desktop' => $agent->isDesktop(),
|
||||
'platform' => $agent->platform(),
|
||||
'browser' => $agent->browser(),
|
||||
],
|
||||
'ip_address' => is_string($session->ip_address) ? $session->ip_address : '',
|
||||
'is_current_device' => $session->id === $request->session()->getId(),
|
||||
'last_active' => Carbon::createFromTimestamp($session->last_activity)->diffForHumans(),
|
||||
];
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new agent instance from the given session.
|
||||
*/
|
||||
protected function createAgent(string $userAgent): UserAgentDto
|
||||
{
|
||||
return tap(new UserAgentDto, fn ($agent) => $agent->setUserAgent($userAgent));
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class ShareInertiaData
|
||||
$permissions = app(PermissionStore::class);
|
||||
Inertia::share([
|
||||
'auth' => [
|
||||
'permissions' => $request->user() !== null && $request->user()->currentTeam !== null ? $permissions->getPermissions($request->user()->currentTeam) : [],
|
||||
'permissions' => $request->user() !== null && $request->user()->currentOrganization !== null ? $permissions->getPermissions($request->user()->currentOrganization) : [],
|
||||
'user' => function () use ($request): array {
|
||||
/** @var User|null $user */
|
||||
$user = $request->user();
|
||||
@@ -35,6 +35,8 @@ class ShareInertiaData
|
||||
return [];
|
||||
}
|
||||
|
||||
$currentOrganization = $user->currentOrganization;
|
||||
|
||||
return array_merge([
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
@@ -47,12 +49,12 @@ class ShareInertiaData
|
||||
'profile_photo_url' => $user->profile_photo_url,
|
||||
'two_factor_enabled' => Features::enabled(Features::twoFactorAuthentication())
|
||||
&& ! is_null($user->two_factor_secret),
|
||||
'current_team' => $user->currentTeam !== null ? [
|
||||
'id' => $user->currentTeam->id,
|
||||
'user_id' => $user->currentTeam->user_id,
|
||||
'name' => $user->currentTeam->name,
|
||||
'personal_team' => $user->currentTeam->personal_team,
|
||||
'currency' => $user->currentTeam->currency,
|
||||
'current_team' => $currentOrganization !== null ? [
|
||||
'id' => $currentOrganization->id,
|
||||
'user_id' => $currentOrganization->user_id,
|
||||
'name' => $currentOrganization->name,
|
||||
'personal_team' => $currentOrganization->personal_team,
|
||||
'currency' => $currentOrganization->currency,
|
||||
] : null,
|
||||
], array_filter([
|
||||
'all_teams' => $user->organizations->map(function (Organization $organization): array {
|
||||
|
||||
Reference in New Issue
Block a user