mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	add email white list
This commit is contained in:
		@@ -9,6 +9,8 @@
 | 
			
		||||
* 功能新增:新增GeeK易支付支付渠道,支持支付宝,微信支付,QQ钱包,京东支付,抖音支付,Paypal支付等支付方式
 | 
			
		||||
* Bug修复:修复注册页面 tab 组件没有自动选中问题 [#6](https://github.com/yangjian102621/geekai-plus/issues/6)
 | 
			
		||||
* 功能优化:Luma生成视频任务增加自动翻译功能
 | 
			
		||||
* Bug修复:Suno 和 Luma 任务没有判断用户算力
 | 
			
		||||
* 功能新增:邮箱注册增加邮箱后缀白名单,防止使用某些垃圾邮箱注册薅羊毛
 | 
			
		||||
 | 
			
		||||
## v4.1.3
 | 
			
		||||
* 功能优化:重构用户登录模块,给所有的登录组件增加行为验证码功能,支持用户绑定手机,邮箱和微信
 | 
			
		||||
 
 | 
			
		||||
@@ -164,5 +164,6 @@ type SystemConfig struct {
 | 
			
		||||
	Copyright   string `json:"copyright"`     // 版权信息
 | 
			
		||||
	MarkMapText string `json:"mark_map_text"` // 思维导入的默认文本
 | 
			
		||||
 | 
			
		||||
	EnabledVerify bool `json:"enabled_verify"` // 是否启用验证码
 | 
			
		||||
	EnabledVerify  bool     `json:"enabled_verify"`   // 是否启用验证码
 | 
			
		||||
	EmailWhiteList []string `json:"email_white_list"` // 邮箱白名单列表
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,20 @@ func (h *SmsHandler) SendCode(c *gin.Context) {
 | 
			
		||||
			resp.ERROR(c, "系统已禁用邮箱注册!")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// 检查邮箱后缀是否在白名单
 | 
			
		||||
		if len(h.App.SysConfig.EmailWhiteList) > 0 {
 | 
			
		||||
			inWhiteList := false
 | 
			
		||||
			for _, suffix := range h.App.SysConfig.EmailWhiteList {
 | 
			
		||||
				if strings.HasSuffix(data.Receiver, suffix) {
 | 
			
		||||
					inWhiteList = true
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if !inWhiteList {
 | 
			
		||||
				resp.ERROR(c, "邮箱后缀不在白名单中")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		err = h.smtp.SendVerifyCode(data.Receiver, code)
 | 
			
		||||
	} else {
 | 
			
		||||
		if !utils.Contains(h.App.SysConfig.RegisterWays, "mobile") {
 | 
			
		||||
 
 | 
			
		||||
@@ -47,6 +47,7 @@ watch(() => props.value, (newValue) => {
 | 
			
		||||
  model.value = newValue
 | 
			
		||||
})
 | 
			
		||||
const model = ref(props.value)
 | 
			
		||||
// eslint-disable-next-line no-undef
 | 
			
		||||
const emits = defineEmits(['update:value']);
 | 
			
		||||
const onInput = (value) => {
 | 
			
		||||
  emits('update:value',value)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								web/src/components/ui/ItemsInput.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								web/src/components/ui/ItemsInput.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <!-- 多项目输入组件 -->
 | 
			
		||||
  <div class="items-input-box">
 | 
			
		||||
    <el-tag
 | 
			
		||||
        v-for="tag in tags"
 | 
			
		||||
        :key="tag"
 | 
			
		||||
        closable
 | 
			
		||||
        :disable-transitions="false"
 | 
			
		||||
        @close="handleClose(tag)"
 | 
			
		||||
    >
 | 
			
		||||
      {{ tag }}
 | 
			
		||||
    </el-tag>
 | 
			
		||||
    <el-input
 | 
			
		||||
        v-if="inputVisible"
 | 
			
		||||
        ref="InputRef"
 | 
			
		||||
        v-model="inputValue"
 | 
			
		||||
        class="w-20"
 | 
			
		||||
        size="small"
 | 
			
		||||
        @keyup.enter="handleInputConfirm"
 | 
			
		||||
        @blur="handleInputConfirm"
 | 
			
		||||
    />
 | 
			
		||||
    <el-button v-else class="button-new-tag" size="small" @click="showInput">
 | 
			
		||||
      + 新增
 | 
			
		||||
    </el-button>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup>
 | 
			
		||||
 | 
			
		||||
import {nextTick, ref, watch} from "vue";
 | 
			
		||||
// eslint-disable-next-line no-undef
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  value : {
 | 
			
		||||
    type: Array,
 | 
			
		||||
    default: () => []
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
// eslint-disable-next-line no-undef
 | 
			
		||||
const emits = defineEmits(['update:value']);
 | 
			
		||||
const tags = ref(props.value)
 | 
			
		||||
const inputValue = ref('')
 | 
			
		||||
const inputVisible = ref(false)
 | 
			
		||||
const InputRef = ref(null)
 | 
			
		||||
 | 
			
		||||
watch(() => props.value, (newValue) => {
 | 
			
		||||
  tags.value = newValue
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const handleClose = (tag) => {
 | 
			
		||||
  tags.value.splice(tags.value.indexOf(tag), 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const showInput = () => {
 | 
			
		||||
  inputVisible.value = true
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    InputRef.value?.input?.focus()
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const handleInputConfirm = () => {
 | 
			
		||||
  if (inputValue.value) {
 | 
			
		||||
    tags.value.push(inputValue.value)
 | 
			
		||||
  }
 | 
			
		||||
  inputVisible.value = false
 | 
			
		||||
  inputValue.value = ''
 | 
			
		||||
  emits('update:value', tags.value)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="stylus">
 | 
			
		||||
.items-input-box {
 | 
			
		||||
  display flex
 | 
			
		||||
 | 
			
		||||
  .el-tag {
 | 
			
		||||
    display flex
 | 
			
		||||
    margin-right 6px
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -133,6 +133,10 @@
 | 
			
		||||
                  </el-checkbox-group>
 | 
			
		||||
                </el-form-item>
 | 
			
		||||
 | 
			
		||||
                <el-form-item label="邮件域名白名单" prop="register_ways">
 | 
			
		||||
                  <items-input v-model:value="system['email_white_list']"/>
 | 
			
		||||
                </el-form-item>
 | 
			
		||||
 | 
			
		||||
                <el-form-item label="微信客服二维码" prop="wechat_card_url">
 | 
			
		||||
                  <el-input v-model="system['wechat_card_url']" placeholder="微信客服二维码">
 | 
			
		||||
                    <template #append>
 | 
			
		||||
@@ -410,6 +414,7 @@ import MdEditor from "md-editor-v3";
 | 
			
		||||
import 'md-editor-v3/lib/style.css';
 | 
			
		||||
import Menu from "@/views/admin/Menu.vue";
 | 
			
		||||
import {copyObj, dateFormat} from "@/utils/libs";
 | 
			
		||||
import ItemsInput from "@/components/ui/ItemsInput.vue";
 | 
			
		||||
 | 
			
		||||
const activeName = ref('basic')
 | 
			
		||||
const system = ref({models: []})
 | 
			
		||||
@@ -475,7 +480,6 @@ const save = function (key) {
 | 
			
		||||
  if (key === 'system') {
 | 
			
		||||
    systemFormRef.value.validate((valid) => {
 | 
			
		||||
      if (valid) {
 | 
			
		||||
        system.value['power_price'] = parseFloat(system.value['power_price']) ?? 0
 | 
			
		||||
        httpPost('/api/admin/config/update', {key: key, config: system.value, config_bak: configBak.value}).then(() => {
 | 
			
		||||
          ElMessage.success("操作成功!")
 | 
			
		||||
        }).catch(e => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user