From 09262b594a0544db35ab6eb49f3d89d5ddd4ee5c Mon Sep 17 00:00:00 2001 From: xudaotutou <13435638964@163.com> Date: Fri, 21 Feb 2025 15:36:32 +0800 Subject: [PATCH] feat:add captcha (#5389) --- frontend/desktop/package.json | 2 + .../src/components/signin/Captcha/index.tsx | 109 ++++++++++++++++++ .../src/components/signin/auth/useSms.tsx | 28 +++-- .../desktop/src/components/signin/index.tsx | 11 +- .../desktop/src/pages/api/auth/phone/sms.ts | 13 ++- .../src/pages/api/platform/getAppConfig.ts | 6 +- .../src/pages/api/platform/getAuthConfig.ts | 9 ++ frontend/desktop/src/pages/signin.tsx | 14 ++- .../src/services/backend/middleware/sms.ts | 66 +++++++++++ frontend/desktop/src/services/backend/sms.ts | 67 ++++++++--- .../desktop/src/services/backend/svc/sms.ts | 2 +- frontend/desktop/src/stores/script.ts | 19 +++ frontend/desktop/src/types/system.ts | 27 ++++- frontend/pnpm-lock.yaml | 18 +++ 14 files changed, 355 insertions(+), 36 deletions(-) create mode 100644 frontend/desktop/src/components/signin/Captcha/index.tsx create mode 100644 frontend/desktop/src/stores/script.ts diff --git a/frontend/desktop/package.json b/frontend/desktop/package.json index 5a3379fb9d6..ede5862733e 100644 --- a/frontend/desktop/package.json +++ b/frontend/desktop/package.json @@ -17,8 +17,10 @@ "postinstall": "pnpm gen:global && pnpm gen:region" }, "dependencies": { + "@alicloud/captcha20230305": "1.1.3", "@alicloud/dysmsapi20170525": "^2.0.24", "@alicloud/openapi-client": "^0.4.6", + "@alicloud/tea-typescript": "^1.8.0", "@alicloud/tea-util": "^1.4.7", "@chakra-ui/anatomy": "^2.2.1", "@chakra-ui/icons": "^2.1.1", diff --git a/frontend/desktop/src/components/signin/Captcha/index.tsx b/frontend/desktop/src/components/signin/Captcha/index.tsx new file mode 100644 index 00000000000..6188c6818ee --- /dev/null +++ b/frontend/desktop/src/components/signin/Captcha/index.tsx @@ -0,0 +1,109 @@ +import request from '@/services/request'; +import { useConfigStore } from '@/stores/config'; +import useScriptStore from '@/stores/script'; +import { Box, Button, ButtonProps, Link, LinkProps } from '@chakra-ui/react'; +import { delay } from 'lodash'; +import React, { + ReactElement, + forwardRef, + useEffect, + useId, + useImperativeHandle, + useRef, + useState +} from 'react'; +import { v4 } from 'uuid'; +export type TCaptchaInstance = { + getToken: () => Promise; + reset: () => void; +}; + +const HiddenCaptchaComponent = forwardRef(function HiddenCaptchaComponent(props, ref) { + const captchaElementRef = useRef(null); + const captchaInstanceRef = useRef(null); + const tokenRef = useRef(''); + const buttonRef = useRef(null); + const { authConfig } = useConfigStore(); + useImperativeHandle( + ref, + () => { + return { + getToken: async () => { + buttonRef.current?.click(); + await new Promise((res) => { + setTimeout(res, 1000); + }); + const token = tokenRef.current; + return token; + }, + reset() { + tokenRef.current = ''; + } + }; + }, + [] + ); + const { captchaIsLoaded } = useScriptStore(); + const [buttonId] = useState('captcha_button_pop'); + const [captchaId] = useState('captcha_' + v4().slice(0, 8)); + + // @ts-ignore + const getInstance = (instance) => { + captchaInstanceRef.current = instance; + }; + + const onBizResultCallback = () => {}; + useEffect(() => { + if (!captchaIsLoaded) return; + const initAliyunCaptchaOptions = { + SceneId: authConfig?.captcha.ali.sceneId, + prefix: authConfig?.captcha.ali.prefix, + mode: 'popup', + element: '#' + captchaId, + button: '#' + buttonId, + async captchaVerifyCallback(captchaToken: string) { + try { + tokenRef.current = captchaToken; + return { + captchaResult: true + }; + } catch (err) { + tokenRef.current = ''; + return { + captchaResult: false + }; + } + }, + onBizResultCallback: onBizResultCallback, + getInstance, + slideStyle: { + width: 360, + height: 40 + }, + immediate: false, + language: 'cn', + region: 'cn' + }; + + // @ts-ignore + window.initAliyunCaptcha(initAliyunCaptchaOptions); + + return () => { + captchaInstanceRef.current = null; + }; + }, [captchaIsLoaded]); + return ( + <> +