Skip to content

Commit 724a7bb

Browse files
committed
feat(engine): ask for token when unauth
1 parent 6569c9f commit 724a7bb

25 files changed

+482
-91
lines changed

frontend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@
5050
"@radix-ui/react-tooltip": "^1.1.1",
5151
"@radix-ui/react-visually-hidden": "^1.0.3",
5252
"@rivet-gg/icons": "file:./vendor/rivet-icons.tgz",
53-
"@rivetkit/actor": "file:./vendor/rivetkit-actor.tgz",
54-
"@rivetkit/core": "file:./vendor/rivetkit-core.tgz",
53+
"rivetkit": "*",
5554
"@rivetkit/engine-api-full": "workspace:*",
5655
"@sentry/react": "^8.26.0",
5756
"@sentry/vite-plugin": "^2.22.2",

frontend/src/app.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ declare module "@tanstack/react-router" {
2222
}
2323
}
2424

25+
declare module "@tanstack/react-query" {
26+
interface Register {
27+
queryMeta: {
28+
mightRequireAuth?: boolean;
29+
};
30+
}
31+
}
32+
2533
export const router = createRouter({
2634
basepath: import.meta.env.BASE_URL,
2735
routeTree,
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as EngineCredentialsForm from "@/app/forms/engine-credentials-form";
2+
import {
3+
DialogDescription,
4+
DialogFooter,
5+
DialogHeader,
6+
DialogTitle,
7+
Flex,
8+
getConfig,
9+
ls,
10+
toast,
11+
} from "@/components";
12+
import { queryClient } from "@/queries/global";
13+
import { createClient } from "@/queries/manager-engine";
14+
15+
export default function ProvideEngineCredentialsDialogContent() {
16+
return (
17+
<EngineCredentialsForm.Form
18+
defaultValues={{ token: "" }}
19+
errors={
20+
ls.engineCredentials.get(getConfig().apiUrl)
21+
? { token: { message: "Invalid token.", type: "manual" } }
22+
: {}
23+
}
24+
onSubmit={async (values, form) => {
25+
const client = createClient({
26+
token: values.token,
27+
});
28+
29+
try {
30+
await client.namespaces.list();
31+
32+
await queryClient.invalidateQueries({
33+
refetchType: "active",
34+
});
35+
36+
ls.engineCredentials.set(getConfig().apiUrl, values.token);
37+
38+
toast.success(
39+
"Successfully authenticated with Rivet Engine",
40+
);
41+
} catch (e) {
42+
if (e && typeof e === "object" && "statusCode" in e) {
43+
if (e.statusCode === 403) {
44+
form.setError("token", {
45+
message: "Invalid token.",
46+
});
47+
return;
48+
}
49+
}
50+
51+
form.setError("token", {
52+
message: "Failed to connect. Please try again.",
53+
});
54+
return;
55+
}
56+
}}
57+
>
58+
<DialogHeader>
59+
<DialogTitle>Missing Rivet Engine credentials</DialogTitle>
60+
<DialogDescription>
61+
It looks like the instance of Rivet Engine that you're
62+
connected to requires additional credentials, please provide
63+
them below.
64+
</DialogDescription>
65+
</DialogHeader>
66+
<Flex gap="4" direction="col">
67+
<EngineCredentialsForm.Token />
68+
</Flex>
69+
<DialogFooter>
70+
<EngineCredentialsForm.Submit type="submit" allowPristine>
71+
Save
72+
</EngineCredentialsForm.Submit>
73+
</DialogFooter>
74+
</EngineCredentialsForm.Form>
75+
);
76+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { type UseFormReturn, useFormContext } from "react-hook-form";
2+
import z from "zod";
3+
import {
4+
createSchemaForm,
5+
FormControl,
6+
FormField,
7+
FormItem,
8+
FormLabel,
9+
FormMessage,
10+
Input,
11+
} from "@/components";
12+
13+
export const formSchema = z.object({
14+
token: z.string().nonempty("Token is required"),
15+
});
16+
17+
export type FormValues = z.infer<typeof formSchema>;
18+
export type SubmitHandler = (
19+
values: FormValues,
20+
form: UseFormReturn<FormValues>,
21+
) => Promise<void>;
22+
23+
const { Form, Submit, SetValue } = createSchemaForm(formSchema);
24+
export { Form, Submit, SetValue };
25+
26+
export const Token = ({ className }: { className?: string }) => {
27+
const { control } = useFormContext<FormValues>();
28+
return (
29+
<FormField
30+
control={control}
31+
name="token"
32+
render={({ field }) => (
33+
<FormItem className={className}>
34+
<FormLabel className="col-span-1">Token</FormLabel>
35+
<FormControl className="row-start-2">
36+
<Input
37+
placeholder="Enter a token..."
38+
type="password"
39+
{...field}
40+
/>
41+
</FormControl>
42+
<FormMessage className="col-span-1" />
43+
</FormItem>
44+
)}
45+
/>
46+
);
47+
};

frontend/src/app/use-dialog.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import { createDialogHook, useDialog } from "@/components/actors";
1+
import {
2+
useDialog as baseUseDialog,
3+
createDialogHook,
4+
} from "@/components/actors";
25

3-
const d = useDialog as typeof useDialog &
4-
Record<string, ReturnType<typeof createDialogHook>>;
5-
d.CreateNamespace = createDialogHook(
6-
import("@/app/dialogs/create-namespace-dialog"),
7-
);
8-
9-
export { d as useDialog };
6+
export const useDialog = {
7+
...baseUseDialog,
8+
CreateNamespace: createDialogHook(
9+
import("@/app/dialogs/create-namespace-dialog"),
10+
),
11+
ProvideEngineCredentials: createDialogHook(
12+
import("@/app/dialogs/provide-engine-credentials-dialog"),
13+
),
14+
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export {
22
createActorInspectorClient,
33
createManagerInspectorClient,
4-
} from "@rivetkit/core/inspector";
4+
} from "rivetkit/inspector";

frontend/src/components/actors/actor-events-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import {
66
faUnlink,
77
Icon,
88
} from "@rivet-gg/icons";
9-
import type { RecordedRealtimeEvent } from "@rivetkit/core/inspector";
109
import { useQuery } from "@tanstack/react-query";
1110
import { format } from "date-fns";
1211
import { type PropsWithChildren, useEffect, useRef } from "react";
12+
import type { RecordedRealtimeEvent } from "rivetkit/inspector";
1313
import { Badge } from "../ui/badge";
1414
import { useActor } from "./actor-queries-context";
1515
import { ActorObjectInspector } from "./console/actor-inspector";

frontend/src/components/actors/actor-queries-context.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { createActorInspectorClient } from "@rivetkit/core/inspector";
21
import { queryOptions } from "@tanstack/react-query";
32
import { createContext, useContext } from "react";
3+
import { createActorInspectorClient } from "rivetkit/inspector";
44
import type { ActorId } from "./queries";
55

66
type RequestOptions = Parameters<typeof createActorInspectorClient>[1];

frontend/src/components/actors/database/database-table.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
faLink,
66
Icon,
77
} from "@rivet-gg/icons";
8-
import type { Column, Columns, ForeignKeys } from "@rivetkit/core/inspector";
98
import {
109
createColumnHelper,
1110
// SortingState,
@@ -19,6 +18,7 @@ import {
1918
useReactTable as useTable,
2019
} from "@tanstack/react-table";
2120
import { Fragment, useMemo, useState } from "react";
21+
import type { Column, Columns, ForeignKeys } from "rivetkit/inspector";
2222
import {
2323
Badge,
2424
Button,

frontend/src/components/actors/manager-context.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { CreateActor as InspectorCreateActor } from "@rivetkit/core/inspector";
21
import {
32
infiniteQueryOptions,
43
type MutationOptions,
54
type QueryClient,
65
queryOptions,
76
} from "@tanstack/react-query";
87
import { createContext, useContext } from "react";
8+
import type { CreateActor as InspectorCreateActor } from "rivetkit/inspector";
99
import { z } from "zod";
1010
import { queryClient } from "@/queries/global";
1111
import {

0 commit comments

Comments
 (0)