mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-03 06:52:13 +08:00
fix(auth): replace submit turnstile widget with VerifyTurnstileForRegister
Port upstream's VerifyTurnstileForRegister which skips the duplicate Turnstile check when email verify flow is already completed, instead of requiring a second Turnstile widget on the verify page.
This commit is contained in:
@@ -113,8 +113,8 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Turnstile 验证 — 始终执行,防止机器人自动化注册
|
||||
if err := h.authService.VerifyTurnstile(c.Request.Context(), req.TurnstileToken, ip.GetClientIP(c)); err != nil {
|
||||
// Turnstile 验证(邮箱验证码注册场景避免重复校验一次性 token)
|
||||
if err := h.authService.VerifyTurnstileForRegister(c.Request.Context(), req.TurnstileToken, ip.GetClientIP(c), req.VerifyCode); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -308,6 +308,17 @@ func (s *AuthService) SendVerifyCodeAsync(ctx context.Context, email string) (*S
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VerifyTurnstileForRegister 在注册场景下验证 Turnstile。
|
||||
// 当邮箱验证开启且已提交验证码时,说明验证码发送阶段已完成 Turnstile 校验,
|
||||
// 此处跳过二次校验,避免一次性 token 在注册提交时重复使用导致误报失败。
|
||||
func (s *AuthService) VerifyTurnstileForRegister(ctx context.Context, token, remoteIP, verifyCode string) error {
|
||||
if s.IsEmailVerifyEnabled(ctx) && strings.TrimSpace(verifyCode) != "" {
|
||||
logger.LegacyPrintf("service.auth", "%s", "[Auth] Email verify flow detected, skip duplicate Turnstile check on register")
|
||||
return nil
|
||||
}
|
||||
return s.VerifyTurnstile(ctx, token, remoteIP)
|
||||
}
|
||||
|
||||
// VerifyTurnstile 验证Turnstile token
|
||||
func (s *AuthService) VerifyTurnstile(ctx context.Context, token string, remoteIP string) error {
|
||||
required := s.cfg != nil && s.cfg.Server.Mode == "release" && s.cfg.Turnstile.Required
|
||||
|
||||
@@ -69,20 +69,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Turnstile Widget for Submit -->
|
||||
<div v-if="turnstileEnabled && turnstileSiteKey && !showResendTurnstile">
|
||||
<TurnstileWidget
|
||||
ref="submitTurnstileRef"
|
||||
:site-key="turnstileSiteKey"
|
||||
@verify="onSubmitTurnstileVerify"
|
||||
@expire="onSubmitTurnstileExpire"
|
||||
@error="onSubmitTurnstileError"
|
||||
/>
|
||||
<p v-if="errors.submitTurnstile" class="input-error-text mt-2 text-center">
|
||||
{{ errors.submitTurnstile }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Turnstile Widget for Resend -->
|
||||
<div v-if="turnstileEnabled && turnstileSiteKey && showResendTurnstile">
|
||||
<TurnstileWidget
|
||||
@@ -115,7 +101,7 @@
|
||||
</transition>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button type="submit" :disabled="isLoading || !verifyCode || (turnstileEnabled && !submitTurnstileToken)" class="btn btn-primary w-full">
|
||||
<button type="submit" :disabled="isLoading || !verifyCode" class="btn btn-primary w-full">
|
||||
<svg
|
||||
v-if="isLoading"
|
||||
class="-ml-1 mr-2 h-4 w-4 animate-spin text-white"
|
||||
@@ -223,10 +209,6 @@ const turnstileEnabled = ref<boolean>(false)
|
||||
const turnstileSiteKey = ref<string>('')
|
||||
const siteName = ref<string>('Sub2API')
|
||||
|
||||
// Turnstile for submit
|
||||
const submitTurnstileRef = ref<InstanceType<typeof TurnstileWidget> | null>(null)
|
||||
const submitTurnstileToken = ref<string>('')
|
||||
|
||||
// Turnstile for resend
|
||||
const turnstileRef = ref<InstanceType<typeof TurnstileWidget> | null>(null)
|
||||
const resendTurnstileToken = ref<string>('')
|
||||
@@ -234,8 +216,7 @@ const showResendTurnstile = ref<boolean>(false)
|
||||
|
||||
const errors = ref({
|
||||
code: '',
|
||||
turnstile: '',
|
||||
submitTurnstile: ''
|
||||
turnstile: ''
|
||||
})
|
||||
|
||||
// ==================== Lifecycle ====================
|
||||
@@ -303,21 +284,6 @@ function startCountdown(seconds: number): void {
|
||||
|
||||
// ==================== Turnstile Handlers ====================
|
||||
|
||||
function onSubmitTurnstileVerify(token: string): void {
|
||||
submitTurnstileToken.value = token
|
||||
errors.value.submitTurnstile = ''
|
||||
}
|
||||
|
||||
function onSubmitTurnstileExpire(): void {
|
||||
submitTurnstileToken.value = ''
|
||||
errors.value.submitTurnstile = 'Verification expired, please try again'
|
||||
}
|
||||
|
||||
function onSubmitTurnstileError(): void {
|
||||
submitTurnstileToken.value = ''
|
||||
errors.value.submitTurnstile = 'Verification failed, please try again'
|
||||
}
|
||||
|
||||
function onTurnstileVerify(token: string): void {
|
||||
resendTurnstileToken.value = token
|
||||
errors.value.turnstile = ''
|
||||
@@ -419,7 +385,7 @@ async function handleVerify(): Promise<void> {
|
||||
email: email.value,
|
||||
password: password.value,
|
||||
verify_code: verifyCode.value.trim(),
|
||||
turnstile_token: submitTurnstileToken.value || undefined,
|
||||
turnstile_token: initialTurnstileToken.value || undefined,
|
||||
promo_code: promoCode.value || undefined,
|
||||
invitation_code: invitationCode.value || undefined
|
||||
})
|
||||
@@ -433,12 +399,6 @@ async function handleVerify(): Promise<void> {
|
||||
// Redirect to dashboard
|
||||
await router.push('/dashboard')
|
||||
} catch (error: unknown) {
|
||||
// Reset submit turnstile on error
|
||||
if (submitTurnstileRef.value) {
|
||||
submitTurnstileRef.value.reset()
|
||||
submitTurnstileToken.value = ''
|
||||
}
|
||||
|
||||
const err = error as { message?: string; response?: { data?: { detail?: string } } }
|
||||
|
||||
if (err.response?.data?.detail) {
|
||||
|
||||
Reference in New Issue
Block a user