Automatische Tests und Passwort Vergessen
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import Layout from "#layouts/Layout.astro";
|
||||
import { berechnungNutzenergiebedarfHeizen } from "#lib/Berechnungen/BedarfsausweisWohnen/BerechnungNutzenergiebedarfHeizen.js"
|
||||
import A12NutzenergiebedarfHeizung from "#components/Tabellen/A12NutzenergiebedarfHeizung.svelte";
|
||||
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||
import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types";
|
||||
import A1AnlagenBeschreibung from "#components/Tabellen/A1AnlagenBeschreibung.svelte";
|
||||
import A1AllgemeineAnlagenbeschreibung from "#components/Tabellen/A1AllgemeineAnlagenbeschreibung.svelte";
|
||||
import A2WaermequellenSolareEinstrahlungWintergarten from "#components/Tabellen/A2WaermequellenSolareEinstrahlungWintergarten.svelte";
|
||||
@@ -20,7 +20,7 @@ import A14AufwandszahlenMittlereBelastung from "#components/Tabellen/A14Aufwands
|
||||
import A15AufwandszahlenGesamtErzeugernutzWaerme from "#components/Tabellen/A15AufwandszahlenGesamtErzeugernutzWaerme.svelte";
|
||||
|
||||
const ausweis: BedarfsausweisWohnenClient = {};
|
||||
const gebaeude_aufnahme: GebaeudeAufnahmeClient = { flaeche: 152 }
|
||||
const gebaeude_aufnahme: AufnahmeClient = { flaeche: 152 }
|
||||
|
||||
---
|
||||
|
||||
|
||||
137
src/pages/api/auth/forgot-password.ts
Normal file
137
src/pages/api/auth/forgot-password.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
import * as nodemailer from "nodemailer"
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { decodeToken, encodeToken } from "#lib/auth/token.js";
|
||||
import { TokenType } from "#lib/auth/types.js";
|
||||
import { hashPassword } from "#lib/password.js";
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
input: z.object({
|
||||
email: z.string().email()
|
||||
}),
|
||||
output: z.void(),
|
||||
async fetch(input, context, transfer) {
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
email: input.email
|
||||
}
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
// Wir senden einen INTERNAL_SERVER_ERROR zurück, damit man nicht aus dem Fehler schließen kann, ob es den Nutzer gibt.
|
||||
throw new APIError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
|
||||
})
|
||||
}
|
||||
|
||||
// Wir generieren einen Token der für 30 Minuten gültig ist, damit der Nutzer das Passwort zurücksetzen kann.
|
||||
const resetToken = encodeToken({
|
||||
exp: Date.now() + 15 * 60 * 1000,
|
||||
typ: TokenType.Reset,
|
||||
uid: user.uid
|
||||
})
|
||||
|
||||
const transport = nodemailer.createTransport({
|
||||
host: "smtp.ionos.de",
|
||||
port: 465,
|
||||
secure: true,
|
||||
auth: {
|
||||
user: "info@online-energieausweis.org",
|
||||
pass: "Katendeich5a2024!"
|
||||
}
|
||||
})
|
||||
|
||||
const info = await transport.sendMail({
|
||||
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
||||
to: input.email,
|
||||
subject: "Zurücksetzen ihres Passworts",
|
||||
text: `Hallo ${user.vorname},
|
||||
|
||||
sie haben eine Anfrage zum Zurücksetzen ihres Passworts gestellt. Klicken sie auf den folgenden Link, um ein neues Passwort festzulegen:
|
||||
|
||||
https://ibcornelsen.de/auth/passwort-zuruecksetzen?t=${resetToken}
|
||||
|
||||
Dieser Link ist für die nächsten 15 Minuten gültig. Falls du diese Anfrage nicht gestellt hast, kannst du diese E-Mail ignorieren - dein Passwort bleibt unverändert.
|
||||
|
||||
Falls du Hilfe benötigst, kontaktiere uns unter info@online-energieausweis.org.
|
||||
|
||||
Viele Grüße,
|
||||
IBCornelsen`
|
||||
})
|
||||
|
||||
if (info.rejected) {
|
||||
throw new APIError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const POST = defineApiRoute({
|
||||
input: z.object({
|
||||
token: z.string(),
|
||||
passwort: z.string()
|
||||
}),
|
||||
output: z.void(),
|
||||
async fetch(input, context, transfer) {
|
||||
const decoded = decodeToken(input.token);
|
||||
|
||||
if (!decoded.exp || decoded.exp < Date.now() || decoded.typ !== TokenType.Reset || !decoded.uid) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Der von ihnen benutzte Token ist nicht mehr gültig."
|
||||
})
|
||||
}
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
uid: decoded.uid
|
||||
}
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Kein Benutzer passt zu dem genutzten Token."
|
||||
})
|
||||
}
|
||||
|
||||
const hashed = hashPassword(input.passwort)
|
||||
|
||||
await prisma.benutzer.update({
|
||||
where: {
|
||||
uid: decoded.uid
|
||||
},
|
||||
data: {
|
||||
passwort: hashed
|
||||
}
|
||||
})
|
||||
|
||||
const transport = nodemailer.createTransport({
|
||||
host: "smtp.ionos.de",
|
||||
port: 465,
|
||||
secure: true,
|
||||
auth: {
|
||||
user: "info@online-energieausweis.org",
|
||||
pass: "Katendeich5a2024!"
|
||||
}
|
||||
})
|
||||
|
||||
const info = await transport.sendMail({
|
||||
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
||||
to: user.email,
|
||||
subject: "Ihr Passwort wurde erfolgreich zurückgesetzt",
|
||||
text: `Hallo ${user.vorname},
|
||||
|
||||
Ihr Passwort wurde erfolgreich zurückgesetzt. Sie können sich jetzt mit Ihrem neuen Passwort anmelden.
|
||||
|
||||
Falls Sie diese Änderung nicht selbst vorgenommen haben, setzen Sie Ihr Passwort bitte sofort erneut zurück und kontaktieren Sie unseren Support unter info@online-energieausweis.org.
|
||||
|
||||
Viele Grüße,
|
||||
IBCornelsen`
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -2,6 +2,8 @@
|
||||
import PasswortZuruecksetzenModule from "../../modules/Auth/PasswortZuruecksetzenModule.svelte";
|
||||
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
|
||||
import MinimalLayout from "#layouts/MinimalLayout.astro";
|
||||
import { decodeToken } from "#lib/auth/token";
|
||||
import { TokenType } from "#lib/auth/types";
|
||||
|
||||
const valid = await validateAccessTokenServer(Astro)
|
||||
|
||||
@@ -9,10 +11,19 @@ if (valid) {
|
||||
return Astro.redirect("/dashboard")
|
||||
}
|
||||
|
||||
const token = Astro.url.searchParams.get("token")
|
||||
const token = Astro.url.searchParams.get("t")
|
||||
|
||||
if (!token) {
|
||||
return Astro.redirect("/login")
|
||||
return Astro.redirect("/")
|
||||
}
|
||||
|
||||
const decoded = decodeToken(token)
|
||||
|
||||
console.log(decoded.exp, Date.now());
|
||||
|
||||
|
||||
if (!decoded.exp || decoded.exp < Date.now() || decoded.typ !== TokenType.Reset) {
|
||||
return Astro.redirect("/")
|
||||
}
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user