Skip to content

Commit 1bbd00e

Browse files
dd32claude
andcommitted
Auto-revoke invite links on publish
Once a post transitions to `publish`, its invite link is revoked. Existing co-authors keep their access; the shared URL simply stops admitting new people. The author can regenerate a fresh link after publish if they want to continue adding collaborators. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 281d73b commit 1bbd00e

3 files changed

Lines changed: 58 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A WordPress plugin that allows multiple authors to edit a single post via shared
77
## Features
88

99
- **Co-author management** -- Add or remove co-authors from any post via the block editor sidebar panel.
10-
- **Shared invite links** -- Generate a shareable URL that lets any registered user join as a co-author.
10+
- **Shared invite links** -- Generate a shareable URL that lets any registered user join as a co-author. Links expire after 24 hours and are automatically revoked when the post is published; existing co-authors keep their access.
1111
- **Capability-aware** -- Co-authors can edit and read their assigned posts without gaining broader site permissions.
1212
- **Multisite support** -- Invited users are automatically added to the site with a subscriber role so they can access the editor.
1313
- **Author preservation** -- When a post's author is reassigned, the previous author is automatically kept as a co-author.

includes/class-map-invite.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ class Invite {
2323
*/
2424
public static function init(): void {
2525
add_action( 'template_redirect', array( __CLASS__, 'handle_invite_request' ) );
26+
add_action( 'transition_post_status', array( __CLASS__, 'revoke_on_publish' ), 10, 3 );
27+
}
28+
29+
/**
30+
* Auto-revoke an active invite when a post transitions to `publish`.
31+
*
32+
* Existing co-authors keep their access; the shared link simply stops
33+
* admitting new people. The author can regenerate a fresh link if more
34+
* collaborators need to be added post-publish.
35+
*/
36+
public static function revoke_on_publish( string $new_status, string $old_status, \WP_Post $post ): void {
37+
if ( 'publish' === $new_status && 'publish' !== $old_status ) {
38+
self::revoke_invite( $post->ID );
39+
}
2640
}
2741

2842
/**

tests/Test_Invite.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,49 @@ public function test_expired_token_is_cleaned_up_on_lookup(): void {
167167
$this->assertSame( '', get_post_meta( $this->post_id, '_map_invite_token', true ) );
168168
}
169169

170+
public function test_invite_is_revoked_when_post_is_published(): void {
171+
Invite::init();
172+
173+
$draft = self::factory()->post->create(
174+
array(
175+
'post_author' => $this->author_id,
176+
'post_status' => 'draft',
177+
)
178+
);
179+
Invite::create_invite_url( $draft );
180+
$this->assertTrue( Invite::get_invite_status( $draft )['active'] );
181+
182+
wp_update_post(
183+
array(
184+
'ID' => $draft,
185+
'post_status' => 'publish',
186+
)
187+
);
188+
189+
$this->assertFalse( Invite::get_invite_status( $draft )['active'] );
190+
}
191+
192+
public function test_publish_to_publish_does_not_revoke(): void {
193+
Invite::init();
194+
195+
$published = self::factory()->post->create(
196+
array(
197+
'post_author' => $this->author_id,
198+
'post_status' => 'publish',
199+
)
200+
);
201+
Invite::create_invite_url( $published );
202+
203+
wp_update_post(
204+
array(
205+
'ID' => $published,
206+
'post_title' => 'edited',
207+
)
208+
);
209+
210+
$this->assertTrue( Invite::get_invite_status( $published )['active'] );
211+
}
212+
170213
public function test_shared_invite_can_be_used_by_multiple_users(): void {
171214
$url = Invite::create_invite_url( $this->post_id );
172215
$token = $this->extract_token( $url );

0 commit comments

Comments
 (0)