mirror of https://github.com/certd/certd
				
				
				
			chore: plus
							parent
							
								
									d5d54d4d3b
								
							
						
					
					
						commit
						8e50e5dee3
					
				|  | @ -7,11 +7,13 @@ | |||
|       <a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off"> | ||||
|         <a-form-item label="OTP多重验证登录" :name="['authenticator', 'enabled']"> | ||||
|           <div class="flex mt-5"> | ||||
|             <a-switch v-model:checked="formState.authenticator.enabled" @change="onAuthenticatorEnabledChanged" /> | ||||
|             <a-switch v-model:checked="formState.authenticator.enabled" :disabled="!settingsStore.isPlus" @change="onAuthenticatorEnabledChanged" /> | ||||
| 
 | ||||
|             <a-button v-if="formState.authenticator.enabled && formState.authenticator.verified" :disabled="authenticatorOpenRef" size="small" class="ml-2" type="primary" @click="authenticatorForm.open = true"> | ||||
|             <a-button v-if="formState.authenticator.enabled && formState.authenticator.verified" :disabled="authenticatorOpenRef" size="small" class="ml-5" type="primary" @click="authenticatorForm.open = true"> | ||||
|               重新绑定 | ||||
|             </a-button> | ||||
| 
 | ||||
|             <vip-button class="ml-5" mode="button"></vip-button> | ||||
|           </div> | ||||
| 
 | ||||
|           <div class="helper">是否开启多重验证登录</div> | ||||
|  | @ -45,7 +47,8 @@ import * as api from "./api"; | |||
| import { UserTwoFactorSetting } from "./api"; | ||||
| import { Modal, notification } from "ant-design-vue"; | ||||
| import { merge } from "lodash-es"; | ||||
| 
 | ||||
| import { useSettingStore } from "/@/store/settings"; | ||||
| const settingsStore = useSettingStore(); | ||||
| defineOptions({ | ||||
|   name: "UserSecurity", | ||||
| }); | ||||
|  | @ -92,7 +95,7 @@ const doAuthenticatorSave = async (form: any) => { | |||
|   authenticatorForm.open = false; | ||||
| }; | ||||
| 
 | ||||
