Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/Http/Controllers/Api/PluginAccessController.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ protected function getAccessiblePlugins(User $user): array
}
}

// Team members get access to official plugins and owner's purchased plugins
if ($user->isUltraTeamMember()) {
// Ultra subscribers and team members get access to official plugins
if ($user->hasUltraAccess() || $user->isUltraTeamMember()) {
$officialPlugins = Plugin::query()
->where('type', PluginType::Paid)
->where('is_official', true)
Expand Down
4 changes: 2 additions & 2 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,8 @@ public function hasPluginAccess(Plugin $plugin): bool
return true;
}

// Ultra team members get access to all official (first-party) plugins
if ($plugin->isOfficial() && $this->isUltraTeamMember()) {
// Ultra subscribers and team members get access to all official (first-party) plugins
if ($plugin->isOfficial() && ($this->hasUltraAccess() || $this->isUltraTeamMember())) {
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 93 additions & 0 deletions tests/Feature/UltraPluginAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,99 @@ public function test_team_member_with_own_subscription_sees_regular_price_for_th
$this->assertEquals(4900, $bestPrice->amount);
}

// ---- Ultra subscribers without a team ----

public function test_ultra_subscriber_without_team_has_access_to_official_plugin(): void
{
$user = User::factory()->create();
$this->createPaidMaxSubscription($user);
$plugin = $this->createOfficialPlugin();

// User has Ultra subscription but no team created
$this->assertNull($user->ownedTeam);
$this->assertTrue($user->hasPluginAccess($plugin));
}

public function test_ultra_subscriber_without_team_does_not_have_access_to_third_party_plugin(): void
{
$user = User::factory()->create();
$this->createPaidMaxSubscription($user);
$plugin = $this->createThirdPartyPlugin();

$this->assertFalse($user->hasPluginAccess($plugin));
}

public function test_comped_ultra_subscriber_without_team_has_access_to_official_plugin(): void
{
$user = User::factory()->create();
$this->createCompedUltraSubscription($user);
$plugin = $this->createOfficialPlugin();

$this->assertNull($user->ownedTeam);
$this->assertTrue($user->hasPluginAccess($plugin));
}

public function test_legacy_comped_max_without_team_does_not_have_access_to_official_plugin(): void
{
$user = User::factory()->create();
$this->createCompedMaxSubscription($user);
$plugin = $this->createOfficialPlugin();

$this->assertFalse($user->hasPluginAccess($plugin));
}

public function test_satis_api_includes_official_plugins_for_ultra_subscriber_without_team(): void
{
$user = User::factory()->create([
'plugin_license_key' => 'ultra-no-team-key',
]);
$this->createPaidMaxSubscription($user);

$plugin = Plugin::factory()->create([
'name' => 'nativephp/secure-storage',
'type' => PluginType::Paid,
'status' => PluginStatus::Approved,
'is_active' => true,
'is_official' => true,
]);

$response = $this->withHeaders([
'X-API-Key' => config('services.bifrost.api_key'),
'Authorization' => 'Basic '.base64_encode("{$user->email}:ultra-no-team-key"),
])->getJson('/api/plugins/access');

$response->assertStatus(200);

$pluginNames = array_column($response->json('plugins'), 'name');
$this->assertContains('nativephp/secure-storage', $pluginNames);
}

public function test_satis_check_access_returns_true_for_ultra_subscriber_without_team(): void
{
$user = User::factory()->create([
'plugin_license_key' => 'ultra-no-team-key',
]);
$this->createPaidMaxSubscription($user);

Plugin::factory()->create([
'name' => 'nativephp/secure-storage',
'type' => PluginType::Paid,
'status' => PluginStatus::Approved,
'is_active' => true,
'is_official' => true,
]);

$response = $this->withHeaders([
'X-API-Key' => config('services.bifrost.api_key'),
'Authorization' => 'Basic '.base64_encode("{$user->email}:ultra-no-team-key"),
])->getJson('/api/plugins/access/nativephp/secure-storage');

$response->assertStatus(200)
->assertJson([
'has_access' => true,
]);
}

// ---- Comped Ultra subscriptions ----

public function test_comped_ultra_user_has_active_ultra_subscription(): void
Expand Down
Loading