added backup and email client

This commit is contained in:
2026-02-01 00:02:35 +01:00
parent ff857be01a
commit e4fdfbc95f
210 changed files with 24211 additions and 742 deletions
@@ -8,6 +8,7 @@ import {
EmailExistsResult,
EmailOperationResult,
CreateEmailParams,
MailEncryption,
} from './types.js';
import { PleskEmailProvider } from './pleskProvider.js';
@@ -68,6 +69,10 @@ export interface CreateProviderConfigData {
password?: string;
domain: string;
defaultForwardEmail?: string;
// Verschlüsselungs-Einstellungen
imapEncryption?: MailEncryption;
smtpEncryption?: MailEncryption;
allowSelfSignedCerts?: boolean;
isActive?: boolean;
isDefault?: boolean;
}
@@ -95,6 +100,9 @@ export async function createProviderConfig(data: CreateProviderConfigData) {
passwordEncrypted,
domain: data.domain,
defaultForwardEmail: data.defaultForwardEmail || null,
imapEncryption: data.imapEncryption ?? 'SSL',
smtpEncryption: data.smtpEncryption ?? 'SSL',
allowSelfSignedCerts: data.allowSelfSignedCerts ?? false,
isActive: data.isActive ?? true,
isDefault: data.isDefault ?? false,
},
@@ -123,6 +131,9 @@ export async function updateProviderConfig(
if (data.domain !== undefined) updateData.domain = data.domain;
if (data.defaultForwardEmail !== undefined)
updateData.defaultForwardEmail = data.defaultForwardEmail || null;
if (data.imapEncryption !== undefined) updateData.imapEncryption = data.imapEncryption;
if (data.smtpEncryption !== undefined) updateData.smtpEncryption = data.smtpEncryption;
if (data.allowSelfSignedCerts !== undefined) updateData.allowSelfSignedCerts = data.allowSelfSignedCerts;
if (data.isActive !== undefined) updateData.isActive = data.isActive;
if (data.isDefault !== undefined) updateData.isDefault = data.isDefault;
@@ -179,6 +190,13 @@ async function getProviderInstance(): Promise<IEmailProvider> {
password,
domain: dbConfig.domain,
defaultForwardEmail: dbConfig.defaultForwardEmail || undefined,
imapServer: dbConfig.imapServer || undefined,
imapPort: dbConfig.imapPort || undefined,
smtpServer: dbConfig.smtpServer || undefined,
smtpPort: dbConfig.smtpPort || undefined,
imapEncryption: dbConfig.imapEncryption as MailEncryption,
smtpEncryption: dbConfig.smtpEncryption as MailEncryption,
allowSelfSignedCerts: dbConfig.allowSelfSignedCerts,
isActive: dbConfig.isActive,
isDefault: dbConfig.isDefault,
};
@@ -239,6 +257,169 @@ export async function provisionEmail(
}
}
// E-Mail mit echter Mailbox erstellen (IMAP/SMTP-Zugang)
export async function provisionEmailWithMailbox(
localPart: string,
customerEmail: string,
password: string
): Promise<EmailOperationResult & { email?: string }> {
try {
const provider = await getProviderInstance();
const config = await getActiveProviderConfig();
// Weiterleitungsziele zusammenstellen
const forwardTargets: string[] = [customerEmail];
// Unsere eigene Weiterleitungsadresse hinzufügen falls konfiguriert
if (config?.defaultForwardEmail) {
forwardTargets.push(config.defaultForwardEmail);
}
// Prüfen ob existiert
const exists = await provider.emailExists(localPart);
if (exists.exists) {
return {
success: true,
message: `E-Mail ${exists.email} existiert bereits`,
email: exists.email,
};
}
// Mit Mailbox erstellen
const result = await provider.createEmailWithMailbox({
localPart,
forwardTargets,
password,
});
return result;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unbekannter Fehler';
return {
success: false,
error: errorMessage,
};
}
}
// Mailbox für existierende E-Mail-Weiterleitung aktivieren
export async function enableMailboxForExistingEmail(
localPart: string,
password: string
): Promise<EmailOperationResult> {
try {
const provider = await getProviderInstance();
const result = await provider.enableMailboxForExisting({
localPart,
password,
});
return result;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unbekannter Fehler';
return {
success: false,
error: errorMessage,
};
}
}
// Mailbox-Passwort beim Provider aktualisieren
export async function updateMailboxPassword(
localPart: string,
password: string
): Promise<EmailOperationResult> {
try {
const provider = await getProviderInstance();
const result = await provider.updateMailboxPassword({
localPart,
password,
});
return result;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unbekannter Fehler';
return {
success: false,
error: errorMessage,
};
}
}
// IMAP/SMTP-Einstellungen vom aktiven Provider holen
export interface ImapSmtpSettings {
imapServer: string;
imapPort: number;
imapEncryption: MailEncryption; // SSL, STARTTLS oder NONE
smtpServer: string;
smtpPort: number;
smtpEncryption: MailEncryption; // SSL, STARTTLS oder NONE
allowSelfSignedCerts: boolean; // Selbstsignierte Zertifikate erlauben
domain: string;
}
export async function getImapSmtpSettings(): Promise<ImapSmtpSettings | null> {
const config = await getActiveProviderConfig();
if (!config) return null;
// Default-Server: Hostname aus der apiUrl extrahieren (z.B. rs001871.fastrootserver.de aus https://rs001871.fastrootserver.de:8443)
// Der Plesk-Server ist gleichzeitig der Mail-Server
let defaultServer: string;
try {
const url = new URL(config.apiUrl);
defaultServer = url.hostname;
} catch {
// Fallback falls apiUrl ungültig
defaultServer = `mail.${config.domain}`;
}
// Verschlüsselungs-Einstellungen
const imapEncryption = (config.imapEncryption ?? 'SSL') as MailEncryption;
const smtpEncryption = (config.smtpEncryption ?? 'SSL') as MailEncryption;
// Ports basierend auf Verschlüsselung berechnen:
// SSL: IMAP 993, SMTP 465
// STARTTLS: IMAP 143, SMTP 587
// NONE: IMAP 143, SMTP 25
//
// Standard-Ports werden IMMER basierend auf Verschlüsselung berechnet.
// Nur benutzerdefinierte Ports (nicht 993/143/465/587/25) werden aus der DB übernommen.
const getImapPort = (enc: MailEncryption, storedPort: number | null) => {
const standardPorts = [993, 143];
// Wenn ein nicht-standard Port gespeichert ist, diesen verwenden
if (storedPort && !standardPorts.includes(storedPort)) {
return storedPort;
}
// Sonst basierend auf Verschlüsselung
return enc === 'SSL' ? 993 : 143;
};
const getSmtpPort = (enc: MailEncryption, storedPort: number | null) => {
const standardPorts = [465, 587, 25];
// Wenn ein nicht-standard Port gespeichert ist, diesen verwenden
if (storedPort && !standardPorts.includes(storedPort)) {
return storedPort;
}
// Sonst basierend auf Verschlüsselung
if (enc === 'SSL') return 465;
if (enc === 'STARTTLS') return 587;
return 25; // NONE
};
return {
imapServer: config.imapServer || defaultServer,
imapPort: getImapPort(imapEncryption, config.imapPort),
imapEncryption,
smtpServer: config.smtpServer || defaultServer,
smtpPort: getSmtpPort(smtpEncryption, config.smtpPort),
smtpEncryption,
allowSelfSignedCerts: config.allowSelfSignedCerts ?? false,
domain: config.domain,
};
}
// E-Mail löschen
export async function deprovisionEmail(localPart: string): Promise<EmailOperationResult> {
try {
@@ -328,6 +509,13 @@ async function getProviderInstanceById(id: number): Promise<IEmailProvider> {
password,
domain: dbConfig.domain,
defaultForwardEmail: dbConfig.defaultForwardEmail || undefined,
imapServer: dbConfig.imapServer || undefined,
imapPort: dbConfig.imapPort || undefined,
smtpServer: dbConfig.smtpServer || undefined,
smtpPort: dbConfig.smtpPort || undefined,
imapEncryption: dbConfig.imapEncryption as MailEncryption,
smtpEncryption: dbConfig.smtpEncryption as MailEncryption,
allowSelfSignedCerts: dbConfig.allowSelfSignedCerts,
isActive: dbConfig.isActive,
isDefault: dbConfig.isDefault,
};