rebreak-monorepo/backend/server/api/mail/proxy-config.get.ts

137 lines
4.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { randomUUID } from "crypto";
import { getImapProxyAccounts, getMailConnections } from "../../db/mail";
import { getProfile } from "../../db/profile";
import { getPlanLimits } from "../../utils/plan-features";
import { detectSmtpProvider } from "../../utils/imap-providers";
import { decrypt } from "../../utils/crypto";
function escapeXml(s: string): string {
return s
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;");
}
export default defineEventHandler(async (event) => {
const user = await requireUser(event);
const profile = await getProfile(user.id);
const limits = getPlanLimits(profile?.plan ?? "free");
if (limits.mailAgents !== Infinity) {
throw createError({ statusCode: 403, message: "Nur für Legend-User verfügbar" });
}
const [accounts, connections] = await Promise.all([
getImapProxyAccounts(user.id),
getMailConnections(user.id),
]);
if (accounts.length === 0) {
throw createError({ statusCode: 404, message: "Noch keine Proxy-Konten eingerichtet" });
}
const connMap = new Map(connections.map((c) => [c.id, c]));
const payloads: string[] = [];
for (const account of accounts) {
const conn = connMap.get(account.connectionId);
if (!conn) continue;
let proxyPassword: string;
try {
proxyPassword = decrypt(account.proxyPassword);
} catch {
continue; // Legacy scrypt hash skip, user needs to re-generate via proxy-account.post
}
let realPassword = "";
try {
realPassword = decrypt(conn.passwordEncrypted);
} catch { /* SMTP password omitted */ }
const smtp = detectSmtpProvider(conn.imapHost);
payloads.push(`<dict>
<key>EmailAccountDescription</key>
<string>ReBreak Filter ${escapeXml(conn.email)}</string>
<key>EmailAccountName</key>
<string>${escapeXml(conn.email)}</string>
<key>EmailAccountType</key>
<string>EmailTypeIMAP</string>
<key>EmailAddress</key>
<string>${escapeXml(conn.email)}</string>
<key>IncomingMailServerHostName</key>
<string>imap.rebreak.org</string>
<key>IncomingMailServerPortNumber</key>
<integer>993</integer>
<key>IncomingMailServerUseSSL</key>
<true/>
<key>IncomingMailServerUsername</key>
<string>${escapeXml(account.proxyUsername)}</string>
<key>IncomingMailServerPassword</key>
<string>${escapeXml(proxyPassword)}</string>
<key>OutgoingMailServerHostName</key>
<string>${escapeXml(smtp.host)}</string>
<key>OutgoingMailServerPortNumber</key>
<integer>${smtp.port}</integer>
<key>OutgoingMailServerUseSSL</key>
<true/>
<key>OutgoingMailServerUsername</key>
<string>${escapeXml(conn.email)}</string>${realPassword ? `
<key>OutgoingMailServerPassword</key>
<string>${escapeXml(realPassword)}</string>` : ""}
<key>SMIMEEnabled</key>
<false/>
<key>PayloadDescription</key>
<string>Mail-Filter für ${escapeXml(conn.email)}</string>
<key>PayloadDisplayName</key>
<string>ReBreak ${escapeXml(conn.email)}</string>
<key>PayloadIdentifier</key>
<string>org.rebreak.mail.${conn.id}</string>
<key>PayloadType</key>
<string>com.apple.mail.managed</string>
<key>PayloadUUID</key>
<string>${randomUUID()}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>`);
}
if (payloads.length === 0) {
throw createError({ statusCode: 400, message: "Proxy-Konten müssen zuerst neu erstellt werden" });
}
const plist = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
${payloads.join("\n ")}
</array>
<key>PayloadDescription</key>
<string>Blockiert Casino-Mails automatisch bevor sie in deinen Posteingang gelangen</string>
<key>PayloadDisplayName</key>
<string>ReBreak Mail Filter</string>
<key>PayloadIdentifier</key>
<string>org.rebreak.mail.profile.${user.id}</string>
<key>PayloadOrganization</key>
<string>ReBreak</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>${randomUUID()}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>`;
setHeader(event, "Content-Type", "application/x-apple-aspen-config");
setHeader(event, "Content-Disposition", 'attachment; filename="rebreak-mail-filter.mobileconfig"');
return plist;
});