mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 22:02:00 +00:00
Refactor authentication actions and add user verification functionality
- Updated signin and signup actions to correctly handle phone number redirection and date of birth formatting. - Introduced a new user-actions file to implement user verification logic. - Added an auth guard to restrict access based on user roles. - Enhanced the auth configuration to include user roles and language settings. - Improved validation schemas for user input in the signup form.
This commit is contained in:
parent
1b43c85491
commit
3f68d835fe
@ -44,7 +44,9 @@ export async function signin(previousState: ActionState, formData: FormData) {
|
|||||||
await authClient.phoneNumber.sendOtp({
|
await authClient.phoneNumber.sendOtp({
|
||||||
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
||||||
});
|
});
|
||||||
redirect(`/verify-otp?phone_number=${encodeURIComponent(phoneNumber)}`);
|
redirect(
|
||||||
|
`/verify-otp?phone_number=${encodeURIComponent(NUMBER_WITH_COUNTRY_CODE)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionState = {
|
type ActionState = {
|
||||||
@ -112,16 +114,17 @@ export async function signup(_actionState: ActionState, formData: FormData) {
|
|||||||
atollId: parsedData.data.atoll_id,
|
atollId: parsedData.data.atoll_id,
|
||||||
house_name: parsedData.data.house_name,
|
house_name: parsedData.data.house_name,
|
||||||
id_card: parsedData.data.id_card,
|
id_card: parsedData.data.id_card,
|
||||||
dob: parsedData.data.dob,
|
dob: new Date(parsedData.data.dob),
|
||||||
|
role: "USER",
|
||||||
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await authClient.phoneNumber.sendOtp({
|
await authClient.phoneNumber.sendOtp({
|
||||||
phoneNumber: newUser.phoneNumber,
|
phoneNumber: newUser.phoneNumber,
|
||||||
});
|
});
|
||||||
// redirect(
|
redirect(
|
||||||
// `/verify-otp?phone_number=${encodeURIComponent(newUser.phoneNumber)}`,
|
`/verify-otp?phone_number=${encodeURIComponent(newUser.phoneNumber)}`,
|
||||||
// );
|
);
|
||||||
|
|
||||||
return { message: "Post created" };
|
return { message: "Post created" };
|
||||||
}
|
}
|
||||||
|
25
actions/user-actions.ts
Normal file
25
actions/user-actions.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import prisma from "@/lib/db";
|
||||||
|
import { revalidatePath } from "next/cache";
|
||||||
|
|
||||||
|
export async function VerifyUser(userId: string) {
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!user) {
|
||||||
|
throw new Error("User not found");
|
||||||
|
}
|
||||||
|
user.verified = true;
|
||||||
|
await prisma.user.update({
|
||||||
|
where: {
|
||||||
|
id: userId,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
verified: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
revalidatePath("/users");
|
||||||
|
}
|
13
lib/auth-guard.ts
Normal file
13
lib/auth-guard.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { auth } from "@/lib/auth";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
import { headers } from "next/headers";
|
||||||
|
|
||||||
|
const session = await auth.api.getSession({
|
||||||
|
headers: await headers(),
|
||||||
|
});
|
||||||
|
export async function AdminAuthGuard() {
|
||||||
|
if (session?.user.role !== "ADMIN") {
|
||||||
|
return redirect("/login");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
15
lib/auth.ts
15
lib/auth.ts
@ -6,6 +6,21 @@ import { phoneNumber } from "better-auth/plugins";
|
|||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
|
user: {
|
||||||
|
additionalFields: {
|
||||||
|
role: {
|
||||||
|
type: "string",
|
||||||
|
required: false,
|
||||||
|
defaultValue: "USER",
|
||||||
|
input: false, // don't allow user to set role
|
||||||
|
},
|
||||||
|
lang: {
|
||||||
|
type: "string",
|
||||||
|
required: false,
|
||||||
|
defaultValue: "en",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
database: prismaAdapter(prisma, {
|
database: prismaAdapter(prisma, {
|
||||||
provider: "sqlite", // or "mysql", "postgresql", ...etc
|
provider: "sqlite", // or "mysql", "postgresql", ...etc
|
||||||
}),
|
}),
|
||||||
|
@ -6,8 +6,14 @@ export const signUpFormSchema = z.object({
|
|||||||
.min(2, { message: "ID Card is required" })
|
.min(2, { message: "ID Card is required" })
|
||||||
.regex(/^[A][0-9]{6}$/, "Please enter a valid ID Card number."),
|
.regex(/^[A][0-9]{6}$/, "Please enter a valid ID Card number."),
|
||||||
atoll_id: z.string().min(2, { message: "Atoll is required." }),
|
atoll_id: z.string().min(2, { message: "Atoll is required." }),
|
||||||
island_id: z.string().min(2, { message: "Island is required." }),
|
island_id: z
|
||||||
|
.string({ required_error: "Island is required." })
|
||||||
|
.min(2, { message: "Island is required." }),
|
||||||
house_name: z.string().min(2, { message: "House name is required." }),
|
house_name: z.string().min(2, { message: "House name is required." }),
|
||||||
dob: z.coerce.date({ message: "Date of birth is required." }),
|
dob: z.coerce.date({ message: "Date of birth is required." }),
|
||||||
phone_number: z.string().min(7, { message: "Phone number is required." }).regex(/^[79][0-9]{2}[0-9]{4}$/, "Please enter a valid phone number").transform((val) => val.replace(/\D/g, "")),
|
phone_number: z
|
||||||
|
.string()
|
||||||
|
.min(7, { message: "Phone number is required." })
|
||||||
|
.regex(/^[79][0-9]{2}[0-9]{4}$/, "Please enter a valid phone number")
|
||||||
|
.transform((val) => val.replace(/\D/g, "")),
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user