From cf0f1fb1f88d4c10f9e39f0b69f97ff9a651a86b Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 3 Nov 2024 10:40:41 +0000 Subject: [PATCH] fix: unable to cancel erasure request after confirmation --- extend.php | 5 ++ ...rasureModal.js => RequestErasureModal.tsx} | 50 +++++++++++++------ ..._table_set_verification_token_nullable.php | 18 +++++++ .../DeleteErasureRequestController.php | 1 + .../Controller/ConfirmErasureController.php | 1 + tests/integration/api/CancelErasureTest.php | 3 ++ 6 files changed, 62 insertions(+), 16 deletions(-) rename js/src/forum/components/{RequestErasureModal.js => RequestErasureModal.tsx} (76%) create mode 100644 migrations/2024_11_03_000002_modify_erasure_table_set_verification_token_nullable.php diff --git a/extend.php b/extend.php index 2de4476..a79567e 100644 --- a/extend.php +++ b/extend.php @@ -11,8 +11,10 @@ namespace Flarum\Gdpr; +use Flarum\Api\Controller\ShowForumController; use Flarum\Api\Controller\ShowUserController; use Flarum\Api\Serializer\BasicUserSerializer; +use Flarum\Api\Serializer\CurrentUserSerializer; use Flarum\Api\Serializer\ForumSerializer; use Flarum\Api\Serializer\UserSerializer; use Flarum\Extend; @@ -60,6 +62,9 @@ (new Extend\ApiController(ShowUserController::class)) ->addInclude('erasureRequest'), + (new Extend\ApiController(ShowForumController::class)) + ->addInclude('actor.erasureRequest'), + (new Extend\ApiSerializer(ForumSerializer::class)) ->attributes(AddForumAttributes::class), diff --git a/js/src/forum/components/RequestErasureModal.js b/js/src/forum/components/RequestErasureModal.tsx similarity index 76% rename from js/src/forum/components/RequestErasureModal.js rename to js/src/forum/components/RequestErasureModal.tsx index 496c782..112c787 100644 --- a/js/src/forum/components/RequestErasureModal.js +++ b/js/src/forum/components/RequestErasureModal.tsx @@ -4,13 +4,22 @@ import Button from 'flarum/common/components/Button'; import extractText from 'flarum/common/utils/extractText'; import ItemList from 'flarum/common/utils/ItemList'; import Stream from 'flarum/common/utils/Stream'; +import Mithril from 'mithril'; +import type User from 'flarum/common/models/User'; +import type ErasureRequest from '../../common/models/ErasureRequest'; export default class RequestErasureModal extends Modal { - oninit(vnode) { + reason: Stream; + password: Stream; + user!: User | null; + + oninit(vnode: Mithril.Vnode) { super.oninit(vnode); this.reason = Stream(''); this.password = Stream(''); + + this.user = app.session.user; } className() { @@ -30,11 +39,11 @@ export default class RequestErasureModal extends Modal { } fields() { - const items = new ItemList(); + const items = new ItemList(); - const currRequest = app.session.user.erasureRequest(); + const currRequest = this.user?.erasureRequest() as ErasureRequest | null; - if (currRequest) { + if (currRequest && currRequest.status() !== 'cancelled') { items.add( 'status',
@@ -87,7 +96,12 @@ export default class RequestErasureModal extends Modal {
@@ -111,17 +125,19 @@ export default class RequestErasureModal extends Modal { return items; } - oncancel(e) { + oncancel(e: Event) { this.loading = true; m.redraw(); - app.session.user - .erasureRequest() - .delete() - .then(() => { - this.loading = false; - m.redraw(); - }); + if (this.user) { + this.user + .erasureRequest() + .delete() + .then(() => { + this.loading = false; + m.redraw(); + }); + } } data() { @@ -133,16 +149,18 @@ export default class RequestErasureModal extends Modal { }; } - onsubmit(e) { + onsubmit(e: Event) { e.preventDefault(); this.loading = true; app.store - .createRecord('user-erasure-requests') + .createRecord('user-erasure-requests') .save(this.data(), { meta: { password: this.password() } }) .then((erasureRequest) => { - app.session.user.pushData({ relationships: { erasureRequest } }); + if (this.user) { + this.user.pushData({ relationships: { erasureRequest } }); + } this.loading = false; m.redraw(); }) diff --git a/migrations/2024_11_03_000002_modify_erasure_table_set_verification_token_nullable.php b/migrations/2024_11_03_000002_modify_erasure_table_set_verification_token_nullable.php new file mode 100644 index 0000000..c3ef181 --- /dev/null +++ b/migrations/2024_11_03_000002_modify_erasure_table_set_verification_token_nullable.php @@ -0,0 +1,18 @@ + function (Builder $schema) { + $schema->table('gdpr_erasure', function (Blueprint $table) { + $table->string('verification_token')->nullable()->change(); + }); + }, + 'down' => function (Builder $schema) { + $schema->table('gdpr_erasure', function (Blueprint $table) { + $table->string('verification_token')->nullable(false)->change(); + }); + }, +]; diff --git a/src/Api/Controller/DeleteErasureRequestController.php b/src/Api/Controller/DeleteErasureRequestController.php index 6a5a7ff..2bc96ac 100644 --- a/src/Api/Controller/DeleteErasureRequestController.php +++ b/src/Api/Controller/DeleteErasureRequestController.php @@ -43,6 +43,7 @@ public function delete(ServerRequestInterface $request) $erasureRequest->status = ErasureRequest::STATUS_CANCELLED; $erasureRequest->cancelled_at = Carbon::now(); + $erasureRequest->verification_token = null; $erasureRequest->save(); diff --git a/src/Http/Controller/ConfirmErasureController.php b/src/Http/Controller/ConfirmErasureController.php index aa0f329..9a08d95 100644 --- a/src/Http/Controller/ConfirmErasureController.php +++ b/src/Http/Controller/ConfirmErasureController.php @@ -46,6 +46,7 @@ public function handle(Request $request): ResponseInterface $erasureRequest->user_confirmed_at = Carbon::now(); $erasureRequest->status = ErasureRequest::STATUS_USER_CONFIRMED; + $erasureRequest->cancelled_at = null; $erasureRequest->save(); return new RedirectResponse($this->url->to('forum')->base().'?erasureRequestConfirmed=1'); diff --git a/tests/integration/api/CancelErasureTest.php b/tests/integration/api/CancelErasureTest.php index 1ed1cbe..c88c633 100644 --- a/tests/integration/api/CancelErasureTest.php +++ b/tests/integration/api/CancelErasureTest.php @@ -97,6 +97,7 @@ public function user_can_cancel_own_unconfirmed_erasure_request() $erasureRequest = ErasureRequest::query()->find(1); $this->assertEquals(ErasureRequest::STATUS_CANCELLED, $erasureRequest->status); + $this->assertNull($erasureRequest->verification_token); $notification = Notification::query()->where('user_id', 4)->where('type', 'gdpr_erasure_cancelled')->first(); @@ -119,6 +120,7 @@ public function user_can_cancel_own_confirmed_erasure_request() $erasureRequest = ErasureRequest::query()->find(2); $this->assertEquals(ErasureRequest::STATUS_CANCELLED, $erasureRequest->status); + $this->assertNull($erasureRequest->verification_token); $notification = Notification::query()->where('user_id', 5)->where('type', 'gdpr_erasure_cancelled')->first(); @@ -155,6 +157,7 @@ public function moderator_can_cancel_others_erasure_request() $erasureRequest = ErasureRequest::query()->find(1); $this->assertEquals(ErasureRequest::STATUS_CANCELLED, $erasureRequest->status); + $this->assertNull($erasureRequest->verification_token); $notification = Notification::query()->where('user_id', 4)->where('type', 'gdpr_erasure_cancelled')->first();