开启 ppr 优化渲染性能

This commit is contained in:
2025-12-11 14:10:52 +08:00
parent 8fb6ba2f22
commit 5db63273bc
50 changed files with 2635 additions and 10426 deletions

91
src/lib/cap/index.ts Normal file
View File

@@ -0,0 +1,91 @@
import 'server-only'
import Cap, {ChallengeData} from '@cap.js/server'
import {cookies} from 'next/headers'
import {createHmac, randomBytes, timingSafeEqual} from 'crypto'
import {CLIENT_SECRET} from '@/lib/api'
type Sign = {
data: string
timestamp: number
nonce: string
sign: string
}
function sign(data: string, timestamp: number) {
if (!CLIENT_SECRET) throw new Error('无法完成签名')
const hash = createHmac('sha256', CLIENT_SECRET)
const nonce = String(randomBytes(16))
hash.update(data).update(nonce).update(String(timestamp))
return {
data, timestamp, nonce,
sign: hash.digest('hex'),
}
}
function verify({data, timestamp, nonce, sign}: Sign) {
if (!CLIENT_SECRET) throw new Error('无法完成验证')
const hash = createHmac('sha256', CLIENT_SECRET)
hash.update(data).update(nonce).update(String(timestamp))
const excepted = Buffer.from(sign)
const received = Buffer.from(hash.digest('hex'))
return timingSafeEqual(excepted, received)
}
export async function getCap() {
return new Cap({
disableAutoCleanup: true,
noFSState: true,
storage: {
challenges: {
store: async (token: string, data: ChallengeData) => {
const cookie = await cookies()
const rs = sign(JSON.stringify({token, data}), data.expires)
cookie.set(`challenge:${token}`, JSON.stringify(rs), {
secure: process.env.NODE_ENV === 'production',
expires: data.expires,
sameSite: true,
httpOnly: true,
})
},
read: async (token: string) => {
const cookie = await cookies()
const json = cookie.get(`challenge:${token}`)?.value
if (!json) return null
const sign = JSON.parse(json) as Sign
if (!verify(sign)) return null
return JSON.parse(sign.data)['data']
},
delete: async (token: string) => {
const cookie = await cookies()
cookie.delete(`challenge:${token}`)
},
deleteExpired: async () => {},
},
tokens: {
store: async (token: string, expires: number) => {
const cookie = await cookies()
const rs = sign(JSON.stringify({token, expires}), expires)
cookie.set(token, JSON.stringify(rs), {
secure: process.env.NODE_ENV === 'production',
expires: expires,
sameSite: true,
httpOnly: true,
})
},
get: async (token: string) => {
const cookie = await cookies()
const json = cookie.get(token)?.value
if (!json) return null
const sign = JSON.parse(json) as Sign
if (!verify(sign)) return null
return JSON.parse(sign.data)['expires']
},
delete: async (token: string) => {
const cookie = await cookies()
cookie.delete(`token:${token}`)
},
deleteExpired: async () => {},
},
},
})
}