Skip to content

Commit d5b4c27

Browse files
Push up
1 parent a47fc7d commit d5b4c27

1 file changed

Lines changed: 28 additions & 15 deletions

File tree

index.js

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ async function handleHostingRegister(request, env) {
554554

555555
// Notify Discord
556556
sendDiscordWebhook(env,
557-
`${statusEmoji} **New Hosting Provider Registration**\n**Organization:** ${body.org}\n**Email:** ${body.email}\n**Location:** ${body.location}\n**Mirror:** ${body.mirror_url}\n**Website:** ${body.website || 'N/A'}\n**Discord User ID:** ${body.discord_user_id || 'N/A'}\n**Subscribed:** ${body.subscribe ? 'Yes' : 'No'}\n**Vetting Score:** ${vetResult.score}\n**Status:** ${statusLabel}\n**ID:** ${id}\n\nTo approve: POST to /api/hosting/admin/approve-removal with { provider_id: "${id}", admin_key: "ADMIN_SECRET" }\nTo reject: POST to /api/hosting/admin/reject-removal with same\nAdmin page: https://acreetionos.org/api/hosting/admin/pending`
557+
`${statusEmoji} **New Hosting Provider Registration**\n**Organization:** ${body.org}\n**Email:** ${body.email}\n**Location:** ${body.location}\n**Mirror:** ${body.mirror_url}\n**Website:** ${body.website || 'N/A'}\n**Discord User ID:** ${body.discord_user_id || 'N/A'}\n**Subscribed:** ${body.subscribe ? 'Yes' : 'No'}\n**Vetting Score:** ${vetResult.score}\n**Status:** ${statusLabel}\n**ID:** ${id}\n\nTo approve: POST to /api/hosting/admin/approve-removal with { provider_id: "${id}", admin_key: "ADMIN_SECRET" }\nTo reject: POST to /api/hosting/admin/reject-removal with same\nTo approve removal: add "action": "approve-removal" to the body\nAdmin page: https://acreetionos.org/api/hosting/admin/pending`
558558
);
559559

560560
if (vetResult.flags.length > 0) {
@@ -847,10 +847,19 @@ async function scanISOSuspicious(env) {
847847
const objects = await listR2(env, 'acreetionos-hosting', 'provider-');
848848
const flagged = [];
849849
const errors = [];
850-
const vtQuarantined = [];
851850
const vtDisabled = [];
852851

853852
let quota = await getScanQuota(env);
853+
854+
// Reset VT quota if the daily window has expired
855+
if (quota.vt_reset && Date.now() > quota.vt_reset) {
856+
quota.vt_remaining = 500;
857+
quota.vt_reset = Date.now() + 86400000;
858+
quota.vt_disabled = false;
859+
delete quota.vt_disabled_at;
860+
await saveScanQuota(env, quota);
861+
}
862+
854863
let useVt = !quota.vt_disabled && env.SCAN_MASTER;
855864

856865
for (const obj of objects) {
@@ -971,11 +980,12 @@ async function scanISOSuspicious(env) {
971980
}
972981
}
973982

974-
return { flagged, errors, vt_disabled: quota.vt_disabled, vt_quarantined: vtDisabled };
983+
return { flagged, errors, vt_disabled: quota.vt_disabled, vt_quota_exhausted_for: vtDisabled };
975984
}
976985

977986
async function checkStaleProviders(env) {
978987
const objects = await listR2(env, 'acreetionos-hosting', 'provider-');
988+
const warned = [];
979989
const expired = [];
980990
const now = Date.now();
981991
const twoWeeks = 14 * 24 * 60 * 60 * 1000;
@@ -997,9 +1007,7 @@ async function checkStaleProviders(env) {
9971007
const emailBody = `Hi ${data.org},\n\nYour AcreetionOS hosting provider listing has been flagged as inactive.\n\nYour ISO mirror (${data.mirror_url}) has not been reachable for 14 days. Per our requirements, providers must maintain an active mirror.\n\nIf you believe this is an error, please contact us at developers@acreetionos.org or re-register at https://acreetionos.org/hosting.html\n\nIf we don't hear from you within 7 days, your listing will be automatically removed.\n\n- AcreetionOS Team`;
9981008
await sendHostingEmail(env, data.email, 'AcreetionOS Hosting — Inactivity Warning', emailBody);
9991009

1000-
sendDiscordWebhook(env,
1001-
`**⚠️ Provider Inactivity Warning**\n**Provider:** ${data.org}\n**Email:** ${data.email}\n**ISO:** ${data.mirror_url}\n**Last seen:** ${data.last_seen || 'Never'}\n**Grace period:** 7 days before removal\n\nWarning email sent to provider.`
1002-
);
1010+
warned.push({ org: data.org, email: data.email, last_seen: data.last_seen });
10031011
}
10041012

10051013
// Remove after 21 days (14 days + 7 day grace)
@@ -1015,7 +1023,7 @@ async function checkStaleProviders(env) {
10151023
// This is a safety net for providers not scanned recently
10161024
}
10171025

1018-
return expired;
1026+
return { warned, expired };
10191027
}
10201028

10211029
async function handleHostingScan(request, env) {
@@ -1029,9 +1037,9 @@ async function handleHostingScan(request, env) {
10291037

10301038
let needsClamav = false;
10311039

1032-
// Auto-deregister flagged providers (VT-confirmed only)
1040+
// Auto-deregister flagged providers (VT-confirmed only — local_quick cannot confirm malware)
10331041
for (const flagged of result.flagged) {
1034-
if (flagged.scan_method === 'virustotal' || (flagged.scan_method === 'local_quick' && flagged.malicious)) {
1042+
if (flagged.scan_method === 'virustotal') {
10351043
await deleteR2(env, 'acreetionos-hosting', 'provider-' + flagged.id);
10361044
sendDiscordWebhook(env,
10371045
`**🚨 MALWARE DETECTED — Provider Auto-Deregistered**\n**Provider:** ${flagged.org}\n**Email:** ${flagged.email}\n**ISO:** ${flagged.mirror_url}\n**Method:** ${flagged.scan_method}\n**Malicious detections:** ${flagged.malicious || 0}\n**Issues:** ${(flagged.issues || []).join(', ')}\n\nProvider has been immediately removed from the website.`
@@ -1057,10 +1065,15 @@ async function handleHostingScan(request, env) {
10571065
}
10581066

10591067
// Check for stale/expired providers (not seen in 14+ days)
1060-
const expired = await checkStaleProviders(env);
1061-
if (expired.length > 0) {
1068+
const staleResult = await checkStaleProviders(env);
1069+
if (staleResult.warned.length > 0) {
1070+
sendDiscordWebhook(env,
1071+
`**⚠️ Providers Warned (Inactive 14+ Days)**\n${staleResult.warned.map(e => `- ${e.org} (${e.email}) — Last seen: ${e.last_seen || 'never'}`).join('\n')}\n\nWarning email sent. 7-day grace period started.`
1072+
);
1073+
}
1074+
if (staleResult.expired.length > 0) {
10621075
sendDiscordWebhook(env,
1063-
`**⏰ Providers Expired (Inactive 14+ Days)**\n${expired.map(e => `- ${e.org} (${e.email}) — Last seen: ${e.last_seen || 'never'}`).join('\n')}\n\nThey have been removed and notified.`
1076+
`**⏰ Providers Removed (Inactive 21+ Days)**\n${staleResult.expired.map(e => `- ${e.org} (${e.email}) — Last seen: ${e.last_seen || 'never'}`).join('\n')}\n\nThey have been removed and notified.`
10641077
);
10651078
}
10661079

@@ -1669,7 +1682,7 @@ async function handleCVEFeed(env, ctx) {
16691682
return new Response(JSON.stringify({ error: 'No CVE data available', cves: [], count: 0 }), { headers: corsHeaders({ headers: { get: () => '' } }) });
16701683
}
16711684

1672-
async function handleCVEStatus(env) {
1685+
async function handleCVEStatus(env, ctx) {
16731686
const cached = await getR2(env, 'acreetionos-hosting', 'cve-cache.json');
16741687
if (cached && cached.cves) {
16751688
const critical = cached.cves.filter(c =>
@@ -1695,7 +1708,7 @@ async function handleCVEStatus(env) {
16951708
headers: { 'Content-Type': 'application/json', 'Cache-Control': 'public, max-age=600', ...corsHeaders({ headers: { get: () => '' } }) }
16961709
});
16971710
}
1698-
return handleCVEFeed(env);
1711+
return handleCVEFeed(env, ctx);
16991712
}
17001713

17011714
async function handleCVEEmbed() {
@@ -2092,7 +2105,7 @@ export default {
20922105
return handleCVEFeed(env, ctx);
20932106
}
20942107
if (url.pathname === '/api/cve/status' && request.method === 'GET') {
2095-
return handleCVEStatus(env);
2108+
return handleCVEStatus(env, ctx);
20962109
}
20972110
if (url.pathname === '/api/cve/fix' && request.method === 'POST') {
20982111
return handleCVEFix(request, env);

0 commit comments

Comments
 (0)