Initial local backup snapshot

This commit is contained in:
Selecta Keke 2026-06-24 00:02:55 -03:00
commit acd9e14ba5
367 changed files with 118038 additions and 0 deletions

125
shared/mailProviders.ts Normal file
View file

@ -0,0 +1,125 @@
export const supportedMailProviders = ["custom", "ovh", "gmail", "outlook"] as const;
export type SupportedMailProvider = typeof supportedMailProviders[number];
export type MailEnvInput = {
smtpProvider?: string;
smtpHost?: string;
smtpPort?: string;
smtpUser?: string;
smtpPass?: string;
smtpFrom?: string;
smtpSecure?: string;
smtpRequireTls?: string;
};
export type ResolvedMailConfig = {
provider: SupportedMailProvider;
host: string;
port: number | null;
secure: boolean;
requireTLS: boolean;
user: string;
pass: string;
from: string;
missing: string[];
ready: boolean;
};
export const providerDefaults: Record<
Exclude<SupportedMailProvider, "custom">,
{ host: string; port: number; secure: boolean; requireTLS: boolean }
> = {
ovh: {
host: "smtp.mail.ovh.net",
port: 465,
secure: true,
requireTLS: false,
},
gmail: {
host: "smtp.gmail.com",
port: 465,
secure: true,
requireTLS: false,
},
outlook: {
host: "smtp.office365.com",
port: 587,
secure: false,
requireTLS: true,
},
};
function normalizeProvider(value?: string): SupportedMailProvider {
const normalized = String(value || "")
.trim()
.toLowerCase();
if (normalized === "ovh" || normalized === "gmail" || normalized === "outlook") {
return normalized;
}
return "custom";
}
function parseBoolean(value?: string, fallback = false): boolean {
const normalized = String(value || "")
.trim()
.toLowerCase();
if (!normalized) {
return fallback;
}
return ["1", "true", "yes", "oui", "on"].includes(normalized);
}
function parsePort(value?: string, fallback: number | null = null): number | null {
const trimmed = String(value || "").trim();
if (!trimmed) {
return fallback;
}
const port = Number(trimmed);
if (!Number.isFinite(port) || port <= 0) {
return fallback;
}
return port;
}
export function resolveMailConfig(input: MailEnvInput): ResolvedMailConfig {
const provider = normalizeProvider(input.smtpProvider);
const defaults = provider === "custom" ? null : providerDefaults[provider];
const host = String(input.smtpHost || defaults?.host || "").trim();
const port = parsePort(input.smtpPort, defaults?.port ?? null);
const secure = parseBoolean(input.smtpSecure, defaults?.secure ?? false);
const requireTLS = parseBoolean(input.smtpRequireTls, defaults?.requireTLS ?? false);
const user = String(input.smtpUser || "").trim();
const pass = String(input.smtpPass || "").trim();
const from = String(input.smtpFrom || "").trim();
const missing: string[] = [];
if (!host) {
missing.push("SMTP_HOST");
}
if (!port) {
missing.push("SMTP_PORT");
}
if (!from) {
missing.push("SMTP_FROM");
}
if (user && !pass) {
missing.push("SMTP_PASS");
}
if (pass && !user) {
missing.push("SMTP_USER");
}
return {
provider,
host,
port,
secure,
requireTLS,
user,
pass,
from,
missing,
ready: missing.length === 0,
};
}