mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-06-15 13:32:43 +01:00
175 lines
5.5 KiB
PHP
175 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Exceptions\Api\CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers;
|
|
use App\Exceptions\Api\UserResendEmailVerificationNoPendingEmailApiException;
|
|
use App\Http\Requests\V1\User\UserUpdateRequest;
|
|
use App\Http\Resources\V1\User\UserResource;
|
|
use App\Mail\VerifyUpdatedEmailMail;
|
|
use App\Models\User;
|
|
use App\Service\DeletionService;
|
|
use App\Support\Base64File;
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
/**
|
|
* Get the current user
|
|
*
|
|
* This endpoint is independent of the organization.
|
|
*
|
|
* @operationId getMe
|
|
*
|
|
* @throws AuthorizationException
|
|
*/
|
|
public function me(): UserResource
|
|
{
|
|
$user = $this->user();
|
|
|
|
return new UserResource($user);
|
|
}
|
|
|
|
/**
|
|
* Update the current user
|
|
*
|
|
* This endpoint is independent of the organization.
|
|
*
|
|
* @operationId updateUser
|
|
*/
|
|
public function update(User $user, UserUpdateRequest $request): UserResource
|
|
{
|
|
if ($user->getKey() !== $this->user()->getKey()) {
|
|
throw new AuthorizationException;
|
|
}
|
|
|
|
if ($request->hasPhotoKey()) {
|
|
$photoDisk = (string) config('jetstream.profile_photo_disk', 'public');
|
|
$previousPhotoPath = $user->profile_photo_path;
|
|
$newPhoto = $request->getPhoto();
|
|
|
|
if ($newPhoto === null) {
|
|
$user->profile_photo_path = null;
|
|
} else {
|
|
$decoded = Base64File::decode($newPhoto);
|
|
assert($decoded !== null);
|
|
$extension = Base64File::extension($decoded['mime_type']);
|
|
assert($extension !== null);
|
|
|
|
$photoPath = 'profile-photos/'.Str::uuid().'.'.$extension;
|
|
Storage::disk($photoDisk)->put($photoPath, $decoded['data'], 'public');
|
|
$user->profile_photo_path = $photoPath;
|
|
}
|
|
|
|
if ($previousPhotoPath !== null) {
|
|
Storage::disk($photoDisk)->delete($previousPhotoPath);
|
|
}
|
|
}
|
|
|
|
$emailToVerify = null;
|
|
$email = $request->getEmail();
|
|
if ($email !== null && $email !== Str::lower($user->email)) {
|
|
$emailToVerify = $email;
|
|
$user->pending_email = $email;
|
|
}
|
|
|
|
if ($request->getName() !== null) {
|
|
$user->name = $request->getName();
|
|
}
|
|
|
|
if ($request->getTimezone() !== null) {
|
|
$user->timezone = $request->getTimezone();
|
|
}
|
|
|
|
if ($request->getWeekStart() !== null) {
|
|
$user->week_start = $request->getWeekStart();
|
|
}
|
|
|
|
$user->save();
|
|
|
|
if ($emailToVerify !== null) {
|
|
Mail::to($emailToVerify)->send(new VerifyUpdatedEmailMail($user, $emailToVerify));
|
|
}
|
|
|
|
return new UserResource($user);
|
|
}
|
|
|
|
/**
|
|
* Reset the pending email for a user.
|
|
*
|
|
* This endpoint is independent of the organization.
|
|
*
|
|
* @operationId resetUserPendingEmail
|
|
*
|
|
* @throws AuthorizationException Thrown when the authenticated user does not match the user whose email is pending verification.
|
|
*/
|
|
public function resetPendingEmail(User $user): JsonResponse
|
|
{
|
|
if ($user->getKey() !== $this->user()->getKey()) {
|
|
throw new AuthorizationException;
|
|
}
|
|
|
|
$user->pending_email = null;
|
|
$user->save();
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
/**
|
|
* Resend the pending email update verification email.
|
|
*
|
|
* This endpoint is independent of the organization.
|
|
*
|
|
* @operationId resendUserEmailVerification
|
|
*
|
|
* @throws AuthorizationException Thrown when the authenticated user does not match the user whose email is pending verification.
|
|
* @throws UserResendEmailVerificationNoPendingEmailApiException Thrown when the user does not have a pending email to verify.
|
|
*/
|
|
public function resendEmailVerification(User $user): JsonResponse
|
|
{
|
|
if ($user->getKey() !== $this->user()->getKey()) {
|
|
throw new AuthorizationException;
|
|
}
|
|
|
|
if ($user->pending_email === null) {
|
|
throw new UserResendEmailVerificationNoPendingEmailApiException;
|
|
}
|
|
|
|
Mail::to($user->pending_email)
|
|
->queue(new VerifyUpdatedEmailMail($user, $user->pending_email));
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
/**
|
|
* Handles the deletion of a user.
|
|
*
|
|
* This endpoint is independent of the organization.
|
|
*
|
|
* @operationId deleteUser
|
|
*
|
|
* @param User $user The user instance to be deleted.
|
|
* @param DeletionService $deletionService The service responsible for performing the user deletion.
|
|
* @return JsonResponse A JSON response with a 204 No Content status upon successful deletion.
|
|
*
|
|
* @throws AuthorizationException Thrown when the authenticated user does not match the user to be deleted.
|
|
* @throws CanNotDeleteUserWhoIsOwnerOfOrganizationWithMultipleMembers Thrown when the user to be deleted is the owner of an organization with multiple members.
|
|
*/
|
|
public function destroy(User $user, DeletionService $deletionService): JsonResponse
|
|
{
|
|
if ($user->getKey() !== $this->user()->getKey()) {
|
|
throw new AuthorizationException;
|
|
}
|
|
|
|
$deletionService->deleteUser($user);
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
}
|