fix: retire access to __NEXT_DATA__ and __remixContext

fix #362
This commit is contained in:
pionxzh
2026-07-06 02:14:59 +08:00
parent e579f4f676
commit f5ef7fe301
2 changed files with 6 additions and 68 deletions

View File

@@ -1,6 +1,6 @@
import urlcat from 'urlcat'
import { apiUrl, baseUrl } from './constants'
import { getChatIdFromUrl, getConversationFromSharePage, getPageAccessToken, isSharePage } from './page'
import { getChatIdFromUrl, getConversationFromSharePage, isSharePage } from './page'
import { blobToDataURL } from './utils/dom'
import { memorize } from './utils/memorize'
@@ -792,9 +792,6 @@ async function _fetchSession(): Promise<ApiSession> {
const fetchSession = memorize(_fetchSession)
async function getAccessToken(): Promise<string> {
const pageAccessToken = getPageAccessToken()
if (pageAccessToken) return pageAccessToken
const session = await fetchSession()
return session.accessToken
}

View File

@@ -1,44 +1,9 @@
import { unsafeWindow } from 'vite-plugin-monkey/dist/client'
import { getBase64FromImageUrl, getBase64FromImg } from './utils/dom'
import { getBase64FromImg } from './utils/dom'
declare global {
interface Window {
__NEXT_DATA__?: {
assetPrefix: string
buildId: string
gssp: boolean
isFallback: boolean
page: string
props: {
pageProps: {
allowBrowserStorage: boolean
canManageBrowserStorage: boolean
geoOk: boolean
isUserInCanPayGroup: boolean
serviceAnnouncement: {
paid: unknown
public: unknown
}
serviceStatus: unknown
user: {
email: string
group: unknown[]
id: string
image: string
intercom_hash: string
mfa: boolean
name: string
picture: string
}
userCountry: string
serverResponse?: {
type: 'data'
data: any // Basically ApiConversation
}
}
}
}
__remixContext: {
__reactRouterContext: {
basename: string
future: {}
state: {
@@ -75,16 +40,6 @@ declare global {
}
}
export function getPageAccessToken(): string | null {
return unsafeWindow?.__remixContext?.state?.loaderData?.root?.clientBootstrap?.session?.accessToken ?? null
}
function getUserProfile() {
const user = unsafeWindow?.__NEXT_DATA__?.props?.pageProps?.user ?? unsafeWindow?.__remixContext?.state?.loaderData?.root?.clientBootstrap?.session?.user
if (!user) throw new Error('No user found.')
return user
}
export function getChatIdFromUrl() {
// /share/1e5sf-asdf-1234
// /c/1e5sf-asdf-1234
@@ -100,31 +55,17 @@ export function isSharePage() {
}
export function getConversationFromSharePage() {
if (window.__NEXT_DATA__?.props?.pageProps?.serverResponse?.data) {
// Next.js or OpenAI started to freeze some objects, so we do a
// deep copy here to avoid polluting the original object
return JSON.parse(JSON.stringify(window.__NEXT_DATA__.props.pageProps.serverResponse.data))
}
if (window.__remixContext?.state?.loaderData?.['routes/share.$shareId.($action)']?.serverResponse?.data) {
return JSON.parse(JSON.stringify(window.__remixContext.state.loaderData['routes/share.$shareId.($action)'].serverResponse.data))
if (unsafeWindow.__reactRouterContext?.state?.loaderData?.['routes/share.$shareId.($action)']?.serverResponse?.data) {
return JSON.parse(JSON.stringify(unsafeWindow.__reactRouterContext.state.loaderData['routes/share.$shareId.($action)'].serverResponse.data))
}
return null
}
const defaultAvatar = 'data:image/svg+xml,%3Csvg%20stroke%3D%22currentColor%22%20fill%3D%22none%22%20stroke-width%3D%221.5%22%20viewBox%3D%22-6%20-6%2036%2036%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20style%3D%22color%3A%20white%3B%20background%3A%20%23ab68ff%3B%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M20%2021v-2a4%204%200%200%200-4-4H8a4%204%200%200%200-4%204v2%22%3E%3C%2Fpath%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%227%22%20r%3D%224%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E'
export async function getUserAvatar(): Promise<string> {
try {
const { picture } = getUserProfile()
if (picture) return await getBase64FromImageUrl(picture)
}
catch (e) {
console.error(e)
}
try {
const avatars = Array.from(document.querySelectorAll<HTMLImageElement>('img[alt]:not([aria-hidden])'))
// starts with data: means it's not (lazy)loaded yet
const avatar = avatars.find(avatar => !avatar.src.startsWith('data:'))
const avatar = avatars.find(avatar => avatar.src.startsWith('https://cdn.auth0.com/avatars/'))
if (avatar) return getBase64FromImg(avatar)
}
catch (e) {