| Feedback, | Feedback, | ||||
| } from '../types' | } from '../types' | ||||
| import { CONVERSATION_ID_INFO } from '../constants' | import { CONVERSATION_ID_INFO } from '../constants' | ||||
| import { buildChatItemTree } from '../utils' | |||||
| import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams } from '../utils' | |||||
| import { addFileInfos, sortAgentSorts } from '../../../tools/utils' | import { addFileInfos, sortAgentSorts } from '../../../tools/utils' | ||||
| import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' | import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' | ||||
| import { | import { | ||||
| }, [isInstalledApp, installedAppInfo, appInfo]) | }, [isInstalledApp, installedAppInfo, appInfo]) | ||||
| const appId = useMemo(() => appData?.app_id, [appData]) | const appId = useMemo(() => appData?.app_id, [appData]) | ||||
| const [userId, setUserId] = useState<string>() | |||||
| useEffect(() => { | |||||
| getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => { | |||||
| setUserId(user_id) | |||||
| }) | |||||
| }, []) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (appData?.site.default_language) | if (appData?.site.default_language) | ||||
| changeLanguage(appData.site.default_language) | changeLanguage(appData.site.default_language) | ||||
| setSidebarCollapseState(localState === 'collapsed') | setSidebarCollapseState(localState === 'collapsed') | ||||
| } | } | ||||
| }, [appId]) | }, [appId]) | ||||
| const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, string>>(CONVERSATION_ID_INFO, { | |||||
| const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, Record<string, string>>>(CONVERSATION_ID_INFO, { | |||||
| defaultValue: {}, | defaultValue: {}, | ||||
| }) | }) | ||||
| const currentConversationId = useMemo(() => conversationIdInfo?.[appId || ''] || '', [appId, conversationIdInfo]) | |||||
| const currentConversationId = useMemo(() => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '', [appId, conversationIdInfo, userId]) | |||||
| const handleConversationIdInfoChange = useCallback((changeConversationId: string) => { | const handleConversationIdInfoChange = useCallback((changeConversationId: string) => { | ||||
| if (appId) { | if (appId) { | ||||
| let prevValue = conversationIdInfo?.[appId || ''] | |||||
| if (typeof prevValue === 'string') | |||||
| prevValue = {} | |||||
| setConversationIdInfo({ | setConversationIdInfo({ | ||||
| ...conversationIdInfo, | ...conversationIdInfo, | ||||
| [appId || '']: changeConversationId, | |||||
| [appId || '']: { | |||||
| ...prevValue, | |||||
| [userId || 'DEFAULT']: changeConversationId, | |||||
| }, | |||||
| }) | }) | ||||
| } | } | ||||
| }, [appId, conversationIdInfo, setConversationIdInfo]) | |||||
| }, [appId, conversationIdInfo, setConversationIdInfo, userId]) | |||||
| const [newConversationId, setNewConversationId] = useState('') | const [newConversationId, setNewConversationId] = useState('') | ||||
| const chatShouldReloadKey = useMemo(() => { | const chatShouldReloadKey = useMemo(() => { |
| Feedback, | Feedback, | ||||
| } from '../types' | } from '../types' | ||||
| import { CONVERSATION_ID_INFO } from '../constants' | import { CONVERSATION_ID_INFO } from '../constants' | ||||
| import { buildChatItemTree, getProcessedInputsFromUrlParams } from '../utils' | |||||
| import { buildChatItemTree, getProcessedInputsFromUrlParams, getProcessedSystemVariablesFromUrlParams } from '../utils' | |||||
| import { getProcessedFilesFromResponse } from '../../file-uploader/utils' | import { getProcessedFilesFromResponse } from '../../file-uploader/utils' | ||||
| import { | import { | ||||
| fetchAppInfo, | fetchAppInfo, | ||||
| }, [appInfo]) | }, [appInfo]) | ||||
| const appId = useMemo(() => appData?.app_id, [appData]) | const appId = useMemo(() => appData?.app_id, [appData]) | ||||
| const [userId, setUserId] = useState<string>() | |||||
| useEffect(() => { | |||||
| getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => { | |||||
| setUserId(user_id) | |||||
| }) | |||||
| }, []) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (appInfo?.site.default_language) | if (appInfo?.site.default_language) | ||||
| changeLanguage(appInfo.site.default_language) | changeLanguage(appInfo.site.default_language) | ||||
| }, [appInfo]) | }, [appInfo]) | ||||
| const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, string>>(CONVERSATION_ID_INFO, { | |||||
| const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, Record<string, string>>>(CONVERSATION_ID_INFO, { | |||||
| defaultValue: {}, | defaultValue: {}, | ||||
| }) | }) | ||||
| const currentConversationId = useMemo(() => conversationIdInfo?.[appId || ''] || '', [appId, conversationIdInfo]) | |||||
| const currentConversationId = useMemo(() => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '', [appId, conversationIdInfo, userId]) | |||||
| const handleConversationIdInfoChange = useCallback((changeConversationId: string) => { | const handleConversationIdInfoChange = useCallback((changeConversationId: string) => { | ||||
| if (appId) { | if (appId) { | ||||
| let prevValue = conversationIdInfo?.[appId || ''] | |||||
| if (typeof prevValue === 'string') | |||||
| prevValue = {} | |||||
| setConversationIdInfo({ | setConversationIdInfo({ | ||||
| ...conversationIdInfo, | ...conversationIdInfo, | ||||
| [appId || '']: changeConversationId, | |||||
| [appId || '']: { | |||||
| ...prevValue, | |||||
| [userId || 'DEFAULT']: changeConversationId, | |||||
| }, | |||||
| }) | }) | ||||
| } | } | ||||
| }, [appId, conversationIdInfo, setConversationIdInfo]) | |||||
| }, [appId, conversationIdInfo, setConversationIdInfo, userId]) | |||||
| const [newConversationId, setNewConversationId] = useState('') | const [newConversationId, setNewConversationId] = useState('') | ||||
| const chatShouldReloadKey = useMemo(() => { | const chatShouldReloadKey = useMemo(() => { |
| import { fetchAccessToken } from '@/service/share' | import { fetchAccessToken } from '@/service/share' | ||||
| import { getProcessedSystemVariablesFromUrlParams } from '../base/chat/utils' | import { getProcessedSystemVariablesFromUrlParams } from '../base/chat/utils' | ||||
| export const isTokenV1 = (token: Record<string, any>) => { | |||||
| return !token.version | |||||
| } | |||||
| export const getInitialTokenV2 = (): Record<string, any> => ({ | |||||
| version: 2, | |||||
| }) | |||||
| export const checkOrSetAccessToken = async () => { | export const checkOrSetAccessToken = async () => { | ||||
| const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | ||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' }) | |||||
| let accessTokenJson = { [sharedToken]: '' } | |||||
| const userId = (await getProcessedSystemVariablesFromUrlParams()).user_id | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2()) | |||||
| let accessTokenJson = getInitialTokenV2() | |||||
| try { | try { | ||||
| accessTokenJson = JSON.parse(accessToken) | accessTokenJson = JSON.parse(accessToken) | ||||
| if (isTokenV1(accessTokenJson)) | |||||
| accessTokenJson = getInitialTokenV2() | |||||
| } | } | ||||
| catch { | catch { | ||||
| } | } | ||||
| if (!accessTokenJson[sharedToken]) { | |||||
| const sysUserId = (await getProcessedSystemVariablesFromUrlParams()).user_id | |||||
| const res = await fetchAccessToken(sharedToken, sysUserId) | |||||
| accessTokenJson[sharedToken] = res.access_token | |||||
| if (!accessTokenJson[sharedToken]?.[userId || 'DEFAULT']) { | |||||
| const res = await fetchAccessToken(sharedToken, userId) | |||||
| accessTokenJson[sharedToken] = { | |||||
| ...accessTokenJson[sharedToken], | |||||
| [userId || 'DEFAULT']: res.access_token, | |||||
| } | |||||
| localStorage.setItem('token', JSON.stringify(accessTokenJson)) | localStorage.setItem('token', JSON.stringify(accessTokenJson)) | ||||
| } | } | ||||
| } | } | ||||
| export const setAccessToken = async (sharedToken: string, token: string) => { | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' }) | |||||
| let accessTokenJson = { [sharedToken]: '' } | |||||
| export const setAccessToken = async (sharedToken: string, token: string, user_id?: string) => { | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2()) | |||||
| let accessTokenJson = getInitialTokenV2() | |||||
| try { | try { | ||||
| accessTokenJson = JSON.parse(accessToken) | accessTokenJson = JSON.parse(accessToken) | ||||
| if (isTokenV1(accessTokenJson)) | |||||
| accessTokenJson = getInitialTokenV2() | |||||
| } | } | ||||
| catch { | catch { | ||||
| localStorage.removeItem(CONVERSATION_ID_INFO) | localStorage.removeItem(CONVERSATION_ID_INFO) | ||||
| accessTokenJson[sharedToken] = token | |||||
| accessTokenJson[sharedToken] = { | |||||
| ...accessTokenJson[sharedToken], | |||||
| [user_id || 'DEFAULT']: token, | |||||
| } | |||||
| localStorage.setItem('token', JSON.stringify(accessTokenJson)) | localStorage.setItem('token', JSON.stringify(accessTokenJson)) | ||||
| } | } | ||||
| export const removeAccessToken = () => { | export const removeAccessToken = () => { | ||||
| const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | ||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' }) | |||||
| let accessTokenJson = { [sharedToken]: '' } | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2()) | |||||
| let accessTokenJson = getInitialTokenV2() | |||||
| try { | try { | ||||
| accessTokenJson = JSON.parse(accessToken) | accessTokenJson = JSON.parse(accessToken) | ||||
| if (isTokenV1(accessTokenJson)) | |||||
| accessTokenJson = getInitialTokenV2() | |||||
| } | } | ||||
| catch { | catch { | ||||
| const baseFetch = base | const baseFetch = base | ||||
| export const upload = (options: any, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise<any> => { | |||||
| export const upload = async (options: any, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise<any> => { | |||||
| const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX | const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX | ||||
| const token = getAccessToken(isPublicAPI) | |||||
| const token = await getAccessToken(isPublicAPI) | |||||
| const defaultOptions = { | const defaultOptions = { | ||||
| method: 'POST', | method: 'POST', | ||||
| url: (url ? `${urlPrefix}${url}` : `${urlPrefix}/files/upload`) + (searchParams || ''), | url: (url ? `${urlPrefix}${url}` : `${urlPrefix}/files/upload`) + (searchParams || ''), | ||||
| }) | }) | ||||
| } | } | ||||
| export const ssePost = ( | |||||
| export const ssePost = async ( | |||||
| url: string, | url: string, | ||||
| fetchOptions: FetchOptionType, | fetchOptions: FetchOptionType, | ||||
| otherOptions: IOtherOptions, | otherOptions: IOtherOptions, | ||||
| if (body) | if (body) | ||||
| options.body = JSON.stringify(body) | options.body = JSON.stringify(body) | ||||
| const accessToken = getAccessToken(isPublicAPI) | |||||
| const accessToken = await getAccessToken(isPublicAPI) | |||||
| ; (options.headers as Headers).set('Authorization', `Bearer ${accessToken}`) | ; (options.headers as Headers).set('Authorization', `Bearer ${accessToken}`) | ||||
| globalThis.fetch(urlWithPrefix, options as RequestInit) | globalThis.fetch(urlWithPrefix, options as RequestInit) |
| import type { IOtherOptions } from './base' | import type { IOtherOptions } from './base' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config' | import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config' | ||||
| import { getInitialTokenV2, isTokenV1 } from '@/app/components/share/utils' | |||||
| import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils' | |||||
| const TIME_OUT = 100000 | const TIME_OUT = 100000 | ||||
| } | } | ||||
| } | } | ||||
| export const getPublicToken = () => { | |||||
| let token = '' | |||||
| const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' }) | |||||
| let accessTokenJson = { [sharedToken]: '' } | |||||
| try { | |||||
| accessTokenJson = JSON.parse(accessToken) | |||||
| } | |||||
| catch { } | |||||
| token = accessTokenJson[sharedToken] | |||||
| return token || '' | |||||
| } | |||||
| export function getAccessToken(isPublicAPI?: boolean) { | |||||
| export async function getAccessToken(isPublicAPI?: boolean) { | |||||
| if (isPublicAPI) { | if (isPublicAPI) { | ||||
| const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0] | ||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' }) | |||||
| let accessTokenJson = { [sharedToken]: '' } | |||||
| const userId = (await getProcessedSystemVariablesFromUrlParams()).user_id | |||||
| const accessToken = localStorage.getItem('token') || JSON.stringify({ version: 2 }) | |||||
| let accessTokenJson: Record<string, any> = { version: 2 } | |||||
| try { | try { | ||||
| accessTokenJson = JSON.parse(accessToken) | accessTokenJson = JSON.parse(accessToken) | ||||
| if (isTokenV1(accessTokenJson)) | |||||
| accessTokenJson = getInitialTokenV2() | |||||
| } | } | ||||
| catch { | catch { | ||||
| } | } | ||||
| return accessTokenJson[sharedToken] | |||||
| return accessTokenJson[sharedToken]?.[userId || 'DEFAULT'] | |||||
| } | } | ||||
| else { | else { | ||||
| return localStorage.getItem('console_token') || '' | return localStorage.getItem('console_token') || '' | ||||
| } | } | ||||
| } | } | ||||
| const beforeRequestPublicAuthorization: BeforeRequestHook = (request) => { | |||||
| const token = getAccessToken(true) | |||||
| const beforeRequestPublicAuthorization: BeforeRequestHook = async (request) => { | |||||
| const token = await getAccessToken(true) | |||||
| request.headers.set('Authorization', `Bearer ${token}`) | request.headers.set('Authorization', `Bearer ${token}`) | ||||
| } | } | ||||
| const beforeRequestAuthorization: BeforeRequestHook = (request) => { | |||||
| const accessToken = getAccessToken() | |||||
| const beforeRequestAuthorization: BeforeRequestHook = async (request) => { | |||||
| const accessToken = await getAccessToken() | |||||
| request.headers.set('Authorization', `Bearer ${accessToken}`) | request.headers.set('Authorization', `Bearer ${accessToken}`) | ||||
| } | } | ||||