From ef0105098b277f2aa578f3fd3c7aebea1df544ce Mon Sep 17 00:00:00 2001 From: boban Date: Sat, 16 May 2026 11:17:54 +0200 Subject: [PATCH] fix: workspace membership + middleware owner fallback - DemoDataSeeder now creates workspace_members record for owner + sets default_workspace_id - ResolveWorkspace middleware accepts workspace owners even without explicit member record - Applied membership fix for nexxo@nimuli.com via PHP (existing installs) Co-Authored-By: Claude Sonnet 4.6 --- app/Http/Middleware/ResolveWorkspace.php | 4 +++- database/seeders/DemoDataSeeder.php | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Http/Middleware/ResolveWorkspace.php b/app/Http/Middleware/ResolveWorkspace.php index ac5c34d..a93c371 100644 --- a/app/Http/Middleware/ResolveWorkspace.php +++ b/app/Http/Middleware/ResolveWorkspace.php @@ -20,7 +20,9 @@ class ResolveWorkspace // 404 instead of 403 — don't leak existence across workspace boundaries $user = $request->user(); - if (! $user || ! $user->workspaceMemberships()->where('workspace_id', $workspace->id)->exists()) { + $isMember = $user && $user->workspaceMemberships()->where('workspace_id', $workspace->id)->exists(); + $isOwner = $user && $workspace->owner_id === $user->id; + if (! $isMember && ! $isOwner) { abort(404); } diff --git a/database/seeders/DemoDataSeeder.php b/database/seeders/DemoDataSeeder.php index e1271ba..0035418 100644 --- a/database/seeders/DemoDataSeeder.php +++ b/database/seeders/DemoDataSeeder.php @@ -5,6 +5,7 @@ namespace Database\Seeders; use App\Domains\Analytics\Models\Click; use App\Domains\Link\Models\Link; use App\Domains\Workspace\Models\Workspace; +use App\Domains\Workspace\Models\WorkspaceMember; use App\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Carbon; @@ -24,6 +25,13 @@ class DemoDataSeeder extends Seeder ] ); + // Ensure owner has a membership record and default workspace set + WorkspaceMember::firstOrCreate( + ['workspace_id' => $workspace->id, 'user_id' => $user->id], + ['role' => 'owner', 'joined_at' => now()] + ); + $user->updateQuietly(['default_workspace_id' => $workspace->id]); + $this->command->info("Workspace: {$workspace->name} ({$workspace->ulid})"); $slugs = ['nimuli', 'get-started', 'pricing', 'blog', 'docs', 'github', 'twitter', 'linkedin', 'youtube', 'discord', 'product', 'api', 'signup', 'login-link', 'partner', 'careers', 'press', 'legal', 'status', 'support'];