Merge branch 'langgenius:main' into main

pull/19680/head
wowzap 1 year ago committed by GitHub
commit f6a4241a6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -62,27 +62,27 @@ def initialize_extensions(app: DifyApp):
) )
extensions = [ extensions = [
ext_timezone,
ext_logging,
ext_warnings,
ext_import_modules,
ext_set_secretkey,
ext_compress,
ext_code_based_extension,
ext_database,
ext_app_metrics, ext_app_metrics,
ext_migrate, ext_blueprints,
ext_redis,
ext_storage,
ext_celery, ext_celery,
ext_code_based_extension,
ext_commands,
ext_compress,
ext_database,
ext_hosting_provider,
ext_import_modules,
ext_logging,
ext_login, ext_login,
ext_mail, ext_mail,
ext_hosting_provider, ext_migrate,
ext_sentry,
ext_proxy_fix,
ext_blueprints,
ext_commands,
ext_otel, ext_otel,
ext_proxy_fix,
ext_redis,
ext_sentry,
ext_set_secretkey,
ext_storage,
ext_timezone,
ext_warnings,
] ]
for ext in extensions: for ext in extensions:
short_name = ext.__name__.split(".")[-1] short_name = ext.__name__.split(".")[-1]

@ -52,7 +52,7 @@ class Account(UserMixin, Base):
@current_tenant.setter @current_tenant.setter
def current_tenant(self, value: "Tenant"): def current_tenant(self, value: "Tenant"):
tenant = value tenant = value
ta = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=self.id).first() ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=self.id).first()
if ta: if ta:
tenant.current_role = ta.role tenant.current_role = ta.role
else: else:

@ -47,7 +47,9 @@ def mail_clean_document_notify_task():
if not tenant: if not tenant:
continue continue
# check current owner # check current owner
current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first() current_owner_join = (
db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, role="owner").first()
)
if not current_owner_join: if not current_owner_join:
continue continue
account = Account.query.filter(Account.id == current_owner_join.account_id).first() account = Account.query.filter(Account.id == current_owner_join.account_id).first()

@ -615,7 +615,10 @@ class TenantService:
): ):
"""Check if user have a workspace or not""" """Check if user have a workspace or not"""
available_ta = ( available_ta = (
TenantAccountJoin.query.filter_by(account_id=account.id).order_by(TenantAccountJoin.id.asc()).first() db.session.query(TenantAccountJoin)
.filter_by(account_id=account.id)
.order_by(TenantAccountJoin.id.asc())
.first()
) )
if available_ta: if available_ta:
@ -669,7 +672,7 @@ class TenantService:
if not tenant: if not tenant:
raise TenantNotFoundError("Tenant not found.") raise TenantNotFoundError("Tenant not found.")
ta = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=account.id).first() ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=account.id).first()
if ta: if ta:
tenant.role = ta.role tenant.role = ta.role
else: else:
@ -698,7 +701,7 @@ class TenantService:
if not tenant_account_join: if not tenant_account_join:
raise AccountNotLinkTenantError("Tenant not found or account is not a member of the tenant.") raise AccountNotLinkTenantError("Tenant not found or account is not a member of the tenant.")
else: else:
TenantAccountJoin.query.filter( db.session.query(TenantAccountJoin).filter(
TenantAccountJoin.account_id == account.id, TenantAccountJoin.tenant_id != tenant_id TenantAccountJoin.account_id == account.id, TenantAccountJoin.tenant_id != tenant_id
).update({"current": False}) ).update({"current": False})
tenant_account_join.current = True tenant_account_join.current = True
@ -790,7 +793,7 @@ class TenantService:
if operator.id == member.id: if operator.id == member.id:
raise CannotOperateSelfError("Cannot operate self.") raise CannotOperateSelfError("Cannot operate self.")
ta_operator = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=operator.id).first() ta_operator = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=operator.id).first()
if not ta_operator or ta_operator.role not in perms[action]: if not ta_operator or ta_operator.role not in perms[action]:
raise NoPermissionError(f"No permission to {action} member.") raise NoPermissionError(f"No permission to {action} member.")
@ -803,7 +806,7 @@ class TenantService:
TenantService.check_member_permission(tenant, operator, account, "remove") TenantService.check_member_permission(tenant, operator, account, "remove")
ta = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=account.id).first() ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=account.id).first()
if not ta: if not ta:
raise MemberNotInTenantError("Member not in tenant.") raise MemberNotInTenantError("Member not in tenant.")
@ -815,15 +818,23 @@ class TenantService:
"""Update member role""" """Update member role"""
TenantService.check_member_permission(tenant, operator, member, "update") TenantService.check_member_permission(tenant, operator, member, "update")
target_member_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=member.id).first() target_member_join = (
db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=member.id).first()
)
if not target_member_join:
raise MemberNotInTenantError("Member not in tenant.")
if target_member_join.role == new_role: if target_member_join.role == new_role:
raise RoleAlreadyAssignedError("The provided role is already assigned to the member.") raise RoleAlreadyAssignedError("The provided role is already assigned to the member.")
if new_role == "owner": if new_role == "owner":
# Find the current owner and change their role to 'admin' # Find the current owner and change their role to 'admin'
current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first() current_owner_join = (
current_owner_join.role = "admin" db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, role="owner").first()
)
if current_owner_join:
current_owner_join.role = "admin"
# Update the role of the target member # Update the role of the target member
target_member_join.role = new_role target_member_join.role = new_role
@ -962,7 +973,7 @@ class RegisterService:
TenantService.switch_tenant(account, tenant.id) TenantService.switch_tenant(account, tenant.id)
else: else:
TenantService.check_member_permission(tenant, inviter, account, "add") TenantService.check_member_permission(tenant, inviter, account, "add")
ta = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, account_id=account.id).first() ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=account.id).first()
if not ta: if not ta:
TenantService.create_tenant_member(tenant, account, role) TenantService.create_tenant_member(tenant, account, role)

