Test
This commit is contained in:
7
app/api/health/route.ts
Normal file
7
app/api/health/route.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { logLine } from "@/lib/logger";
|
||||
|
||||
export async function GET() {
|
||||
logLine("health.hit", { ok: true });
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import { prisma } from "@/lib/prisma";
|
||||
import { DEFAULT_ALERTS, DEFAULT_DEFAULTS, DEFAULT_SHIFT } from "@/lib/settings";
|
||||
import { buildVerifyEmail, sendEmail } from "@/lib/email";
|
||||
import { getBaseUrl } from "@/lib/appUrl";
|
||||
import { logLine } from "@/lib/logger";
|
||||
|
||||
|
||||
function slugify(input: string) {
|
||||
const trimmed = input.trim().toLowerCase();
|
||||
@@ -120,10 +122,16 @@ export async function POST(req: Request) {
|
||||
text: emailContent.text,
|
||||
html: emailContent.html,
|
||||
});
|
||||
} catch {
|
||||
} catch (err: any) {
|
||||
emailSent = false;
|
||||
logLine("signup.verify_email.failed", {
|
||||
email,
|
||||
message: err?.message,
|
||||
code: err?.code,
|
||||
response: err?.response,
|
||||
responseCode: err?.responseCode,
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
verificationRequired: true,
|
||||
|
||||
56
lib/email.ts
56
lib/email.ts
@@ -1,4 +1,6 @@
|
||||
import nodemailer from "nodemailer";
|
||||
import { logLine } from "@/lib/logger";
|
||||
|
||||
|
||||
type EmailPayload = {
|
||||
to: string;
|
||||
@@ -25,11 +27,23 @@ function getTransporter() {
|
||||
throw new Error("SMTP not configured");
|
||||
}
|
||||
|
||||
const smtpDebug = process.env.SMTP_DEBUG === "true";
|
||||
logLine("smtp.config", {
|
||||
host,
|
||||
port,
|
||||
secure,
|
||||
user,
|
||||
from: process.env.SMTP_FROM,
|
||||
smtpDebug,
|
||||
});
|
||||
|
||||
cachedTransport = nodemailer.createTransport({
|
||||
host,
|
||||
port,
|
||||
secure,
|
||||
auth: { user, pass },
|
||||
logger: smtpDebug,
|
||||
debug: smtpDebug,
|
||||
});
|
||||
|
||||
return cachedTransport;
|
||||
@@ -40,15 +54,55 @@ export async function sendEmail(payload: EmailPayload) {
|
||||
if (!from) {
|
||||
throw new Error("SMTP_FROM not configured");
|
||||
}
|
||||
logLine("email.send.start", {
|
||||
to: payload.to,
|
||||
subject: payload.subject,
|
||||
from,
|
||||
});
|
||||
|
||||
|
||||
const transporter = getTransporter();
|
||||
return transporter.sendMail({
|
||||
try {
|
||||
const info = await transporter.sendMail({
|
||||
from,
|
||||
to: payload.to,
|
||||
subject: payload.subject,
|
||||
text: payload.text,
|
||||
html: payload.html,
|
||||
headers: {
|
||||
"X-Mailer": "MIS Control Tower",
|
||||
},
|
||||
|
||||
replyTo: from,
|
||||
});
|
||||
|
||||
// Nodemailer response details:
|
||||
logLine("email.send.ok", {
|
||||
to: payload.to,
|
||||
from,
|
||||
messageId: info.messageId,
|
||||
response: info.response,
|
||||
accepted: info.accepted,
|
||||
rejected: info.rejected,
|
||||
pending: (info as any).pending,
|
||||
});
|
||||
|
||||
return info;
|
||||
} catch (err: any) {
|
||||
logLine("email.send.err", {
|
||||
to: payload.to,
|
||||
from,
|
||||
name: err?.name,
|
||||
message: err?.message,
|
||||
code: err?.code,
|
||||
command: err?.command,
|
||||
response: err?.response,
|
||||
responseCode: err?.responseCode,
|
||||
stack: err?.stack,
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function buildVerifyEmail(params: { appName: string; verifyUrl: string }) {
|
||||
|
||||
20
lib/logger.ts
Normal file
20
lib/logger.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
const LOG_PATH = process.env.LOG_FILE || "/tmp/mis-control-tower.log";
|
||||
|
||||
export function logLine(event: string, data: Record<string, any> = {}) {
|
||||
const line = JSON.stringify({
|
||||
ts: new Date().toISOString(),
|
||||
event,
|
||||
...data,
|
||||
});
|
||||
console.log(line);
|
||||
try {
|
||||
fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true });
|
||||
fs.appendFileSync(LOG_PATH, line + "\n", { encoding: "utf8" });
|
||||
} catch {
|
||||
// If file logging fails, we still want something:
|
||||
console.error("[logLine-failed]", line);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user