新增规则触发人机验证和加载失败提示
This commit is contained in:
@@ -255,7 +255,11 @@ const en = {
|
||||
backgroundUrlDesc: 'Image URL',
|
||||
localUpload: ' Local upload',
|
||||
imageLink: 'Image URL',
|
||||
backgroundWarning: 'Image file size affects website load speed.'
|
||||
imageLinkErrorMsg: 'Invalid image URL',
|
||||
backgroundWarning: 'Image file size affects website load speed.',
|
||||
rulesVerify: 'Rules',
|
||||
rulesVerifyTitle: 'Trigger After {count} Daily Uses per IP',
|
||||
botVerifyMsg: 'Please verify that you are human',
|
||||
}
|
||||
|
||||
export default en
|
||||
|
||||
@@ -4,8 +4,8 @@ import zh from './zh.js'
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
messages: {
|
||||
en,
|
||||
zh
|
||||
zh,
|
||||
en
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -255,6 +255,10 @@ const zh = {
|
||||
backgroundUrlDesc: '在线图片链接',
|
||||
localUpload: '本地上传',
|
||||
imageLink: '图片链接',
|
||||
imageLinkErrorMsg: '图片链接不正确',
|
||||
backgroundWarning: '图片文件大小会影响网站加载速度',
|
||||
rulesVerify: '规则',
|
||||
rulesVerifyTitle: 'IP 每天使用 {count} 次后触发',
|
||||
botVerifyMsg: '请完成人机验证',
|
||||
}
|
||||
export default zh
|
||||
@@ -6,6 +6,7 @@ import {permsToRouter} from "@/perm/perm.js";
|
||||
import router from "@/router";
|
||||
import {websiteConfig} from "@/request/setting.js";
|
||||
import {cvtR2Url} from "@/utils/convert.js";
|
||||
import i18n from "@/i18n/index.js";
|
||||
|
||||
export async function init() {
|
||||
document.title = '\u200B'
|
||||
@@ -15,11 +16,12 @@ export async function init() {
|
||||
const accountStore = useAccountStore();
|
||||
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
if (!settingStore.lang) {
|
||||
settingStore.lang = navigator.language.split('-')[0]
|
||||
}
|
||||
|
||||
i18n.global.locale.value = settingStore.lang
|
||||
|
||||
let setting = null;
|
||||
|
||||
if (token) {
|
||||
|
||||
@@ -103,7 +103,10 @@
|
||||
:class="verifyShow ? 'turnstile-show' : 'turnstile-hide'"
|
||||
:data-sitekey="settingStore.settings.siteKey"
|
||||
data-callback="onTurnstileSuccess"
|
||||
></div>
|
||||
data-error-callback="onTurnstileError"
|
||||
>
|
||||
<span style="font-size: 12px;color: #F56C6C" v-if="botJsError">人机验证模块加载失败,请刷新浏览器</span>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="setNameShow" :title="$t('changeUserName')" >
|
||||
<div class="container">
|
||||
@@ -145,6 +148,7 @@ const accountName = ref(null)
|
||||
const addRef = ref({})
|
||||
let account = null
|
||||
let turnstileId = null
|
||||
const botJsError = ref(false)
|
||||
let verifyToken = ''
|
||||
const addForm = reactive({
|
||||
email: '',
|
||||
@@ -170,11 +174,19 @@ const openSelect = () => {
|
||||
mySelect.value.toggleMenu()
|
||||
}
|
||||
|
||||
window.onTurnstileError = (e) => {
|
||||
console.log('人机验加载失败')
|
||||
nextTick(() => {
|
||||
if (!turnstileId) {
|
||||
turnstileId = window.turnstile.render('.register-turnstile')
|
||||
} else {
|
||||
window.turnstile.reset(turnstileId);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
window.onTurnstileSuccess = (token) => {
|
||||
verifyToken = token;
|
||||
setTimeout(() => {
|
||||
verifyShow.value = false
|
||||
},1500)
|
||||
};
|
||||
|
||||
function setName() {
|
||||
@@ -338,14 +350,27 @@ function submit() {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!verifyToken && settingStore.settings.addEmailVerify === 0) {
|
||||
verifyShow.value = true
|
||||
if (!turnstileId) {
|
||||
if (!verifyToken && (settingStore.settings.addEmailVerify === 0 || (settingStore.settings.addEmailVerify === 2 && settingStore.settings.addVerifyOpen))) {
|
||||
if (!verifyShow.value) {
|
||||
verifyShow.value = true
|
||||
nextTick(() => {
|
||||
turnstileId = window.turnstile.render('.add-email-turnstile')
|
||||
if (!turnstileId) {
|
||||
try {
|
||||
turnstileId = window.turnstile.render('.add-email-turnstile')
|
||||
} catch (e) {
|
||||
botJsError.value = true
|
||||
console.log('人机验证js加载失败')
|
||||
}
|
||||
} else {
|
||||
window.turnstile.reset('.add-email-turnstile')
|
||||
}
|
||||
})
|
||||
} else if (!botJsError.value) {
|
||||
ElMessage({
|
||||
message: t('botVerifyMsg'),
|
||||
type: "error",
|
||||
plain: true
|
||||
})
|
||||
} else {
|
||||
window.turnstile.reset(turnstileId)
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -357,16 +382,24 @@ function submit() {
|
||||
addForm.email = ''
|
||||
accounts.push(account)
|
||||
verifyToken = ''
|
||||
settingStore.settings.addVerifyOpen = account.addVerifyOpen
|
||||
ElMessage({
|
||||
message: t('addSuccessMsg'),
|
||||
type: "success",
|
||||
plain: true
|
||||
})
|
||||
verifyShow.value = false
|
||||
userStore.refreshUserInfo()
|
||||
}).catch(res => {
|
||||
if (res.code === 400) {
|
||||
verifyToken = ''
|
||||
window.turnstile.reset(turnstileId)
|
||||
if (turnstileId) {
|
||||
window.turnstile.reset(turnstileId)
|
||||
} else {
|
||||
nextTick(() => {
|
||||
turnstileId = window.turnstile.render('.add-email-turnstile')
|
||||
})
|
||||
}
|
||||
verifyShow.value = true
|
||||
}
|
||||
addLoading.value = false
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
<span class="form-title">{{settingStore.settings.title}}</span>
|
||||
<span class="form-desc" v-if="show === 'login'">{{$t('loginTitle')}}</span>
|
||||
<span class="form-desc" v-else>{{$t('regTitle')}}</span>
|
||||
<div v-if="show === 'login'">
|
||||
<div v-show="show === 'login'">
|
||||
<el-input class="email-input" v-model="form.email" type="text" :placeholder="$t('emailAccount')" autocomplete="off">
|
||||
<template #append>
|
||||
<div @click.stop="openSelect">
|
||||
<el-select
|
||||
v-if="show === 'login'"
|
||||
ref="mySelect"
|
||||
v-model="suffix"
|
||||
:placeholder="$t('select')"
|
||||
@@ -43,11 +44,12 @@
|
||||
>{{$t('loginBtn')}}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-show="show !== 'login'">
|
||||
<el-input class="email-input" v-model="registerForm.email" type="text" :placeholder="$t('emailAccount')" autocomplete="off">
|
||||
<template #append>
|
||||
<div @click.stop="openSelect">
|
||||
<el-select
|
||||
v-if="show !== 'login'"
|
||||
ref="mySelect"
|
||||
v-model="suffix"
|
||||
:placeholder="$t('select')"
|
||||
@@ -75,7 +77,12 @@
|
||||
class="register-turnstile"
|
||||
:data-sitekey="settingStore.settings.siteKey"
|
||||
data-callback="onTurnstileSuccess"
|
||||
></div>
|
||||
data-error-callback="onTurnstileError"
|
||||
data-after-interactive-callback="loadAfter"
|
||||
data-before-interactive-callback="loadBefore"
|
||||
>
|
||||
<span style="font-size: 12px;color: #F56C6C" v-if="botJsError">人机验证模块加载失败,请刷新浏览器</span>
|
||||
</div>
|
||||
<el-button class="btn" type="primary" @click="submitRegister" :loading="registerLoading"
|
||||
>{{$t('regBtn')}}
|
||||
</el-button>
|
||||
@@ -129,15 +136,30 @@ suffix.value = domainList[0]
|
||||
const verifyShow = ref(false)
|
||||
let verifyToken = ''
|
||||
let turnstileId = null
|
||||
|
||||
let botJsError = ref(false)
|
||||
|
||||
window.onTurnstileSuccess = (token) => {
|
||||
verifyToken = token;
|
||||
setTimeout(() => {
|
||||
verifyShow.value = false
|
||||
}, 2000)
|
||||
};
|
||||
|
||||
window.onTurnstileError = (e) => {
|
||||
console.log('人机验加载失败')
|
||||
nextTick(() => {
|
||||
if (!turnstileId) {
|
||||
turnstileId = window.turnstile.render('.register-turnstile')
|
||||
} else {
|
||||
window.turnstile.reset(turnstileId);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
window.loadAfter = (e) => {
|
||||
console.log('loadAfter')
|
||||
}
|
||||
|
||||
window.loadBefore = (e) => {
|
||||
console.log('loadBefore')
|
||||
}
|
||||
|
||||
const loginOpacity = computed(() => {
|
||||
return `rgba(255, 255, 255, ${settingStore.settings.loginOpacity})`
|
||||
@@ -158,7 +180,6 @@ const openSelect = () => {
|
||||
mySelect.value.toggleMenu()
|
||||
}
|
||||
|
||||
|
||||
const submit = () => {
|
||||
|
||||
if (!form.email) {
|
||||
@@ -267,15 +288,26 @@ function submitRegister() {
|
||||
|
||||
}
|
||||
|
||||
if (!verifyToken && settingStore.settings.registerVerify === 0) {
|
||||
verifyShow.value = true
|
||||
if (!turnstileId) {
|
||||
if (!verifyToken && (settingStore.settings.registerVerify === 0 || (settingStore.settings.registerVerify === 2 && settingStore.settings.regVerifyOpen))) {
|
||||
if (!verifyShow.value) {
|
||||
verifyShow.value = true
|
||||
nextTick(() => {
|
||||
turnstileId = window.turnstile.render('.register-turnstile')
|
||||
if (!turnstileId) {
|
||||
try {
|
||||
turnstileId = window.turnstile.render('.register-turnstile')
|
||||
} catch (e) {
|
||||
botJsError.value = true
|
||||
console.log('人机验证js加载失败')
|
||||
}
|
||||
} else {
|
||||
window.turnstile.reset('.register-turnstile')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
nextTick(() => {
|
||||
window.turnstile.reset(turnstileId);
|
||||
} else if (!botJsError.value) {
|
||||
ElMessage({
|
||||
message: t('botVerifyMsg'),
|
||||
type: "error",
|
||||
plain: true
|
||||
})
|
||||
}
|
||||
return;
|
||||
@@ -290,27 +322,38 @@ function submitRegister() {
|
||||
code: registerForm.code
|
||||
}
|
||||
|
||||
register(form).then(() => {
|
||||
register(form).then(({regVerifyOpen}) => {
|
||||
show.value = 'login'
|
||||
registerForm.email = ''
|
||||
registerForm.password = ''
|
||||
registerForm.confirmPassword = ''
|
||||
registerForm.code = ''
|
||||
registerLoading.value = false
|
||||
turnstileId = null
|
||||
verifyToken = ''
|
||||
settingStore.settings.regVerifyOpen = regVerifyOpen
|
||||
verifyShow.value = false
|
||||
ElMessage({
|
||||
message: t('regSuccessMsg'),
|
||||
type: 'success',
|
||||
plain: true,
|
||||
})
|
||||
}).catch(res => {
|
||||
|
||||
registerLoading.value = false
|
||||
|
||||
if (res.code === 400) {
|
||||
verifyToken = ''
|
||||
window.turnstile.reset(turnstileId)
|
||||
settingStore.settings.regVerifyOpen = true
|
||||
if (turnstileId) {
|
||||
window.turnstile.reset(turnstileId)
|
||||
} else {
|
||||
nextTick(() => {
|
||||
turnstileId = window.turnstile.render('.register-turnstile')
|
||||
})
|
||||
}
|
||||
verifyShow.value = true
|
||||
|
||||
}
|
||||
registerLoading.value = false
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -230,15 +230,39 @@
|
||||
<div class="setting-item">
|
||||
<div><span>{{$t('signUpVerification')}}</span></div>
|
||||
<div>
|
||||
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
|
||||
v-model="setting.registerVerify"/>
|
||||
<el-button class="opt-button" size="small" type="primary" @click="openRegVerifyCount">
|
||||
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
|
||||
</el-button>
|
||||
<el-select
|
||||
@change="change"
|
||||
:style="`width: ${ locale === 'en' ? 100 : 80 }px;`"
|
||||
v-model="setting.registerVerify"
|
||||
placeholder="Select"
|
||||
class="bot-verify-select"
|
||||
>
|
||||
<el-option key="1" :value="0" :label="$t('enable')" />
|
||||
<el-option key="1" :value="1" :label="$t('disable')" />
|
||||
<el-option key="1" :value="2" :label="$t('rulesVerify')" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div><span>{{$t('addEmailVerification')}}</span></div>
|
||||
<div>
|
||||
<el-switch @change="change" :before-change="beforeChange" :active-value="0" :inactive-value="1"
|
||||
v-model="setting.addEmailVerify"/>
|
||||
<el-button class="opt-button" size="small" type="primary" @click="openAddVerifyCount">
|
||||
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
|
||||
</el-button>
|
||||
<el-select
|
||||
@change="change"
|
||||
:style="`width: ${ locale === 'en' ? 100 : 80 }px;`"
|
||||
v-model="setting.addEmailVerify"
|
||||
placeholder="Select"
|
||||
class="bot-verify-select"
|
||||
>
|
||||
<el-option key="1" :value="0" :label="$t('enable')" />
|
||||
<el-option key="1" :value="1" :label="$t('disable')" />
|
||||
<el-option key="1" :value="2" :label="$t('rulesVerify')" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
@@ -450,6 +474,19 @@
|
||||
<el-table-column :width="tokenColumnWidth" property="value" label="Token" fixed="right" :show-overflow-tooltip="true" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="showRegVerifyCount" :title="$t('rulesVerifyTitle',{count: regVerifyCount})" @closed="regVerifyCount = setting.regVerifyCount" >
|
||||
<form>
|
||||
<el-input-number type="text" v-model="regVerifyCount" :min="1" >
|
||||
</el-input-number>
|
||||
<el-button type="primary" :loading="settingLoading" @click="saveRegVerifyCount">{{$t('save')}}</el-button>
|
||||
</form>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="showAddVerifyCount" :title="$t('rulesVerifyTitle',{count: addVerifyCount})" @closed="addVerifyCount = setting.addVerifyCount">
|
||||
<form>
|
||||
<el-input-number type="text" v-model="addVerifyCount" :min="1"/>
|
||||
<el-button type="primary" :loading="settingLoading" @click="saveAddVerifyCount">{{$t('save')}}</el-button>
|
||||
</form>
|
||||
</el-dialog>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
@@ -497,7 +534,11 @@ const loginOpacity = ref(0)
|
||||
const backgroundUrl = ref('')
|
||||
let backgroundFile = {}
|
||||
const showSetBackground = ref(false)
|
||||
let regVerifyCount = ref(1)
|
||||
let addVerifyCount = ref(1)
|
||||
let backup = '{}'
|
||||
const showAddVerifyCount = ref(false)
|
||||
const showRegVerifyCount = ref(false)
|
||||
const resendTokenForm = reactive({
|
||||
domain: '',
|
||||
token: '',
|
||||
@@ -542,8 +583,20 @@ settingQuery().then(settingData => {
|
||||
backgroundUrl.value = setting.value.background?.startsWith('http') ? setting.value.background : ''
|
||||
editTitle.value = setting.value.title
|
||||
r2DomainInput.value = setting.value.r2Domain
|
||||
addVerifyCount.value = setting.value.addVerifyCount
|
||||
regVerifyCount.value = setting.value.regVerifyCount
|
||||
})
|
||||
|
||||
function openAddVerifyCount() {
|
||||
if (settingLoading.value) return
|
||||
showAddVerifyCount.value = true
|
||||
}
|
||||
|
||||
function openRegVerifyCount() {
|
||||
if (settingLoading.value) return
|
||||
showRegVerifyCount.value = true
|
||||
}
|
||||
|
||||
const resendList = computed(() => {
|
||||
|
||||
let list = Object.keys(setting.value.resendTokens).map(key => {
|
||||
@@ -566,6 +619,20 @@ const resendList = computed(() => {
|
||||
return list;
|
||||
});
|
||||
|
||||
function saveAddVerifyCount() {
|
||||
if(!addVerifyCount.value) {
|
||||
addVerifyCount.value = 1
|
||||
}
|
||||
editSetting({addVerifyCount: addVerifyCount.value})
|
||||
}
|
||||
|
||||
function saveRegVerifyCount() {
|
||||
if (!regVerifyCount.value) {
|
||||
regVerifyCount.value = 1
|
||||
}
|
||||
editSetting({regVerifyCount: regVerifyCount.value})
|
||||
}
|
||||
|
||||
const compareByLengthAndUpperCase = (a, b, key) => {
|
||||
const getUpperCaseCount = (str) => (str.match(/[A-Z]/g) || []).length;
|
||||
if (a[key].length === b[key].length) {
|
||||
@@ -742,9 +809,9 @@ async function saveBackground() {
|
||||
if (localUpShow.value) {
|
||||
image = await fileToBase64(backgroundFile,true);
|
||||
} else {
|
||||
if (!backgroundUrl.value.startsWith('http')) {
|
||||
if (backgroundUrl.value && !backgroundUrl.value.startsWith('http')) {
|
||||
ElMessage({
|
||||
message: '图片地址不正确',
|
||||
message: t('imageLinkErrorMsg'),
|
||||
type: "error",
|
||||
plain: true
|
||||
})
|
||||
@@ -872,8 +939,9 @@ function editSetting(settingForm, refreshStatus = true) {
|
||||
tgSettingShow.value = false
|
||||
thirdEmailShow.value = false
|
||||
forwardRulesShow.value = false
|
||||
showAddVerifyCount.value = false
|
||||
showRegVerifyCount.value = false
|
||||
}).catch((e) => {
|
||||
console.error(e)
|
||||
loginOpacity.value = setting.value.loginOpacity
|
||||
setting.value = {...setting.value, ...JSON.parse(backup)}
|
||||
}).finally(() => {
|
||||
@@ -941,7 +1009,9 @@ function editSetting(settingForm, refreshStatus = true) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.bot-verify-select {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.settings-card {
|
||||
background-color: #fff;
|
||||
|
||||
Reference in New Issue
Block a user