修复 R7E 真机反馈回流与移动入口 WF8-11A R7E-16A R7E-16B BIZ8-12A

这个提交包含在:
2026-05-14 21:53:20 +08:00
父节点 45900e0673
当前提交 5491e922e6
共修改 26 个文件,包含 281 行新增和 56 行删除
+15 -10
查看文件
@@ -182,6 +182,17 @@ function sanitizeReturnTo(value) {
return trimmed;
}
function isWecomWebViewRequest(request) {
const userAgent = String(request.headers["user-agent"] ?? "").toLowerCase();
return userAgent.includes("wxwork");
}
function buildWecomLoginRedirect(origin, targetPath) {
const params = new URLSearchParams({ returnTo: targetPath });
const path = `/api/auth/wecom/login?${params.toString()}`;
return origin ? `${origin}${path}` : path;
}
function parseAccessTokenTtlSeconds(value) {
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
return Math.floor(value);
@@ -737,8 +748,7 @@ async function authRoutes(fastify) {
const payload = verified.payload && typeof verified.payload === "object" ? verified.payload : {};
const targetPath = typeof payload.targetPath === "string" ? payload.targetPath.trim() : "";
const exp = Number(payload.exp ?? 0);
if (!targetPath || !targetPath.startsWith("/")) {
if (!targetPath || !targetPath.startsWith("/") || targetPath.startsWith("//")) {
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
@@ -746,16 +756,11 @@ async function authRoutes(fastify) {
details: { targetPath: "invalid_target_path" },
});
}
if (!Number.isFinite(exp) || Date.now() / 1000 > exp) {
throw new AppError({
code: "AUTH_001",
message: "深链已过期",
statusCode: 401,
details: { token: "expired" },
});
}
const origin = String(fastify.config.appOrigin || "").split(",")[0].trim().replace(/\/+$/, "");
if (isWecomWebViewRequest(request)) {
return reply.redirect(buildWecomLoginRedirect(origin, targetPath));
}
return reply.redirect(origin ? `${origin}${targetPath}` : targetPath);
});
+3 -2
查看文件
@@ -607,12 +607,12 @@ async function portalRoutes(fastify) {
select: { project_id: true },
}).then((items) => items.length)
: Promise.resolve(0),
roleCapabilities.canUseFinance
roleCapabilities.canUseFinance && featureEnabled.paymentBatch
? fastify.prisma.paymentBatch.count({
where: { status: { in: ["draft", "reviewed", "failed"] } },
})
: Promise.resolve(0),
roleCapabilities.canUseFinance
roleCapabilities.canUseFinance && featureEnabled.paymentBatch
? fastify.prisma.paymentBatchItem.count({ where: { status: "failed" } })
: Promise.resolve(0),
buildRecentActivities(fastify.prisma),
@@ -814,6 +814,7 @@ async function portalRoutes(fastify) {
pendingBatchCount: pendingFinanceBatchCount,
failedItemCount: failedFinanceItemCount,
riskCount,
paymentBatchEnabled: featureEnabled.paymentBatch,
href: "/ap-operations",
}
: null,
@@ -24,7 +24,6 @@ function buildDetailUrl(config, targetPath) {
const token = signPayload(
{
targetPath: normalizedPath,
exp: Math.floor(Date.now() / 1000) + 15 * 60,
},
config.jwtSecret,
);