优化后端鉴权与日志安全
This commit is contained in:
@@ -37,7 +37,7 @@ export async function runCloudtentaclesFullDebugFlow(payload: JsonObject = {}) {
|
||||
const beforeAsset = await runFlowStep('查询购买前余额', () => getCloudtentaclesAsset(payload))
|
||||
await sleep(350)
|
||||
const skuList = await runFlowStep('查询 SKU 列表', () => listCloudtentaclesSku(payload))
|
||||
const targetSku = skuList.items.find((item) => Number(item.id || 0) === skuId) || null
|
||||
const targetSku = skuList.items.find((item: JsonObject) => Number(item.id || 0) === skuId) || null
|
||||
|
||||
if (!targetSku) {
|
||||
throw createHttpError(`cloudtentacles 未找到 SKU ${skuId}`, {
|
||||
|
||||
@@ -176,7 +176,7 @@ export async function validateCloudtentaclesSession(payload: JsonObject = {}) {
|
||||
userInfo: isPlainObject(userInfoResult.payload?.data) ? userInfoResult.payload.data : {},
|
||||
asset: Number(assetResult.payload?.data || 0),
|
||||
permissions: Array.isArray(permissionResult.payload?.data)
|
||||
? permissionResult.payload.data.map((item) => String(item || '').trim()).filter(Boolean)
|
||||
? permissionResult.payload.data.map((item: unknown) => String(item || '').trim()).filter(Boolean)
|
||||
: [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ import { PROJECT_ROOT } from '../../../config/runtime.js'
|
||||
const CLOUDTENTACLES_SESSION_FILE_PATH = path.join(PROJECT_ROOT, 'data', 'cloudtentacles-session.json')
|
||||
|
||||
type JsonObject = Record<string, any>
|
||||
type CloudtentaclesSessionState = ReturnType<typeof createDefaultCloudtentaclesSessionState>
|
||||
type CloudtentaclesSessionStatesFile = {
|
||||
sessions: Record<string, CloudtentaclesSessionState>
|
||||
}
|
||||
|
||||
export function getCloudtentaclesSessionFilePath() {
|
||||
return CLOUDTENTACLES_SESSION_FILE_PATH
|
||||
@@ -127,7 +131,7 @@ export function pruneCloudtentaclesSessionStates(sourceKeys: unknown[] = []) {
|
||||
// Internal helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function loadCloudtentaclesSessionStatesFromFile() {
|
||||
function loadCloudtentaclesSessionStatesFromFile(): CloudtentaclesSessionStatesFile {
|
||||
if (!fs.existsSync(CLOUDTENTACLES_SESSION_FILE_PATH)) {
|
||||
return createDefaultCloudtentaclesSessionStates()
|
||||
}
|
||||
@@ -162,7 +166,7 @@ function normalizeCloudtentaclesSessionState(rawValue: unknown) {
|
||||
* Handles old format (single object without sessions key) by auto-wrapping
|
||||
* into { sessions: { 'default': ... } }.
|
||||
*/
|
||||
function normalizeSessionStatesFile(rawValue: unknown) {
|
||||
function normalizeSessionStatesFile(rawValue: unknown): CloudtentaclesSessionStatesFile {
|
||||
// Old format: { token: 'xxx', ... } (single object, no sessions key)
|
||||
if (isPlainObject(rawValue) && !rawValue.sessions) {
|
||||
return {
|
||||
@@ -194,7 +198,7 @@ function createDefaultCloudtentaclesSessionState() {
|
||||
}
|
||||
}
|
||||
|
||||
function createDefaultCloudtentaclesSessionStates() {
|
||||
function createDefaultCloudtentaclesSessionStates(): CloudtentaclesSessionStatesFile {
|
||||
return {
|
||||
sessions: {
|
||||
'default': createDefaultCloudtentaclesSessionState(),
|
||||
|
||||
@@ -200,7 +200,7 @@ export async function probeCloudtentaclesBindUrl(payload: JsonObject = {}) {
|
||||
finalUrl: bindUrl,
|
||||
reason: 'missing_signature_params',
|
||||
roleInfo: normalizeAmsBindRoleInfo(null),
|
||||
raw: null,
|
||||
raw: null as null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ export async function probeCloudtentaclesBindUrl(payload: JsonObject = {}) {
|
||||
finalUrl: bindUrl,
|
||||
reason: error instanceof Error ? error.message : String(error || 'probe_failed'),
|
||||
roleInfo: normalizeAmsBindRoleInfo(null),
|
||||
raw: null,
|
||||
raw: null as null,
|
||||
durationMs: Date.now() - startedAt,
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ export async function getCloudtentaclesBindInfo(payload: JsonObject = {}) {
|
||||
})
|
||||
|
||||
const items = Array.isArray(result.payload?.data) ? result.payload.data : []
|
||||
const matchedItem = items.find((item) => Number(item?.id || 0) === id) || items[0] || {}
|
||||
const matchedItem = items.find((item: JsonObject) => Number(item?.id || 0) === id) || items[0] || {}
|
||||
const bindInfo = parseBindInfo(matchedItem?.bind_info)
|
||||
|
||||
return {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from '../../open-91/shared.js'
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { nowIso } from '../../../utils/time.js'
|
||||
import type { OrderItemRow, OrderRow } from '../../../types/repository-rows.js'
|
||||
|
||||
export const OPEN_91_PENDING_CONFIG_STATUS = 'pending_config'
|
||||
export const OPEN_91_MANUAL_FAILED_STATUS = 'manual_failed'
|
||||
@@ -68,7 +69,7 @@ export function buildOpen91SourceEvent(payload: JsonObject = {}, config: JsonObj
|
||||
}
|
||||
}
|
||||
|
||||
export async function upsertOpen91PendingOrder(payload = {}, config = {}) {
|
||||
export async function upsertOpen91PendingOrder(payload: JsonObject = {}, config: JsonObject = {}) {
|
||||
const event = buildOpen91SourceEvent(payload, config)
|
||||
const now = nowIso()
|
||||
const existing = await findOrderByPlatformOrderId({
|
||||
@@ -127,11 +128,11 @@ export async function upsertOpen91PendingOrder(payload = {}, config = {}) {
|
||||
return {
|
||||
order,
|
||||
orderItems,
|
||||
tasks: [],
|
||||
tasks: [] as JsonObject[],
|
||||
}
|
||||
}
|
||||
|
||||
export async function retryOpen91Order(orderId) {
|
||||
export async function retryOpen91Order(orderId: string | number) {
|
||||
const order = await getRequiredOpen91Order(orderId)
|
||||
const items = await listOrderItemsByOrderId(order.id)
|
||||
const event = buildOpen91SourceEventFromOrder(order, items)
|
||||
@@ -154,7 +155,7 @@ export async function retryOpen91Order(orderId) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function failOpen91Order(orderId, reason = '') {
|
||||
export async function failOpen91Order(orderId: string | number, reason = '') {
|
||||
const order = await getRequiredOpen91Order(orderId)
|
||||
const now = nowIso()
|
||||
const rawPayload = parseJsonObject(order.raw_payload_json)
|
||||
@@ -245,7 +246,7 @@ export async function listOpen91Orders({ page = 1, pageSize = 20, status = 'pend
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRequiredOpen91Order(orderId) {
|
||||
export async function getRequiredOpen91Order(orderId: string | number) {
|
||||
const order = await getOrderById(Number(orderId))
|
||||
|
||||
if (!order || order.provider !== OPEN_91_PROVIDER || order.platform !== OPEN_91_PLATFORM) {
|
||||
@@ -258,11 +259,11 @@ export async function getRequiredOpen91Order(orderId) {
|
||||
return order
|
||||
}
|
||||
|
||||
function buildOpen91SourceEventFromOrder(order, items = []) {
|
||||
function buildOpen91SourceEventFromOrder(order: OrderRow, items: OrderItemRow[] = []) {
|
||||
const rawPayload = parseJsonObject(order.raw_payload_json)
|
||||
const body = parseJsonObject(rawPayload.body)
|
||||
const normalizedItems = Array.isArray(items) ? items : []
|
||||
const eventItems = normalizedItems.map((item) => {
|
||||
const eventItems = normalizedItems.map((item: OrderItemRow) => {
|
||||
const snapshot = parseJsonObject(item.item_snapshot_json)
|
||||
const productNo = String(snapshot.productNo || snapshot.externalSkuCode || item.sku_code || '').trim()
|
||||
|
||||
@@ -301,7 +302,7 @@ function buildOpen91SourceEventFromOrder(order, items = []) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapOpen91AdminOrderRow(row) {
|
||||
function mapOpen91AdminOrderRow(row: JsonObject) {
|
||||
const rawPayload = parseJsonObject(row.raw_payload_json)
|
||||
const items = Array.isArray(row.items_json) ? row.items_json : []
|
||||
const firstItem = items[0] || {}
|
||||
@@ -327,7 +328,7 @@ function mapOpen91AdminOrderRow(row) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseJsonObject(value) {
|
||||
function parseJsonObject(value: unknown): JsonObject {
|
||||
if (!value) {
|
||||
return {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user