From 2199986a973880fc935176a7d1f036811cb4502f Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Fri, 25 Apr 2025 23:57:47 +0800 Subject: [PATCH] update --- package-lock.json | 106 ++++++++++++++++++++++ packages/frontend/package.json | 1 + packages/frontend/src/main.ts | 14 +-- packages/frontend/src/views/LoginView.vue | 25 ++--- 4 files changed, 121 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 492881a..ef8ba4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -745,6 +745,21 @@ "node": ">=18.12.0" } }, + "node_modules/@nuxt/schema": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-3.16.2.tgz", + "integrity": "sha512-2HZPM372kuI/uw9VU/hOoYuzv803oZAtyoEKC5dQCQTKAQ293AjypF3WljMXUSReFS/hcbBSgGzYUPHr3Qo+pg==", + "license": "MIT", + "dependencies": { + "consola": "^3.4.2", + "defu": "^6.1.4", + "pathe": "^2.0.3", + "std-env": "^3.8.1" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/@peculiar/asn1-android": { "version": "2.3.16", "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.3.16.tgz", @@ -1916,6 +1931,18 @@ "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", "license": "MIT" }, + "node_modules/@vueuse/shared": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.1.tgz", + "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==", + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -5086,6 +5113,18 @@ "wrappy": "1" } }, + "node_modules/p-defer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.1.tgz", + "integrity": "sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6646,6 +6685,18 @@ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "license": "Unlicense" }, + "node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -7031,6 +7082,32 @@ } } }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/vue-i18n": { "version": "9.14.4", "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.4.tgz", @@ -7057,6 +7134,34 @@ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", "license": "MIT" }, + "node_modules/vue-recaptcha": { + "version": "3.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/vue-recaptcha/-/vue-recaptcha-3.0.0-alpha.6.tgz", + "integrity": "sha512-hwxxAXENLN6GKJhH6s+NJV1f6llSFEQ0jMTxjEunpR6CMbQ5xc7DAHFtwrsDutGnbS8wl9yp30jsYcCToZEhTQ==", + "license": "MIT", + "workspaces": [ + ".", + "docs" + ], + "dependencies": { + "@nuxt/kit": "^3.4.3", + "@nuxt/schema": "^3.4.3", + "@vueuse/shared": "^10.1.0", + "defu": "^6.1.2", + "p-defer": "^4.0.0", + "std-env": "^3.3.2", + "type-fest": "^3.9.0", + "vue-demi": "^0.14.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/vue-recaptcha-v3": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/vue-recaptcha-v3/-/vue-recaptcha-v3-2.0.1.tgz", @@ -7389,6 +7494,7 @@ "vite-plugin-monaco-editor": "^1.1.0", "vue": "^3.3.0", "vue-i18n": "^9.14.4", + "vue-recaptcha": "^3.0.0-alpha.6", "vue-recaptcha-v3": "^2.0.1", "vue-router": "^4.5.0", "vuedraggable": "^4.1.0", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index f3572b0..658282a 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -23,6 +23,7 @@ "vite-plugin-monaco-editor": "^1.1.0", "vue": "^3.3.0", "vue-i18n": "^9.14.4", + "vue-recaptcha": "^3.0.0-alpha.6", "vue-recaptcha-v3": "^2.0.1", "vue-router": "^4.5.0", "vuedraggable": "^4.1.0", diff --git a/packages/frontend/src/main.ts b/packages/frontend/src/main.ts index fa557e3..132351d 100644 --- a/packages/frontend/src/main.ts +++ b/packages/frontend/src/main.ts @@ -12,8 +12,8 @@ import './style.css'; import '@fortawesome/fontawesome-free/css/all.min.css'; // 导入 splitpanes CSS import 'splitpanes/dist/splitpanes.css'; -// 导入 reCAPTCHA v3 -import { VueReCaptcha } from 'vue-recaptcha-v3'; +// 导入 vue-recaptcha (用于 v2) +import VueRecaptchaPlugin from 'vue-recaptcha'; const pinia = createPinia(); // 创建 Pinia 实例 pinia.use(piniaPluginPersistedstate); // 使用持久化插件 @@ -24,14 +24,8 @@ app.use(pinia); // 使用配置好的 Pinia 实例 // 注意:在状态初始化完成前,暂时不 use(router) app.use(i18n); // 使用 i18n -// 初始化 reCAPTCHA v3 -// 重要提示:请将 'YOUR_RECAPTCHA_V3_SITE_KEY' 替换为您从 Google reCAPTCHA 获取的实际 Site Key -app.use(VueReCaptcha, { - siteKey: 'YOUR_RECAPTCHA_V3_SITE_KEY', // <-- 在此处替换您的 Site Key - loaderOptions: { - autoHideBadge: true // 可选:自动隐藏 reCAPTCHA 徽章 - } -}); +// 注册 vue-recaptcha 插件,传递一个空选项对象 +app.use(VueRecaptchaPlugin, {}); // --- 应用初始化逻辑 --- // 使用 async IIFE 来允许顶层 await diff --git a/packages/frontend/src/views/LoginView.vue b/packages/frontend/src/views/LoginView.vue index 2ee4335..021a382 100644 --- a/packages/frontend/src/views/LoginView.vue +++ b/packages/frontend/src/views/LoginView.vue @@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n'; import { useAuthStore } from '../stores/auth.store'; import VueHcaptcha from '@hcaptcha/vue3-hcaptcha'; // <-- Import hCaptcha component // import { useReCaptcha } from 'vue-recaptcha-v3'; // <-- v3 hook, not needed for v2 widget -// TODO: Import a reCAPTCHA v2 component, e.g., import VueRecaptchaV2 from 'vue-recaptcha-v2'; +import TheVueRecaptcha from 'vue-recaptcha'; // <-- Use a different name for import const { t } = useI18n(); const authStore = useAuthStore(); @@ -21,9 +21,9 @@ const twoFactorToken = ref(''); // 用于存储 2FA 验证码 const rememberMe = ref(false); // 新增:记住我状态,默认为 false const captchaToken = ref(null); // NEW: Store CAPTCHA token const captchaError = ref(null); // NEW: Store CAPTCHA specific error -const hcaptchaWidget = ref | null>(null); // NEW: Ref for hCaptcha component instance +const hcaptchaWidget = ref | null>(null); // Ref for hCaptcha component instance // const recaptchaInstance = useReCaptcha(); // v3 instance, not needed for v2 widget -const recaptchaV2Widget = ref(null); // NEW: Ref for reCAPTCHA v2 component instance (replace 'any' with actual type) +// No specific ref needed for VueRecaptcha v2 component usually, events handle token // --- CAPTCHA Event Handlers --- @@ -46,8 +46,7 @@ const resetCaptchaWidget = () => { captchaToken.value = null; // Reset hCaptcha if it exists hcaptchaWidget.value?.reset(); - // Reset reCAPTCHA v2 if it exists and component supports it - // recaptchaV2Widget.value?.reset(); // Assuming the component has a reset method + // vue-recaptcha v2 component might reset automatically or not have an explicit method easily accessible via ref }; // --- End CAPTCHA Event Handlers --- @@ -164,21 +163,17 @@ onMounted(() => { theme="auto" > - +
- - + - --> -
- 此处需要集成 Google reCAPTCHA v2 组件。 -
+ theme="light" + size="normal" + >

{{ t('login.recaptchaV3Notice') }}