Skip to content

Commit c91b01d

Browse files
committed
review fixes
1 parent 680b9c5 commit c91b01d

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
PlusIcon,
88
} from "@heroicons/react/20/solid";
99
import { DialogClose } from "@radix-ui/react-dialog";
10-
import { type MetaFunction, Form, useFetcher, useSearchParams } from "@remix-run/react";
10+
import { type MetaFunction, Form, useSearchParams } from "@remix-run/react";
1111
import { useEffect, useState } from "react";
12-
import { typedjson, useTypedLoaderData } from "remix-typedjson";
12+
import { typedjson, useTypedFetcher, useTypedLoaderData } from "remix-typedjson";
1313
import { z } from "zod";
1414
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
1515
import { CopyableText } from "~/components/primitives/CopyableText";
@@ -104,7 +104,7 @@ const CreateApiKeySchema = z.object({
104104
presetId: z.string().trim().min(1),
105105
taskScope: z.enum(["all", "selected"]).optional(),
106106
taskIdentifiers: z
107-
.array(z.string())
107+
.array(z.string().trim().min(1, "Task identifiers cannot be blank"))
108108
.max(MAX_API_KEY_TASK_IDENTIFIERS, {
109109
message: `You can select at most ${MAX_API_KEY_TASK_IDENTIFIERS} tasks`,
110110
})
@@ -560,8 +560,9 @@ function NewApiKeyDialog({
560560
availableTasks: string[];
561561
presets: ApiKeyPreset[] | null;
562562
}) {
563-
const fetcher = useFetcher<typeof action>();
563+
const fetcher = useTypedFetcher<typeof action>();
564564
const actionData = fetcher.data as ApiKeyActionData | undefined;
565+
const [showError, setShowError] = useState(false);
565566
const [open, setOpen] = useState(false);
566567
const [name, setName] = useState("");
567568
const [expiresAt, setExpiresAt] = useState<Date>();
@@ -572,8 +573,14 @@ function NewApiKeyDialog({
572573
const [createdApiKey, setCreatedApiKey] = useState<string>();
573574

574575
useEffect(() => {
575-
if (fetcher.state === "idle" && actionData?.ok && actionData.action === "create") {
576+
if (fetcher.state !== "idle") {
577+
return;
578+
}
579+
580+
if (actionData?.ok && actionData.action === "create") {
576581
setCreatedApiKey(actionData.apiKey);
582+
} else if (actionData && !actionData.ok) {
583+
setShowError(true);
577584
}
578585
}, [actionData, fetcher.state]);
579586

@@ -593,6 +600,7 @@ function NewApiKeyDialog({
593600
setTaskScope("all");
594601
setSelectedTasks([]);
595602
setCreatedApiKey(undefined);
603+
setShowError(false);
596604
}
597605
}}
598606
>
@@ -635,7 +643,7 @@ function NewApiKeyDialog({
635643
/>
636644
</div>
637645
) : (
638-
<fetcher.Form method="post">
646+
<fetcher.Form method="post" onSubmit={() => setShowError(false)}>
639647
<input type="hidden" name="action" value="create" />
640648
{expiresAt ? (
641649
<input type="hidden" name="expiresAt" value={expiresAt.toISOString()} />
@@ -741,7 +749,7 @@ function NewApiKeyDialog({
741749
</InputGroup>
742750
) : null}
743751

744-
{actionData && !actionData.ok ? (
752+
{showError && actionData && !actionData.ok ? (
745753
<Paragraph variant="small" className="text-error">
746754
{actionData.error}
747755
</Paragraph>

apps/webapp/test/publicTokensRoute.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ describe("POST /api/v1/auth/public-tokens", () => {
203203
// A single parse governs both the cap check and the claim.
204204
const exp = (validation as { payload: { exp: number } }).payload.exp;
205205
expect(exp).toBeGreaterThanOrEqual(before + 600);
206-
expect(exp).toBeLessThanOrEqual(before + 601);
206+
expect(exp).toBeLessThanOrEqual(before + 605);
207207
});
208208

209209
it("does not allow a public JWT bearer to mint another token", async () => {

0 commit comments

Comments
 (0)