| function onAuthenticatorEnabledChanged(value) { | ||||
| function onAuthenticatorEnabledChanged(value: any) { | ||||
|   if (!value) { | ||||
|     //要关闭 | ||||
|     if (formState.authenticator.verified) { | ||||
|  |  | |||
|  | @ -66,34 +66,34 @@ import { useSettingStore } from "/@/store/settings"; | |||
| import { notification } from "ant-design-vue"; | ||||
| 
 | ||||
| defineOptions({ | ||||
|   name: "SettingRegister" | ||||
|   name: "SettingRegister", | ||||
| }); | ||||
| 
 | ||||
| const testMobile = ref(""); | ||||
| async function testSendSms() { | ||||
|   if (!testMobile.value) { | ||||
|     notification.error({ | ||||
|       message: "请输入测试手机号" | ||||
|       message: "请输入测试手机号", | ||||
|     }); | ||||
|     return; | ||||
|   } | ||||
|   await api.TestSms({ | ||||
|     mobile: testMobile.value | ||||
|     mobile: testMobile.value, | ||||
|   }); | ||||
|   notification.success({ | ||||
|     message: "发送成功" | ||||
|     message: "发送成功", | ||||
|   }); | ||||
| } | ||||
| const formState = reactive<Partial<SysSettings>>({ | ||||
|   public: { | ||||
|     registerEnabled: false | ||||
|     registerEnabled: false, | ||||
|   }, | ||||
|   private: { | ||||
|     sms: { | ||||
|       type: "aliyun", | ||||
|       config: {} | ||||
|     } | ||||
|   } | ||||
|       config: {}, | ||||
|     }, | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| const rules = { | ||||
|  | @ -103,13 +103,13 @@ const rules = { | |||
|         return Promise.reject("密码登录和手机号登录至少开启一个"); | ||||
|       } | ||||
|       return Promise.resolve(); | ||||
|     } | ||||
|     }, | ||||
|   }, | ||||
|   required: { | ||||
|     required: true, | ||||
|     trigger: "change", | ||||
|     message: "此项必填" | ||||
|   } | ||||
|     message: "此项必填", | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| async function smsTypeChange(value: string) { | ||||
|  | @ -124,13 +124,13 @@ async function loadTypeDefine(type: string) { | |||
|   const define: any = await api.GetSmsTypeDefine(type); | ||||
|   const keys = Object.keys(define.input); | ||||
|   const inputs: any = {}; | ||||
|   keys.forEach((key) => { | ||||
|   keys.forEach(key => { | ||||
|     const value = define.input[key]; | ||||
|     value.simpleKey = key; | ||||
|     value.key = "private.sms.config." + key; | ||||
|     if (!value.component) { | ||||
|       value.component = { | ||||
|         name: "a-input" | ||||
|         name: "a-input", | ||||
|       }; | ||||
|     } | ||||
|     if (!value.component.name) { | ||||
|  | @ -165,7 +165,7 @@ const onFinish = async (form: any) => { | |||
|     await api.SysSettingsSave(form); | ||||
|     await settingsStore.loadSysSettings(); | ||||
|     notification.success({ | ||||
|       message: "保存成功" | ||||
|       message: "保存成功", | ||||
|     }); | ||||
|   } finally { | ||||
|     saveLoading.value = false; | ||||
|  |  | |||
|  | @ -3,7 +3,11 @@ | |||
|     <a-form ref="formRef" :model="formState" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off"> | ||||
|       <h2>站点隐藏</h2> | ||||
|       <a-form-item label="启用站点隐藏" :name="['hidden', 'enabled']" :required="true"> | ||||
|         <a-switch v-model:checked="formState.hidden.enabled" /> | ||||
|         <div class="flex"> | ||||
|           <a-switch v-model:checked="formState.hidden.enabled" :disabled="!settingsStore.isPlus" /> | ||||
|           <vip-button class="ml-5" mode="button"></vip-button> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="helper"> | ||||
|           可以在平时关闭站点的可访问性,需要时再打开,增强站点安全性 | ||||
|           <a href="https://certd.docmirror.cn/guide/feature/safe/hidden" class="flex items-center" target="_blank"> | ||||
|  | @ -52,10 +56,11 @@ import { merge } from "lodash-es"; | |||
| import { Modal, notification } from "ant-design-vue"; | ||||
| import { request } from "/@/api/service"; | ||||
| import { util, utils } from "/@/utils"; | ||||
| import { useSettingStore } from "/@/store/settings"; | ||||
| defineOptions({ | ||||
|   name: "SettingSafe", | ||||
| }); | ||||
| 
 | ||||
| const settingsStore = useSettingStore(); | ||||
| const api = { | ||||
|   async SettingGet() { | ||||
|     return await request({ | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import {ALL, Body, Controller, Inject, Post, Provide} from '@midwayjs/core'; | |||
| import {BaseController, SysSafeSetting} from '@certd/lib-server'; | ||||
| import {cloneDeep} from 'lodash-es'; | ||||
| import {SafeService} from "../../../modules/sys/settings/safe-service.js"; | ||||
| import {isPlus} from "@certd/plus-core"; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  | @ -24,6 +25,9 @@ export class SysSettingsController extends BaseController { | |||
| 
 | ||||
|   @Post("/save", { summary: "sys:settings:edit" }) | ||||
|   async safeSave(@Body(ALL) body: any) { | ||||
|     if (!isPlus()) { | ||||
|       throw new Error('本功能需要开通专业版') | ||||
|     } | ||||
|     await this.safeService.saveSafeSetting(body); | ||||
|     return this.ok({}); | ||||
|   } | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import { UserSettingsService } from "../../../modules/mine/service/user-settings | |||
| import { UserTwoFactorSetting } from "../../../modules/mine/service/models.js"; | ||||
| import { merge } from "lodash-es"; | ||||
| import { TwoFactorService } from "../../../modules/mine/service/two-factor-service.js"; | ||||
| import {isPlus} from "@certd/plus-core"; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
|  | @ -27,6 +28,9 @@ export class UserTwoFactorSettingController extends BaseController { | |||
| 
 | ||||
|   @Post("/save", { summary: Constants.per.authOnly }) | ||||
|   async save(@Body(ALL) bean: any) { | ||||
|     if (!isPlus()) { | ||||
|       throw new Error('本功能需要开通专业版') | ||||
|     } | ||||
|     const userId = this.getUserId(); | ||||
|     const setting = new UserTwoFactorSetting(); | ||||
|     merge(setting, bean); | ||||
|  | @ -50,6 +54,9 @@ export class UserTwoFactorSettingController extends BaseController { | |||
| 
 | ||||
|   @Post("/authenticator/save", { summary: Constants.per.authOnly }) | ||||
|   async authenticatorSave(@Body(ALL) bean: any) { | ||||
|     if (!isPlus()) { | ||||
|       throw new Error('本功能需要开通专业版') | ||||
|     } | ||||
|     const userId = this.getUserId(); | ||||
|     await this.twoFactorService.saveAuthenticator({ | ||||
|         userId, | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ import {LoginErrorException} from '@certd/lib-server/dist/basic/exception/login- | |||
| import {CodeService} from '../../basic/service/code-service.js'; | ||||
| import {TwoFactorService} from "../../mine/service/two-factor-service.js"; | ||||
| import {UserSettingsService} from '../../mine/service/user-settings-service.js'; | ||||
| import {isPlus} from "@certd/plus-core"; | ||||
| 
 | ||||
| /** | ||||
|  * 系统用户 | ||||
|  | @ -146,6 +147,9 @@ export class LoginService { | |||
| 
 | ||||
|   async checkTwoFactorEnabled(userId: number) { | ||||
|     //检查是否开启多重认证
 | ||||
|     if (!isPlus()) { | ||||
|       return true | ||||
|     } | ||||
| 
 | ||||
|     const twoFactorSetting = await this.twoFactorService.getSetting(userId) | ||||
| 
 | ||||
|  | @ -162,6 +166,10 @@ export class LoginService { | |||
|   } | ||||
| 
 | ||||
|   async loginByTwoFactor(req: { loginCode: string; verifyCode: string }) { | ||||
|     //检查是否开启多重认证
 | ||||
|     if (!isPlus()) { | ||||
|       throw new Error('本功能需要开通专业版') | ||||
|     } | ||||
|     const userId = cache.get(`login_2fa_code:${req.loginCode}`) | ||||
|     if (!userId) { | ||||
|       throw new AuthException('登录状态已失效,请重新登录') | ||||
|  | @ -180,7 +188,6 @@ export class LoginService { | |||
|   } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   /** | ||||
|    * 生成token | ||||
|    * @param user 用户对象 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 xiaojunnuo
						xiaojunnuo