Initial commit

This commit is contained in:
juluo
2025-10-08 14:48:45 +08:00
committed by GitHub
commit 8b93d6f42f
108 changed files with 27618 additions and 0 deletions

137
api/user.ts Normal file
View File

@@ -0,0 +1,137 @@
import { VercelRequest, VercelResponse } from '@vercel/node'
import { CheerioAPI, load } from 'cheerio'
import { ajax, replacePximgUrlsInObject } from './utils.js'
export default async (req: VercelRequest, res: VercelResponse) => {
const token = req.cookies.PHPSESSID || req.query.token
if (!token) {
return res.status(403).send({ message: '未配置用户密钥' })
}
ajax
.get('/', { params: req.query, headers: req.headers })
.then(async ({ data }) => {
const $ = load(data)
let meta: { userData: any; token: string }
const $legacyGlobalMeta = $('meta[name="global-data"]')
const $nextDataScript = $('script#__NEXT_DATA__')
try {
if ($legacyGlobalMeta.length > 0) {
meta = resolveLegacyGlobalMeta($)
} else if ($nextDataScript.length > 0) {
meta = resolveNextData($)
} else {
throw new Error('未知的元数据类型', {
cause: {
error: new TypeError('No valid resolver found'),
meta: null,
},
})
}
} catch (error: any) {
return res.status(401).send({
message: error.message,
cause: error.cause,
})
}
res.setHeader('cache-control', 'no-cache')
res.setHeader(
'set-cookie',
`CSRFTOKEN=${meta.token}; path=/; secure; sameSite=Lax`
)
res.send(replacePximgUrlsInObject(meta))
})
.catch((err) => {
return res
.status(err?.response?.status || 500)
.send(err?.response?.data || err)
})
}
function resolveLegacyGlobalMeta($: CheerioAPI): {
userData: any
token: string
} {
const $meta = $('meta[name="global-data"]')
if ($meta.length === 0 || !$meta.attr('content')) {
throw new Error('无效的用户密钥', {
cause: {
error: new TypeError('No global-data meta found'),
meta: $meta.prop('outerHTML'),
},
})
}
let meta: any
try {
meta = JSON.parse($meta.attr('content') as string)
} catch (error) {
throw new Error('解析元数据时出错', {
cause: {
error,
meta: $meta.attr('content'),
},
})
}
if (!meta.userData) {
throw new Error('无法获取登录状态', {
cause: {
error: new TypeError('userData is not defined'),
meta,
},
})
}
return {
userData: meta.userData,
token: meta.token || '',
}
}
function resolveNextData($: CheerioAPI): {
userData: any
token: string
} {
const $nextDataScript = $('script#__NEXT_DATA__')
if ($nextDataScript.length === 0) {
throw new Error('无法获取元数据', {
cause: {
error: new TypeError('No #__NEXT_DATA__ script found'),
meta: null,
},
})
}
let nextData: any
let perloadState: any
try {
nextData = JSON.parse($nextDataScript.text())
perloadState = JSON.parse(
nextData?.props?.pageProps?.serverSerializedPreloadedState
)
} catch (error) {
throw new Error('解析元数据时出错', {
cause: {
error,
meta: $nextDataScript.text(),
},
})
}
const userData = perloadState?.userData?.self
if (!userData) {
throw new Error('意料外的元数据', {
cause: {
error: new TypeError('userData is not defined'),
meta: nextData,
},
})
}
const token = perloadState?.api?.token || ''
return { userData, token }
}