forked from wangziqi/gongxue-base
feat: add platform audit alert notifications
This commit is contained in:
@@ -321,11 +321,17 @@ function validateEnv() {
|
||||
pass('env.asset_security_scan_fail_open', 'asset security scanning fails closed');
|
||||
}
|
||||
|
||||
if (envBool('WORKER_CRM_ALLOW_INSECURE_LOCALHOST', false)) {
|
||||
block('env.worker_crm_insecure_localhost', 'WORKER_CRM_ALLOW_INSECURE_LOCALHOST must be false in production');
|
||||
} else {
|
||||
pass('env.worker_crm_insecure_localhost', 'CRM worker insecure localhost webhook mode is disabled');
|
||||
}
|
||||
if (envBool('WORKER_CRM_ALLOW_INSECURE_LOCALHOST', false)) {
|
||||
block('env.worker_crm_insecure_localhost', 'WORKER_CRM_ALLOW_INSECURE_LOCALHOST must be false in production');
|
||||
} else {
|
||||
pass('env.worker_crm_insecure_localhost', 'CRM worker insecure localhost webhook mode is disabled');
|
||||
}
|
||||
|
||||
if (envBool('WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST', false)) {
|
||||
block('env.worker_platform_audit_notification_insecure_localhost', 'WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST must be false in production');
|
||||
} else {
|
||||
pass('env.worker_platform_audit_notification_insecure_localhost', 'Platform audit notification worker insecure localhost webhook mode is disabled');
|
||||
}
|
||||
|
||||
const requiredPositiveNumbers = [
|
||||
'WORKER_CRM_BATCH_SIZE',
|
||||
@@ -419,6 +425,51 @@ async function validateDatabase() {
|
||||
pass('db.payment_provider_secrets', 'Active payment accounts have private secret rows');
|
||||
}
|
||||
|
||||
const unsafePlatformAuditNotificationRows = await pool.query(`
|
||||
select id, channel_code, provider, webhook_url
|
||||
from public.platform_audit_notification_channels
|
||||
where enabled = true
|
||||
and (
|
||||
webhook_url !~* '^https://'
|
||||
or webhook_url ~* '^https?://(localhost|127\\.0\\.0\\.1|\\[?::1\\]?)'
|
||||
)
|
||||
`);
|
||||
if (unsafePlatformAuditNotificationRows.rowCount > 0) {
|
||||
block('db.platform_audit_notification_webhooks', 'Enabled platform audit notification webhooks must use production HTTPS URLs', {
|
||||
count: unsafePlatformAuditNotificationRows.rowCount,
|
||||
samples: unsafePlatformAuditNotificationRows.rows.slice(0, 5).map(row => ({
|
||||
id: row.id,
|
||||
channelCode: row.channel_code,
|
||||
provider: row.provider,
|
||||
})),
|
||||
});
|
||||
} else {
|
||||
pass('db.platform_audit_notification_webhooks', 'Enabled platform audit notification webhooks use production HTTPS URLs');
|
||||
}
|
||||
|
||||
const missingPlatformAuditNotificationSecretRows = await pool.query(`
|
||||
select c.id, c.channel_code, c.provider, c.secret_ref
|
||||
from public.platform_audit_notification_channels c
|
||||
left join app_private.platform_secrets s
|
||||
on s.secret_scope = split_part(c.secret_ref, ':', 2)
|
||||
and s.secret_key = split_part(c.secret_ref, ':', 3)
|
||||
where c.enabled = true
|
||||
and c.provider in ('dingtalk', 'feishu')
|
||||
and (c.secret_ref is null or c.secret_ref !~ '^app_private\\.platform_secrets:' or s.id is null)
|
||||
`);
|
||||
if (missingPlatformAuditNotificationSecretRows.rowCount > 0) {
|
||||
block('db.platform_audit_notification_secrets', 'Signed platform audit notification channels require app_private.platform_secrets rows', {
|
||||
count: missingPlatformAuditNotificationSecretRows.rowCount,
|
||||
samples: missingPlatformAuditNotificationSecretRows.rows.slice(0, 5).map(row => ({
|
||||
id: row.id,
|
||||
channelCode: row.channel_code,
|
||||
provider: row.provider,
|
||||
})),
|
||||
});
|
||||
} else {
|
||||
pass('db.platform_audit_notification_secrets', 'Signed platform audit notification channels have private secret rows');
|
||||
}
|
||||
|
||||
const unverifiedDomainRows = await pool.query(`
|
||||
select count(*)::int as count
|
||||
from public.tenant_domains
|
||||
|
||||
Reference in New Issue
Block a user