chore: remove sso_enforced_for_web_protocol、enable_web_sso_switch_component、sso_enforced_for_web from systemFeatures , instead with webapp_auth

pull/18656/head
NFish 1 year ago
parent 0c492abfc9
commit 7eb52770ad

@ -20,7 +20,7 @@ import cn from '@/utils/classnames'
import { useStore } from '@/app/components/app/store'
import AppSideBar from '@/app/components/app-sidebar'
import type { NavIcon } from '@/app/components/app-sidebar/navLink'
import { fetchAppDetail, fetchAppSSO } from '@/service/apps'
import { fetchAppDetail } from '@/service/apps'
import { useAppContext } from '@/context/app-context'
import Loading from '@/app/components/base/loading'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
@ -32,6 +32,13 @@ export type IAppDetailLayoutProps = {
params: { appId: string }
}
type NavigationType = {
name: string
href: string
icon: NavIcon
selectedIcon: NavIcon
}
const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const {
children,
@ -50,12 +57,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
})))
const [isLoadingAppDetail, setIsLoadingAppDetail] = useState(false)
const [appDetailRes, setAppDetailRes] = useState<App | null>(null)
const [navigation, setNavigation] = useState<Array<{
name: string
href: string
icon: NavIcon
selectedIcon: NavIcon
}>>([])
const [navigation, setNavigation] = useState<Array<NavigationType>>([])
const { systemFeatures } = useGlobalPublicStore()
const getNavigations = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
@ -142,15 +144,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
router.replace(`/app/${appId}/configuration`)
}
else {
setAppDetail({ ...res, enable_sso: false })
setNavigation(getNavigations(appId, isCurrentWorkspaceEditor, res.mode))
if (systemFeatures.enable_web_sso_switch_component && canIEditApp) {
fetchAppSSO({ appId }).then((ssoRes) => {
setAppDetail({ ...res, enable_sso: ssoRes.enabled })
})
}
setAppDetail({ ...res })
setNavigation(getNavigations(appId, isCurrentWorkspaceEditor, res.mode) as Array<NavigationType>)
}
}, [appDetailRes, appId, getNavigations, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace, pathname, router, setAppDetail, systemFeatures.enable_web_sso_switch_component])
}, [appDetailRes, appId, getNavigations, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace, pathname, router, setAppDetail])
useUnmount(() => {
setAppDetail()

@ -8,19 +8,16 @@ import Loading from '@/app/components/base/loading'
import { ToastContext } from '@/app/components/base/toast'
import {
fetchAppDetail,
fetchAppSSO,
updateAppSSO,
updateAppSiteAccessToken,
updateAppSiteConfig,
updateAppSiteStatus,
} from '@/service/apps'
import type { App, AppSSO } from '@/types/app'
import type { App } from '@/types/app'
import type { UpdateAppSiteCodeResponse } from '@/models/app'
import { asyncRunSafe } from '@/utils'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import type { IAppCardProps } from '@/app/components/app/overview/appCard'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useGlobalPublicStore } from '@/context/global-public-context'
export type ICardViewProps = {
appId: string
@ -31,19 +28,12 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
const { notify } = useContext(ToastContext)
const appDetail = useAppStore(state => state.appDetail)
const setAppDetail = useAppStore(state => state.setAppDetail)
const { systemFeatures } = useGlobalPublicStore()
const updateAppDetail = async () => {
try {
const res = await fetchAppDetail({ url: '/apps', id: appId })
if (systemFeatures.enable_web_sso_switch_component) {
const ssoRes = await fetchAppSSO({ appId })
setAppDetail({ ...res, enable_sso: ssoRes.enabled })
}
else {
setAppDetail({ ...res })
}
}
catch (error) { console.error(error) }
}
@ -93,16 +83,6 @@ const CardView: FC<ICardViewProps> = ({ appId }) => {
if (!err)
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
if (systemFeatures.enable_web_sso_switch_component) {
const [sso_err] = await asyncRunSafe<AppSSO>(
updateAppSSO({ id: appId, enabled: Boolean(params.enable_sso) }) as Promise<AppSSO>,
)
if (sso_err) {
handleCallbackResult(sso_err)
return
}
}
handleCallbackResult(err)
}

@ -1,7 +1,7 @@
'use client'
import { useRouter, useSearchParams } from 'next/navigation'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import React, { useCallback, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import Toast from '@/app/components/base/toast'
@ -9,6 +9,7 @@ import { fetchWebOAuth2SSOUrl, fetchWebOIDCSSOUrl, fetchWebSAMLSSOUrl } from '@/
import { setAccessToken } from '@/app/components/share/utils'
import Button from '@/app/components/base/button'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { SSOProtocol } from '@/types/feature'
const WebSSOForm: FC = () => {
const { t } = useTranslation()
@ -27,15 +28,15 @@ const WebSSOForm: FC = () => {
})
}
const getAppCodeFromRedirectUrl = () => {
const getAppCodeFromRedirectUrl = useCallback(() => {
const appCode = redirectUrl?.split('/').pop()
if (!appCode)
return null
return appCode
}
}, [redirectUrl])
const processTokenAndRedirect = async () => {
const processTokenAndRedirect = useCallback(async () => {
const appCode = getAppCodeFromRedirectUrl()
if (!appCode || !tokenFromUrl || !redirectUrl) {
showErrorToast('redirect url or app code or token is invalid.')
@ -44,7 +45,7 @@ const WebSSOForm: FC = () => {
await setAccessToken(appCode, tokenFromUrl)
router.push(redirectUrl)
}
}, [getAppCodeFromRedirectUrl, redirectUrl, router, tokenFromUrl])
const handleSSOLogin = async () => {
const appCode = getAppCodeFromRedirectUrl()
@ -53,18 +54,18 @@ const WebSSOForm: FC = () => {
return
}
switch (systemFeatures.sso_enforced_for_web_protocol) {
case 'saml': {
switch (systemFeatures.webapp_auth.sso_config.protocol) {
case SSOProtocol.SAML: {
const samlRes = await fetchWebSAMLSSOUrl(appCode, redirectUrl)
router.push(samlRes.url)
break
}
case 'oidc': {
case SSOProtocol.OIDC: {
const oidcRes = await fetchWebOIDCSSOUrl(appCode, redirectUrl)
router.push(oidcRes.url)
break
}
case 'oauth2': {
case SSOProtocol.OAuth2: {
const oauth2Res = await fetchWebOAuth2SSOUrl(appCode, redirectUrl)
router.push(oauth2Res.url)
break
@ -74,6 +75,14 @@ const WebSSOForm: FC = () => {
}
}
const goWebApp = () => {
if (!redirectUrl) {
showErrorToast('redirect url is invalid.')
return
}
router.push(redirectUrl)
}
useEffect(() => {
const init = async () => {
if (message) {
@ -88,8 +97,8 @@ const WebSSOForm: FC = () => {
}
init()
}, [message, tokenFromUrl]) // Added dependencies to useEffect
}, [message, processTokenAndRedirect, tokenFromUrl])
if (systemFeatures.webapp_auth.enable) {
return (
<div className="flex items-center justify-center h-full">
<div className={cn('flex flex-col items-center w-full grow justify-center', 'px-6', 'md:px-[108px]')}>
@ -98,5 +107,11 @@ const WebSSOForm: FC = () => {
</div>
)
}
else {
return <div className="flex items-center justify-center h-full">
<p>Current App is not required for login, you can <span className='text-text-accent cursor-pointer' onClick={goWebApp}>click here</span> continue.</p>
</div>
}
}
export default React.memo(WebSSOForm)

@ -17,7 +17,7 @@ export type IAppDetailNavProps = {
desc: string
isExternal?: boolean
icon: string
icon_background: string
icon_background: string | null
navigation: Array<{
name: string
href: string

@ -30,7 +30,7 @@ export default function AccessControl(props: AccessControlProps) {
const specificMembers = useAccessControlStore(s => s.specificMembers)
const currentMenu = useAccessControlStore(s => s.currentMenu)
const setCurrentMenu = useAccessControlStore(s => s.setCurrentMenu)
const hideTip = systemFeatures.enable_web_sso_switch_component && systemFeatures.sso_enforced_for_web
const hideTip = systemFeatures
useEffect(() => {
setAppId(app.id)

@ -20,7 +20,7 @@ export default function SpecificGroupsOrMembers() {
const setSpecificMembers = useAccessControlStore(s => s.setSpecificMembers)
const { t } = useTranslation()
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
const hideTip = systemFeatures.enable_web_sso_switch_component && systemFeatures.sso_enforced_for_web
const hideTip = systemFeatures.webapp_auth.enable
const { isPending, data } = useAppWhiteListSubjects(appId, Boolean(appId) && currentMenu === AccessMode.SPECIFIC_GROUPS_MEMBERS)
useEffect(() => {

@ -1,5 +1,5 @@
import type { LangFuseConfig, LangSmithConfig, OpikConfig, TracingProvider } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type'
import type { App, AppSSO, AppTemplate, SiteConfig } from '@/types/app'
import type { App, AppTemplate, SiteConfig } from '@/types/app'
/* export type App = {
id: string
@ -89,8 +89,6 @@ export type DSLImportResponse = {
error: string
}
export type AppSSOResponse = { enabled: AppSSO['enable_sso'] }
export type AppTemplatesResponse = {
data: AppTemplate[]
}

@ -1,6 +1,6 @@
import type { Fetcher } from 'swr'
import { del, get, patch, post, put } from './base'
import type { ApiKeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDailyMessagesResponse, AppDetailResponse, AppListResponse, AppSSOResponse, AppStatisticsResponse, AppTemplatesResponse, AppTokenCostsResponse, AppVoicesListResponse, CreateApiKeyResponse, DSLImportMode, DSLImportResponse, GenerationIntroductionResponse, TracingConfig, TracingStatus, UpdateAppModelConfigResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse, WorkflowDailyConversationsResponse } from '@/models/app'
import type { ApiKeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDailyMessagesResponse, AppDetailResponse, AppListResponse, AppStatisticsResponse, AppTemplatesResponse, AppTokenCostsResponse, AppVoicesListResponse, CreateApiKeyResponse, DSLImportMode, DSLImportResponse, GenerationIntroductionResponse, TracingConfig, TracingStatus, UpdateAppModelConfigResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse, WorkflowDailyConversationsResponse } from '@/models/app'
import type { CommonResponse } from '@/models/common'
import type { AppIconType, AppMode, ModelConfig } from '@/types/app'
import type { TracingProvider } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type'
@ -13,13 +13,6 @@ export const fetchAppDetail = ({ url, id }: { url: string; id: string }) => {
return get<AppDetailResponse>(`${url}/${id}`)
}
export const fetchAppSSO = async ({ appId }: { appId: string }) => {
return get<AppSSOResponse>(`/enterprise/app-setting/sso?appID=${appId}`)
}
export const updateAppSSO = async ({ id, enabled }: { id: string; enabled: boolean }) => {
return post('/enterprise/app-setting/sso', { body: { app_id: id, enabled } })
}
export const fetchAppTemplates: Fetcher<AppTemplatesResponse, { url: string }> = ({ url }) => {
return get<AppTemplatesResponse>(url)
}

@ -512,7 +512,7 @@ export const ssePost = (
}).catch(() => {
res.json().then((data: any) => {
if (isPublicAPI) {
if (data.code === 'web_sso_auth_required')
if (data.code === 'web_sso_auth_required' || data.code === 'web_app_access_denied')
requiredWebSSOLogin()
if (data.code === 'unauthorized') {
@ -566,7 +566,7 @@ export const request = async<T>(url: string, options = {}, otherOptions?: IOther
// special code
const { code, message } = errRespData
// webapp sso
if (code === 'web_sso_auth_required') {
if (code === 'web_sso_auth_required' || code === 'web_app_access_denied') {
requiredWebSSOLogin()
return Promise.reject(err)
}

@ -21,9 +21,6 @@ type License = {
export type SystemFeatures = {
sso_enforced_for_signin: boolean
sso_enforced_for_signin_protocol: SSOProtocol | ''
sso_enforced_for_web: boolean
sso_enforced_for_web_protocol: SSOProtocol | ''
enable_web_sso_switch_component: boolean
enable_email_code_login: boolean
enable_email_password_login: boolean
enable_social_oauth_login: boolean
@ -38,14 +35,18 @@ export type SystemFeatures = {
favicon: string
application_title: string
}
webapp_auth: {
enable: boolean
allow_sso: boolean
sso_config: {
protocol: SSOProtocol
}
}
}
export const defaultSystemFeatures: SystemFeatures = {
sso_enforced_for_signin: false,
sso_enforced_for_signin_protocol: '',
sso_enforced_for_web: false,
sso_enforced_for_web_protocol: '',
enable_web_sso_switch_component: false,
enable_email_code_login: false,
enable_email_password_login: false,
enable_social_oauth_login: false,
@ -63,4 +64,11 @@ export const defaultSystemFeatures: SystemFeatures = {
favicon: '',
application_title: 'test title',
},
webapp_auth: {
enable: false,
allow_sso: false,
sso_config: {
protocol: SSOProtocol.SAML,
},
},
}

Loading…
Cancel
Save