Skip to content

Commit

Permalink
refactor: migrate settings page back-end code to controllers (#2596)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Aug 17, 2024
1 parent 21495c0 commit 9d67b54
Show file tree
Hide file tree
Showing 53 changed files with 1,402 additions and 512 deletions.
3 changes: 1 addition & 2 deletions app/Actions/ClearAccountDataAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ public function execute(User $user): void
);

// TODO $user->activities()->delete();
// TODO $user->emailConfirmations()->delete();
DB::statement('DELETE FROM EmailConfirmations WHERE User = :username', ['username' => $user->User]);
$user->emailConfirmations()->delete();
$user->relatedUsers()->detach();
$user->inverseRelatedUsers()->detach();
// TODO $user->ratings()->delete();
Expand Down
14 changes: 14 additions & 0 deletions app/Community/Concerns/ActsAsCommunityMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Community\Concerns;

use App\Community\Enums\UserRelationship;
use App\Models\EmailConfirmation;
use App\Models\ForumTopicComment;
use App\Models\MessageThreadParticipant;
use App\Models\Subscription;
Expand Down Expand Up @@ -103,6 +104,11 @@ public function isFriendsWith(User $user): bool
return $this->isFollowing($user) && $user->isFollowing($this);
}

public function isEmailVerified(): bool
{
return !empty($this->email_verified_at);
}

public function isForumVerified(): bool
{
return !empty($this->forum_verified_at);
Expand Down Expand Up @@ -161,6 +167,14 @@ public function comments(): MorphMany
return $this->morphMany(UserComment::class, 'commentable')->with('user');
}

/**
* @return HasMany<EmailConfirmation>
*/
public function emailConfirmations(): HasMany
{
return $this->hasMany(EmailConfirmation::class, 'user_id', 'ID');
}

/**
* @return HasMany<MessageThreadParticipant>
*/
Expand Down
14 changes: 10 additions & 4 deletions app/Community/Controllers/UserCommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@

use App\Community\Actions\AddCommentAction;
use App\Community\Actions\GetUrlToCommentDestinationAction;
use App\Community\Enums\ArticleType;
use App\Community\Requests\CommentRequest;
use App\Models\Comment;
use App\Models\User;
use App\Models\UserComment;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserCommentController extends CommentController
{
Expand Down Expand Up @@ -95,12 +98,15 @@ protected function destroy(UserComment $comment): RedirectResponse
->with('success', $this->resourceActionSuccessMessage('user.comment', 'delete'));
}

public function destroyAll(User $user): RedirectResponse
public function destroyAll(Request $request, int $targetUserId): JsonResponse
{
$this->authorize('deleteComments', $user);
$targetUser = User::findOrFail($targetUserId);
$this->authorize('clearUserWall', $targetUser);

$user->comments()->delete();
Comment::where('ArticleType', ArticleType::User)
->where('ArticleID', $targetUser->id)
->delete();

return back()->with('success', $this->resourceActionSuccessMessage('user.comment', 'delete'));
return response()->json(['success' => true]);
}
}
121 changes: 121 additions & 0 deletions app/Community/Controllers/UserSettingsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

declare(strict_types=1);

namespace App\Community\Controllers;

use App\Community\Data\UpdateEmailData;
use App\Community\Data\UpdatePasswordData;
use App\Community\Data\UpdateProfileData;
use App\Community\Data\UpdateWebsitePrefsData;
use App\Community\Enums\ArticleType;
use App\Community\Requests\ResetConnectApiKeyRequest;
use App\Community\Requests\ResetWebApiKeyRequest;
use App\Community\Requests\UpdateEmailRequest;
use App\Community\Requests\UpdatePasswordRequest;
use App\Community\Requests\UpdateProfileRequest;
use App\Community\Requests\UpdateWebsitePrefsRequest;
use App\Enums\Permissions;
use App\Http\Controller;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class UserSettingsController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(Request $request, string $section = 'profile'): View
{
$this->authorize('updateSettings', $section);

if (!view()->exists("settings.$section")) {
abort(404, 'Not found');
}

return view("settings.$section");
}

public function updatePassword(UpdatePasswordRequest $request): JsonResponse
{
$data = UpdatePasswordData::fromRequest($request);

/** @var User $user */
$user = $request->user();

changePassword($user->username, $data->newPassword);
generateAppToken($user->username, $tokenInOut);

return response()->json(['success' => true]);
}

