65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import { decode, encode } from 'next-auth/jwt'
|
|
import type { NextRequest } from 'next/server'
|
|
import { resolveSecureAuthCookieFromRequest } from '@/lib/auth-cookie'
|
|
|
|
const PROFILE_TOKEN_PURPOSE = 'dingtalk-profile-completion'
|
|
const PROFILE_TOKEN_MAX_AGE_SECONDS = 10 * 60
|
|
const PROFILE_COOKIE_PATH = '/api/dingtalk/complete-profile'
|
|
const PROFILE_COOKIE_NAME = 'dingtalk-profile-token'
|
|
const SECURE_PROFILE_COOKIE_NAME = '__Secure-dingtalk-profile-token'
|
|
|
|
function getSecret() {
|
|
const secret = process.env.NEXTAUTH_SECRET
|
|
if (!secret) {
|
|
throw new Error('登录会话未配置 NEXTAUTH_SECRET')
|
|
}
|
|
return secret
|
|
}
|
|
|
|
export function getDingtalkProfileCookiePath() {
|
|
return PROFILE_COOKIE_PATH
|
|
}
|
|
|
|
export function getDingtalkProfileCookieName(request: NextRequest) {
|
|
return resolveSecureAuthCookieFromRequest(request)
|
|
? SECURE_PROFILE_COOKIE_NAME
|
|
: PROFILE_COOKIE_NAME
|
|
}
|
|
|
|
export function getDingtalkProfileCookieCandidates(request: NextRequest) {
|
|
const preferred = getDingtalkProfileCookieName(request)
|
|
return preferred === SECURE_PROFILE_COOKIE_NAME
|
|
? [SECURE_PROFILE_COOKIE_NAME, PROFILE_COOKIE_NAME]
|
|
: [PROFILE_COOKIE_NAME, SECURE_PROFILE_COOKIE_NAME]
|
|
}
|
|
|
|
export async function createDingtalkProfileToken(userId: string) {
|
|
return encode({
|
|
secret: getSecret(),
|
|
maxAge: PROFILE_TOKEN_MAX_AGE_SECONDS,
|
|
token: {
|
|
sub: userId,
|
|
purpose: PROFILE_TOKEN_PURPOSE,
|
|
} as any,
|
|
})
|
|
}
|
|
|
|
export async function verifyDingtalkProfileToken(token: string | null | undefined) {
|
|
const normalizedToken = String(token || '').trim()
|
|
if (!normalizedToken) {
|
|
return null
|
|
}
|
|
|
|
try {
|
|
const payload = await decode({ token: normalizedToken, secret: getSecret() })
|
|
if (payload?.purpose !== PROFILE_TOKEN_PURPOSE || !payload.sub) {
|
|
return null
|
|
}
|
|
return String(payload.sub)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export const DINGTALK_PROFILE_TOKEN_MAX_AGE_SECONDS = PROFILE_TOKEN_MAX_AGE_SECONDS
|