KI-AGENT: Password-Reset gegen hängenden Mailversand absichern
This commit is contained in:
@@ -6,7 +6,7 @@ import { sendMail } from "../../utils/mailer";
|
||||
import { authUsers } from "../../../db/schema";
|
||||
import { authTenantUsers } from "../../../db/schema";
|
||||
import { tenants } from "../../../db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import {
|
||||
createAccessToken,
|
||||
issueRefreshToken,
|
||||
@@ -211,6 +211,8 @@ export default async function authRoutes(server: FastifyInstance) {
|
||||
.select({
|
||||
id: authUsers.id,
|
||||
email: authUsers.email,
|
||||
passwordHash: authUsers.passwordHash,
|
||||
mustChangePassword: authUsers.must_change_password,
|
||||
})
|
||||
.from(authUsers)
|
||||
.where(eq(authUsers.email, email.toLowerCase()))
|
||||
@@ -228,12 +230,11 @@ export default async function authRoutes(server: FastifyInstance) {
|
||||
.update(authUsers)
|
||||
.set({
|
||||
passwordHash,
|
||||
// @ts-ignore
|
||||
mustChangePassword: true,
|
||||
must_change_password: true,
|
||||
})
|
||||
.where(eq(authUsers.id, user.id));
|
||||
|
||||
await sendMail(
|
||||
const mailResult = await sendMail(
|
||||
user.email,
|
||||
"FEDEO | Dein neues Passwort",
|
||||
`
|
||||
@@ -241,9 +242,26 @@ export default async function authRoutes(server: FastifyInstance) {
|
||||
<p>Dein Passwort wurde zurückgesetzt.</p>
|
||||
<p><strong>Neues Passwort:</strong> ${plainPassword}</p>
|
||||
<p>Bitte ändere es nach dem Login umgehend.</p>
|
||||
`
|
||||
`
|
||||
);
|
||||
|
||||
if (!mailResult.success) {
|
||||
// Ein fehlgeschlagener Mailversand darf das bisherige Passwort nicht
|
||||
// unbrauchbar machen. Die Hash-Bedingung schützt parallele Resets.
|
||||
await server.db
|
||||
.update(authUsers)
|
||||
.set({
|
||||
passwordHash: user.passwordHash,
|
||||
must_change_password: user.mustChangePassword,
|
||||
})
|
||||
.where(and(
|
||||
eq(authUsers.id, user.id),
|
||||
eq(authUsers.passwordHash, passwordHash),
|
||||
));
|
||||
|
||||
return reply.code(502).send({ error: "Password reset email could not be sent" });
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@ export const initMailer = async () => {
|
||||
host: secrets.MAILER_SMTP_HOST,
|
||||
port: Number(secrets.MAILER_SMTP_PORT) || 587,
|
||||
secure: secrets.MAILER_SMTP_SSL === "true", // true für 465, false für andere Ports
|
||||
// Ohne explizite Timeouts kann ein API-Request bei einem nicht erreichbaren
|
||||
// SMTP-Server mehrere Minuten offen bleiben.
|
||||
connectionTimeout: 10_000,
|
||||
greetingTimeout: 10_000,
|
||||
socketTimeout: 20_000,
|
||||
auth: {
|
||||
user: secrets.MAILER_SMTP_USER,
|
||||
pass: secrets.MAILER_SMTP_PASS,
|
||||
@@ -34,4 +39,4 @@ export async function sendMail(
|
||||
console.error("❌ Fehler beim Mailversand:", err)
|
||||
return { success: false, error: err }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user