同步修改页面逻辑

This commit is contained in:
not-like-juvenile
2026-03-12 18:05:32 +08:00
parent 4acbb8ced5
commit e70211f1d2
9 changed files with 522 additions and 44 deletions

View File

@@ -70,18 +70,45 @@ function stableEventDedupeKey({ tracking_no, carrier, status_code, event_time, e
async function upsertRaw(payload, tracking_no, carrier, signature_valid) {
try {
const body = {
const received_at = new Date().toISOString()
const minimal = {
carrier: carrier || null,
tracking_no: tracking_no || null,
body: payload,
received_at: new Date().toISOString(),
received_at,
signature_valid: signature_valid
}
const resp = await supaFetch('platform_express_event_raw', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
// Prefer inserting richer metadata when the upgraded schema is present.
// If the database schema is older (missing columns), fall back to minimal.
const meta = arguments && arguments.length >= 5 ? arguments[4] : null
const extended = Object.assign({}, minimal, {
source: 'webhook',
client_id: meta && meta.client_id ? meta.client_id : null,
signature: meta && meta.signature ? meta.signature : null,
ts_header: meta && meta.ts_header ? meta.ts_header : null,
request_id: meta && meta.request_id ? meta.request_id : null,
remote_ip: meta && meta.remote_ip ? meta.remote_ip : null,
headers: meta && meta.headers ? meta.headers : null,
dedupe_key: meta && meta.dedupe_key ? meta.dedupe_key : null
})
const tryInsert = async (row) => {
return await supaFetch('platform_express_event_raw', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(row)
})
}
let resp = await tryInsert(extended)
if (resp && !resp.ok) {
const txt = await resp.text().catch(() => '')
if (resp.status === 400 && /column .* does not exist/i.test(txt)) {
resp = await tryInsert(minimal)
}
}
return resp
} catch (e) {
console.warn('upsertRaw error', e)
@@ -178,13 +205,25 @@ async function start() {
}
const app = express()
app.use(bodyParser.json({ limit: '1mb' }))
// Capture raw body for signature verification.
app.use(bodyParser.json({
limit: '1mb',
verify: (req, res, buf) => {
try {
req.rawBody = buf ? buf.toString('utf8') : ''
} catch (e) {
req.rawBody = ''
}
}
}))
app.post('/webhook/express/status', async (req, res) => {
const ts = req.headers['x-timestamp'] || req.headers['X-TIMESTAMP'] || ''
const sig = req.headers['x-signature'] || req.headers['X-SIGNATURE'] || ''
const cid = req.headers['x-client-id'] || req.headers['X-CLIENT-ID'] || ''
const bodyText = JSON.stringify(req.body || {})
const ts = req.headers['x-timestamp'] || ''
const sig = req.headers['x-signature'] || ''
const cid = req.headers['x-client-id'] || ''
const bodyText = (req.rawBody && typeof req.rawBody === 'string' && req.rawBody.length > 0)
? req.rawBody
: JSON.stringify(req.body || {})
let sigValid = true
if (WEBHOOK_SECRET) {
@@ -192,13 +231,32 @@ async function start() {
sigValid = calc === String(sig)
}
// Optional strict mode: reject invalid signature when secret is configured.
if (WEBHOOK_SECRET && !sigValid && process.env.WEBHOOK_REJECT_INVALID_SIGNATURE === 'true') {
return res.status(401).json({ ok: false, message: 'invalid signature' })
}
// persist raw (best-effort)
await upsertRaw(
req.body || {},
req.body && (req.body.mailNo || req.body.tracking_no),
req.body && (req.body.carrier || req.body.company),
sigValid
)
const tracking_no_raw = req.body && (req.body.mailNo || req.body.tracking_no)
const carrier_raw = req.body && (req.body.carrier || req.body.company)
const dedupe_key_raw = (() => {
try {
const base = String(bodyText || '') + '|' + String(ts || '')
return 'RAW_' + crypto.createHash('sha256').update(base).digest('hex').slice(0, 32)
} catch (e) {
return null
}
})()
await upsertRaw(req.body || {}, tracking_no_raw, carrier_raw, sigValid, {
client_id: String(cid || '') || null,
signature: String(sig || '') || null,
ts_header: String(ts || '') || null,
remote_ip: (req.ip || (req.connection && req.connection.remoteAddress) || null),
request_id: null,
headers: req.headers || null,
dedupe_key: dedupe_key_raw
})
// find waybill
const tracking_no = req.body && (req.body.mailNo || req.body.tracking_no)