diff --git a/src/app/(main)/settings/layout.tsx b/src/app/(main)/settings/layout.tsx index 3e74e29..ea197bd 100644 --- a/src/app/(main)/settings/layout.tsx +++ b/src/app/(main)/settings/layout.tsx @@ -20,7 +20,7 @@ export default function Layout({ children }: { children: React.ReactNode }) { { label: "Change Login Password", href: "/settings/change_login_password" }, { label: "Change transaction Password", href: "/settings/change_txn_password" }, { label: "Set transaction Password", href: "/settings/set_txn_password" }, - { label: "Preferred Name", href: "/settings/user_id" }, + { label: "Preferred Name", href: "/settings/user_name" }, ]; useEffect(() => { const token = localStorage.getItem("access_token"); diff --git a/src/app/(main)/settings/user_id/page.tsx b/src/app/(main)/settings/user_name/page.tsx similarity index 92% rename from src/app/(main)/settings/user_id/page.tsx rename to src/app/(main)/settings/user_name/page.tsx index eed5737..f4cac0d 100644 --- a/src/app/(main)/settings/user_id/page.tsx +++ b/src/app/(main)/settings/user_name/page.tsx @@ -32,13 +32,13 @@ export default function SetPreferredNameSimple() { const icon = ; - // 🟢 Fetch name + generate captcha on mount + // Fetch name + generate captcha on mount useEffect(() => { checkPreferredName(); regenerateCaptcha(); }, []); - // 🟢 OTP timer + // OTP timer useEffect(() => { let interval: number | undefined; if (timerActive && countdown > 0) { @@ -55,7 +55,7 @@ export default function SetPreferredNameSimple() { }; }, [timerActive, countdown]); - // 🟢 API: Fetch preferred name + // API: Fetch preferred name async function checkPreferredName() { try { const token = localStorage.getItem("access_token"); @@ -77,20 +77,23 @@ export default function SetPreferredNameSimple() { } } - // 🟢 Captcha + // Captcha const regenerateCaptcha = async () => { const newCaptcha = await generateCaptcha(); setCaptcha(newCaptcha); setCaptchaInput(""); }; - // 🟢 Live Validation (kept from your previous version) function onPreferredNameChange(value: string) { const sanitized = value.replace(/[^A-Za-z0-9@_]/g, "").slice(0, 11); setPreferredName(sanitized); if (sanitized.length > 0 && (sanitized.length < 5 || sanitized.length > 11)) { setPreferredNameError("Preferred Name must be 5–11 characters."); + } else if (!/[A-Za-z]/.test(sanitized)) { + setPreferredNameError("Preferred Name must contain at least one letter."); + } else if (!/[@_]/.test(sanitized)) { + setPreferredNameError("Preferred Name must contain at least one special character (@ or _)."); } else { setPreferredNameError(null); } @@ -107,7 +110,7 @@ export default function SetPreferredNameSimple() { } } - // 🟢 OTP + // OTP async function handleSendOtp() { try { await sendOtp({ type: "USERNAME_UPDATED" }); @@ -147,7 +150,7 @@ export default function SetPreferredNameSimple() { } } - // 🟢 Update Preferred Name API + // Update Preferred Name API async function handleUpdatePreferredName() { const token = localStorage.getItem("access_token"); if (!token) { @@ -199,7 +202,7 @@ export default function SetPreferredNameSimple() { regenerateCaptcha(); }; - // 🟢 Main Submit + // Main Submit const handleSubmit = async () => { if (step === "form") { if (!preferredName || !confirmName || !captchaInput) { @@ -210,6 +213,14 @@ export default function SetPreferredNameSimple() { }); return; } + if(preferredName !== confirmName){ + notifications.show({ + title: "Mismatch Input", + message: "Preferred name and Confirm preferred name not same.", + color: "red", + }); + return; + } if (preferredNameError || confirmNameError) { notifications.show({ @@ -286,7 +297,11 @@ export default function SetPreferredNameSimple() { mb="xs" rightSection={icon} readOnly={step !== "form"} + onCopy={(e) => e.preventDefault()} + onPaste={(e) => e.preventDefault()} + onCut={(e) => e.preventDefault()} error={confirmNameError || undefined} + /> @@ -396,6 +411,10 @@ export default function SetPreferredNameSimple() { You can change your username a maximum of 5 times. + + Preferred Name must contain at least one alphabet and one special character (@ or _). + + diff --git a/src/app/_util/otp.ts b/src/app/_util/otp.ts index 4014c58..ee61e80 100644 --- a/src/app/_util/otp.ts +++ b/src/app/_util/otp.ts @@ -14,8 +14,8 @@ interface SendOtpPayload { } function getStoredMobileNumber(): string { - // const mobileNumber = localStorage.getItem('remitter_mobile_no'); - const mobileNumber = "6297421727"; + const mobileNumber = localStorage.getItem('remitter_mobile_no'); + // const mobileNumber = "7890544527"; if (!mobileNumber) throw new Error('Mobile number not found.'); return mobileNumber; } diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index a8234f4..b23a034 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -45,8 +45,8 @@ export default function Login() { } try { - // await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile }); - await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "6297421727" }); + await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: mobile }); + // await sendOtp({ type: 'LOGIN_OTP', username: CIF, mobileNumber: "7890544527" }); notifications.show({ color: 'orange', title: 'OTP Required', @@ -67,8 +67,8 @@ export default function Login() { async function handleVerifyOtp(mobile?: string) { try { if (mobile) { - // await verifyLoginOtp(otp, mobile); - await verifyLoginOtp(otp, '6297421727'); + await verifyLoginOtp(otp, mobile); + // await verifyLoginOtp(otp, '7890544527'); return true; } } @@ -124,14 +124,15 @@ export default function Login() { try { // --- Validation (before any API call) --- if (!otpRequired && !otpVerified) { - const onlyDigit = /^\d{11}$/; + // const onlyDigit = /^\d{11}$/; + const onlyDigit = /^[A-Za-z0-9@_]{5,11}$/; if (!onlyDigit.test(CIF)) { notifications.show({ withBorder: true, color: "red", title: "Invalid UserId", - message: "UserID must be 11 digit", + message: "The User ID or Username must contain 5 to 11 alphanumeric characters.", autoClose: 5000, }); setIsLogging(false); @@ -178,6 +179,7 @@ export default function Login() { // --- LOGIN API FLOW --- if (!otpRequired || otpVerified) { + const isNumeric = /^\d+$/.test(CIF); const response = await fetch("api/auth/login", { method: "POST", headers: { @@ -185,7 +187,8 @@ export default function Login() { "X-Login-Type": "IB", }, body: JSON.stringify({ - customerNo: CIF, + customerNo: isNumeric ? CIF : null, + userName: isNumeric ? null : CIF, password: psw, otp: otp, }), @@ -522,14 +525,15 @@ export default function Login() { /> - +
{ - const input = e.currentTarget.value.replace(/\D/g, ""); + // const input = e.currentTarget.value.replace(/\D/g, ""); + const input = e.currentTarget.value.replace(/[^A-Za-z0-9@_]/g, ""); if (input.length <= 11) SetCIF(input); }} withAsterisk @@ -609,10 +613,17 @@ export default function Login() { )} - - + + + Note: + + Existing users logging in to the new Internet Banking for the first time should use their CIF number to avoid login issues. + + +