diff --git a/apps/application/serializers/application_serializers.py b/apps/application/serializers/application_serializers.py index 49400d2e5..c06277d7f 100644 --- a/apps/application/serializers/application_serializers.py +++ b/apps/application/serializers/application_serializers.py @@ -312,6 +312,20 @@ class ApplicationSerializer(serializers.Serializer): if 'show_source' in instance and instance.get('show_source') is not None: application_access_token.show_source = instance.get('show_source') application_access_token.save() + application_setting_model = DBModelManage.get_model('application_setting') + X_PACK_LICENSE_IS_VALID = (settings.XPACK_LICENSE_IS_VALID if hasattr(settings, + 'XPACK_LICENSE_IS_VALID') else False) + if application_setting_model is not None and X_PACK_LICENSE_IS_VALID: + application_setting, _ = application_setting_model.objects.get_or_create( + application_id=self.data.get('application_id')) + if application_setting is not None: + application_setting.authentication = instance.get('authentication') + application_setting.authentication_value = { + "type": "password", + "value": instance.get('authentication_value') + } + application_setting.save() + get_application_access_token(application_access_token.access_token, False) return self.one(with_valid=False) @@ -734,7 +748,8 @@ class ApplicationSerializer(serializers.Serializer): 'draggable': application_setting.draggable, 'show_guide': application_setting.show_guide, 'avatar': application_setting.avatar, - 'float_icon': application_setting.float_icon} + 'float_icon': application_setting.float_icon, + 'authentication': application_setting.authentication} return ApplicationSerializer.Query.reset_application( {**ApplicationSerializer.ApplicationModel(application).data, 'stt_model_id': application.stt_model_id, diff --git a/ui/src/api/application.ts b/ui/src/api/application.ts index f03e9950f..c32f232df 100644 --- a/ui/src/api/application.ts +++ b/ui/src/api/application.ts @@ -387,6 +387,15 @@ const updatePlatformStatus: (application_id: string, data: any) => Promise { return post(`/platform/${application_id}/status`, data) } +/** + * 验证密码 + */ +const validatePassword: (application_id: string, password: string) => Promise> = ( + application_id, + password +) => { + return get(`/application/${application_id}/auth/${password}`, undefined) +} export default { getAllAppilcation, @@ -419,5 +428,6 @@ export default { getPlatformStatus, getPlatformConfig, updatePlatformConfig, - updatePlatformStatus + updatePlatformStatus, + validatePassword } diff --git a/ui/src/locales/lang/en_US/views/application-overview.ts b/ui/src/locales/lang/en_US/views/application-overview.ts index d6f64ff8e..2875f3349 100644 --- a/ui/src/locales/lang/en_US/views/application-overview.ts +++ b/ui/src/locales/lang/en_US/views/application-overview.ts @@ -65,6 +65,8 @@ export default { dialogTitle: 'Access Restrictions', showSourceLabel: 'Show Source', clientQueryLimitLabel: 'Each Client Query Limit', + authentication: 'Authentication', + authenticationValue: 'Authentication Password', timesDays: 'Times/Day', whitelistLabel: 'Whitelist', whitelistPlaceholder: diff --git a/ui/src/locales/lang/zh_CN/views/application-overview.ts b/ui/src/locales/lang/zh_CN/views/application-overview.ts index 1b583e236..058b93986 100644 --- a/ui/src/locales/lang/zh_CN/views/application-overview.ts +++ b/ui/src/locales/lang/zh_CN/views/application-overview.ts @@ -65,6 +65,8 @@ export default { showSourceLabel: '显示知识来源', clientQueryLimitLabel: '每个客户端提问限制', timesDays: '次/天', + authentication: '身份验证', + authenticationValue: '验证密码', whitelistLabel: '白名单', whitelistPlaceholder: '请输入允许嵌入第三方的源地址,一行一个,如:\nhttp://127.0.0.1:5678\nhttps://dataease.io', diff --git a/ui/src/stores/modules/application.ts b/ui/src/stores/modules/application.ts index 7e96d2b4c..742374d81 100644 --- a/ui/src/stores/modules/application.ts +++ b/ui/src/stores/modules/application.ts @@ -119,6 +119,18 @@ const useApplicationStore = defineStore({ reject(error) }) }) + }, + async validatePassword(id: string, password: string, loading?: Ref) { + return new Promise((resolve, reject) => { + applicationApi + .validatePassword(id, password) + .then((data) => { + resolve(data) + }) + .catch((error) => { + reject(error) + }) + }) } } }) diff --git a/ui/src/views/application-overview/component/LimitDialog.vue b/ui/src/views/application-overview/component/LimitDialog.vue index db2a94ea6..d794d4ac7 100644 --- a/ui/src/views/application-overview/component/LimitDialog.vue +++ b/ui/src/views/application-overview/component/LimitDialog.vue @@ -27,6 +27,30 @@ $t('views.applicationOverview.appInfo.LimitDialog.timesDays') }} + + + + + + + + + + + + + ({ access_num: 0, white_active: true, - white_list: '' + white_list: '', + authentication_value: '', + authentication: false }) const dialogVisible = ref(false) @@ -93,6 +121,8 @@ const open = (data: any) => { form.value.access_num = data.access_num form.value.white_active = data.white_active form.value.white_list = data.white_list?.length ? data.white_list?.join('\n') : '' + form.value.authentication_value = data.authentication_value + form.value.authentication = data.authentication dialogVisible.value = true } @@ -103,7 +133,9 @@ const submit = async (formEl: FormInstance | undefined) => { const obj = { white_list: form.value.white_list ? form.value.white_list.split('\n') : [], white_active: form.value.white_active, - access_num: form.value.access_num + access_num: form.value.access_num, + authentication: form.value.authentication, + authentication_value: form.value.authentication_value } applicationApi.putAccessToken(id as string, obj, loading).then((res) => { emit('refresh') @@ -114,6 +146,17 @@ const submit = async (formEl: FormInstance | undefined) => { } }) } +function generateAuthenticationValue(length: number = 10) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + const randomValues = new Uint8Array(length) + window.crypto.getRandomValues(randomValues) + return Array.from(randomValues) + .map((value) => chars[value % chars.length]) + .join('') +} +function refreshAuthentication() { + form.value.authentication_value = generateAuthenticationValue() +} defineExpose({ open }) diff --git a/ui/src/views/chat/embed/index.vue b/ui/src/views/chat/embed/index.vue index 867025733..527205b10 100644 --- a/ui/src/views/chat/embed/index.vue +++ b/ui/src/views/chat/embed/index.vue @@ -1,101 +1,130 @@