mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-07-14 22:45:50 +00:00
Enhance user verification and data validation features
- Updated `next.config.ts` to include remote image patterns for user verification. - Introduced `VerifyUserDetails` function in `lib/person.ts` to validate user data against national records. - Added `usePerson` hook for fetching national data based on ID card. - Enhanced `signup` and `signin` functions in `auth-actions.ts` to handle user verification status and send notifications for pending verifications. - Refactored `VerifyUser` function in `user-actions.ts` to incorporate national data validation. - Improved UI components in the user verification page to display both database and national information. - Updated `InputReadOnly` component to support customizable label classes for better styling. These changes improve the user verification process, ensuring data integrity and enhancing the overall user experience.
This commit is contained in:
@ -2,11 +2,13 @@
|
||||
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import prisma from "@/lib/db";
|
||||
import VerifyUserDetails from "@/lib/person";
|
||||
import { signUpFormSchema } from "@/lib/schemas";
|
||||
import { headers } from "next/headers";
|
||||
// import type { User } from "@prisma/client";
|
||||
import { redirect } from "next/navigation";
|
||||
import { z } from "zod";
|
||||
import { SendUserRejectionDetailSMS } from "./user-actions";
|
||||
const formSchema = z.object({
|
||||
phoneNumber: z
|
||||
.string()
|
||||
@ -41,6 +43,14 @@ export async function signin(previousState: ActionState, formData: FormData) {
|
||||
if (!userExists) {
|
||||
return redirect(`/signup?phone_number=${phoneNumber}`);
|
||||
}
|
||||
|
||||
if (!userExists?.verified)
|
||||
return {
|
||||
message:
|
||||
"Your account is on pending verification. Please wait for a response from admin or contact shihaam.",
|
||||
status: "error",
|
||||
};
|
||||
|
||||
await authClient.phoneNumber.sendOtp({
|
||||
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
||||
});
|
||||
@ -79,6 +89,7 @@ export async function signup(_actionState: ActionState, formData: FormData) {
|
||||
NUMBER_WITH_COUNTRY_CODE = `+960${parsedData.data.phone_number.split("-").join("")}`;
|
||||
}
|
||||
console.log({ NUMBER_WITH_COUNTRY_CODE });
|
||||
|
||||
const idCardExists = await prisma.user.findFirst({
|
||||
where: {
|
||||
id_card: parsedData.data.id_card,
|
||||
@ -120,14 +131,39 @@ export async function signup(_actionState: ActionState, formData: FormData) {
|
||||
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
||||
},
|
||||
});
|
||||
await authClient.phoneNumber.sendOtp({
|
||||
phoneNumber: newUser.phoneNumber,
|
||||
});
|
||||
const isValidPerson = await VerifyUserDetails({ user: newUser });
|
||||
|
||||
if (!isValidPerson) {
|
||||
await SendUserRejectionDetailSMS({
|
||||
details: `
|
||||
A new user has requested for verification.
|
||||
USER DETAILS:
|
||||
Name: ${parsedData.data.name}
|
||||
Address: ${parsedData.data.address}
|
||||
ID Card: ${parsedData.data.id_card}
|
||||
DOB: ${parsedData.data.dob}
|
||||
ACC No: ${parsedData.data.accNo}
|
||||
Verify the user with the folloiwing link: ${process.env.BETTER_AUTH_URL}/users/${newUser.id}/verify
|
||||
`,
|
||||
phoneNumber: process.env.ADMIN_PHONENUMBER ?? "",
|
||||
});
|
||||
return {
|
||||
message:
|
||||
"Your account has been requested for verification. Please wait for a response from admin.",
|
||||
payload: formData,
|
||||
db_error: "invalidPersonValidation",
|
||||
};
|
||||
}
|
||||
|
||||
if (isValidPerson) {
|
||||
await authClient.phoneNumber.sendOtp({
|
||||
phoneNumber: newUser.phoneNumber,
|
||||
});
|
||||
}
|
||||
redirect(
|
||||
`/verify-otp?phone_number=${encodeURIComponent(newUser.phoneNumber)}`,
|
||||
);
|
||||
|
||||
return { message: "Post created" };
|
||||
return { message: "User created successfully" };
|
||||
}
|
||||
|
||||
export const sendOtp = async (phoneNumber: string, code: string) => {
|
||||
|
@ -1,25 +1,4 @@
|
||||
"use server";
|
||||
// const raw = {
|
||||
// group_settings_id: "",
|
||||
// address1: "",
|
||||
// city: "F",
|
||||
// state: "Dharanboodhoo",
|
||||
// postal_code: "12040",
|
||||
// country_id: "462",
|
||||
// address2: "Skyvilla",
|
||||
// contacts: [
|
||||
// {
|
||||
// first_name: "Abdulla",
|
||||
// last_name: "Aidhaan",
|
||||
// email: "",
|
||||
// phone: "778-0588",
|
||||
// send_email: false,
|
||||
// custom_value1: "1971-02-24",
|
||||
// custom_value2: "A265117",
|
||||
// custom_value3: "",
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
|
||||
type CreateClientProps = {
|
||||
group_settings_id: string;
|
||||
|
@ -1,6 +1,8 @@
|
||||
"use server";
|
||||
|
||||
import usePerson from "@/hooks/use-person";
|
||||
import prisma from "@/lib/db";
|
||||
import VerifyUserDetails from "@/lib/person";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
import { CreateClient } from "./ninja/client";
|
||||
@ -18,33 +20,42 @@ export async function VerifyUser(userId: string) {
|
||||
if (!user) {
|
||||
throw new Error("User not found");
|
||||
}
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
data: {
|
||||
verified: true,
|
||||
},
|
||||
});
|
||||
const ninjaClient = await CreateClient({
|
||||
group_settings_id: "",
|
||||
address1: "",
|
||||
city: user.atoll?.name || "",
|
||||
state: user.island?.name || "",
|
||||
postal_code: "",
|
||||
country_id: "462",
|
||||
address2: user.address || "",
|
||||
contacts: {
|
||||
first_name: user.name?.split(" ")[0] || "",
|
||||
last_name: user.name?.split(" ")[1] || "",
|
||||
email: user.email || "",
|
||||
phone: user.phoneNumber || "",
|
||||
send_email: false,
|
||||
custom_value1: user.dob?.toISOString().split("T")[0] || "",
|
||||
custom_value2: user.id_card || "",
|
||||
custom_value3: "",
|
||||
},
|
||||
});
|
||||
const isValidPerson = await VerifyUserDetails({ user });
|
||||
|
||||
if (!isValidPerson)
|
||||
throw new Error("The user details does not match national data.");
|
||||
|
||||
if (isValidPerson) {
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
data: {
|
||||
verified: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ninjaClient = await CreateClient({
|
||||
group_settings_id: "",
|
||||
address1: "",
|
||||
city: user.atoll?.name || "",
|
||||
state: user.island?.name || "",
|
||||
postal_code: "",
|
||||
country_id: "462",
|
||||
address2: user.address || "",
|
||||
contacts: {
|
||||
first_name: user.name?.split(" ")[0] || "",
|
||||
last_name: user.name?.split(" ")[1] || "",
|
||||
email: user.email || "",
|
||||
phone: user.phoneNumber || "",
|
||||
send_email: false,
|
||||
custom_value1: user.dob?.toISOString().split("T")[0] || "",
|
||||
custom_value2: user.id_card || "",
|
||||
custom_value3: "",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
revalidatePath("/users");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user