feat: update codex live chat workflow
This commit is contained in:
@@ -39,6 +39,61 @@ const deleteSchema = z.object({
|
||||
});
|
||||
|
||||
const protectedBoardPostAutomationFields = new Set(['automation_plan_item_id', 'automation_received_at']);
|
||||
const secretFieldPattern = /(?:^|_|-)(?:password|passwd|pwd|passcode|secret|token|api[_-]?key|access[_-]?key|private[_-]?key)(?:$|_|-)/i;
|
||||
const loginFieldPattern =
|
||||
/(?:^|_|-)(?:login[_-]?id|login[_-]?name|username|user[_-]?name|user[_-]?id|account[_-]?id|account[_-]?name|admin[_-]?id|admin[_-]?name|member[_-]?id|member[_-]?name|email)(?:$|_|-)/i;
|
||||
|
||||
function maskCredentialValue(value: string) {
|
||||
const trimmed = value.trim();
|
||||
|
||||
if (!trimmed) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (trimmed.length <= 2) {
|
||||
return '*'.repeat(trimmed.length);
|
||||
}
|
||||
|
||||
if (trimmed.length <= 4) {
|
||||
return `${trimmed[0]}${'*'.repeat(trimmed.length - 2)}${trimmed.at(-1) ?? ''}`;
|
||||
}
|
||||
|
||||
return `${trimmed.slice(0, 2)}${'*'.repeat(Math.max(2, trimmed.length - 4))}${trimmed.slice(-2)}`;
|
||||
}
|
||||
|
||||
function shouldMaskLoginField(fieldName: string, row: Record<string, unknown>) {
|
||||
if (!loginFieldPattern.test(fieldName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Object.keys(row).some((candidateField) => secretFieldPattern.test(candidateField));
|
||||
}
|
||||
|
||||
export function maskCrudRowSensitiveFields<T>(value: T): T {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => maskCrudRowSensitiveFields(item)) as T;
|
||||
}
|
||||
|
||||
if (!value || typeof value !== 'object') {
|
||||
return value;
|
||||
}
|
||||
|
||||
const row = value as Record<string, unknown>;
|
||||
const result: Record<string, unknown> = {};
|
||||
|
||||
Object.entries(row).forEach(([fieldName, fieldValue]) => {
|
||||
if (typeof fieldValue === 'string') {
|
||||
if (secretFieldPattern.test(fieldName) || shouldMaskLoginField(fieldName, row)) {
|
||||
result[fieldName] = maskCredentialValue(fieldValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result[fieldName] = maskCrudRowSensitiveFields(fieldValue);
|
||||
});
|
||||
|
||||
return result as T;
|
||||
}
|
||||
|
||||
function applyFilters(query: Knex.QueryBuilder, filters: z.infer<typeof filterSchema>[] = []) {
|
||||
filters.forEach((filter) => {
|
||||
@@ -138,7 +193,7 @@ export async function registerCrudRoutes(app: FastifyInstance) {
|
||||
ok: true,
|
||||
table,
|
||||
count: rows.length,
|
||||
rows,
|
||||
rows: maskCrudRowSensitiveFields(rows),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -150,7 +205,7 @@ export async function registerCrudRoutes(app: FastifyInstance) {
|
||||
return {
|
||||
ok: true,
|
||||
table,
|
||||
rows: inserted,
|
||||
rows: maskCrudRowSensitiveFields(inserted),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -197,7 +252,7 @@ export async function registerCrudRoutes(app: FastifyInstance) {
|
||||
ok: true,
|
||||
table,
|
||||
count: rows.length,
|
||||
rows,
|
||||
rows: maskCrudRowSensitiveFields(rows),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -214,7 +269,7 @@ export async function registerCrudRoutes(app: FastifyInstance) {
|
||||
ok: true,
|
||||
table,
|
||||
count: rows.length,
|
||||
rows,
|
||||
rows: maskCrudRowSensitiveFields(rows),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user