mirror of https://github.com/langgenius/dify.git
Feature:during account initialization, set the interface language to be consistent with the display language(#27029) (#27042)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
This commit is contained in:
parent
9a9d6a4a2b
commit
2bcf96565a
|
|
@ -31,3 +31,9 @@ def supported_language(lang):
|
|||
|
||||
error = f"{lang} is not a valid language."
|
||||
raise ValueError(error)
|
||||
|
||||
|
||||
def get_valid_language(lang: str | None) -> str:
|
||||
if lang and lang in languages:
|
||||
return lang
|
||||
return languages[0]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from flask_restx import Resource, reqparse
|
|||
|
||||
import services
|
||||
from configs import dify_config
|
||||
from constants.languages import languages
|
||||
from constants.languages import get_valid_language
|
||||
from controllers.console import console_ns
|
||||
from controllers.console.auth.error import (
|
||||
AuthenticationFailedError,
|
||||
|
|
@ -204,10 +204,12 @@ class EmailCodeLoginApi(Resource):
|
|||
.add_argument("email", type=str, required=True, location="json")
|
||||
.add_argument("code", type=str, required=True, location="json")
|
||||
.add_argument("token", type=str, required=True, location="json")
|
||||
.add_argument("language", type=str, required=False, location="json")
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
user_email = args["email"]
|
||||
language = args["language"]
|
||||
|
||||
token_data = AccountService.get_email_code_login_data(args["token"])
|
||||
if token_data is None:
|
||||
|
|
@ -241,7 +243,9 @@ class EmailCodeLoginApi(Resource):
|
|||
if account is None:
|
||||
try:
|
||||
account = AccountService.create_account_and_tenant(
|
||||
email=user_email, name=user_email, interface_language=languages[0]
|
||||
email=user_email,
|
||||
name=user_email,
|
||||
interface_language=get_valid_language(language),
|
||||
)
|
||||
except WorkSpaceNotAllowedCreateError:
|
||||
raise NotAllowedCreateWorkspace()
|
||||
|
|
|
|||
|
|
@ -74,12 +74,17 @@ class SetupApi(Resource):
|
|||
.add_argument("email", type=email, required=True, location="json")
|
||||
.add_argument("name", type=StrLen(30), required=True, location="json")
|
||||
.add_argument("password", type=valid_password, required=True, location="json")
|
||||
.add_argument("language", type=str, required=False, location="json")
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# setup
|
||||
RegisterService.setup(
|
||||
email=args["email"], name=args["name"], password=args["password"], ip_address=extract_remote_ip(request)
|
||||
email=args["email"],
|
||||
name=args["name"],
|
||||
password=args["password"],
|
||||
ip_address=extract_remote_ip(request),
|
||||
language=args["language"],
|
||||
)
|
||||
|
||||
return {"result": "success"}, 201
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from sqlalchemy.orm import Session
|
|||
from werkzeug.exceptions import Unauthorized
|
||||
|
||||
from configs import dify_config
|
||||
from constants.languages import language_timezone_mapping, languages
|
||||
from constants.languages import get_valid_language, language_timezone_mapping
|
||||
from events.tenant_event import tenant_was_created
|
||||
from extensions.ext_database import db
|
||||
from extensions.ext_redis import redis_client, redis_fallback
|
||||
|
|
@ -1259,7 +1259,7 @@ class RegisterService:
|
|||
return f"member_invite:token:{token}"
|
||||
|
||||
@classmethod
|
||||
def setup(cls, email: str, name: str, password: str, ip_address: str):
|
||||
def setup(cls, email: str, name: str, password: str, ip_address: str, language: str):
|
||||
"""
|
||||
Setup dify
|
||||
|
||||
|
|
@ -1269,11 +1269,10 @@ class RegisterService:
|
|||
:param ip_address: ip address
|
||||
"""
|
||||
try:
|
||||
# Register
|
||||
account = AccountService.create_account(
|
||||
email=email,
|
||||
name=name,
|
||||
interface_language=languages[0],
|
||||
interface_language=get_valid_language(language),
|
||||
password=password,
|
||||
is_setup=True,
|
||||
)
|
||||
|
|
@ -1315,7 +1314,7 @@ class RegisterService:
|
|||
account = AccountService.create_account(
|
||||
email=email,
|
||||
name=name,
|
||||
interface_language=language or languages[0],
|
||||
interface_language=get_valid_language(language),
|
||||
password=password,
|
||||
is_setup=is_setup,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ def setup_account(request) -> Generator[Account, None, None]:
|
|||
name=name,
|
||||
password=secrets.token_hex(16),
|
||||
ip_address="localhost",
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
with _CACHED_APP.test_request_context():
|
||||
|
|
|
|||
|
|
@ -2299,6 +2299,7 @@ class TestRegisterService:
|
|||
name=admin_name,
|
||||
password=admin_password,
|
||||
ip_address=ip_address,
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# Verify account was created
|
||||
|
|
@ -2348,6 +2349,7 @@ class TestRegisterService:
|
|||
name=admin_name,
|
||||
password=admin_password,
|
||||
ip_address=ip_address,
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# Verify no entities were created (rollback worked)
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ class TestRegisterService:
|
|||
mock_dify_setup.return_value = mock_dify_setup_instance
|
||||
|
||||
# Execute test
|
||||
RegisterService.setup("admin@example.com", "Admin User", "password123", "192.168.1.1")
|
||||
RegisterService.setup("admin@example.com", "Admin User", "password123", "192.168.1.1", "en-US")
|
||||
|
||||
# Verify results
|
||||
mock_create_account.assert_called_once_with(
|
||||
|
|
@ -925,6 +925,7 @@ class TestRegisterService:
|
|||
"Admin User",
|
||||
"password123",
|
||||
"192.168.1.1",
|
||||
"en-US",
|
||||
)
|
||||
|
||||
# Verify rollback operations were called
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ type AccountFormValues = z.infer<typeof accountFormSchema>
|
|||
|
||||
const InstallForm = () => {
|
||||
useDocumentTitle('')
|
||||
const { t } = useTranslation()
|
||||
const { t, i18n } = useTranslation()
|
||||
const docLink = useDocLink()
|
||||
const router = useRouter()
|
||||
const [showPassword, setShowPassword] = React.useState(false)
|
||||
|
|
@ -58,6 +58,7 @@ const InstallForm = () => {
|
|||
await setup({
|
||||
body: {
|
||||
...data,
|
||||
language: i18n.language,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@ import I18NContext from '@/context/i18n'
|
|||
import { resolvePostLoginRedirect } from '../utils/post-login-redirect'
|
||||
|
||||
export default function CheckCode() {
|
||||
const { t } = useTranslation()
|
||||
const { t, i18n } = useTranslation()
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const email = decodeURIComponent(searchParams.get('email') as string)
|
||||
const token = decodeURIComponent(searchParams.get('token') as string)
|
||||
const invite_token = decodeURIComponent(searchParams.get('invite_token') || '')
|
||||
const language = i18n.language
|
||||
const [code, setVerifyCode] = useState('')
|
||||
const [loading, setIsLoading] = useState(false)
|
||||
const { locale } = useContext(I18NContext)
|
||||
|
|
@ -40,7 +41,7 @@ export default function CheckCode() {
|
|||
return
|
||||
}
|
||||
setIsLoading(true)
|
||||
const ret = await emailLoginWithCode({ email, code, token })
|
||||
const ret = await emailLoginWithCode({ email, code, token, language })
|
||||
if (ret.result === 'success') {
|
||||
if (invite_token) {
|
||||
router.replace(`/signin/invite-settings?${searchParams.toString()}`)
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ export const uploadRemoteFileInfo = (url: string, isPublic?: boolean, silent?: b
|
|||
export const sendEMailLoginCode = (email: string, language = 'en-US') =>
|
||||
post<CommonResponse & { data: string }>('/email-code-login', { body: { email, language } })
|
||||
|
||||
export const emailLoginWithCode = (data: { email: string; code: string; token: string }) =>
|
||||
export const emailLoginWithCode = (data: { email: string; code: string; token: string; language: string }) =>
|
||||
post<LoginResponse>('/email-code-login/validity', { body: data })
|
||||
|
||||
export const sendResetPasswordCode = (email: string, language = 'en-US') =>
|
||||
|
|
|
|||
Loading…
Reference in New Issue