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
36 changes: 26 additions & 10 deletions services/cubejs/src/routes/metaAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
provisionUserFromFraiOS,
} from "../utils/dataSourceHelpers.js";
import { compileMetaForBranch } from "../utils/metaForBranch.js";
import { extractCubes, resolvePartitionTeamIds } from "./discover.js";
import { extractCubes } from "./discover.js";

function getRequestId(req) {
return (
Expand Down Expand Up @@ -129,11 +129,14 @@ async function metaForDatasource(
/**
* GET /api/v1/meta-all
*
* Aggregated cube catalog across every datasource the caller can see.
* One request walks all partition-filtered datasources, resolves their
* active branch + latest version, compiles each, and returns a summary
* per cube (name, title, description, measures, dimensions, segments, meta,
* `dataschema_id`, `file_name`).
* Aggregated cube catalog scoped to the JWT's active team (partition).
* The caller may be a member of multiple teams across orgs; this endpoint
* returns only the datasources of the team that matches the JWT partition,
* matched by `team.name === partition` OR `team.settings.partition ===
* partition`. The dual match avoids the failure mode where a team's
* `settings.partition` drifted from its name (e.g. after a copy/migration)
* and the user — though a member of the right-named team — got an empty
* catalog because the soft setting didn't agree with the JWT.
*
* Auth: WorkOS RS256 or FraiOS HS256 Bearer token (same as /discover).
*
Expand Down Expand Up @@ -189,11 +192,24 @@ export default async function metaAll(req, res, cubejs) {
return res.json({ datasources: [] });
}

const partitionTeamIds = resolvePartitionTeamIds(
user.members,
payload.partition
// Scope to the partition's team. A team matches the JWT partition if
// `team.name === partition` (canonical, set at team-creation by
// deriveTeamName) OR `team.settings.partition === partition` (soft
// setting). Either is sufficient — see route docstring for why both.
const partition = payload.partition;
const partitionTeamIds = new Set(
(user.members || [])
.filter((m) => {
const t = m?.team;
if (!t) return false;
if (!partition) return false;
return (
t.name === partition || t.settings?.partition === partition
);
})
.map((m) => m.team_id)
);
const filtered = partitionTeamIds
const filtered = partition
? user.dataSources.filter((ds) => partitionTeamIds.has(ds.team_id))
: user.dataSources;

Expand Down
1 change: 1 addition & 0 deletions services/cubejs/src/utils/dataSourceHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ const userQuery = `
team_id
properties
team {
name
settings
datasources {
${sourceFragment}
Expand Down
Loading