public function updateEmail(UpdateEmailRequest $request): JsonResponse
{
$data = UpdateEmailData::fromRequest($request);

/** @var User $user */
$user = $request->user();

// The user will need to reconfirm their email address.
$user->EmailAddress = $data->newEmail;
$user->setAttribute('Permissions', Permissions::Unregistered);
$user->email_verified_at = null;
$user->save();

// TODO move this to an action, use Fortify, do something else.
// sendValidationEmail cannot be invoked while under test.
if (app()->environment() !== 'testing') {
sendValidationEmail($user, $data->newEmail);
}

addArticleComment(
'Server',
ArticleType::UserModeration,
$user->id,
"{$user->username} changed their email address"
);

return response()->json(['success' => true]);
}

public function updateProfile(UpdateProfileRequest $request): JsonResponse
{
$data = UpdateProfileData::fromRequest($request);

/** @var User $user */
$user = $request->user();

$user->update($data->toArray());

return response()->json(['success' => true]);
}

// TODO migrate to $user->preferences blob
public function updatePreferences(UpdateWebsitePrefsRequest $request): JsonResponse
{
$data = UpdateWebsitePrefsData::fromRequest($request);

/** @var User $user */
$user = $request->user();

$user->update($data->toArray());

return response()->json(['success' => true]);
}

public function resetWebApiKey(ResetWebApiKeyRequest $request): JsonResponse
{
$newKey = generateAPIKey($request->user()->username);

return response()->json(['newKey' => $newKey]);
}

public function resetConnectApiKey(ResetConnectApiKeyRequest $request): JsonResponse
{
generateAppToken($request->user()->username, $newToken);

return response()->json(['success' => true]);
}
}
23 changes: 23 additions & 0 deletions app/Community/Data/UpdateEmailData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Community\Requests\UpdateEmailRequest;
use Spatie\LaravelData\Data;

class UpdateEmailData extends Data
{
public function __construct(
public string $newEmail,
) {
}

public static function fromRequest(UpdateEmailRequest $request): self
{
return new self(
newEmail: $request->newEmail,
);
}
}
23 changes: 23 additions & 0 deletions app/Community/Data/UpdatePasswordData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Community\Requests\UpdatePasswordRequest;
use Spatie\LaravelData\Data;

class UpdatePasswordData extends Data
{
public function __construct(
public string $newPassword,
) {
}

public static function fromRequest(UpdatePasswordRequest $request): self
{
return new self(
newPassword: $request->newPassword,
);
}
}
37 changes: 37 additions & 0 deletions app/Community/Data/UpdateProfileData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Community\Requests\UpdateProfileRequest;
use App\Models\User;
use Spatie\LaravelData\Data;

class UpdateProfileData extends Data
{
public function __construct(
public string $motto,
public bool $userWallActive,
) {
}

public static function fromRequest(UpdateProfileRequest $request): self
{
/** @var User $user */
$user = $request->user();

return new self(
motto: $request->motto ?? $user->Motto,
userWallActive: $request->userWallActive ?? $user->UserWallActive,
);
}

public function toArray(): array
{
return [
'Motto' => $this->motto,
'UserWallActive' => $this->userWallActive,
];
}
}
30 changes: 30 additions & 0 deletions app/Community/Data/UpdateWebsitePrefsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Community\Requests\UpdateWebsitePrefsRequest;
use Spatie\LaravelData\Data;

class UpdateWebsitePrefsData extends Data
{
public function __construct(
public int $websitePrefs,
) {
}

public static function fromRequest(UpdateWebsitePrefsRequest $request): self
{
return new self(
websitePrefs: $request->websitePrefs,
);
}

public function toArray(): array
{
return [
'websitePrefs' => $this->websitePrefs,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Http\Requests;
namespace App\Community\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
Expand Down
24 changes: 24 additions & 0 deletions app/Community/Requests/ResetConnectApiKeyRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Community\Requests;

use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;

class ResetConnectApiKeyRequest extends FormRequest
{
public function authorize(): bool
{
/** @var User $user */
$user = $this->user();

return $user->can('manipulateApiKeys', $user);
}

public function rules(): array
{
return [];
}
}
24 changes: 24 additions & 0 deletions app/Community/Requests/ResetWebApiKeyRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Community\Requests;

use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;

class ResetWebApiKeyRequest extends FormRequest
{
public function authorize(): bool
{
/** @var User $user */
$user = $this->user();

return $user->can('manipulateApiKeys', $user);
}

public function rules(): array
{
return [];
}
}
Loading

0 comments on commit 9d67b54

Please sign in to comment.