优化后端鉴权与日志安全
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
||||
normalizeActor,
|
||||
parseTaskContext,
|
||||
} from "./kuaishou-cloud/task-context.js";
|
||||
import type { TaskRow } from "../../types/repository-rows.js";
|
||||
|
||||
export {
|
||||
isKuaishouCloudBindUrlFresh,
|
||||
@@ -58,7 +59,7 @@ export {
|
||||
resolvePersistedCloudtentaclesContextWithFallback,
|
||||
} from "./kuaishou-cloud/cloudtentacles-context.js";
|
||||
|
||||
export async function ensureTaskClaimLink(task) {
|
||||
export async function ensureTaskClaimLink(task: TaskRow) {
|
||||
const tokenStatus = String(task?.primary_claim_token_status || "").trim();
|
||||
const token = String(
|
||||
task?.primary_claim_token || task?.claim_token || ""
|
||||
@@ -82,7 +83,7 @@ export async function ensureTaskClaimLink(task) {
|
||||
}
|
||||
|
||||
export async function prepareKuaishouCloudFulfillmentTask(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
@@ -246,7 +247,7 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
bindUrl: preparedBinding.bindUrl,
|
||||
bindPreparedAt: now,
|
||||
bindExpiresAt: resolveKuaishouCloudBindUrlExpiresAt(now),
|
||||
bindProbeAt: null,
|
||||
bindProbeAt: null as null,
|
||||
bindProbeStatus: "pending",
|
||||
bindProbeMessage: "",
|
||||
roleName: "",
|
||||
@@ -256,9 +257,9 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
status: "pending",
|
||||
name: "",
|
||||
rid: "",
|
||||
refreshedAt: null,
|
||||
refreshedAt: null as null,
|
||||
errorMessage: "",
|
||||
rawInfo: null,
|
||||
rawInfo: null as null,
|
||||
},
|
||||
purchase: {
|
||||
...flowWithResolvedBinding.purchase,
|
||||
@@ -312,7 +313,7 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
}
|
||||
|
||||
export async function refreshKuaishouCloudTaskBindUrl(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
@@ -413,7 +414,7 @@ export async function refreshKuaishouCloudTaskBindUrl(
|
||||
bindUrl: preparedBinding.bindUrl,
|
||||
bindPreparedAt: now,
|
||||
bindExpiresAt: resolveKuaishouCloudBindUrlExpiresAt(now),
|
||||
bindProbeAt: null,
|
||||
bindProbeAt: null as null,
|
||||
bindProbeStatus: "pending",
|
||||
bindProbeMessage: "",
|
||||
roleName:
|
||||
@@ -485,7 +486,7 @@ export async function refreshKuaishouCloudTaskBindUrl(
|
||||
}
|
||||
|
||||
export async function probeKuaishouCloudTaskBindUrl(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
@@ -503,7 +504,7 @@ export async function probeKuaishouCloudTaskBindUrl(
|
||||
return {
|
||||
task,
|
||||
flow,
|
||||
probe: null,
|
||||
probe: null as null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -518,7 +519,7 @@ export async function probeKuaishouCloudTaskBindUrl(
|
||||
return {
|
||||
task,
|
||||
flow,
|
||||
probe: null,
|
||||
probe: null as null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -582,7 +583,7 @@ export async function probeKuaishouCloudTaskBindUrl(
|
||||
* @param {{ taskContext?: any, flow?: any, now?: string, actor?: any, error?: unknown }} [input]
|
||||
*/
|
||||
async function markKuaishouCloudBindUrlRefreshFailed(
|
||||
task,
|
||||
task: TaskRow,
|
||||
{ taskContext, flow, now, actor, error }: JsonObject = {}
|
||||
) {
|
||||
const errorMessage =
|
||||
@@ -648,7 +649,7 @@ async function markKuaishouCloudBindUrlRefreshFailed(
|
||||
}
|
||||
|
||||
export async function refreshKuaishouCloudTaskRoleInfo(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
import { KUAISHOU_CLOUD_FIXED_VN_KEY, type JsonObject } from "./domain.js";
|
||||
|
||||
export function resolveKuaishouCloudBindingResources(
|
||||
flow,
|
||||
{ skuItems = [], knapsackItems = [] } = {}
|
||||
flow: JsonObject,
|
||||
{ skuItems = [], knapsackItems = [] }: { skuItems?: unknown[], knapsackItems?: unknown[] } = {}
|
||||
) {
|
||||
const normalizedSkuItems = Array.isArray(skuItems)
|
||||
? skuItems.filter(isCloudSkuLikeItem)
|
||||
@@ -70,7 +70,7 @@ export function resolveKuaishouCloudBindingResources(
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveKuaishouCloudVnKeyCandidates(_input = {}) {
|
||||
export function resolveKuaishouCloudVnKeyCandidates(_input: JsonObject = {}) {
|
||||
return [KUAISHOU_CLOUD_FIXED_VN_KEY];
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ export async function prepareKuaishouCloudBindResourceWithFallback(input: JsonOb
|
||||
);
|
||||
}
|
||||
|
||||
function collectKuaishouCloudNameCandidates(flow) {
|
||||
function collectKuaishouCloudNameCandidates(flow: JsonObject) {
|
||||
return Array.from(
|
||||
new Set(
|
||||
[
|
||||
@@ -171,10 +171,10 @@ function collectKuaishouCloudNameCandidates(flow) {
|
||||
);
|
||||
}
|
||||
|
||||
function findCloudItemByNames(items, nameCandidates, preferredId = 0) {
|
||||
function findCloudItemByNames(items: JsonObject[], nameCandidates: string[], preferredId = 0) {
|
||||
const normalizedItems = Array.isArray(items) ? items : [];
|
||||
const normalizedNames = nameCandidates
|
||||
.map((item) => ({
|
||||
.map((item: string) => ({
|
||||
raw: String(item || "").trim(),
|
||||
normalized: normalizeProductName(item),
|
||||
}))
|
||||
@@ -182,34 +182,34 @@ function findCloudItemByNames(items, nameCandidates, preferredId = 0) {
|
||||
|
||||
if (normalizedNames.length === 0 || normalizedItems.length === 0) {
|
||||
return preferredId > 0
|
||||
? normalizedItems.find((item) => Number(item.id || 0) === preferredId) ||
|
||||
? normalizedItems.find((item: JsonObject) => Number(item.id || 0) === preferredId) ||
|
||||
null
|
||||
: null;
|
||||
}
|
||||
|
||||
if (preferredId > 0) {
|
||||
const preferred =
|
||||
normalizedItems.find((item) => Number(item.id || 0) === preferredId) ||
|
||||
normalizedItems.find((item: JsonObject) => Number(item.id || 0) === preferredId) ||
|
||||
null;
|
||||
if (preferred) {
|
||||
return preferred;
|
||||
}
|
||||
}
|
||||
|
||||
const exactMatches = normalizedItems.filter((item) => {
|
||||
const exactMatches = normalizedItems.filter((item: JsonObject) => {
|
||||
const itemName = normalizeProductName(item.name);
|
||||
return normalizedNames.some(
|
||||
(candidate) => candidate.normalized === itemName
|
||||
(candidate: { normalized: string }) => candidate.normalized === itemName
|
||||
);
|
||||
});
|
||||
if (exactMatches.length > 0) {
|
||||
return exactMatches[0];
|
||||
}
|
||||
|
||||
const partialMatches = normalizedItems.filter((item) => {
|
||||
const partialMatches = normalizedItems.filter((item: JsonObject) => {
|
||||
const itemName = normalizeProductName(item.name);
|
||||
return normalizedNames.some(
|
||||
(candidate) =>
|
||||
(candidate: { normalized: string }) =>
|
||||
itemName.includes(candidate.normalized) ||
|
||||
candidate.normalized.includes(itemName)
|
||||
);
|
||||
@@ -224,13 +224,15 @@ function findCloudItemByNames(items, nameCandidates, preferredId = 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function isCloudSkuLikeItem(item) {
|
||||
return Boolean(item) && typeof item === "object" && Number(item.id || 0) > 0;
|
||||
function isCloudSkuLikeItem(item: unknown): item is JsonObject {
|
||||
const current = item && typeof item === "object" ? item as JsonObject : {};
|
||||
return Number(current.id || 0) > 0;
|
||||
}
|
||||
|
||||
function isRecoverableKuaishouCloudVnKeyError(error) {
|
||||
const errorCode = String(error?.errorCode || error?.code || "").trim();
|
||||
const errorMessage = String(error?.message || "").trim();
|
||||
function isRecoverableKuaishouCloudVnKeyError(error: unknown) {
|
||||
const current = error && typeof error === "object" ? error as JsonObject : {};
|
||||
const errorCode = String(current.errorCode || current.code || "").trim();
|
||||
const errorMessage = String(current.message || "").trim();
|
||||
return (
|
||||
errorCode === "cloudtentacles_vn_bind_url_failed" &&
|
||||
errorMessage.includes("不支持的游戏类型")
|
||||
|
||||
@@ -45,7 +45,7 @@ export function resolvePersistedCloudtentaclesContext(sourceKey = "default") {
|
||||
*/
|
||||
export function resolvePersistedCloudtentaclesContextWithFallback(
|
||||
primarySourceKey = "default",
|
||||
fallbacks = []
|
||||
fallbacks: unknown[] = []
|
||||
) {
|
||||
const candidates = [
|
||||
String(primarySourceKey || "default").trim() || "default",
|
||||
|
||||
@@ -8,12 +8,13 @@ export const KUAISHOU_CLOUD_FIXED_VN_KEY = "1";
|
||||
|
||||
export type JsonObject = Record<string, any>;
|
||||
|
||||
export function isKuaishouCloudTask(task) {
|
||||
return String(task?.executor_key || "").trim() === "kuaishou_ct_assisted";
|
||||
export function isKuaishouCloudTask(task: unknown) {
|
||||
const source = task && typeof task === "object" ? task as JsonObject : {};
|
||||
return String(source.executor_key || "").trim() === "kuaishou_ct_assisted";
|
||||
}
|
||||
|
||||
export function normalizeKuaishouCloudFlow(value) {
|
||||
const source = value && typeof value === "object" ? value : {};
|
||||
export function normalizeKuaishouCloudFlow(value: unknown) {
|
||||
const source: JsonObject = value && typeof value === "object" ? value as JsonObject : {};
|
||||
const binding =
|
||||
source.binding && typeof source.binding === "object" ? source.binding : {};
|
||||
const role =
|
||||
@@ -129,8 +130,8 @@ export function normalizeKuaishouCloudFlow(value) {
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeKuaishouCloudRoleInfo(value) {
|
||||
const rawInfo = value && typeof value === "object" ? value : null;
|
||||
export function normalizeKuaishouCloudRoleInfo(value: unknown) {
|
||||
const rawInfo: JsonObject | null = value && typeof value === "object" ? value as JsonObject : null;
|
||||
const nestedBindInfo =
|
||||
rawInfo?.sBindInfo && typeof rawInfo.sBindInfo === "object"
|
||||
? rawInfo.sBindInfo
|
||||
@@ -157,15 +158,15 @@ export function normalizeKuaishouCloudRoleInfo(value) {
|
||||
};
|
||||
}
|
||||
|
||||
export function maskPhone(value) {
|
||||
export function maskPhone(value: unknown) {
|
||||
return maskPhoneValue(value);
|
||||
}
|
||||
|
||||
export function maskCode(value) {
|
||||
export function maskCode(value: unknown) {
|
||||
return maskCodeValue(value);
|
||||
}
|
||||
|
||||
export function resolveKuaishouCloudBindUrlExpiresAt(preparedAt) {
|
||||
export function resolveKuaishouCloudBindUrlExpiresAt(preparedAt: unknown) {
|
||||
const preparedTime = Date.parse(String(preparedAt || ""));
|
||||
if (!Number.isFinite(preparedTime)) {
|
||||
return null;
|
||||
@@ -176,7 +177,7 @@ export function resolveKuaishouCloudBindUrlExpiresAt(preparedAt) {
|
||||
return new Date(preparedTime + Math.max(1, ttlSeconds) * 1000).toISOString();
|
||||
}
|
||||
|
||||
export function isKuaishouCloudBindUrlFresh(flow, now = new Date()) {
|
||||
export function isKuaishouCloudBindUrlFresh(flow: unknown, now = new Date()) {
|
||||
const normalizedFlow = normalizeKuaishouCloudFlow(flow);
|
||||
if (!normalizedFlow.binding.bindUrl) {
|
||||
return false;
|
||||
@@ -195,7 +196,7 @@ export function isKuaishouCloudBindUrlFresh(flow, now = new Date()) {
|
||||
return expiresTime > now.getTime();
|
||||
}
|
||||
|
||||
export function normalizeStringArray(value) {
|
||||
export function normalizeStringArray(value: unknown) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((v) => String(v || "").trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { parseTaskContext as parseTaskContextValue } from "../../../utils/task-json.js";
|
||||
import type { TaskRow } from "../../../types/repository-rows.js";
|
||||
|
||||
export function normalizeActor(actor) {
|
||||
type JsonObject = Record<string, any>;
|
||||
|
||||
export function normalizeActor(actor: unknown) {
|
||||
if (!actor || typeof actor !== "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const source = String(actor.source || "").trim();
|
||||
const userId = Number(actor.userId || 0) || 0;
|
||||
const username = String(actor.username || "").trim();
|
||||
const role = String(actor.role || "").trim();
|
||||
const current = actor as JsonObject;
|
||||
const source = String(current.source || "").trim();
|
||||
const userId = Number(current.userId || 0) || 0;
|
||||
const username = String(current.username || "").trim();
|
||||
const role = String(current.role || "").trim();
|
||||
|
||||
if (!source && !userId && !username && !role) {
|
||||
return null;
|
||||
@@ -22,19 +26,19 @@ export function normalizeActor(actor) {
|
||||
};
|
||||
}
|
||||
|
||||
export function parseTaskContext(task) {
|
||||
export function parseTaskContext(task: Partial<TaskRow> | null | undefined) {
|
||||
return parseTaskContextValue(task);
|
||||
}
|
||||
|
||||
export function getTaskClaimExpiresAt(task) {
|
||||
export function getTaskClaimExpiresAt(task: Partial<TaskRow> | null | undefined) {
|
||||
return task?.claim_expires_at || task?.primary_claim_expires_at || null;
|
||||
}
|
||||
|
||||
export function isClaimExpired(expiredAt) {
|
||||
export function isClaimExpired(expiredAt: unknown) {
|
||||
if (!expiredAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const timestamp = new Date(expiredAt).getTime();
|
||||
const timestamp = new Date(expiredAt instanceof Date ? expiredAt : String(expiredAt || "")).getTime();
|
||||
return Number.isFinite(timestamp) && timestamp <= Date.now();
|
||||
}
|
||||
|
||||
@@ -20,9 +20,10 @@ import {
|
||||
} from "./domain.js";
|
||||
import { resolvePersistedCloudtentaclesContextWithFallback } from "./cloudtentacles-context.js";
|
||||
import { normalizeActor, parseTaskContext } from "./task-context.js";
|
||||
import type { TaskRow } from "../../../types/repository-rows.js";
|
||||
|
||||
export async function dispatchKuaishouCloudFulfillmentTask(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
@@ -157,7 +158,7 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
||||
}
|
||||
|
||||
export async function returnKuaishouCloudFulfillmentTask(
|
||||
task,
|
||||
task: TaskRow,
|
||||
options: JsonObject = {}
|
||||
) {
|
||||
if (!isKuaishouCloudTask(task)) {
|
||||
|
||||
Reference in New Issue
Block a user