- imap-providers: IONOS/1&1/1blu, msn.com, magenta.de, yahoo.co.uk, ymail.com, tutanota hinzugefügt - detectImapProviderAsync: MX-Lookup-Fallback für Custom-Domains (IONOS kundenserver.de/ionos.de Pattern) - connect.post.ts: nutzt jetzt detectImapProviderAsync statt sync-Variante - ConnectMailSheet: rohe Server-Errors werden via humanizeMailError() + t() übersetzt - useMailConnect: IONOS/t-online/freenet Domains in Client-Side-Detection ergänzt - Locale de/en: provider_other, app_password_guide_other, host_unreachable, unknown Text präzisiert Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
import { useCallback, useState } from 'react';
|
|
import { apiFetch } from '../lib/api';
|
|
|
|
export type MailProvider =
|
|
| 'gmail'
|
|
| 'icloud'
|
|
| 'outlook'
|
|
| 'yahoo'
|
|
| 'gmx'
|
|
| 'other';
|
|
|
|
type ConnectBody = {
|
|
email: string;
|
|
password: string;
|
|
// Provider-Feld wird NICHT an das Backend gesendet — der Server erkennt
|
|
// den Provider automatisch via Email-Domain (detectImapProvider in connect.post.ts).
|
|
// Optionale Custom-IMAP-Felder für "other":
|
|
imapHost?: string;
|
|
imapPort?: number;
|
|
useTls?: boolean;
|
|
rejectUnauthorized?: boolean;
|
|
};
|
|
|
|
type ConnectResult = {
|
|
connected: boolean;
|
|
email: string;
|
|
provider: string;
|
|
custom: boolean;
|
|
};
|
|
|
|
export type UseMailConnectReturn = {
|
|
connect: (params: ConnectBody) => Promise<{ ok: boolean; error?: string }>;
|
|
connecting: boolean;
|
|
error: string | null;
|
|
/** Leitet aus der Email-Domain den Provider ab (rein client-seitig, zur UI-Hilfe). */
|
|
detectProvider: (email: string) => MailProvider;
|
|
};
|
|
|
|
const PROVIDER_DOMAIN_MAP: Record<string, MailProvider> = {
|
|
// Google
|
|
'gmail.com': 'gmail',
|
|
'googlemail.com': 'gmail',
|
|
// Apple
|
|
'icloud.com': 'icloud',
|
|
'me.com': 'icloud',
|
|
'mac.com': 'icloud',
|
|
// Microsoft
|
|
'outlook.com': 'outlook',
|
|
'hotmail.com': 'outlook',
|
|
'hotmail.de': 'outlook',
|
|
'live.com': 'outlook',
|
|
'live.de': 'outlook',
|
|
'msn.com': 'outlook',
|
|
// Yahoo
|
|
'yahoo.com': 'yahoo',
|
|
'yahoo.de': 'yahoo',
|
|
'yahoo.co.uk': 'yahoo',
|
|
'ymail.com': 'yahoo',
|
|
// GMX / Web.de
|
|
'gmx.de': 'gmx',
|
|
'gmx.net': 'gmx',
|
|
'gmx.at': 'gmx',
|
|
'gmx.ch': 'gmx',
|
|
'web.de': 'gmx',
|
|
// IONOS / 1&1 → als 'other' behandeln (Server-seitig korrekt erkannt)
|
|
'ionos.de': 'other',
|
|
'1und1.de': 'other',
|
|
'1and1.com': 'other',
|
|
'1and1.de': 'other',
|
|
'1blu.de': 'other',
|
|
// Telekom + Freenet → 'other' (kein eigenes Tile, aber Server kennt sie)
|
|
't-online.de': 'other',
|
|
'freenet.de': 'other',
|
|
};
|
|
|
|
export function detectProvider(email: string): MailProvider {
|
|
const domain = email.trim().toLowerCase().split('@')[1] ?? '';
|
|
return PROVIDER_DOMAIN_MAP[domain] ?? 'other';
|
|
}
|
|
|
|
/**
|
|
* Kapselt POST /api/mail/connect.
|
|
*
|
|
* Backend erwartet: { email, password, imapHost?, imapPort?, useTls?, rejectUnauthorized? }
|
|
* Provider-Detection passiert server-seitig — wir senden keinen provider-Key.
|
|
*/
|
|
export function useMailConnect(): UseMailConnectReturn {
|
|
const [connecting, setConnecting] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const connect = useCallback(async (params: ConnectBody) => {
|
|
setConnecting(true);
|
|
setError(null);
|
|
try {
|
|
await apiFetch<ConnectResult>('/api/mail/connect', {
|
|
method: 'POST',
|
|
body: params,
|
|
});
|
|
return { ok: true };
|
|
} catch (e: any) {
|
|
const msg = e?.message ?? 'Verbindung fehlgeschlagen';
|
|
setError(msg);
|
|
return { ok: false, error: msg };
|
|
} finally {
|
|
setConnecting(false);
|
|
}
|
|
}, []);
|
|
|
|
return { connect, connecting, error, detectProvider };
|
|
}
|