refactor: migrate authentication routes to user router and update related components

This commit continues the refactoring of authentication-related code by:

- Moving authentication routes from `auth.ts` to `user.ts`
- Updating import paths and function calls across components
- Removing commented-out authentication code
- Simplifying user-related queries and mutations
- Updating server-side authentication handling
This commit is contained in:
Mauricio Siu
2025-02-22 22:02:12 -06:00
parent b00c12965a
commit 0478419f7c
30 changed files with 394 additions and 615 deletions

View File

@@ -1,17 +1,11 @@
import { appRouter } from "@/server/api/root";
import { createTRPCContext } from "@/server/api/trpc";
import { validateBearerToken, validateRequest } from "@dokploy/server";
import { validateRequest } from "@dokploy/server";
import { createOpenApiNextHandler } from "@dokploy/trpc-openapi";
import type { NextApiRequest, NextApiResponse } from "next";
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
let { session, user } = await validateBearerToken(req);
if (!session) {
const cookieResult = await validateRequest(req, res);
session = cookieResult.session;
user = cookieResult.user;
}
const { session, user } = await validateRequest(req);
if (!user || !session) {
res.status(401).json({ message: "Unauthorized" });

View File

@@ -52,7 +52,7 @@ export async function getServerSideProps(
});
await helpers.settings.isCloud.prefetch();
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
if (!user) {
return {
redirect: {

View File

@@ -52,7 +52,7 @@ export async function getServerSideProps(
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();

View File

@@ -45,7 +45,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -53,7 +53,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
return {
props: {

View File

@@ -46,7 +46,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -45,7 +45,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
try {
await helpers.project.all.prefetch();
await helpers.settings.isCloud.prefetch();

View File

@@ -209,7 +209,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
return {
props: {

View File

@@ -46,7 +46,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -1,6 +1,5 @@
import { GenerateToken } from "@/components/dashboard/settings/profile/generate-token";
import { ProfileForm } from "@/components/dashboard/settings/profile/profile-form";
import { RemoveSelfAccount } from "@/components/dashboard/settings/profile/remove-self-account";
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
import { appRouter } from "@/server/api/root";
@@ -15,14 +14,14 @@ import superjson from "superjson";
const Page = () => {
const { data } = api.user.get.useQuery();
const { data: isCloud } = api.settings.isCloud.useQuery();
// const { data: isCloud } = api.settings.isCloud.useQuery();
return (
<div className="w-full">
<div className="h-full rounded-xl max-w-5xl mx-auto flex flex-col gap-4">
<ProfileForm />
{(data?.canAccessToAPI || data?.role === "owner") && <GenerateToken />}
{isCloud && <RemoveSelfAccount />}
{/* {isCloud && <RemoveSelfAccount />} */}
</div>
</div>
);
@@ -53,15 +52,7 @@ export async function getServerSideProps(
});
await helpers.settings.isCloud.prefetch();
await helpers.auth.get.prefetch();
if (user?.role === "member") {
// const userR = await helpers.user.one.fetch({
// userId: user.id,
// });
// await helpers.user.byAuthId.prefetch({
// authId: user.authId,
// });
}
await helpers.user.get.prefetch();
if (!user) {
return {

View File

@@ -45,7 +45,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -110,7 +110,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
return {
props: {

View File

@@ -56,7 +56,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -50,7 +50,7 @@ export async function getServerSideProps(
},
transformer: superjson,
});
await helpers.auth.get.prefetch();
await helpers.user.get.prefetch();
await helpers.settings.isCloud.prefetch();
return {

View File

@@ -12,17 +12,13 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { db } from "@/server/db";
import { auth } from "@/server/db/schema";
import { api } from "@/utils/api";
import { authClient } from "@/lib/auth-client";
import { IS_CLOUD } from "@dokploy/server";
import { zodResolver } from "@hookform/resolvers/zod";
import { isBefore } from "date-fns";
import { eq } from "drizzle-orm";
import type { GetServerSidePropsContext } from "next";
import Link from "next/link";
import { useRouter } from "next/router";
import { type ReactElement, useEffect } from "react";
import { type ReactElement, useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
@@ -54,11 +50,12 @@ const loginSchema = z
type Login = z.infer<typeof loginSchema>;
interface Props {
token: string;
tokenResetPassword: string;
}
export default function Home({ token }: Props) {
const { mutateAsync, isLoading, isError, error } =
api.auth.resetPassword.useMutation();
export default function Home({ tokenResetPassword }: Props) {
const [token, setToken] = useState<string | null>(tokenResetPassword);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const router = useRouter();
const form = useForm<Login>({
defaultValues: {
@@ -68,26 +65,32 @@ export default function Home({ token }: Props) {
resolver: zodResolver(loginSchema),
});
useEffect(() => {
const token = new URLSearchParams(window.location.search).get("token");
if (token) {
setToken(token);
}
}, [token]);
useEffect(() => {
form.reset();
}, [form, form.reset, form.formState.isSubmitSuccessful]);
const onSubmit = async (values: Login) => {
await mutateAsync({
resetPasswordToken: token,
password: values.password,
})
.then((_data) => {
toast.success("Password reset successfully", {
duration: 2000,
});
router.push("/");
})
.catch(() => {
toast.error("Error resetting password", {
duration: 2000,
});
});
setIsLoading(true);
const { error } = await authClient.resetPassword({
newPassword: values.password,
token: token || "",
});
if (error) {
setError(error.message || "An error occurred");
} else {
toast.success("Password reset successfully");
router.push("/");
}
setIsLoading(false);
};
return (
<div className="flex h-screen w-full items-center justify-center ">
@@ -104,9 +107,9 @@ export default function Home({ token }: Props) {
<div className="w-full">
<CardContent className="p-0">
{isError && (
{error && (
<AlertBlock type="error" className="my-2">
{error?.message}
{error}
</AlertBlock>
)}
<Form {...form}>
@@ -194,35 +197,9 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
};
}
const authR = await db.query.auth.findFirst({
where: eq(auth.resetPasswordToken, token),
});
if (!authR || authR?.resetPasswordExpiresAt === null) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
const isExpired = isBefore(
new Date(authR.resetPasswordExpiresAt),
new Date(),
);
if (isExpired) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
return {
props: {
token: authR.resetPasswordToken,
tokenResetPassword: token,
},
};
}

View File

@@ -12,7 +12,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { authClient } from "@/lib/auth-client";
import { IS_CLOUD } from "@dokploy/server";
import { zodResolver } from "@hookform/resolvers/zod";
import type { GetServerSidePropsContext } from "next";
@@ -46,8 +46,9 @@ export default function Home() {
is2FAEnabled: false,
authId: "",
});
const { mutateAsync, isLoading, isError, error } =
api.auth.sendResetPasswordEmail.useMutation();
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const _router = useRouter();
const form = useForm<Login>({
defaultValues: {
@@ -61,19 +62,20 @@ export default function Home() {
}, [form, form.reset, form.formState.isSubmitSuccessful]);
const onSubmit = async (values: Login) => {
await mutateAsync({
setIsLoading(true);
const { error } = await authClient.forgetPassword({
email: values.email,
})
.then((_data) => {
toast.success("Email sent", {
duration: 2000,
});
})
.catch(() => {
toast.error("Error sending email", {
duration: 2000,
});
redirectTo: "/reset-password",
});
if (error) {
setError(error.message || "An error occurred");
setIsLoading(false);
} else {
toast.success("Email sent", {
duration: 2000,
});
}
setIsLoading(false);
};
return (
<div className="flex w-full items-center justify-center ">
@@ -89,9 +91,9 @@ export default function Home() {
<div className="mx-auto w-full max-w-lg bg-transparent ">
<CardContent className="p-0">
{isError && (
{error && (
<AlertBlock type="error" className="my-2">
{error?.message}
{error}
</AlertBlock>
)}
{!temp.is2FAEnabled ? (