mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:01:08 +02:00
refactor(mana-auth): route emails through mana-notify instead of Nodemailer
Replace direct Brevo SMTP sending with HTTP calls to mana-notify's notification API. This centralizes all email configuration in one service (mana-notify) and removes the nodemailer dependency from mana-auth. SMTP provider is now swappable via a single env var. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
62d9eb1f2b
commit
b2adaaa30e
5 changed files with 26 additions and 48 deletions
|
|
@ -271,10 +271,7 @@ services:
|
|||
MANA_SUBSCRIPTIONS_URL: http://mana-subscriptions:3063
|
||||
SYNC_DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:-mana123}@postgres:5432/mana_platform
|
||||
BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:-${JWT_SECRET:-your-jwt-secret-change-me}}
|
||||
SMTP_HOST: smtp-relay.brevo.com
|
||||
SMTP_PORT: 587
|
||||
SMTP_USER: ${SMTP_USER:-94cde5002@smtp-brevo.com}
|
||||
SMTP_PASS: ${SMTP_PASSWORD}
|
||||
MANA_NOTIFY_URL: http://mana-notify:3013
|
||||
SYNAPSE_OIDC_CLIENT_SECRET: ${SYNAPSE_OIDC_CLIENT_SECRET:-}
|
||||
MAX_DAILY_SIGNUPS: ${MAX_DAILY_SIGNUPS:-0}
|
||||
CORS_ORIGINS: https://mana.how,https://calendar.mana.how,https://chat.mana.how,https://clock.mana.how,https://contacts.mana.how,https://context.mana.how,https://docs.mana.how,https://element.mana.how,https://inventar.mana.how,https://link.mana.how,https://cards.mana.how,https://matrix.mana.how,https://mukke.mana.how,https://nutriphi.mana.how,https://photos.mana.how,https://picture.mana.how,https://planta.mana.how,https://playground.mana.how,https://presi.mana.how,https://questions.mana.how,https://skilltree.mana.how,https://storage.mana.how,https://times.mana.how,https://todo.mana.how,https://traces.mana.how,https://zitare.mana.how
|
||||
|
|
|
|||
|
|
@ -16,12 +16,10 @@
|
|||
"drizzle-orm": "^0.38.3",
|
||||
"postgres": "^3.4.5",
|
||||
"jose": "^6.1.2",
|
||||
"nodemailer": "^7.0.12",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"zod": "^3.24.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"drizzle-kit": "^0.30.4",
|
||||
"typescript": "^5.9.3"
|
||||
|
|
|
|||
|
|
@ -7,12 +7,7 @@ export interface Config {
|
|||
nodeEnv: string;
|
||||
serviceKey: string;
|
||||
cors: { origins: string[] };
|
||||
smtp: {
|
||||
host: string;
|
||||
port: number;
|
||||
user: string;
|
||||
pass: string;
|
||||
};
|
||||
manaNotifyUrl: string;
|
||||
manaCreditsUrl: string;
|
||||
manaSubscriptionsUrl: string;
|
||||
synapseOidcClientSecret: string;
|
||||
|
|
@ -35,12 +30,7 @@ export function loadConfig(): Config {
|
|||
nodeEnv: env('NODE_ENV', 'development'),
|
||||
serviceKey: env('MANA_CORE_SERVICE_KEY', 'dev-service-key'),
|
||||
cors: { origins: env('CORS_ORIGINS', 'http://localhost:5173').split(',') },
|
||||
smtp: {
|
||||
host: env('SMTP_HOST', 'smtp-relay.brevo.com'),
|
||||
port: parseInt(env('SMTP_PORT', '587'), 10),
|
||||
user: env('SMTP_USER'),
|
||||
pass: env('SMTP_PASS'),
|
||||
},
|
||||
manaNotifyUrl: env('MANA_NOTIFY_URL', 'http://localhost:3013'),
|
||||
manaCreditsUrl: env('MANA_CREDITS_URL', 'http://localhost:3061'),
|
||||
manaSubscriptionsUrl: env('MANA_SUBSCRIPTIONS_URL', 'http://localhost:3063'),
|
||||
synapseOidcClientSecret: env('SYNAPSE_OIDC_CLIENT_SECRET'),
|
||||
|
|
|
|||
|
|
@ -1,40 +1,35 @@
|
|||
/**
|
||||
* Email sending functions using nodemailer.
|
||||
* German language emails with Brevo SMTP.
|
||||
* Email sending via mana-notify service.
|
||||
* All emails are routed through the central notification service
|
||||
* which handles SMTP, retries, and queuing.
|
||||
*/
|
||||
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
let transporter: nodemailer.Transporter | null = null;
|
||||
|
||||
export function initializeEmail(smtp: { host: string; port: number; user: string; pass: string }) {
|
||||
if (!smtp.host || !smtp.user) {
|
||||
console.warn('SMTP not configured — emails will be logged to console');
|
||||
return;
|
||||
}
|
||||
transporter = nodemailer.createTransport({
|
||||
host: smtp.host,
|
||||
port: smtp.port,
|
||||
secure: false,
|
||||
auth: { user: smtp.user, pass: smtp.pass },
|
||||
});
|
||||
}
|
||||
const NOTIFY_URL = process.env.MANA_NOTIFY_URL || 'http://localhost:3013';
|
||||
const SERVICE_KEY = process.env.MANA_CORE_SERVICE_KEY || 'dev-service-key';
|
||||
|
||||
async function send(to: string, subject: string, html: string): Promise<boolean> {
|
||||
if (!transporter) {
|
||||
console.log(`[EMAIL] To: ${to} | Subject: ${subject}`);
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
from: '"ManaCore" <noreply@mana.how>',
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
const res = await fetch(`${NOTIFY_URL}/api/v1/notifications/send`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Service-Key': SERVICE_KEY,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
channel: 'email',
|
||||
appId: 'mana-auth',
|
||||
recipient: to,
|
||||
subject,
|
||||
body: html,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) {
|
||||
console.error('mana-notify error:', res.status, await res.text());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Failed to send email:', error);
|
||||
console.error('Failed to send via mana-notify:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import { createBetterAuth } from './auth/better-auth.config';
|
|||
import { errorHandler } from './middleware/error-handler';
|
||||
import { jwtAuth } from './middleware/jwt-auth';
|
||||
import { serviceAuth } from './middleware/service-auth';
|
||||
import { initializeEmail } from './email/send';
|
||||
import { SecurityEventsService, AccountLockoutService } from './services/security';
|
||||
import { SignupLimitService } from './services/signup-limit';
|
||||
import { ApiKeysService } from './services/api-keys';
|
||||
|
|
@ -31,7 +30,6 @@ const db = getDb(config.databaseUrl);
|
|||
const auth = createBetterAuth(config.databaseUrl);
|
||||
|
||||
// Initialize services
|
||||
initializeEmail(config.smtp);
|
||||
const security = new SecurityEventsService(db);
|
||||
const lockout = new AccountLockoutService(db);
|
||||
const signupLimit = new SignupLimitService(db);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue