From c65e8f8d1808ea2d51e8f1e2c639b4fc7c317169 Mon Sep 17 00:00:00 2001 From: pagoru Date: Wed, 25 Sep 2024 19:35:05 +0200 Subject: [PATCH] feat: fix captcha/otp times on login - fix #57 --- .../src/modules/login/login.component.tsx | 13 ++++-- .../modules/api/v2/account/login.request.ts | 40 +++++++++++-------- app/server/src/system/captcha.ts | 2 + 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/app/client/src/modules/login/login.component.tsx b/app/client/src/modules/login/login.component.tsx index 9efbcec..d087c91 100644 --- a/app/client/src/modules/login/login.component.tsx +++ b/app/client/src/modules/login/login.component.tsx @@ -5,9 +5,10 @@ import styles from "./login.module.scss"; import { useNavigate } from "react-router-dom"; export const LoginComponent: React.FC = () => { const [submittedAt, setSubmittedAt] = useState(); - const [captchaId, setCaptchaId] = useState(); + const [captchaId, setCaptchaId] = useState(null); const [loaded, setLoaded] = useState(false); const [showOTP, setShowOTP] = useState(false); + const [showCaptcha, setShowCaptcha] = useState(false); const { login, refreshSession, getTicketId } = useApi(); let navigate = useNavigate(); @@ -42,7 +43,8 @@ export const LoginComponent: React.FC = () => { window.location.href = redirectUrl; }) .catch(({ status }) => { - if (status === 441) setShowOTP(true); + if (status === 461 || status === 451) setShowCaptcha(true); + if (status === 461 || status === 441) setShowOTP(true); setSubmittedAt(performance.now()); }); }, @@ -56,7 +58,12 @@ export const LoginComponent: React.FC = () => {
- + {showCaptcha && ( + + )} {showOTP && } diff --git a/app/server/src/modules/api/v2/account/login.request.ts b/app/server/src/modules/api/v2/account/login.request.ts index 01d4511..213b9d4 100644 --- a/app/server/src/modules/api/v2/account/login.request.ts +++ b/app/server/src/modules/api/v2/account/login.request.ts @@ -16,7 +16,7 @@ export const loginRequest: RequestType = { const { ticketId, email, password, captchaId, otpToken } = await request.json(); - if (!(await System.captcha.verify(captchaId)) || !email || !password) + if (!email || !password) return Response.json( { status: 403 }, { @@ -85,23 +85,29 @@ export const loginRequest: RequestType = { account.accountId, ]); - if (accountOTP.verified) { - if (!otpToken) - return Response.json( - { status: 441, message: "OTP secret is needed!" }, - { - status: 441, - }, - ); + let isValidOTP = true; - if (!System.otp.verify(accountOTP.secret, otpToken)) - return Response.json( - { status: 441, message: "OTP is not valid!" }, - { - status: 441, - }, - ); - } + if ( + accountOTP.verified && + (!otpToken || !System.otp.verify(accountOTP.secret, otpToken)) + ) + isValidOTP = false; + + if (!(await System.captcha.verify(captchaId))) + return Response.json( + { status: isValidOTP ? 451 : 461, message: "Captcha is not valid!" }, + { + status: isValidOTP ? 451 : 461, + }, + ); + + if (!isValidOTP) + return Response.json( + { status: 441, message: "OTP is not valid!" }, + { + status: 441, + }, + ); if (account.sessionId) { await System.db.delete(["accountsBySession", account.sessionId]); diff --git a/app/server/src/system/captcha.ts b/app/server/src/system/captcha.ts index c7c8754..478350f 100644 --- a/app/server/src/system/captcha.ts +++ b/app/server/src/system/captcha.ts @@ -2,6 +2,8 @@ import { System } from "system/main.ts"; export const captcha = () => { const verify = async (sessionId: string): Promise => { + if (!sessionId) return false; + const { enabled, id, token, url } = System.getConfig().captcha; if (!enabled || !id || !token || !url) return true;