Skip to content

Commit 348d049

Browse files
authored
fix: add authorization checks (#5622)
closes #5621 to publishedBuilds and findManyByIds en…dpoints - Add getProjectPermit check to publishedBuilds endpoint to verify user has access - Add userId filtering to findManyByIds to only return user's own projects or approved marketplace templates - Maintain belt-and-suspenders approach with both authType check and permit verification ## Description 1. What is this PR about (link the issue and add a short description) ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 0000) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env` file
1 parent 9f497a3 commit 348d049

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

packages/dashboard/src/db/projects.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,28 @@ export const findManyByIds = async (
121121
if (projectIds.length === 0) {
122122
return [];
123123
}
124-
const data = await context.postgrest.client
124+
125+
// Get the user ID for ownership filtering
126+
// Allow service context (no authorization) to access any projects (for templates)
127+
const userId =
128+
context.authorization.type === "user"
129+
? context.authorization.userId
130+
: undefined;
131+
132+
let query = context.postgrest.client
125133
.from("DashboardProject")
126134
.select("*, previewImageAsset:Asset (*), latestBuildVirtual (*)")
127135
.in("id", projectIds)
128-
.eq("isDeleted", false)
136+
.eq("isDeleted", false);
137+
138+
// If user context, also filter by userId OR isMarketplaceApproved (public templates)
139+
if (userId !== undefined) {
140+
query = query.or(
141+
`userId.eq.${userId},marketplaceApprovalStatus.eq.APPROVED`
142+
);
143+
}
144+
145+
const data = await query
129146
.order("createdAt", { ascending: false })
130147
.order("id", { ascending: false });
131148
if (data.error) {

packages/project/src/trpc/project-router.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,17 @@ export const projectRouter = router({
124124
ctx.authorization.type !== "user" &&
125125
ctx.authorization.type !== "token"
126126
) {
127-
throw new Error("Not authorized");
127+
throw new AuthorizationError("Not authorized");
128+
}
129+
const permit = await authorizeProject.getProjectPermit(
130+
{
131+
projectId: input.projectId,
132+
permits: ["view", "build", "admin"],
133+
},
134+
ctx
135+
);
136+
if (permit === undefined) {
137+
throw new AuthorizationError("Not authorized to access this project");
128138
}
129139
const publishedBuilds = await ctx.postgrest.client
130140
.from("published_builds")

0 commit comments

Comments
 (0)