diff --git a/core/lib/authentication/api.ts b/core/lib/authentication/api.ts index 5b90d17a7c..3b53427ea8 100644 --- a/core/lib/authentication/api.ts +++ b/core/lib/authentication/api.ts @@ -133,7 +133,10 @@ export type AuthorizationOutput; community: Communities; lastModifiedBy: LastModifiedBy; - user: User; + // is empty for site builder tokens + // should be empty for other tokens, but isn't. + // we are incorrectly passing the user who minted the token to eg getPubs and getStages + user?: User; isSiteBuilderToken?: boolean; }; diff --git a/core/lib/db/queries.ts b/core/lib/db/queries.ts index 4463d2f2fc..bdfe1833c3 100644 --- a/core/lib/db/queries.ts +++ b/core/lib/db/queries.ts @@ -12,23 +12,35 @@ import { autoCache } from "../server/cache/autoCache"; import { viewableStagesCte } from "../server/stages"; import { SAFE_USER_SELECT } from "../server/user"; -export const getStage = cache((stageId: StagesId, userId: UsersId) => { - return autoCache( - db - .with("viewableStages", (db) => viewableStagesCte({ db, userId })) - .selectFrom("stages") - .innerJoin("viewableStages", "viewableStages.stageId", "stages.id") - .select([ - "stages.id", - "communityId", - "stages.name", - "stages.order", - "createdAt", - "updatedAt", - ]) - .where("stages.id", "=", stageId) - ); -}); +export const getStage = cache( + ( + stageId: StagesId, + userOrAuthorizedStages: XOR<{ userId?: UsersId }, { authorizedStages: StagesId[] | "all" }> + ) => { + return autoCache( + db + .with("viewableStages", (db) => { + if (userOrAuthorizedStages.userId) { + return viewableStagesCte({ db, userId: userOrAuthorizedStages.userId }); + } + + return db.selectFrom("stages").select("stages.id as stageId").where(); + where("stages.id", "in", userOrAuthorizedStages.authorizedStages as StagesId[]); + }) + .selectFrom("stages") + .innerJoin("viewableStages", "viewableStages.stageId", "stages.id") + .select([ + "stages.id", + "communityId", + "stages.name", + "stages.order", + "createdAt", + "updatedAt", + ]) + .where("stages.id", "=", stageId) + ); + } +); export const getStageActions = cache( ({ diff --git a/core/lib/server/stages.ts b/core/lib/server/stages.ts index 6c4b94ecbb..659f210a98 100644 --- a/core/lib/server/stages.ts +++ b/core/lib/server/stages.ts @@ -14,7 +14,7 @@ import type { } from "db/public"; import { Capabilities, MembershipType } from "db/public"; -import type { AutoReturnType } from "../types"; +import type { AutoReturnType, XOR } from "../types"; import { db } from "~/kysely/database"; import { autoCache } from "./cache/autoCache"; import { autoRevalidate } from "./cache/autoRevalidate"; @@ -130,7 +130,10 @@ export const getStagesViewableByUser = cache( } ); -type CommunityStageProps = { communityId: CommunitiesId; stageId?: StagesId; userId: UsersId }; +type CommunityStageProps = { communityId: CommunitiesId; stageId?: StagesId } & XOR< + { userId: UsersId }, + { authorizedStages: StagesId[] | "all" } +>; type CommunityStageOptions = { withActionInstances?: "count" | "full" | false; withMembers?: "count" | "full" | false; @@ -140,14 +143,34 @@ type CommunityStageOptions = { * Get all stages the given user has access to */ export const getStages = ( - { communityId, stageId, userId }: CommunityStageProps, + { communityId, stageId, ...userOrAuthorizedStages }: CommunityStageProps, options: CommunityStageOptions = {} ) => { const withActionInstances = options.withActionInstances ?? "count"; return autoCache( db - .with("viewableStages", (db) => viewableStagesCte({ db: db, userId, communityId })) + .with("viewableStages", (db) => { + if (userOrAuthorizedStages.userId) { + return viewableStagesCte({ + db: db, + userId: userOrAuthorizedStages.userId, + communityId, + }); + } + + return db + .selectFrom("stages") + .select("stages.id as stageId") + .where("stages.communityId", "=", communityId) + .$if(userOrAuthorizedStages.authorizedStages !== "all", (qb) => + qb.where( + "stages.id", + "in", + userOrAuthorizedStages.authorizedStages as StagesId[] + ) + ); + }) .selectFrom("stages") .innerJoin("viewableStages", "viewableStages.stageId", "stages.id") .where("communityId", "=", communityId)