Commit graph

4 commits

Author SHA1 Message Date
Paulo Castellano
0eb6f4df24 refactor(permissions): drop explanatory comments, fix stale PostPolicy docblock 2026-06-22 16:35:27 -03:00
Paulo Castellano
5bb39da598 fix(permissions): enforce workspace roles across backend and UI
Viewers could mutate posts, automations and trigger AI write endpoints,
and every role saw create/manage affordances that 403'd on click.

Backend (security):
- PostPolicy update/delete now require member+ (was tenancy-only), which
  also gates the AI write endpoints that authorize('update')
- AutomationPolicy create/update/delete require member+; activate/pause
  delegate to update
- AutomationController authorizes index/store/show; AnalyticsController
  authorizes view
- Comments stay open to members incl. viewer (by design)

Frontend (UI gating via new useWorkspaceRole composable):
- Sidebar: create post / create workspace / automations / library nav
- Accounts grid: connect / disconnect / reconnect (admin+)
- Members: invite / change role / remove / cancel invite (admin+)
- Account billing tab (owner); posts index + calendar create affordances

Tests: PostPolicyTest, AutomationPolicyTest (all four roles) and an
end-to-end WorkspaceRolePermissionsTest; aligned the automation test
suites' account/workspace setup with role pivots.
2026-06-22 16:31:54 -03:00
Paulo Castellano
3b96a9ebdb refactor: move workspace tenancy check on Post into PostPolicy
The same "is this post in the user's current workspace?" check was
duplicated across every Post-related endpoint (5 in Api/PostController
via the ensurePostInCurrentWorkspace helper, 5 in App/PostController
inline). PostPolicy already had a duplicate() method following this
exact pattern — extending it with view/update/delete unifies the
tenancy guard in one place.

- Add view/update/delete to PostPolicy. Each returns
  Response::denyAsNotFound() when the post belongs to a different
  workspace, so we keep the existing 404 behavior (don't leak
  cross-tenant existence) instead of switching to the default 403.

- Update duplicate() to also use denyAsNotFound() for the workspace
  mismatch path. The createPost role check still returns bool/403.

- Replace ensurePostInCurrentWorkspace() calls in Api/PostController
  with $this->authorize('view'|'update'|'delete', $post). Helper deleted.

- Replace inline workspace_id !== $workspace->id checks in
  App/PostController (show/edit/update/destroy/platformMetrics) with
  the same authorize calls. The PostPolicy guard now subsumes both
  the workspace-tenancy check and the role-permission check that was
  previously delegated through Workspace::createPost.
2026-05-04 13:20:52 -03:00
Paulo Castellano
6f3bdb2caa feat: add duplicate post functionality and migrate LinkedIn analytics to the /rest/ API. 2026-05-03 22:37:51 -03:00