feat: 新增企微 OAuth 换码路由与 HMAC 身份票据服务
This commit is contained in:
65
app/api/wecom-oauth/route.ts
Normal file
65
app/api/wecom-oauth/route.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { getRuntimeEnv } from "../../../lib/runtime-env";
|
||||
import {
|
||||
exchangeWecomOAuthCode,
|
||||
fetchWecomExternalContactName,
|
||||
resolveWecomConfig,
|
||||
WecomClientError,
|
||||
type WecomBindings,
|
||||
} from "../../../lib/wecom-client";
|
||||
import { signWecomIdentityTicket } from "../../../lib/wecom-oauth-service";
|
||||
import { partnerOptions, withPartnerCors } from "../../../lib/partner-cors";
|
||||
|
||||
const env = getRuntimeEnv();
|
||||
|
||||
export function OPTIONS(request: Request) {
|
||||
return partnerOptions(request);
|
||||
}
|
||||
|
||||
async function handlePost(request: Request) {
|
||||
try {
|
||||
const body = (await request.json().catch(() => ({}))) as { code?: string };
|
||||
const code = String(body.code ?? "").trim();
|
||||
const config = resolveWecomConfig(env as unknown as WecomBindings);
|
||||
if (!config.corpId || !config.agentId || !config.secret) {
|
||||
return Response.json(
|
||||
{ error: "未配置企业微信授权(WECOM_CORP_ID / WECOM_AGENT_ID / WECOM_SECRET)" },
|
||||
{ status: 501 },
|
||||
);
|
||||
}
|
||||
if (!code) {
|
||||
return Response.json({ error: "缺少授权 code" }, { status: 400 });
|
||||
}
|
||||
const identity = await exchangeWecomOAuthCode(config, code);
|
||||
if (identity.externalUserId) {
|
||||
const displayName =
|
||||
(await fetchWecomExternalContactName(config, identity.externalUserId)) ??
|
||||
"企微客户";
|
||||
const { ticket, expiresIn } = await signWecomIdentityTicket(
|
||||
identity.externalUserId,
|
||||
displayName,
|
||||
);
|
||||
return Response.json({
|
||||
userType: "external",
|
||||
identityTicket: ticket,
|
||||
displayName,
|
||||
expiresIn,
|
||||
});
|
||||
}
|
||||
return Response.json({
|
||||
userType: "internal",
|
||||
userId: identity.userId ?? "",
|
||||
});
|
||||
} catch (error) {
|
||||
const status = error instanceof WecomClientError ? error.status : 500;
|
||||
return Response.json(
|
||||
{ error: error instanceof Error ? error.message : "授权失败" },
|
||||
{ status },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const response = await handlePost(request);
|
||||
response.headers.set("Cache-Control", "private, no-store");
|
||||
return withPartnerCors(request, response);
|
||||
}
|
||||
Reference in New Issue
Block a user