diff --git a/app/Http/Controllers/GitHubIntegrationController.php b/app/Http/Controllers/GitHubIntegrationController.php index c9ad078bd..e113a19de 100644 --- a/app/Http/Controllers/GitHubIntegrationController.php +++ b/app/Http/Controllers/GitHubIntegrationController.php @@ -9,6 +9,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Laravel\Socialite\Facades\Socialite; @@ -206,6 +207,9 @@ public function disconnect(): RedirectResponse 'claude_plugins_repo_access_granted_at' => null, ]); + Cache::forget("github_collab_status_{$user->id}"); + Cache::forget("github_claude_plugins_collab_status_{$user->id}"); + return back()->with('success', 'GitHub account disconnected successfully.'); } diff --git a/resources/views/livewire/customer/integrations.blade.php b/resources/views/livewire/customer/integrations.blade.php index 584250ee9..ccb97de9f 100644 --- a/resources/views/livewire/customer/integrations.blade.php +++ b/resources/views/livewire/customer/integrations.blade.php @@ -37,6 +37,76 @@ + {{-- GitHub Account --}} + +
+
+ +
+ GitHub Account + @if (auth()->user()->github_username) + Connected as {{ '@' . auth()->user()->github_username }} + @else + Connect your GitHub account to access private repositories and publish plugins. + @endif +
+
+
+ @if (auth()->user()->github_username) + + Disconnect + + @else + Connect GitHub + @endif +
+
+
+ + {{-- Disconnect GitHub Confirmation Modal --}} + @if (auth()->user()->github_username) + +
+ @csrf + @method('DELETE') + + Disconnect GitHub? + + + This will unlink {{ '@' . auth()->user()->github_username }} from your NativePHP account. + + + + +
    +
  • Any access to the private nativephp/mobile and nativephp/claude-code repositories will be revoked.
  • +
  • Your GitHub repositories will no longer be available when submitting or managing plugins.
  • +
  • You can reconnect at any time. When re-authorizing, be sure to grant access to any organizations whose repositories you need.
  • +
+
+
+ + @if (! auth()->user()->password) + + + Your account uses GitHub to sign in and has no password set. Consider setting a password in + Settings before disconnecting. + + + @endif + +
+ + Cancel + + Disconnect GitHub +
+
+
+ @endif + {{-- Claude Plugins Access --}}
diff --git a/resources/views/livewire/git-hub-access-banner.blade.php b/resources/views/livewire/git-hub-access-banner.blade.php index 736ed9c9b..159fe0554 100644 --- a/resources/views/livewire/git-hub-access-banner.blade.php +++ b/resources/views/livewire/git-hub-access-banner.blade.php @@ -55,13 +55,6 @@ @endif -
- @csrf - @method('DELETE') - -
@else Connect GitHub diff --git a/tests/Feature/GitHubIntegrationTest.php b/tests/Feature/GitHubIntegrationTest.php index e3a89ef22..ce65628a7 100644 --- a/tests/Feature/GitHubIntegrationTest.php +++ b/tests/Feature/GitHubIntegrationTest.php @@ -154,6 +154,64 @@ public function test_user_cannot_request_repo_access_without_connected_github(): $response->assertSessionHas('error', 'Please connect your GitHub account first.'); } + public function test_user_without_any_license_sees_github_account_card_with_connect_button(): void + { + Http::fake(['api.github.com/*' => Http::response([], 404)]); + + $user = User::factory()->create(); + + $response = $this->actingAs($user)->get('/dashboard/integrations'); + + $response->assertStatus(200); + $response->assertSee('GitHub Account'); + $response->assertSee('Connect GitHub'); + } + + public function test_connected_user_without_any_license_can_see_disconnect_option(): void + { + Http::fake(['api.github.com/*' => Http::response([], 404)]); + + $user = User::factory()->create([ + 'github_username' => 'testuser', + 'github_id' => '123456', + ]); + + $response = $this->actingAs($user)->get('/dashboard/integrations'); + + $response->assertStatus(200); + $response->assertSee('GitHub Account'); + $response->assertSee('Connected as'); + $response->assertSee('@testuser'); + $response->assertSee('Disconnect GitHub?'); + } + + public function test_disconnect_clears_token_and_collaborator_status_caches(): void + { + Http::fake(['api.github.com/*' => Http::response([], 204)]); + + $user = User::factory()->create([ + 'github_username' => 'testuser', + 'github_id' => '123456', + 'github_token' => encrypt('gho_test_token'), + ]); + + Cache::put("github_collab_status_{$user->id}", 'active', 300); + Cache::put("github_claude_plugins_collab_status_{$user->id}", 'active', 300); + + $response = $this->actingAs($user) + ->delete('/dashboard/github/disconnect'); + + $response->assertRedirect(); + $response->assertSessionHas('success'); + + $user->refresh(); + $this->assertNull($user->github_token); + $this->assertNull($user->github_username); + $this->assertNull($user->github_id); + $this->assertFalse(Cache::has("github_collab_status_{$user->id}")); + $this->assertFalse(Cache::has("github_claude_plugins_collab_status_{$user->id}")); + } + public function test_user_can_disconnect_github_account(): void { Http::fake([