Skip to content

Commit 73b888d

Browse files
drew-harrisskeptrunedev
authored andcommitted
fix: auth edge cases
1 parent 505b5d8 commit 73b888d

7 files changed

Lines changed: 87 additions & 78 deletions

File tree

frontends/dashboard/src/components/CreateNewOrgModal.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,11 @@ export const NewOrgModal = (props: NewOrgModalProps) => {
4646
throw new Error("Error creating new organization");
4747
}
4848

49-
void res.json().then((data) => {
49+
void res.json().then(async (data) => {
5050
// Refresh the user context with the new organization
5151
userContext.setSelectedOrg((data as Organization).id);
52-
userContext.login();
53-
// refresh window
54-
window.location.reload();
52+
await userContext.login();
53+
navigate("/org");
5554

5655
createToast({
5756
title: "Success",

frontends/dashboard/src/components/NewDatasetModal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const NewDatasetModal = (props: NewDatasetModalProps) => {
5858
message: "Successfully created dataset",
5959
});
6060
setIsLoading(false);
61+
await userContext.login();
6162
navigate(`/dataset/${dataset.id}`);
6263
} catch (e: unknown) {
6364
setIsLoading(false);

frontends/dashboard/src/components/ShowToasts.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const ShowToasts = () => {
6767
});
6868

6969
return (
70-
<div class="fixed right-5 top-10 z-50 flex flex-col space-y-2 rounded">
70+
<div class="fixed bottom-5 left-5 z-50 flex flex-col space-y-2 rounded">
7171
<For each={toastDetails()}>
7272
{(toastDetail) => (
7373
<div class="pointer-events-auto min-w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">

frontends/dashboard/src/components/dataset-settings/DangerZone.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ import { createMemo, createSignal, useContext, Show } from "solid-js";
22
import { DatasetContext } from "../../contexts/DatasetContext";
33
import { UserContext } from "../../contexts/UserContext";
44
import { createToast } from "../ShowToasts";
5+
import { useNavigate } from "@solidjs/router";
56

67
export const DangerZoneForm = () => {
78
const datasetContext = useContext(DatasetContext);
89
const userContext = useContext(UserContext);
910

11+
const navigate = useNavigate();
12+
1013
const [deleting, setDeleting] = createSignal(false);
1114

1215
const [confirmDeleteText, setConfirmDeleteText] = createSignal("");
@@ -40,7 +43,7 @@ export const DangerZoneForm = () => {
4043
})
4144
.then((res) => {
4245
if (res.ok) {
43-
window.location.href = `/dashboard/${organization_id}/overview`;
46+
navigate("/org");
4447
createToast({
4548
title: "Success",
4649
message: "Dataset deleted successfully!",
@@ -94,6 +97,7 @@ export const DangerZoneForm = () => {
9497
<>
9598
<Show when={datasetContext.dataset != null}>
9699
<form
100+
onSubmit={(e) => e.preventDefault()}
97101
class="rounded-md border border-red-600/20 shadow-sm shadow-red-500/30"
98102
id="danger-zone"
99103
>

frontends/dashboard/src/contexts/UserContext.tsx

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@ export interface UserStore {
3232
setSelectedOrg: (orgId: string) => void;
3333
orgDatasets: Resource<DatasetAndUsage[]>;
3434
deselectOrg: () => void;
35-
login: () => void;
35+
login: () => Promise<void>;
3636
logout: () => void;
3737
}
3838

3939
export const UserContext = createContext<UserStore>({
4040
user: () => null as unknown as SlimUser,
4141
isNewUser: () => false,
42-
login: () => {},
42+
login: () => {
43+
return Promise.resolve();
44+
},
4345
setSelectedOrg: () => {},
4446
orgDatasets: null as unknown as Resource<DatasetAndUsage[]>,
4547
deselectOrg: () => {},
@@ -79,49 +81,45 @@ export const UserContextWrapper = (props: UserStoreContextProps) => {
7981
});
8082
};
8183

82-
const login = () => {
83-
fetch(`${apiHost}/auth/me`, {
84-
credentials: "include",
85-
})
86-
.then((res) => {
87-
if (res.status === 401) {
88-
window.location.href = `${apiHost}/auth?redirect_uri=${window.origin}/`;
84+
const login = async () => {
85+
try {
86+
const res = await fetch(`${apiHost}/auth/me`, {
87+
credentials: "include",
88+
});
89+
if (res.status === 401) {
90+
window.location.href = `${apiHost}/auth?redirect_uri=${window.origin}/`;
91+
}
92+
const data = (await res.json()) as SlimUser;
93+
// cache the user
94+
window.localStorage.setItem("trieve:user", JSON.stringify(data));
95+
96+
// Grab org id from localstorage
97+
const possibleOrgId = window.localStorage.getItem(
98+
`${data.id}:selectedOrg`,
99+
);
100+
if (possibleOrgId) {
101+
const matchingOrg = data.orgs.find((org) => org.id === possibleOrgId);
102+
if (matchingOrg) {
103+
setSelectedOrganization(matchingOrg);
89104
}
90-
return res.json();
91-
})
92-
.then((data: SlimUser) => {
93-
// cache the user
94-
window.localStorage.setItem("trieve:user", JSON.stringify(data));
95-
96-
// Grab org id from localstorage
97-
const possibleOrgId = window.localStorage.getItem(
98-
`${data.id}:selectedOrg`,
99-
);
100-
if (possibleOrgId) {
101-
const matchingOrg = data.orgs.find((org) => org.id === possibleOrgId);
102-
if (matchingOrg) {
103-
setSelectedOrganization(matchingOrg);
104-
}
105+
} else {
106+
const firstOrg = data.orgs.at(0);
107+
if (firstOrg) {
108+
setSelectedOrganization(firstOrg);
105109
} else {
106-
const firstOrg = data.orgs.at(0);
107-
if (firstOrg) {
108-
setSelectedOrganization(firstOrg);
109-
} else {
110-
redirect("/dashboard/new_user");
111-
}
110+
redirect("/dashboard/new_user");
112111
}
113-
114-
setUser(data);
115-
})
116-
.catch((err) => {
117-
setUser(null);
118-
console.error(err);
119-
createToast({
120-
title: "Error",
121-
type: "error",
122-
message: "Error logging in",
123-
});
112+
}
113+
setUser(data);
114+
} catch (err) {
115+
setUser(null);
116+
console.error(err);
117+
createToast({
118+
title: "Error",
119+
type: "error",
120+
message: "Error logging in",
124121
});
122+
}
125123
};
126124

127125
createEffect(() => {
@@ -151,7 +149,7 @@ export const UserContextWrapper = (props: UserStoreContextProps) => {
151149
};
152150

153151
createEffect(() => {
154-
login();
152+
void login();
155153
});
156154

157155
const deselectOrg = () => {

frontends/dashboard/src/layouts/NavbarLayout.tsx

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,45 @@ import { JSX } from "solid-js";
22
import { A } from "@solidjs/router";
33
import { BiRegularLinkExternal } from "solid-icons/bi";
44
import { NavbarOrgWidget } from "../components/NavbarOrgWidget";
5+
import ShowToasts from "../components/ShowToasts";
56

67
interface NavbarLayoutProps {
78
children?: JSX.Element;
89
}
910
export const NavbarLayout = (props: NavbarLayoutProps) => {
1011
return (
11-
<div class="flex h-screen min-h-screen flex-col">
12-
<div class="flex justify-between gap-3 border-b border-b-neutral-300 p-2 px-4 shadow-md">
13-
<div class="flex items-center gap-8">
14-
<A href="/" class="flex items-center gap-1">
15-
<img
16-
class="h-12 w-12 cursor-pointer"
17-
src="https://cdn.trieve.ai/trieve-logo.png"
18-
alt="Logo"
19-
/>
20-
<span class="text-2xl font-semibold">Trieve</span>
21-
</A>
22-
{/* This is portaled by the DatasetSidebarLayout so you can only select a dataset when you are in the dataset view*/}
23-
<div id="dataset-slot" />
12+
<>
13+
<ShowToasts />
14+
<div class="flex h-screen min-h-screen flex-col">
15+
<div class="flex justify-between gap-3 border-b border-b-neutral-300 p-2 px-4 shadow-md">
16+
<div class="flex items-center gap-8">
17+
<A href="/" class="flex items-center gap-1">
18+
<img
19+
class="h-12 w-12 cursor-pointer"
20+
src="https://cdn.trieve.ai/trieve-logo.png"
21+
alt="Logo"
22+
/>
23+
<span class="text-2xl font-semibold">Trieve</span>
24+
</A>
25+
{/* This is portaled by the DatasetSidebarLayout so you can only select a dataset when you are in the dataset view*/}
26+
<div id="dataset-slot" />
27+
</div>
28+
<div class="flex items-center justify-end gap-3">
29+
<a
30+
class="flex items-center gap-2 rounded-md border bg-neutral-100 px-2 py-1 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-600"
31+
href="https://docs.trieve.ai"
32+
target="_blank"
33+
>
34+
<p>API Docs</p>
35+
<BiRegularLinkExternal class="opacity-80" />
36+
</a>
37+
<NavbarOrgWidget />
38+
</div>
2439
</div>
25-
<div class="flex items-center justify-end gap-3">
26-
<a
27-
class="flex items-center gap-2 rounded-md border bg-neutral-100 px-2 py-1 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-600"
28-
href="https://docs.trieve.ai"
29-
target="_blank"
30-
>
31-
<p>API Docs</p>
32-
<BiRegularLinkExternal class="opacity-80" />
33-
</a>
34-
<NavbarOrgWidget />
40+
<div class="flex grow flex-col overflow-scroll bg-neutral-100">
41+
{props.children}
3542
</div>
3643
</div>
37-
<div class="flex grow flex-col overflow-scroll bg-neutral-100">
38-
{props.children}
39-
</div>
40-
</div>
44+
</>
4145
);
4246
};

frontends/dashboard/src/pages/OrgSelect.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { createQuery } from "@tanstack/solid-query";
2-
import { useTrieve } from "../hooks/useTrieve";
31
import { Organization } from "trieve-ts-sdk";
42
import { For } from "solid-js";
3+
import { useNavigate } from "@solidjs/router";
54

65
interface OrgsSelectProps {
76
orgs: Organization[];
87
selectOrg: (orgId: string) => void;
98
}
109

1110
export const OrgSelectPage = (props: OrgsSelectProps) => {
11+
const navigate = useNavigate();
1212
return (
1313
<div class="relative flex min-h-screen flex-col items-center bg-neutral-200 py-36">
1414
<div class="absolute left-4 top-2 mb-8 flex items-center gap-1">
@@ -25,7 +25,10 @@ export const OrgSelectPage = (props: OrgsSelectProps) => {
2525
<For each={props.orgs}>
2626
{(org) => (
2727
<button
28-
onClick={() => props.selectOrg(org.id)}
28+
onClick={() => {
29+
props.selectOrg(org.id);
30+
navigate("/org");
31+
}}
2932
class="flex cursor-pointer items-center justify-between rounded-md border-b border-b-neutral-200 p-2 last:border-b-transparent hover:bg-neutral-100"
3033
>
3134
<div class="flex w-full items-center justify-between">

0 commit comments

Comments
 (0)