Skip to content

Commit 6101edc

Browse files
committed
feat(artifacts): add verification hook
1 parent ce33df3 commit 6101edc

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

client/src/app/pages/Artifacts/Artifacts.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Popover,
1515
TextInput,
1616
} from "@patternfly/react-core";
17-
import { useFetchArtifactsImageData } from "@app/queries/artifacts";
17+
import { useFetchArtifactsImageData, useVerifyArtifact } from "@app/queries/artifacts";
1818
import { LoadingWrapper } from "@app/components/LoadingWrapper";
1919
import { ArtifactResults } from "./components/ArtifactResults";
2020
import { Controller, useForm } from "react-hook-form";
@@ -37,6 +37,14 @@ export const Artifacts = () => {
3737
fetchError: fetchErrorArtifactMetadata,
3838
} = useFetchArtifactsImageData({ uri: artifactUri });
3939

40+
const {
41+
mutate: verifyArtifact,
42+
isPending: isVerifying,
43+
error: verifyError,
44+
data: verifyResult,
45+
reset: resetVerify,
46+
} = useVerifyArtifact();
47+
4048
const {
4149
control,
4250
handleSubmit,
@@ -54,6 +62,8 @@ export const Artifacts = () => {
5462
const uri = data.searchInput?.trim();
5563
if (!uri) return;
5664
setArtifactUri(uri);
65+
// kick off verification (transitional: SAN not required yet in our draft type)
66+
verifyArtifact({ uri });
5767
};
5868

5969
const query = watch("searchInput");

client/src/app/pages/Artifacts/components/ArtifactResultsSummary.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const ArtifactResultsSummary = ({ artifact }: IArtifactResultsProps) => {
5555
</DescriptionListGroup>
5656
<DescriptionListGroup>
5757
<DescriptionListTermHelpText>
58-
<Popover headerContent={<div>Date</div>} bodyContent={<div>Additional pod selector info</div>}>
58+
<Popover headerContent={<div>Date</div>} bodyContent={<div>Date created</div>}>
5959
<DescriptionListTermHelpTextButton> Created </DescriptionListTermHelpTextButton>
6060
</Popover>
6161
</DescriptionListTermHelpText>
@@ -88,7 +88,7 @@ export const ArtifactResultsSummary = ({ artifact }: IArtifactResultsProps) => {
8888
</DescriptionListGroup>
8989
<DescriptionListGroup>
9090
<DescriptionListTermHelpText>
91-
<Popover headerContent={<div>Labels</div>} bodyContent={<div>Additional labels info</div>}>
91+
<Popover headerContent={<div>Signatures</div>} bodyContent={<div>Additional labels info</div>}>
9292
<DescriptionListTermHelpTextButton> Signatures </DescriptionListTermHelpTextButton>
9393
</Popover>
9494
</DescriptionListTermHelpText>

client/src/app/queries/artifacts.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
11
import type { AxiosError } from "axios";
22

33
import { client } from "@app/axios-config/apiInit";
4-
import { getApiV1ArtifactsImage, type _Error, type ImageMetadataResponse } from "@app/client";
4+
import {
5+
getApiV1ArtifactsImage,
6+
type PostApiV1ArtifactsVerifyResponse,
7+
type _Error,
8+
type ImageMetadataResponse,
9+
postApiV1ArtifactsVerify,
10+
type VerifyArtifactRequest,
11+
} from "@app/client";
512
import { useMockableQuery } from "./helpers";
613
import { artifactsImageDataMock } from "./mocks/artifacts.mock";
14+
import { useMutation, useQueryClient } from "@tanstack/react-query";
715

8-
export const ArtifactsKey = "Artifacts";
16+
export const ArtifactsKeys = {
17+
all: ["Artifacts" as const],
18+
image: (uri: string) => ["Artifacts", "image", uri] as const,
19+
verify: (id: string | number) => ["Artifacts", "verify", id] as const,
20+
};
21+
22+
// transitional payload while backend/types evolve
23+
interface VerifyArtifactDraft {
24+
uri: string;
25+
expectedSAN?: string; // optional for now
26+
[k: string]: unknown;
27+
}
928

1029
export const useFetchArtifactsImageData = ({ uri }: { uri: string | null | undefined }) => {
1130
const enabled = typeof uri === "string" && uri.trim().length > 0;
1231
const { data, isLoading, error, refetch } = useMockableQuery<ImageMetadataResponse | null, AxiosError<_Error>>(
1332
{
14-
queryKey: [ArtifactsKey, "image", uri ?? ""],
33+
queryKey: ArtifactsKeys.image(uri ?? ""),
1534
queryFn: async () => {
1635
const response = await getApiV1ArtifactsImage({ client, query: { uri: uri! } });
1736
return response.data ?? null;
@@ -25,3 +44,30 @@ export const useFetchArtifactsImageData = ({ uri }: { uri: string | null | undef
2544

2645
return { artifact: data, isFetching: isLoading, fetchError: error, refetch };
2746
};
47+
48+
export const useVerifyArtifact = () => {
49+
const queryClient = useQueryClient();
50+
return useMutation<PostApiV1ArtifactsVerifyResponse | null, AxiosError<_Error>, VerifyArtifactDraft>({
51+
mutationFn: async (draft) => {
52+
// if the backend/types aren't ready (e.g., missing SAN), return a mock/null
53+
if (!draft.expectedSAN) {
54+
return null;
55+
}
56+
57+
// map the draft payload into the SDK body shape. Include only fields we know.
58+
const res = await postApiV1ArtifactsVerify({
59+
client,
60+
body: {
61+
// the SDK requires `expectedSAN` (string | null); ensure it exists when we reach here
62+
expectedSAN: draft.expectedSAN ?? null,
63+
// use `ociImage` for the artifact reference (since `uri` isn't in the SDK type)
64+
ociImage: draft.uri,
65+
} as VerifyArtifactRequest,
66+
});
67+
return res.data ?? null;
68+
},
69+
onSuccess: () => {
70+
void queryClient.invalidateQueries({ queryKey: ArtifactsKeys.all });
71+
},
72+
});
73+
};

0 commit comments

Comments
 (0)