diff --git a/app/dingtalk-callback/page.tsx b/app/dingtalk-callback/page.tsx index 81cec99..af613e3 100644 --- a/app/dingtalk-callback/page.tsx +++ b/app/dingtalk-callback/page.tsx @@ -5,6 +5,26 @@ import { useRouter, useSearchParams } from 'next/navigation' import { signIn } from 'next-auth/react' import { normalizeInternalRedirectPath } from '@/lib/safe-redirect' +const DINGTALK_DIRECT_LOGIN_SOURCE = 'work_notice_direct' + +function parseDingtalkStateSource(value: string) { + if (!value) return '' + + let raw = value + try { + raw = decodeURIComponent(raw) + } catch { + // URLSearchParams 通常已经解码,这里仅兼容手工拼接的 URL。 + } + + try { + const data = JSON.parse(raw) + return typeof data?.source === 'string' ? data.source : '' + } catch { + return '' + } +} + function DingtalkCallbackContent() { const router = useRouter() const searchParams = useSearchParams() @@ -23,6 +43,12 @@ function DingtalkCallbackContent() { const code = searchParams?.get('code') || searchParams?.get('authCode') const state = searchParams?.get('state') || 'default' + if (parseDingtalkStateSource(state) === DINGTALK_DIRECT_LOGIN_SOURCE) { + setMessage('正在进入素材库...') + window.location.replace(`/api/dingtalk/callback${window.location.search}`) + return + } + if (!code) { throw new Error('授权失败:缺少授权码') } diff --git a/middleware.ts b/middleware.ts index a7794e2..7252f79 100644 --- a/middleware.ts +++ b/middleware.ts @@ -5,27 +5,10 @@ import { getAuthSessionCookieCandidates, resolveSecureAuthCookieFromRequest, } from '@/lib/auth-cookie' -import { - DINGTALK_DIRECT_LOGIN_SOURCE, - parseDingtalkOAuthState, -} from '@/lib/dingtalk-oauth' const API_CORS_ALLOWED_HEADERS = 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key, Authorization, Cookie' -function buildDingtalkDirectLoginRewrite(request: NextRequest) { - const state = request.nextUrl.searchParams.get('state') || '' - const parsedState = parseDingtalkOAuthState(state) - - if (parsedState.source !== DINGTALK_DIRECT_LOGIN_SOURCE) { - return null - } - - const callbackUrl = new URL('/api/dingtalk/callback', request.url) - callbackUrl.search = request.nextUrl.search - return NextResponse.rewrite(callbackUrl) -} - // 注意:不在middleware中启动内存监控 // middleware使用Edge Runtime,不支持Node.js API // 内存监控会在lib/memory-monitor.ts模块加载时自动启动(仅生产环境) @@ -60,13 +43,6 @@ export async function middleware(request: NextRequest) { return response } - if (pathname === '/dingtalk-callback') { - const dingtalkDirectLoginRewrite = buildDingtalkDirectLoginRewrite(request) - if (dingtalkDirectLoginRewrite) { - return dingtalkDirectLoginRewrite - } - } - // 处理需要认证的页面 if (pathname === '/' || pathname.startsWith('/admin')) { const preferredSecureCookie = resolveSecureAuthCookieFromRequest(request) @@ -160,5 +136,5 @@ export async function middleware(request: NextRequest) { } export const config = { - matcher: ['/', '/admin/:path*', '/api/:path*', '/dingtalk-callback'], + matcher: ['/', '/admin/:path*', '/api/:path*'], }