Skip to content

Team invitation acceptance mutates state through GET #186

Description

@wangchenxudev

I hit this while porting the starter kit to Blade. Assumed I'd broken it
myself, but the Inertia and Livewire templates do the same thing.

routes/web.php:

Route::middleware(['auth'])->group(function () {
    Route::get('invitations/{invitation}/accept', [TeamInvitationController::class, 'accept'])->name('invitations.accept');
    Route::delete('invitations/{invitation}', [TeamInvitationController::class, 'decline'])->name('invitations.decline');
});

accept creates the membership, sets accepted_at and switches the user's
current team. Livewire does the same from mount() in
accept-invitation.blade.php.

GET also answers HEAD, and the CSRF middleware treats both as reads, so
anything that just fetches the URL runs the write: wire:navigate prefetch on
hover, browser prefetch, mail scanners. It also switches current team, which
affects whatever the user does next.

Before #120 the email linked straight at this URL, so a navigable GET made
sense. Now the email goes to login and Accept/Decline are both buttons in the
same modal — and Decline is already a DELETE.

Would you take a PR making the Inertia route POST and moving the Livewire
accept out of mount()? Wayfinder should hand router.visit() the right
method. The one cost is a stale tab getting a 419 instead of a login redirect,
though Decline does that today anyway. Looks like it covers Vue, React, Svelte
and Livewire, including the Fortify and WorkOS variants.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions