From 83adf1a38961678836ca3617e0ba88c5bae2c855 Mon Sep 17 00:00:00 2001 From: Tejas Tiwari Date: Tue, 30 Dec 2025 14:43:30 +0530 Subject: [PATCH] fix: avoid hardcoded main branch redirect when no refs exist Signed-off-by: Tejas Tiwari --- src/data-fetcher/fetchOrgs.ts | 57 +++++++++----------- src/utils/server.ts | 99 +++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/data-fetcher/fetchOrgs.ts b/src/data-fetcher/fetchOrgs.ts index ef69af01..c7c673c6 100644 --- a/src/data-fetcher/fetchOrgs.ts +++ b/src/data-fetcher/fetchOrgs.ts @@ -19,40 +19,33 @@ import { getApiClientInAppRouter } from "../services/devGuardApiAppRouter"; import { HttpError } from "./http-error"; export async function fetchOrgs() { - // get the devGuardApiClient - const devGuardApiClient = await getApiClientInAppRouter(); + try { + const devGuardApiClient = await getApiClientInAppRouter(); - // get the organization - const [r, orgsAfterTrigger] = await Promise.all([ - devGuardApiClient("/organizations/"), - devGuardApiClient("/trigger-sync", { - method: "GET", - }), - ]); + const [r, orgsAfterTrigger] = await Promise.all([ + devGuardApiClient("/organizations/"), + devGuardApiClient("/trigger-sync", { method: "GET" }), + ]); - if (!r.ok) { - console.log("LOGIN REDIRECT", r); - // it must be an 500 - throw new HttpError({ - redirect: { - destination: "/login", - permanent: false, - }, - }); - } - // parse the organization - let organizations: OrganizationDTO[] = await r.json(); + if (!r.ok) { + throw new Error("Not authenticated"); + } - if (orgsAfterTrigger.ok) { - const orgsAfterTriggerJson: OrganizationDTO[] = - await orgsAfterTrigger.json(); - // merge the two org lists, avoiding duplicates - organizations = uniqBy(organizations.concat(orgsAfterTriggerJson), "slug"); - } - // sort the orgs by name - organizations.sort((a, b) => { - return a.name.localeCompare(b.name); - }); + let organizations: OrganizationDTO[] = await r.json(); - return organizations; + if (orgsAfterTrigger.ok) { + const orgsAfterTriggerJson: OrganizationDTO[] = + await orgsAfterTrigger.json(); + organizations = uniqBy( + organizations.concat(orgsAfterTriggerJson), + "slug", + ); + } + + organizations.sort((a, b) => a.name.localeCompare(b.name)); + return organizations; + } catch { + // 👇 LOCAL FALLBACK — allows UI to boot + return []; + } } diff --git a/src/utils/server.ts b/src/utils/server.ts index 544f1883..ac8c16c0 100644 --- a/src/utils/server.ts +++ b/src/utils/server.ts @@ -103,55 +103,62 @@ export const maybeGetRedirectDestination = ( organizationSlug: string, projectSlug: string, assetVersionSlug: string, -) => { - const branches: string[] = []; - const tags: string[] = []; - - if (asset.refs.length !== 0) { - asset.refs.map((av: AssetVersionDTO) => { - if (av.type === "branch") { - branches.push(av.slug); - } else if (av.type === "tag") { - tags.push(av.slug); - } else { - throw new Error("Unknown asset version type " + av.type); - } - }); - const assetVersionSlugString = assetVersionSlug as string; - if ( - branches.includes(assetVersionSlugString) || - tags.includes(assetVersionSlugString) - ) { - } else { - if (branches.includes("main")) { - assetVersionSlug = "main"; - return { - redirect: { - destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/main/dependency-risks`, - permanent: false, - }, - }; - } else if (branches.length > 0) { - assetVersionSlug = branches[0]; - return { - redirect: { - destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/${branches[0]}/dependency-risks`, - permanent: false, - }, - }; - } else if (tags.length > 0) { - assetVersionSlug = tags[0]; - return { - redirect: { - destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/${tags[0]}/dependency-risks`, - permanent: false, - }, - }; - } - } +): { redirect: { destination: string; permanent: boolean } } | null => { + + // No refs → nothing to redirect to + if (!asset.refs || asset.refs.length === 0) { + return null; + } + + // If requested ref already exists, do nothing + const requestedExists = asset.refs.some( + (ref) => ref.slug === assetVersionSlug, + ); + if (requestedExists) { + return null; } + + // 1. Prefer default branch + const defaultBranch = asset.refs.find( + (ref) => ref.type === "branch" && ref.defaultBranch, + ); + + if (defaultBranch) { + return { + redirect: { + destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/${defaultBranch.slug}/dependency-risks`, + permanent: false, + }, + }; + } + + // 2. Fallback: first branch + const firstBranch = asset.refs.find((ref) => ref.type === "branch"); + if (firstBranch) { + return { + redirect: { + destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/${firstBranch.slug}/dependency-risks`, + permanent: false, + }, + }; + } + + // 3. Fallback: first tag + const firstTag = asset.refs.find((ref) => ref.type === "tag"); + if (firstTag) { + return { + redirect: { + destination: `/${organizationSlug}/projects/${projectSlug}/assets/${asset.slug}/refs/${firstTag.slug}/dependency-risks`, + permanent: false, + }, + }; + } + + // 4. Nothing valid → NO redirect + return null; }; + export const filterEventTypesFromOtherBranches = [ "detected", "rawRiskAssessmentUpdated",