Merge pull request #3931 from Dokploy/3928-foreign-key-constraint-violation-on-git_provider-during-github-setup-userid-is-empty---v0284

refactor: replace authClient with api.user.session.useQuery in multip…
This commit is contained in:
Mauricio Siu
2026-03-07 18:23:29 -06:00
committed by GitHub
6 changed files with 29 additions and 14 deletions

View File

@@ -23,7 +23,6 @@ import {
CommandList, CommandList,
CommandSeparator, CommandSeparator,
} from "@/components/ui/command"; } from "@/components/ui/command";
import { authClient } from "@/lib/auth-client";
import { api } from "@/utils/api"; import { api } from "@/utils/api";
import { StatusTooltip } from "../shared/status-tooltip"; import { StatusTooltip } from "../shared/status-tooltip";
@@ -56,7 +55,7 @@ export const SearchCommand = () => {
const router = useRouter(); const router = useRouter();
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [search, setSearch] = React.useState(""); const [search, setSearch] = React.useState("");
const { data: session } = authClient.useSession(); const { data: session } = api.user.session.useQuery();
const { data } = api.project.all.useQuery(undefined, { const { data } = api.project.all.useQuery(undefined, {
enabled: !!session, enabled: !!session,
}); });

View File

@@ -12,14 +12,13 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { authClient } from "@/lib/auth-client";
import { api } from "@/utils/api"; import { api } from "@/utils/api";
export const AddGithubProvider = () => { export const AddGithubProvider = () => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const { data: activeOrganization } = api.organization.active.useQuery(); const { data: activeOrganization } = api.organization.active.useQuery();
const { data: session } = authClient.useSession(); const { data: session } = api.user.session.useQuery();
const { data } = api.user.get.useQuery(); const { data } = api.user.get.useQuery();
const [manifest, setManifest] = useState(""); const [manifest, setManifest] = useState("");
const [isOrganization, setIsOrganization] = useState(false); const [isOrganization, setIsOrganization] = useState(false);
@@ -99,8 +98,8 @@ export const AddGithubProvider = () => {
<form <form
action={ action={
isOrganization isOrganization
? `https://github.com/organizations/${organizationName}/settings/apps/new?state=gh_init:${activeOrganization?.id}` ? `https://github.com/organizations/${organizationName}/settings/apps/new?state=gh_init:${activeOrganization?.id}:${session?.user?.id ?? ""}`
: `https://github.com/settings/apps/new?state=gh_init:${activeOrganization?.id}` : `https://github.com/settings/apps/new?state=gh_init:${activeOrganization?.id}:${session?.user?.id ?? ""}`
} }
method="post" method="post"
> >

View File

@@ -37,7 +37,7 @@ export const ShowUsers = () => {
const { mutateAsync } = api.user.remove.useMutation(); const { mutateAsync } = api.user.remove.useMutation();
const utils = api.useUtils(); const utils = api.useUtils();
const { data: session } = authClient.useSession(); const { data: session } = api.user.session.useQuery();
return ( return (
<div className="w-full"> <div className="w-full">

View File

@@ -546,7 +546,7 @@ function SidebarLogo() {
const { state } = useSidebar(); const { state } = useSidebar();
const { data: isCloud } = api.settings.isCloud.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery();
const { data: user } = api.user.get.useQuery(); const { data: user } = api.user.get.useQuery();
const { data: session } = authClient.useSession(); const { data: session } = api.user.session.useQuery();
const { const {
data: organizations, data: organizations,
refetch, refetch,

View File

@@ -10,22 +10,29 @@ type Query = {
state: string; state: string;
installation_id: string; installation_id: string;
setup_action: string; setup_action: string;
userId: string;
}; };
export default async function handler( export default async function handler(
req: NextApiRequest, req: NextApiRequest,
res: NextApiResponse, res: NextApiResponse,
) { ) {
const { code, state, installation_id, userId }: Query = req.query as Query; const { code, state, installation_id }: Query = req.query as Query;
if (!code) { if (!code) {
return res.status(400).json({ error: "Missing code parameter" }); return res.status(400).json({ error: "Missing code parameter" });
} }
const [action, value] = state?.split(":"); const [action, ...rest] = state?.split(":");
// Value could be the organizationId or the githubProviderId // For gh_init: rest[0] = organizationId, rest[1] = userId
// For gh_setup: rest[0] = githubProviderId
if (action === "gh_init") { if (action === "gh_init") {
const organizationId = rest[0];
const userId = rest[1] || (req.query.userId as string);
if (!userId) {
return res.status(400).json({ error: "Missing userId parameter" });
}
const octokit = new Octokit({}); const octokit = new Octokit({});
const { data } = await octokit.request( const { data } = await octokit.request(
"POST /app-manifests/{code}/conversions", "POST /app-manifests/{code}/conversions",
@@ -44,7 +51,7 @@ export default async function handler(
githubWebhookSecret: data.webhook_secret, githubWebhookSecret: data.webhook_secret,
githubPrivateKey: data.pem, githubPrivateKey: data.pem,
}, },
value as string, organizationId as string,
userId, userId,
); );
} else if (action === "gh_setup") { } else if (action === "gh_setup") {
@@ -53,7 +60,7 @@ export default async function handler(
.set({ .set({
githubInstallationId: installation_id, githubInstallationId: installation_id,
}) })
.where(eq(github.githubId, value as string)) .where(eq(github.githubId, rest[0] as string))
.returning(); .returning();
} }

View File

@@ -101,6 +101,16 @@ export const userRouter = createTRPCRouter({
return memberResult; return memberResult;
}), }),
session: protectedProcedure.query(async ({ ctx }) => {
return {
user: {
id: ctx.user.id,
},
session: {
activeOrganizationId: ctx.session.activeOrganizationId,
},
};
}),
get: protectedProcedure.query(async ({ ctx }) => { get: protectedProcedure.query(async ({ ctx }) => {
const memberResult = await db.query.member.findFirst({ const memberResult = await db.query.member.findFirst({
where: and( where: and(