diff --git a/api/src/get/blacklist.ts b/api/src/get/blacklist.ts index e6a4c9c..26735e3 100644 --- a/api/src/get/blacklist.ts +++ b/api/src/get/blacklist.ts @@ -1,38 +1,89 @@ -import { FastifyReply, FastifyRequest } from "fastify" -import run from "../db.js" -import fetchBlackList from "../utils/fetchBlacklist" - -export default async function blacklistIndexHandler(_: FastifyRequest, res: FastifyReply) { - try { - const result = await run(` - SELECT b.name, - COALESCE((SELECT array_agg(version) FROM blacklist_versions WHERE name = b.name), '{}'::TEXT[]) as versions, - COALESCE((SELECT array_agg(ecosystem) FROM blacklist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems, - COALESCE((SELECT array_agg(repository) FROM blacklist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories, - COALESCE((SELECT array_agg(comment) FROM blacklist_comments WHERE name = b.name), '{}'::TEXT[]) as comments - FROM blacklist b; - `, []) - if (result.rows.length === 0) { - return res.send([]) - } - - return res.send(result.rows) - } catch (error) { - console.error("Database error:", error) - return res.status(500).send({ error: "Internal Server Error" }) - } -} - -export async function blacklistHandler(req: FastifyRequest, res: FastifyReply) { - const { ecosystem, name, version } = req.params as OSVHandlerParams - if (!ecosystem || !name || !version) { - return res.status(400).send({ error: "Missing name, version, or ecosystem." }) - } - - try { - return fetchBlackList({name, version, ecosystem, res}) - } catch (error) { - console.error("Database error:", error) - return res.status(500).send({ error: "Internal Server Error" }) - } -} +import { FastifyReply, FastifyRequest } from "fastify" +import run from "../db.js" +import fetchBlackList from "../utils/fetchBlacklist" + +export default async function blacklistIndexHandler(_: FastifyRequest, res: FastifyReply) { + try { + const result = await run(` + SELECT b.name, + COALESCE((SELECT array_agg(version) FROM blacklist_versions WHERE name = b.name), '{}'::TEXT[]) as versions, + COALESCE((SELECT array_agg(ecosystem) FROM blacklist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems, + COALESCE((SELECT array_agg(repository) FROM blacklist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories, + COALESCE((SELECT array_agg(comment) FROM blacklist_comments WHERE name = b.name), '{}'::TEXT[]) as comments + FROM blacklist b; + `, []) + if (result.rows.length === 0) { + return res.send([]) + } + + return res.send(result.rows) + } catch (error) { + console.error("Database error:", error) + return res.status(500).send({ error: "Internal Server Error" }) + } +} + +export async function blacklistHandler(req: FastifyRequest, res: FastifyReply) { + const { ecosystem, name, version } = req.params as OSVHandlerParams + if (!ecosystem || !name || !version) { + return res.status(400).send({ error: "Missing name, version, or ecosystem." }) + } + + try { + return fetchBlackList({name, version, ecosystem, res}) + } catch (error) { + console.error("Database error:", error) + return res.status(500).send({ error: "Internal Server Error" }) + } +} + +export async function blacklistByRepositoryHandler(req: FastifyRequest, res: FastifyReply) { + const { repository } = req.query as { repository?: string }; + + if (!repository) { + return res.status(400).send({ error: "Missing 'repository' query parameter." }); + } + + try { + console.log(`Fetching blacklist data for repository: ${repository}`); + + const result = await run( + ` + SELECT b.name, + COALESCE( + (SELECT array_agg(version) + FROM blacklist_versions + WHERE name = b.name), '{}'::TEXT[] + ) as versions, + COALESCE( + (SELECT array_agg(ecosystem) + FROM blacklist_ecosystems + WHERE name = b.name), '{}'::TEXT[] + ) as ecosystems, + COALESCE( + (SELECT array_agg(repository) + FROM blacklist_repositories + WHERE name = b.name), '{}'::TEXT[] + ) as repositories, + COALESCE( + (SELECT array_agg(comment) + FROM blacklist_comments + WHERE name = b.name), '{}'::TEXT[] + ) as comments + FROM blacklist b + JOIN blacklist_repositories br ON b.name = br.name + WHERE br.repository = $1; + `, + [repository] + ); + + if (result.rows.length === 0) { + return res.status(404).send({ error: `No blacklist entries found for repository: ${repository}` }); + } + + return res.send(result.rows); + } catch (error) { + console.error("Database error:", error); + return res.status(500).send({ error: "Internal Server Error" }); + } +} diff --git a/api/src/get/whitelist.ts b/api/src/get/whitelist.ts index cb603d2..eeb15a5 100644 --- a/api/src/get/whitelist.ts +++ b/api/src/get/whitelist.ts @@ -1,39 +1,90 @@ -import { FastifyReply, FastifyRequest } from "fastify" -import run from "../db.js" -import fetchWhiteList from "../utils/fetchWhitelist" - -export default async function whitelistIndexHandler(_: FastifyRequest, res: FastifyReply) { - try { - const result = await run(` - SELECT b.name, - COALESCE((SELECT array_agg(version) FROM whitelist_versions WHERE name = b.name), '{}'::TEXT[]) as versions, - COALESCE((SELECT array_agg(ecosystem) FROM whitelist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems, - COALESCE((SELECT array_agg(repository) FROM whitelist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories, - COALESCE((SELECT array_agg(comment) FROM whitelist_comments WHERE name = b.name), '{}'::TEXT[]) as comments - FROM whitelist b; - `, []) - if (result.rows.length === 0) { - return res.send([]) - } - - return res.send(result.rows) - } catch (error) { - console.error("Database error:", error) - return res.status(500).send({ error: "Internal Server Error" }) - } -} - -export async function whitelistHandler(req: FastifyRequest, res: FastifyReply) { - const { ecosystem, name, version } = req.params as OSVHandlerParams - - if (!ecosystem || !name || !version) { - return res.status(400).send({ error: "Missing name, version, or ecosystem." }) - } - - try { - return fetchWhiteList({name, version, ecosystem, res}) - } catch (error) { - console.error("Database error:", error) - return res.status(500).send({ error: "Internal Server Error" }) - } -} +import { FastifyReply, FastifyRequest } from "fastify" +import run from "../db.js" +import fetchWhiteList from "../utils/fetchWhitelist" + +export default async function whitelistIndexHandler(_: FastifyRequest, res: FastifyReply) { + try { + const result = await run(` + SELECT b.name, + COALESCE((SELECT array_agg(version) FROM whitelist_versions WHERE name = b.name), '{}'::TEXT[]) as versions, + COALESCE((SELECT array_agg(ecosystem) FROM whitelist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems, + COALESCE((SELECT array_agg(repository) FROM whitelist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories, + COALESCE((SELECT array_agg(comment) FROM whitelist_comments WHERE name = b.name), '{}'::TEXT[]) as comments + FROM whitelist b; + `, []) + if (result.rows.length === 0) { + return res.send([]) + } + + return res.send(result.rows) + } catch (error) { + console.error("Database error:", error) + return res.status(500).send({ error: "Internal Server Error" }) + } +} + +export async function whitelistHandler(req: FastifyRequest, res: FastifyReply) { + const { ecosystem, name, version } = req.params as OSVHandlerParams + + if (!ecosystem || !name || !version) { + return res.status(400).send({ error: "Missing name, version, or ecosystem." }) + } + + try { + return fetchWhiteList({name, version, ecosystem, res}) + } catch (error) { + console.error("Database error:", error) + return res.status(500).send({ error: "Internal Server Error" }) + } +} + +export async function whitelistByRepositoryHandler(req: FastifyRequest, res: FastifyReply) { + const { repository } = req.query as { repository?: string }; + + if (!repository) { + return res.status(400).send({ error: "Missing 'repository' query parameter." }); + } + + try { + console.log(`Fetching whitelist data for repository: ${repository}`); + + const result = await run( + ` + SELECT b.name, + COALESCE( + (SELECT array_agg(version) + FROM whitelist_versions + WHERE name = b.name), '{}'::TEXT[] + ) as versions, + COALESCE( + (SELECT array_agg(ecosystem) + FROM whitelist_ecosystems + WHERE name = b.name), '{}'::TEXT[] + ) as ecosystems, + COALESCE( + (SELECT array_agg(repository) + FROM whitelist_repositories + WHERE name = b.name), '{}'::TEXT[] + ) as repositories, + COALESCE( + (SELECT array_agg(comment) + FROM whitelist_comments + WHERE name = b.name), '{}'::TEXT[] + ) as comments + FROM whitelist b + JOIN whitelist_repositories br ON b.name = br.name + WHERE br.repository = $1; + `, + [repository] + ); + + if (result.rows.length === 0) { + return res.status(404).send({ error: `No whitelist entries found for repository: ${repository}` }); + } + + return res.send(result.rows); + } catch (error) { + console.error("Database error:", error); + return res.status(500).send({ error: "Internal Server Error" }); + } +} diff --git a/api/src/routes.ts b/api/src/routes.ts index 21915fc..4deb55a 100644 --- a/api/src/routes.ts +++ b/api/src/routes.ts @@ -1,34 +1,37 @@ -import indexHandler from "./get/index.js" -import osvHandler from "./get/osv.js" -import whitelistIndexHandler, { whitelistHandler } from "./get/whitelist.js" -import blacklistIndexHandler, { blacklistHandler } from "./get/blacklist.js" -import whitelistPostHandler from "./post/whitelist.js" -import blacklistPostHandler from "./post/blacklist.js" -import whitelistPutHandler from "./put/whitelist.js" -import blacklistPutHandler from "./put/blacklist.js" -import whitelistDeleteHandler from "./delete/whitelist.js" -import blacklistDeleteHandler from "./delete/blacklist.js" -import { FastifyInstance, FastifyPluginOptions } from "fastify" - -export default async function apiRoutes(fastify: FastifyInstance, options: FastifyPluginOptions) { - // GET handlers - fastify.get("/", indexHandler) - fastify.get("/osv/:ecosystem/:name/:version", osvHandler) - fastify.get("/whitelist", whitelistIndexHandler) - fastify.get("/blacklist", blacklistIndexHandler) - fastify.get("/whitelist/:ecosystem/:name/:version", whitelistHandler) - fastify.get("/blacklist/:ecosystem/:name/:version", blacklistHandler) - - // POST handlers - fastify.post("/whitelist", whitelistPostHandler) - fastify.post("/blacklist", blacklistPostHandler) - - // PUT handlers - fastify.put("/whitelist", whitelistPutHandler) - fastify.put("/blacklist", blacklistPutHandler) - - // DELETE handlers - fastify.delete("/whitelist/:name", whitelistDeleteHandler) - fastify.delete("/blacklist/:name", blacklistDeleteHandler) -} - +import indexHandler from "./get/index.js" +import osvHandler from "./get/osv.js" +import whitelistIndexHandler, { whitelistHandler, whitelistByRepositoryHandler } from "./get/whitelist.js" +import blacklistIndexHandler, { blacklistHandler, blacklistByRepositoryHandler } from "./get/blacklist.js" +import whitelistPostHandler from "./post/whitelist.js" +import blacklistPostHandler from "./post/blacklist.js" +import whitelistPutHandler from "./put/whitelist.js" +import blacklistPutHandler from "./put/blacklist.js" +import whitelistDeleteHandler from "./delete/whitelist.js" +import blacklistDeleteHandler from "./delete/blacklist.js" +import { FastifyInstance, FastifyPluginOptions } from "fastify" + +export default async function apiRoutes(fastify: FastifyInstance, options: FastifyPluginOptions) { + // GET handlers + fastify.get("/", indexHandler) + fastify.get("/osv/:ecosystem/:name/:version", osvHandler) + fastify.get("/whitelist", whitelistIndexHandler) + fastify.get("/blacklist", blacklistIndexHandler) + fastify.get("/whitelist/:ecosystem/:name/:version", whitelistHandler) + fastify.get("/blacklist/:ecosystem/:name/:version", blacklistHandler) + fastify.get("/whitelist/:repository", whitelistByRepositoryHandler) + fastify.get("/blacklist/:repository", blacklistByRepositoryHandler) + + + // POST handlers + fastify.post("/whitelist", whitelistPostHandler) + fastify.post("/blacklist", blacklistPostHandler) + + // PUT handlers + fastify.put("/whitelist", whitelistPutHandler) + fastify.put("/blacklist", blacklistPutHandler) + + // DELETE handlers + fastify.delete("/whitelist/:name", whitelistDeleteHandler) + fastify.delete("/blacklist/:name", blacklistDeleteHandler) +} + diff --git a/ui/src/app/dashboard/repositories/config/[repo]/page.tsx b/ui/src/app/dashboard/repositories/config/[repo]/page.tsx new file mode 100644 index 0000000..9baac8c --- /dev/null +++ b/ui/src/app/dashboard/repositories/config/[repo]/page.tsx @@ -0,0 +1,51 @@ +import Link from "next/link" +import fetchRepoConfig, { RepoWhitelistItem, RepoBlacklistItem } from "@/utils/fetchRepoConfig" + +export default async function RepoConfigPage({params}: {params: Promise<{ repo: string }>}){ + const repo = (await params).repo + const { whitelist, blacklist } = await fetchRepoConfig(repo) + return ( +
+
+ + ← Back to Repositories + +
+ +

Repository Config: {repo}

+ +
+
+

Whitelist

+ {whitelist.length === 0 ? ( +

No whitelisted items.

+ ) : ( +
    + {whitelist.map((item: RepoWhitelistItem) => ( +
  • + {item.name}{" "} + {item.versions && item.versions.length > 0 && ( + (Versions: {item.versions.join(", ")}) + )} +
  • + ))} +
+ )} +
+ +
+

Blacklist

+ {blacklist.length === 0 ? ( +

No blacklisted items.

+ ) : ( +
    + {blacklist.map((item: RepoBlacklistItem) => ( +
  • {item.name}
  • + ))} +
+ )} +
+
+
+ ); +} diff --git a/ui/src/app/dashboard/repositories/page.tsx b/ui/src/app/dashboard/repositories/page.tsx index f17ae4e..811f7b6 100644 --- a/ui/src/app/dashboard/repositories/page.tsx +++ b/ui/src/app/dashboard/repositories/page.tsx @@ -1,51 +1,55 @@ -import fetchRepositories from "@/utils/fetchRepositories" - -type Repository = { - key: string - description: string - type: "LOCAL" | "REMOTE" | "VIRTUAL" - url: string - packageType: string -} - -type RepositoryProps = { - repository: Repository - index: number -} - -export default async function Repositories() { - const repositories: Repository[] = await fetchRepositories() - return ( -
-

Repositories

-

List of repositories in Artifactory.

-
-

Key

-

Type

-

URL

-

Package Type

-

Description

-
-
- {repositories.map((repository, index) => )} -
-
- ) -} - -function Repository({repository, index}: RepositoryProps) { - const color = index % 2 !== 0 ? 'bg-normal' : '' - return ( -
-

{repository.key}

-

{repository.type}

-

{repository.url}

-

{repository.packageType}

-

{repository.description}

-
- ) -} +import Link from "next/link"; +import fetchRepositories from "@/utils/fetchRepositories" + +type Repository = { + key: string + description: string + type: "LOCAL" | "REMOTE" | "VIRTUAL" + url: string + packageType: string +} + +type RepositoryProps = { + repository: Repository + index: number +} + +export default async function Repositories() { + const repositories: Repository[] = await fetchRepositories() + return ( +
+

Repositories

+

List of repositories in Artifactory.

+
+

Key

+

Type

+

URL

+

Package Type

+

Description

+
+
+ {repositories.map((repository, index) => )} +
+
+ ) +} + +function Repository({repository, index}: RepositoryProps) { + const color = index % 2 !== 0 ? 'bg-normal' : '' + return ( +
+ {repository.key} + +

{repository.type}

+

{repository.url}

+

{repository.packageType}

+

{repository.description}

+
+ ) +} diff --git a/ui/src/utils/fetchRepoConfig.ts b/ui/src/utils/fetchRepoConfig.ts new file mode 100644 index 0000000..6df31c2 --- /dev/null +++ b/ui/src/utils/fetchRepoConfig.ts @@ -0,0 +1,55 @@ +// src/utils/fetchRepoConfig.ts +export interface RepoWhitelistItem { + name: string; + versions: string[]; + ecosystems: string[]; + repositories: string[]; + comments: string[]; +} + +export interface RepoBlacklistItem { + name: string; + versions: string[]; + ecosystems: string[]; + repositories: string[]; + comments: string[]; +} + +export interface RepoConfig { + whitelist: RepoWhitelistItem[]; + blacklist: RepoBlacklistItem[]; +} + +export default async function fetchRepoConfig( + repository: string +): Promise { + try { + const [whitelistRes, blacklistRes] = await Promise.all([ + fetch( + `http://localhost:8080/api/whitelist/${repository}` + ), + fetch( + `http://localhost:8080/api/blacklist/${repository}` + ), + ]); + + if (!whitelistRes.ok) { + const whitelistErrorText = await whitelistRes.text(); + throw new Error(`Error fetching whitelist: ${whitelistErrorText}`); + } + if (!blacklistRes.ok) { + const blacklistErrorText = await blacklistRes.text(); + throw new Error(`Error fetching blacklist: ${blacklistErrorText}`); + } + + const [whitelist, blacklist] = await Promise.all([ + whitelistRes.json(), + blacklistRes.json(), + ]); + + return { whitelist, blacklist }; + } catch (error) { + console.error("Error fetching repository config:", error); + return { whitelist: [], blacklist: [] }; + } +}