@ -1040,10 +1040,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1335,10 +1333,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1620,10 +1616,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -501,7 +501,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="レスポンス"> <CodeGroup title="レスポンス">
```text {{ title: 'Response' }} ```text {{ title: 'レスポンス' }}
204 No Content 204 No Content
``` ```
</CodeGroup> </CodeGroup>
@ -797,10 +797,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="レスポンス"> <CodeGroup title="レスポンス">
```json {{ title: 'Response' }} ```text {{ title: 'レスポンス' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1092,10 +1090,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="レスポンス"> <CodeGroup title="レスポンス">
```json {{ title: 'Response' }} ```text {{ title: 'レスポンス' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1377,10 +1373,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="レスポンス"> <CodeGroup title="レスポンス">
```json {{ title: 'Response' }} ```text {{ title: 'レスポンス' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -1047,10 +1047,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1342,10 +1340,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1628,10 +1624,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
``` ```
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -738,8 +738,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{"result": "success"} 204 No Content
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -765,10 +765,8 @@ Chat applications support session persistence, allowing previous chat history to
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1432,8 +1430,8 @@ Chat applications support session persistence, allowing previous chat history to
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{"result": "success"} 204 No Content
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -764,10 +764,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</CodeGroup> </CodeGroup>
<CodeGroup title="応答"> <CodeGroup title="応答">
```json {{ title: '応答' }} ```text {{ title: '応答' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -799,10 +799,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1456,8 +1454,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{"result": "success"} 204 No Content
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -798,10 +798,8 @@ Chat applications support session persistence, allowing previous chat history to
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>
@ -1472,8 +1470,8 @@ Chat applications support session persistence, allowing previous chat history to
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{"result": "success"} 204 No Content
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -797,10 +797,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</CodeGroup> </CodeGroup>
<CodeGroup title="応答"> <CodeGroup title="応答">
```json {{ title: '応答' }} ```text {{ title: '応答' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -811,10 +811,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</CodeGroup> </CodeGroup>
<CodeGroup title="Response"> <CodeGroup title="Response">
```json {{ title: 'Response' }} ```text {{ title: 'Response' }}
{ 204 No Content
"result": "success"
}
``` ```
</CodeGroup> </CodeGroup>
</Col> </Col>

@ -1,6 +1,5 @@
'use client' 'use client'
import React, { useCallback, useEffect, useRef, useState } from 'react' import React, { useCallback, useEffect, useRef, useState } from 'react'
import { basePath } from '@/utils/var'
import { t } from 'i18next' import { t } from 'i18next'
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
import s from './index.module.css' import s from './index.module.css'
@ -19,7 +18,8 @@ const InvitationLink = ({
const selector = useRef(`invite-link-${randomString(4)}`) const selector = useRef(`invite-link-${randomString(4)}`)
const copyHandle = useCallback(() => { const copyHandle = useCallback(() => {
copy(`${!value.url.startsWith('http') ? window.location.origin : ''}${basePath}${value.url}`) // No prefix is needed here because the backend has already processed it
copy(`${!value.url.startsWith('http') ? window.location.origin : ''}${value.url}`)
setIsCopied(true) setIsCopied(true)
}, [value]) }, [value])
@ -42,7 +42,7 @@ const InvitationLink = ({
<Tooltip <Tooltip
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
> >
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={copyHandle}>{basePath + value.url}</div> <div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={copyHandle}>{value.url}</div>
</Tooltip> </Tooltip>
</div> </div>
<div className="h-4 shrink-0 border bg-divider-regular" /> <div className="h-4 shrink-0 border bg-divider-regular" />

@ -2,7 +2,7 @@ const translation = {
toVerified: 'Get Education Verified', toVerified: 'Get Education Verified',
toVerifiedTip: { toVerifiedTip: {
front: 'You are now eligible for Education Verified status. Please enter your education information below to complete the process and receive an', front: 'You are now eligible for Education Verified status. Please enter your education information below to complete the process and receive an',
coupon: 'exclusive 50% coupon', coupon: 'exclusive 100% coupon',
end: 'for the Dify Professional Plan.', end: 'for the Dify Professional Plan.',
}, },
currentSigned: 'CURRENTLY SIGNED IN AS', currentSigned: 'CURRENTLY SIGNED IN AS',
@ -38,9 +38,9 @@ const translation = {
submitError: 'Form submission failed. Please try again later.', submitError: 'Form submission failed. Please try again later.',
learn: 'Learn how to get education verified', learn: 'Learn how to get education verified',
successTitle: 'You Have Got Dify Education Verified', successTitle: 'You Have Got Dify Education Verified',
successContent: 'We have issued a 50% discount coupon for the Dify Professional plan to your account. The coupon is valid for one year, please use it within the validity period.', successContent: 'We have issued a 100% discount coupon for the Dify Professional plan to your account. The coupon is valid for one year, please use it within the validity period.',
rejectTitle: 'Your Dify Educational Verification Has Been Rejected', rejectTitle: 'Your Dify Educational Verification Has Been Rejected',
rejectContent: 'Unfortunately, you are not eligible for Education Verified status and therefore cannot receive the exclusive 50% coupon for the Dify Professional Plan if you use this email address.', rejectContent: 'Unfortunately, you are not eligible for Education Verified status and therefore cannot receive the exclusive 100% coupon for the Dify Professional Plan if you use this email address.',
emailLabel: 'Your current email', emailLabel: 'Your current email',
} }

@ -2,7 +2,7 @@ const translation = {
toVerified: '获取教育版认证', toVerified: '获取教育版认证',
toVerifiedTip: { toVerifiedTip: {
front: '您现在符合教育版认证的资格。请在下方输入您的教育信息,以完成认证流程,并领取 Dify Professional 版的', front: '您现在符合教育版认证的资格。请在下方输入您的教育信息,以完成认证流程,并领取 Dify Professional 版的',
coupon: '50% 独家优惠券', coupon: '100% 独家优惠券',
end: '。', end: '。',
}, },
currentSigned: '您当前登录的账户是', currentSigned: '您当前登录的账户是',
@ -38,9 +38,9 @@ const translation = {
submitError: '提交表单失败,请稍后重新提交问卷。', submitError: '提交表单失败,请稍后重新提交问卷。',
learn: '了解如何获取教育版认证', learn: '了解如何获取教育版认证',
successTitle: '您已成功获得 Dify 教育版认证!', successTitle: '您已成功获得 Dify 教育版认证!',
successContent: '我们已向您的账户发放 Dify Professional 版 50% 折扣优惠券。该优惠券有效期为一年,请在有效期内使用。', successContent: '我们已向您的账户发放 Dify Professional 版 100% 折扣优惠券。该优惠券有效期为一年,请在有效期内使用。',
rejectTitle: '您的 Dify 教育版认证已被拒绝', rejectTitle: '您的 Dify 教育版认证已被拒绝',
rejectContent: '非常遗憾,您无法使用此电子邮件以获得教育版认证资格,也无法领取 Dify Professional 版的 50% 独家优惠券。', rejectContent: '非常遗憾,您无法使用此电子邮件以获得教育版认证资格,也无法领取 Dify Professional 版的 100% 独家优惠券。',
emailLabel: '您当前的邮箱', emailLabel: '您当前的邮箱',
} }

Loading…
Cancel
Save