77 lines
2.2 KiB
TypeScript

import {
getActiveBlocklistDomains,
getUserCustomDomains,
} from "../../db/domains";
/**
* GET /api/blocklist/personal
* Query: ?format=hosts|ublock|dns|json (default: hosts)
*/
export default defineEventHandler(async (event) => {
const user = await requireUser(event);
const query = getQuery(event);
const format = (query.format as string) ?? "hosts";
const [globalDomains, userDomains] = await Promise.all([
getActiveBlocklistDomains(),
getUserCustomDomains(user.id),
]);
const allDomains = new Set<string>();
for (const d of globalDomains) allDomains.add(d.domain);
for (const d of userDomains) allDomains.add(d.domain);
const domains = [...allDomains].sort();
const timestamp = new Date().toISOString();
const header = `# Rebreak Personal Blocklist\n# User: ${user.id}\n# Generated: ${timestamp}\n# Total: ${domains.length} domains\n# https://rebreak.app\n\n`;
if (format === "json") {
return {
total: domains.length,
global: globalDomains.length,
custom: userDomains.length,
domains,
generated: timestamp,
};
}
let content = header;
switch (format) {
case "hosts":
content += domains.map((d) => `0.0.0.0 ${d}`).join("\n");
setResponseHeader(event, "content-type", "text/plain; charset=utf-8");
setResponseHeader(
event,
"content-disposition",
'attachment; filename="rebreak-personal-hosts.txt"',
);
break;
case "ublock":
content += domains.map((d) => `||${d}^`).join("\n");
setResponseHeader(event, "content-type", "text/plain; charset=utf-8");
setResponseHeader(
event,
"content-disposition",
'attachment; filename="rebreak-personal-ublock.txt"',
);
break;
case "dns":
content += domains.join("\n");
setResponseHeader(event, "content-type", "text/plain; charset=utf-8");
setResponseHeader(
event,
"content-disposition",
'attachment; filename="rebreak-personal-dns.txt"',
);
break;
default:
content += domains.map((d) => `0.0.0.0 ${d}`).join("\n");
setResponseHeader(event, "content-type", "text/plain; charset=utf-8");
}
setResponseHeader(event, "cache-control", "private, max-age=3600");
return content;
});