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 (
+
+
+
+ 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: [] };
+ }
+}