Matt
Matt
Explore posts from servers
BABetter Auth
Created by Matt on 1/9/2025 in #help
getFullOrganization Returns Data for Non-Members
I have two functions for listing organizations and getting one by slug
export const listOrganizations = cache(async () => {
const organizations = await auth.api.listOrganizations({
headers: await headers(),
});
return organizations;
});

export const getOrganizationBySlug = cache(async (slug: string) => {
const organization = await auth.api.getFullOrganization({
query: {
organizationSlug: slug,
},
headers: await headers(),
});
return organization;
});
export const listOrganizations = cache(async () => {
const organizations = await auth.api.listOrganizations({
headers: await headers(),
});
return organizations;
});

export const getOrganizationBySlug = cache(async (slug: string) => {
const organization = await auth.api.getFullOrganization({
query: {
organizationSlug: slug,
},
headers: await headers(),
});
return organization;
});
Calling them on a simple layout.tsx returns data for the user if they guess the right slug, even if they're not a member of the organization. I would have thought it would error or throw unauth/forbidden? I could of course guard around it on my side but just assume it would be the default.
import { ReactNode } from "react";
import OrganizationAuth from "./auth";
import {
getOrganizationBySlug,
listOrganizations,
} from "@/lib/_queries/organization";

type Params = Promise<{ slug: string }>;

export default async function OrganizationLayout({
children,
params,
}: {
children: ReactNode;
params: Params;
}) {
const { slug } = await params;
const [organization, organizations] = await Promise.all([
getOrganizationBySlug(slug),
listOrganizations(),
]);
console.log(organization?.id);
console.log(organizations);

return <OrganizationAuth>{children}</OrganizationAuth>;
}
import { ReactNode } from "react";
import OrganizationAuth from "./auth";
import {
getOrganizationBySlug,
listOrganizations,
} from "@/lib/_queries/organization";

type Params = Promise<{ slug: string }>;

export default async function OrganizationLayout({
children,
params,
}: {
children: ReactNode;
params: Params;
}) {
const { slug } = await params;
const [organization, organizations] = await Promise.all([
getOrganizationBySlug(slug),
listOrganizations(),
]);
console.log(organization?.id);
console.log(organizations);

return <OrganizationAuth>{children}</OrganizationAuth>;
}
console logs
019432ee-f55f-7424-a42f-9e3e1600fde5 <- orgId from getOrganizationBySlug isn't in the listOrganizations() return below
[
{
id: '0194427a-393f-7527-b7f3-512d93f64210',
name: 'Org 1',
slug: 'org-1',
logo: null,
createdAt: 2025-01-07T20:34:53.887Z,
metadata: null
}
]
019432ee-f55f-7424-a42f-9e3e1600fde5 <- orgId from getOrganizationBySlug isn't in the listOrganizations() return below
[
{
id: '0194427a-393f-7527-b7f3-512d93f64210',
name: 'Org 1',
slug: 'org-1',
logo: null,
createdAt: 2025-01-07T20:34:53.887Z,
metadata: null
}
]
1 replies
TTCTheo's Typesafe Cult
Created by Matt on 7/10/2024 in #questions
Guidance on Client Refresh after Server Action
Hey all, just looking for some guidance or maybe a push in the right direction on how to handle the client side after a revalidatetag/revalidatepath options in a server component. I have the video below that's drawer component getting a promise passed to it then using React.use on the client. Put some of the code below to follow all the way through but wanted to see if there's any thoughts. I'm initially thinking that it's not possible and have to use something client side like SWR but wanted to at least ask and see if anyone has something simple I'm just missing... page.tsx
export default async function Page({params}: PageProps) {
const promise = getPromise(params.slug)
return (
<ClientComponent promise={promise} />
)
export default async function Page({params}: PageProps) {
const promise = getPromise(params.slug)
return (
<ClientComponent promise={promise} />
)
client-component.tsx
export default function ClientComponent({promise}: ClientProps) {
const { Drawer, setShowDrawer } = useDrawer(promise)
const { item1, item2 } = React.use(promise)

return (
<Drawer />
<Card>
...
<Button onClick{() => {setShowDrawer(true)}>Config</Button>
</Card>
)
}
export default function ClientComponent({promise}: ClientProps) {
const { Drawer, setShowDrawer } = useDrawer(promise)
const { item1, item2 } = React.use(promise)

return (
<Drawer />
<Card>
...
<Button onClick{() => {setShowDrawer(true)}>Config</Button>
</Card>
)
}
drawer-component.tsx
function DrawerComponent ({promise, showDrawer, setShowDrawer}: DrawerProps) {
const [isPending, startTransition] = React.useTransition();
const { item1, item2 } = React.use(promise)

function onSubmit(inputs) {
startTransition(async () => {
const { data, error } = await createDirectory(item1, ...inputs)
if (error) {
toast.error
setShowDrawer(false)
}
if (data) { toast.success }
}

const Content = (
<Form {...form}>
<form
onSubmit={(...args) => void form.handleSubmit(onSubmit)(...args)}
>
...
</form>
</Form>
return (
<Drawer>
{Content}
</Drawer>
)
}
function DrawerComponent ({promise, showDrawer, setShowDrawer}: DrawerProps) {
const [isPending, startTransition] = React.useTransition();
const { item1, item2 } = React.use(promise)

function onSubmit(inputs) {
startTransition(async () => {
const { data, error } = await createDirectory(item1, ...inputs)
if (error) {
toast.error
setShowDrawer(false)
}
if (data) { toast.success }
}

const Content = (
<Form {...form}>
<form
onSubmit={(...args) => void form.handleSubmit(onSubmit)(...args)}
>
...
</form>
</Form>
return (
<Drawer>
{Content}
</Drawer>
)
}
actions.ts
export async function createDirectory(item1, inputs) {
noStore()
...
revalidatePath('/path')
return {
data: data
error: null
}
export async function createDirectory(item1, inputs) {
noStore()
...
revalidatePath('/path')
return {
data: data
error: null
}
17 replies
DTDrizzle Team
Created by Matt on 3/27/2024 in #help
Upsert Multiple Rows with Conflicts postgres
Is there a way to upsert multiple rows when there could be conflicts on some of the rows? I have this code I tried below but spreading out the userValues in the set doesn't work of course, the usersValue is an array of users that could contain information about new users or existing users with new information. Is there a way to do it all in this one command or do I need to break it down before attempting the db insert?
await db
.insert(users)
.values(userValues)
.onConflictDoUpdate({
target: users.UserId,
set: {
...userValues,
updatedAt: new Date(),
},
});
await db
.insert(users)
.values(userValues)
.onConflictDoUpdate({
target: users.UserId,
set: {
...userValues,
updatedAt: new Date(),
},
});
13 replies