dify/web/context/web-app-context.tsx

126 lines
4.8 KiB
TypeScript
Raw Normal View History

2025-07-17 10:52:10 +08:00
'use client'
import type { ChatConfig } from '@/app/components/base/chat/types'
import Loading from '@/app/components/base/loading'
import { AccessMode } from '@/models/access-control'
import type { AppData, AppMeta } from '@/models/share'
import { useGetWebAppAccessModeByCode } from '@/service/use-share'
import { usePathname, useSearchParams } from 'next/navigation'
import type { FC, PropsWithChildren } from 'react'
import { useEffect } from 'react'
import { create } from 'zustand'
import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils'
2025-08-27 18:00:25 +08:00
import { useGlobalPublicStore } from './global-public-context'
2025-07-17 10:52:10 +08:00
type WebAppStore = {
shareCode: string | null
updateShareCode: (shareCode: string | null) => void
appInfo: AppData | null
updateAppInfo: (appInfo: AppData | null) => void
appParams: ChatConfig | null
updateAppParams: (appParams: ChatConfig | null) => void
webAppAccessMode: AccessMode
updateWebAppAccessMode: (accessMode: AccessMode) => void
appMeta: AppMeta | null
updateWebAppMeta: (appMeta: AppMeta | null) => void
userCanAccessApp: boolean
updateUserCanAccessApp: (canAccess: boolean) => void
embeddedUserId: string | null
updateEmbeddedUserId: (userId: string | null) => void
embeddedConversationId: string | null
updateEmbeddedConversationId: (conversationId: string | null) => void
2025-07-17 10:52:10 +08:00
}
export const useWebAppStore = create<WebAppStore>(set => ({
shareCode: null,
updateShareCode: (shareCode: string | null) => set(() => ({ shareCode })),
appInfo: null,
updateAppInfo: (appInfo: AppData | null) => set(() => ({ appInfo })),
appParams: null,
updateAppParams: (appParams: ChatConfig | null) => set(() => ({ appParams })),
webAppAccessMode: AccessMode.SPECIFIC_GROUPS_MEMBERS,
updateWebAppAccessMode: (accessMode: AccessMode) => set(() => ({ webAppAccessMode: accessMode })),
appMeta: null,
updateWebAppMeta: (appMeta: AppMeta | null) => set(() => ({ appMeta })),
userCanAccessApp: false,
updateUserCanAccessApp: (canAccess: boolean) => set(() => ({ userCanAccessApp: canAccess })),
embeddedUserId: null,
updateEmbeddedUserId: (userId: string | null) => set(() => ({ embeddedUserId: userId })),
embeddedConversationId: null,
updateEmbeddedConversationId: (conversationId: string | null) =>
set(() => ({ embeddedConversationId: conversationId })),
2025-07-17 10:52:10 +08:00
}))
const getShareCodeFromRedirectUrl = (redirectUrl: string | null): string | null => {
if (!redirectUrl || redirectUrl.length === 0)
return null
const url = new URL(`${window.location.origin}${decodeURIComponent(redirectUrl)}`)
return url.pathname.split('/').pop() || null
}
const getShareCodeFromPathname = (pathname: string): string | null => {
const code = pathname.split('/').pop() || null
if (code === 'webapp-signin')
return null
return code
}
const WebAppStoreProvider: FC<PropsWithChildren> = ({ children }) => {
2025-08-27 18:00:25 +08:00
const isGlobalPending = useGlobalPublicStore(s => s.isGlobalPending)
2025-07-17 10:52:10 +08:00
const updateWebAppAccessMode = useWebAppStore(state => state.updateWebAppAccessMode)
const updateShareCode = useWebAppStore(state => state.updateShareCode)
const updateEmbeddedUserId = useWebAppStore(state => state.updateEmbeddedUserId)
const updateEmbeddedConversationId = useWebAppStore(state => state.updateEmbeddedConversationId)
2025-07-17 10:52:10 +08:00
const pathname = usePathname()
const searchParams = useSearchParams()
const redirectUrlParam = searchParams.get('redirect_url')
const searchParamsString = searchParams.toString()
// Compute shareCode directly
const shareCode = getShareCodeFromRedirectUrl(redirectUrlParam) || getShareCodeFromPathname(pathname)
useEffect(() => {
updateShareCode(shareCode)
}, [shareCode, updateShareCode])
useEffect(() => {
let cancelled = false
const syncEmbeddedUserId = async () => {
try {
const { user_id, conversation_id } = await getProcessedSystemVariablesFromUrlParams()
if (!cancelled) {
updateEmbeddedUserId(user_id || null)
updateEmbeddedConversationId(conversation_id || null)
}
}
catch {
if (!cancelled) {
updateEmbeddedUserId(null)
updateEmbeddedConversationId(null)
}
}
}
syncEmbeddedUserId()
return () => {
cancelled = true
}
}, [searchParamsString, updateEmbeddedUserId, updateEmbeddedConversationId])
const { isLoading, data: accessModeResult } = useGetWebAppAccessModeByCode(shareCode)
2025-07-17 10:52:10 +08:00
useEffect(() => {
refactor: replace localStorage with HTTP-only cookies for auth tokens (#24365) Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com> Signed-off-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Yunlu Wen <wylswz@163.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: GareArc <chen4851@purdue.edu> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: Davide Delbianco <davide.delbianco@outlook.com> Co-authored-by: minglu7 <1347866672@qq.com> Co-authored-by: Ponder <ruan.lj@foxmail.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: heyszt <270985384@qq.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Guangdong Liu <liugddx@gmail.com> Co-authored-by: Eric Guo <eric.guocz@gmail.com> Co-authored-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Co-authored-by: XlKsyt <caixuesen@outlook.com> Co-authored-by: Dhruv Gorasiya <80987415+DhruvGorasiya@users.noreply.github.com> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: GuanMu <ballmanjq@gmail.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Tonlo <123lzs123@gmail.com> Co-authored-by: Yusuke Yamada <yamachu.dev@gmail.com> Co-authored-by: Novice <novice12185727@gmail.com> Co-authored-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: Ademílson Tonato <ademilsonft@outlook.com> Co-authored-by: znn <jubinkumarsoni@gmail.com> Co-authored-by: yangzheli <43645580+yangzheli@users.noreply.github.com>
2025-10-19 21:29:04 +08:00
if (accessModeResult?.accessMode)
2025-07-17 10:52:10 +08:00
updateWebAppAccessMode(accessModeResult.accessMode)
}, [accessModeResult, updateWebAppAccessMode, shareCode])
if (isGlobalPending || isLoading) {
2025-07-17 10:52:10 +08:00
return <div className='flex h-full w-full items-center justify-center'>
<Loading />
</div>
}
return (
<>
{children}
</>
)
}
export default WebAppStoreProvider