diff --git a/.gitignore b/.gitignore
index e71b381610..66249653d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -139,6 +139,7 @@ web/.vscode/settings.json
!.idea/icon.png
.ideaDataSources/
*.iml
+api/.idea
api/.env
api/storage/*
diff --git a/web/app/(shareLayout)/chatbot/[token]/page.tsx b/web/app/(shareLayout)/chatbot/[token]/page.tsx
index 1db5c7e458..6196afecc4 100644
--- a/web/app/(shareLayout)/chatbot/[token]/page.tsx
+++ b/web/app/(shareLayout)/chatbot/[token]/page.tsx
@@ -1,85 +1,10 @@
'use client'
-import React, { useEffect } from 'react'
-import cn from 'classnames'
+import React from 'react'
import EmbeddedChatbot from '@/app/components/base/chat/embedded-chatbot'
-import Loading from '@/app/components/base/loading'
-import { fetchSystemFeatures } from '@/service/share'
-import LogoSite from '@/app/components/base/logo/logo-site'
const Chatbot = () => {
- const [isSSOEnforced, setIsSSOEnforced] = React.useState(true)
- const [loading, setLoading] = React.useState(true)
-
- useEffect(() => {
- fetchSystemFeatures().then((res) => {
- setIsSSOEnforced(res.sso_enforced_for_web)
- setLoading(false)
- })
- }, [])
-
return (
- <>
- {
- loading
- ? (
-
- )
- : (
- <>
- {isSSOEnforced
- ? (
-
-
-
-
-
-
-
-
-
-
- Warning: Chatbot is not available
-
-
- Because SSO is enforced. Please contact your administrator.
-
-
-
-
-
-
- )
- :
- }
- >
- )}
- >
+
)
}
diff --git a/web/app/(shareLayout)/webapp-signin/page.tsx b/web/app/(shareLayout)/webapp-signin/page.tsx
index ebb83884d6..4394cef822 100644
--- a/web/app/(shareLayout)/webapp-signin/page.tsx
+++ b/web/app/(shareLayout)/webapp-signin/page.tsx
@@ -2,150 +2,99 @@
import cn from 'classnames'
import { useRouter, useSearchParams } from 'next/navigation'
import type { FC } from 'react'
-import React, { useEffect, useState } from 'react'
-import { useTranslation } from 'react-i18next'
+import React, { useEffect } from 'react'
import Toast from '@/app/components/base/toast'
-import Button from '@/app/components/base/button'
import { fetchSystemFeatures, fetchWebOAuth2SSOUrl, fetchWebOIDCSSOUrl, fetchWebSAMLSSOUrl } from '@/service/share'
-import LogoSite from '@/app/components/base/logo/logo-site'
import { setAccessToken } from '@/app/components/share/utils'
+import Loading from '@/app/components/base/loading'
const WebSSOForm: FC = () => {
const searchParams = useSearchParams()
+ const router = useRouter()
const redirectUrl = searchParams.get('redirect_url')
const tokenFromUrl = searchParams.get('web_sso_token')
const message = searchParams.get('message')
- const router = useRouter()
- const { t } = useTranslation()
+ const showErrorToast = (message: string) => {
+ Toast.notify({
+ type: 'error',
+ message,
+ })
+ }
- const [isLoading, setIsLoading] = useState(false)
- const [protocol, setProtocol] = useState('')
+ const getAppCodeFromRedirectUrl = () => {
+ const appCode = redirectUrl?.split('/').pop()
+ if (!appCode)
+ return null
- useEffect(() => {
- const fetchFeaturesAndSetToken = async () => {
- await fetchSystemFeatures().then((res) => {
- setProtocol(res.sso_enforced_for_web_protocol)
- })
+ return appCode
+ }
- // Callback from SSO, process token and redirect
- if (tokenFromUrl && redirectUrl) {
- const appCode = redirectUrl.split('/').pop()
- if (!appCode) {
- Toast.notify({
- type: 'error',
- message: 'redirect url is invalid. App code is not found.',
- })
- return
- }
+ const processTokenAndRedirect = async () => {
+ const appCode = getAppCodeFromRedirectUrl()
+ if (!appCode || !tokenFromUrl || !redirectUrl) {
+ showErrorToast('redirect url or app code or token is invalid.')
+ return
+ }
- await setAccessToken(appCode, tokenFromUrl)
- router.push(redirectUrl)
+ await setAccessToken(appCode, tokenFromUrl)
+ router.push(redirectUrl)
+ }
+
+ const handleSSOLogin = async (protocol: string) => {
+ const appCode = getAppCodeFromRedirectUrl()
+ if (!appCode || !redirectUrl) {
+ showErrorToast('redirect url or app code is invalid.')
+ return
+ }
+
+ switch (protocol) {
+ case 'saml': {
+ const samlRes = await fetchWebSAMLSSOUrl(appCode, redirectUrl)
+ router.push(samlRes.url)
+ break
}
- }
-
- fetchFeaturesAndSetToken()
-
- if (message) {
- Toast.notify({
- type: 'error',
- message,
- })
- }
- }, [])
-
- const handleSSOLogin = () => {
- setIsLoading(true)
-
- if (!redirectUrl) {
- Toast.notify({
- type: 'error',
- message: 'redirect url is not found.',
- })
- setIsLoading(false)
- return
- }
-
- const appCode = redirectUrl.split('/').pop()
- if (!appCode) {
- Toast.notify({
- type: 'error',
- message: 'redirect url is invalid. App code is not found.',
- })
- return
- }
-
- if (protocol === 'saml') {
- fetchWebSAMLSSOUrl(appCode, redirectUrl).then((res) => {
- router.push(res.url)
- }).finally(() => {
- setIsLoading(false)
- })
- }
- else if (protocol === 'oidc') {
- fetchWebOIDCSSOUrl(appCode, redirectUrl).then((res) => {
- router.push(res.url)
- }).finally(() => {
- setIsLoading(false)
- })
- }
- else if (protocol === 'oauth2') {
- fetchWebOAuth2SSOUrl(appCode, redirectUrl).then((res) => {
- router.push(res.url)
- }).finally(() => {
- setIsLoading(false)
- })
- }
- else {
- Toast.notify({
- type: 'error',
- message: 'sso protocol is not supported.',
- })
- setIsLoading(false)
+ case 'oidc': {
+ const oidcRes = await fetchWebOIDCSSOUrl(appCode, redirectUrl)
+ router.push(oidcRes.url)
+ break
+ }
+ case 'oauth2': {
+ const oauth2Res = await fetchWebOAuth2SSOUrl(appCode, redirectUrl)
+ router.push(oauth2Res.url)
+ break
+ }
+ default:
+ showErrorToast('SSO protocol is not supported.')
}
}
- return (
-
-
-
-
-
+ useEffect(() => {
+ const init = async () => {
+ const res = await fetchSystemFeatures()
+ const protocol = res.sso_enforced_for_web_protocol
-
-
-
-
{t('login.pageTitle')}
-
-
-
-
-
-
+ if (message) {
+ showErrorToast(message)
+ return
+ }
+
+ if (!tokenFromUrl) {
+ await handleSSOLogin(protocol)
+ return
+ }
+
+ await processTokenAndRedirect()
+ }
+
+ init()
+ }, [message, tokenFromUrl]) // Added dependencies to useEffect
+
+ return (
+
)