67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
|
|
import db from "../db.server";
|
||
|
|
import type { LogEntry } from "./activity.server";
|
||
|
|
|
||
|
|
const SENSITIVE_KEYS = new Set(["api_secret", "app_secret", "apiSecret", "dreame-api-sign", "sign", "signature"]);
|
||
|
|
|
||
|
|
export async function logActivityPush(entry: LogEntry): Promise<void> {
|
||
|
|
await db.activityPushLog.create({
|
||
|
|
data: {
|
||
|
|
shop: entry.shop,
|
||
|
|
orderId: entry.orderId || "unknown",
|
||
|
|
customerId: entry.customerId,
|
||
|
|
email: entry.email,
|
||
|
|
activityId: entry.activityId || "unknown",
|
||
|
|
eventType: entry.eventType,
|
||
|
|
eventId: entry.eventId || "not-generated",
|
||
|
|
status: entry.status,
|
||
|
|
requestBody: sanitizeBody(entry.requestBody),
|
||
|
|
responseBody: sanitizeBody(entry.responseBody),
|
||
|
|
errorMessage: entry.errorMessage,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (Math.random() < 0.05) {
|
||
|
|
await pruneLogs();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function pruneLogs(days = Number(process.env.LOG_RETENTION_DAYS || 7)): Promise<void> {
|
||
|
|
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
||
|
|
await db.activityPushLog.deleteMany({
|
||
|
|
where: {
|
||
|
|
createdAt: {
|
||
|
|
lt: cutoff,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function sanitizeBody(body: string | undefined): string | undefined {
|
||
|
|
if (!body) {
|
||
|
|
return undefined;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
return JSON.stringify(maskSensitive(JSON.parse(body)));
|
||
|
|
} catch {
|
||
|
|
return body.replace(/[a-f0-9]{32}/gi, "[redacted-md5]");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function maskSensitive(value: unknown): unknown {
|
||
|
|
if (Array.isArray(value)) {
|
||
|
|
return value.map(maskSensitive);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (value && typeof value === "object") {
|
||
|
|
return Object.fromEntries(
|
||
|
|
Object.entries(value as Record<string, unknown>).map(([key, child]) => [
|
||
|
|
key,
|
||
|
|
SENSITIVE_KEYS.has(key) ? "[redacted]" : maskSensitive(child),
|
||
|
|
]),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return value;
|
||
|
|
}
|