Speichern
This commit is contained in:
@@ -206,6 +206,7 @@ Table benutzer {
|
|||||||
rolle BenutzerRolle [not null, default: 'USER']
|
rolle BenutzerRolle [not null, default: 'USER']
|
||||||
firma String
|
firma String
|
||||||
lex_office_id String
|
lex_office_id String
|
||||||
|
verified Boolean [not null, default: false]
|
||||||
BedarfsausweisWohnen BedarfsausweisWohnen [not null]
|
BedarfsausweisWohnen BedarfsausweisWohnen [not null]
|
||||||
documenttemplates documenttemplates [not null]
|
documenttemplates documenttemplates [not null]
|
||||||
objekte Objekt [not null]
|
objekte Objekt [not null]
|
||||||
|
|||||||
48
prisma/migrations/20250307174552_user_verified/migration.sql
Normal file
48
prisma/migrations/20250307174552_user_verified/migration.sql
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Anteilshaber" ALTER COLUMN "uid" SET DEFAULT 'ant-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Aufnahme" ALTER COLUMN "uid" SET DEFAULT 'auf-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "BedarfsausweisGewerbe" ALTER COLUMN "uid" SET DEFAULT 'bag-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "BedarfsausweisWohnen" ALTER COLUMN "uid" SET DEFAULT 'baw-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Bild" ALTER COLUMN "uid" SET DEFAULT 'img-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Event" ALTER COLUMN "uid" SET DEFAULT 'evt-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "GEGEinpreisung" ALTER COLUMN "uid" SET DEFAULT 'gge-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "GEGNachweisGewerbe" ALTER COLUMN "uid" SET DEFAULT 'gnw-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "GEGNachweisWohnen" ALTER COLUMN "uid" SET DEFAULT 'gnw-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Objekt" ALTER COLUMN "uid" SET DEFAULT 'obj-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Rechnung" ALTER COLUMN "uid" SET DEFAULT 'inv-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Tickets" ALTER COLUMN "uid" SET DEFAULT 'tkt-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Unterlage" ALTER COLUMN "uid" SET DEFAULT 'pln-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "VerbrauchsausweisGewerbe" ALTER COLUMN "uid" SET DEFAULT 'vag-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "VerbrauchsausweisWohnen" ALTER COLUMN "uid" SET DEFAULT 'vaw-' || gen_random_uuid();
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "benutzer" ADD COLUMN "verified" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
ALTER COLUMN "uid" SET DEFAULT 'usr-' || gen_random_uuid();
|
||||||
@@ -21,6 +21,8 @@ model Benutzer {
|
|||||||
firma String?
|
firma String?
|
||||||
lex_office_id String?
|
lex_office_id String?
|
||||||
|
|
||||||
|
verified Boolean @default(false)
|
||||||
|
|
||||||
Anteilshaber Anteilshaber[] @ignore
|
Anteilshaber Anteilshaber[] @ignore
|
||||||
BedarfsausweisWohnen BedarfsausweisWohnen[]
|
BedarfsausweisWohnen BedarfsausweisWohnen[]
|
||||||
documenttemplates documenttemplates[]
|
documenttemplates documenttemplates[]
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ export const createCaller = createCallerFactory({
|
|||||||
"admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"),
|
"admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"),
|
||||||
"admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"),
|
"admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"),
|
||||||
"admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"),
|
"admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"),
|
||||||
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
|
|
||||||
"ausweise": await import("../src/pages/api/ausweise/index.ts"),
|
"ausweise": await import("../src/pages/api/ausweise/index.ts"),
|
||||||
|
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
|
||||||
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
|
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
|
||||||
"auth/forgot-password": await import("../src/pages/api/auth/forgot-password.ts"),
|
"auth/forgot-password": await import("../src/pages/api/auth/forgot-password.ts"),
|
||||||
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
|
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
|
||||||
|
|||||||
@@ -15,7 +15,11 @@ export async function ausweisSpeichern(
|
|||||||
) {
|
) {
|
||||||
if (objekt.uid) {
|
if (objekt.uid) {
|
||||||
await api.objekt._uid.PATCH.fetch({
|
await api.objekt._uid.PATCH.fetch({
|
||||||
...exclude(objekt, ["uid"])
|
adresse: objekt.adresse,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
ort: objekt.ort,
|
||||||
|
plz: objekt.plz
|
||||||
}, {
|
}, {
|
||||||
params: {
|
params: {
|
||||||
uid: objekt.uid
|
uid: objekt.uid
|
||||||
@@ -26,7 +30,11 @@ export async function ausweisSpeichern(
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const { uid } = await api.objekt.PUT.fetch({
|
const { uid } = await api.objekt.PUT.fetch({
|
||||||
...exclude(objekt, ["uid"])
|
adresse: objekt.adresse,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
ort: objekt.ort,
|
||||||
|
plz: objekt.plz
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
@@ -50,8 +58,64 @@ export async function ausweisSpeichern(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
console.log(aufnahme);
|
||||||
|
|
||||||
const { uid } = await api.aufnahme.PUT.fetch({
|
const { uid } = await api.aufnahme.PUT.fetch({
|
||||||
aufnahme,
|
aufnahme: {
|
||||||
|
baujahr_gebaeude: aufnahme.baujahr_gebaeude,
|
||||||
|
baujahr_heizung: aufnahme.baujahr_heizung,
|
||||||
|
alternative_heizung: aufnahme.alternative_heizung,
|
||||||
|
alternative_kuehlung: aufnahme.alternative_kuehlung,
|
||||||
|
alternative_lueftung: aufnahme.alternative_lueftung,
|
||||||
|
alternative_warmwasser: aufnahme.alternative_warmwasser,
|
||||||
|
aussenwand_gedaemmt: aufnahme.aussenwand_gedaemmt,
|
||||||
|
aussenwand_min_12cm_gedaemmt: aufnahme.aussenwand_min_12cm_gedaemmt,
|
||||||
|
ausweisart: aufnahme.ausweisart,
|
||||||
|
baujahr_klima: aufnahme.baujahr_klima,
|
||||||
|
brennstoff_1: aufnahme.brennstoff_1,
|
||||||
|
brennstoff_2: aufnahme.brennstoff_2,
|
||||||
|
brennwert_kessel: aufnahme.brennwert_kessel,
|
||||||
|
dachgeschoss: aufnahme.dachgeschoss,
|
||||||
|
dachgeschoss_gedaemmt: aufnahme.dachgeschoss_gedaemmt,
|
||||||
|
dachgeschoss_min_12cm_gedaemmt: aufnahme.dachgeschoss_min_12cm_gedaemmt,
|
||||||
|
doppel_verglasung: aufnahme.doppel_verglasung,
|
||||||
|
dreifach_verglasung: aufnahme.dreifach_verglasung,
|
||||||
|
durchlauf_erhitzer: aufnahme.durchlauf_erhitzer,
|
||||||
|
einfach_verglasung: aufnahme.einfach_verglasung,
|
||||||
|
einheiten: aufnahme.einheiten,
|
||||||
|
einzelofen: aufnahme.einzelofen,
|
||||||
|
energieeffizienzklasse: aufnahme.energieeffizienzklasse,
|
||||||
|
erstellungsdatum: aufnahme.erstellungsdatum,
|
||||||
|
fenster_dicht: aufnahme.fenster_dicht,
|
||||||
|
fenster_teilweise_undicht: aufnahme.fenster_teilweise_undicht,
|
||||||
|
flaeche: aufnahme.flaeche,
|
||||||
|
gebaeudeteil: aufnahme.gebaeudeteil,
|
||||||
|
gebaeudetyp: aufnahme.gebaeudetyp,
|
||||||
|
heizungsrohre_gedaemmt: aufnahme.heizungsrohre_gedaemmt,
|
||||||
|
isolier_verglasung: aufnahme.isolier_verglasung,
|
||||||
|
keller: aufnahme.keller,
|
||||||
|
keller_decke_gedaemmt: aufnahme.keller_decke_gedaemmt,
|
||||||
|
keller_wand_gedaemmt: aufnahme.keller_wand_gedaemmt,
|
||||||
|
kuehlung: aufnahme.kuehlung,
|
||||||
|
leerstand: aufnahme.leerstand,
|
||||||
|
lueftung: aufnahme.lueftung,
|
||||||
|
niedertemperatur_kessel: aufnahme.niedertemperatur_kessel,
|
||||||
|
nutzflaeche: aufnahme.nutzflaeche,
|
||||||
|
oberste_geschossdecke_gedaemmt: aufnahme.oberste_geschossdecke_gedaemmt,
|
||||||
|
oberste_geschossdecke_min_12cm_gedaemmt: aufnahme.oberste_geschossdecke_min_12cm_gedaemmt,
|
||||||
|
photovoltaik: aufnahme.photovoltaik,
|
||||||
|
raum_temperatur_regler: aufnahme.raum_temperatur_regler,
|
||||||
|
rolllaeden_kaesten_gedaemmt: aufnahme.rolllaeden_kaesten_gedaemmt,
|
||||||
|
saniert: aufnahme.saniert,
|
||||||
|
solarsystem_warmwasser: aufnahme.solarsystem_warmwasser,
|
||||||
|
standard_kessel: aufnahme.standard_kessel,
|
||||||
|
tueren_dicht: aufnahme.tueren_dicht,
|
||||||
|
tueren_undicht: aufnahme.tueren_undicht,
|
||||||
|
waermepumpe: aufnahme.waermepumpe,
|
||||||
|
warmwasser_rohre_gedaemmt: aufnahme.warmwasser_rohre_gedaemmt,
|
||||||
|
zentralheizung: aufnahme.zentralheizung,
|
||||||
|
zirkulation: aufnahme.zirkulation
|
||||||
|
},
|
||||||
uid_objekt: objekt.uid
|
uid_objekt: objekt.uid
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
import HelpLabel from "#components/labels/HelpLabel.svelte";
|
import HelpLabel from "#components/labels/HelpLabel.svelte";
|
||||||
import Inputlabel from "#components/labels/InputLabel.svelte";
|
import Inputlabel from "#components/labels/InputLabel.svelte";
|
||||||
|
|
||||||
//import Label from "#components/Label.svelte";
|
|
||||||
|
|
||||||
import { auditHeizungGebaeudeBaujahr } from "../Verbrauchsausweis/audits/HeizungGebaeudeBaujahr.js";
|
import { auditHeizungGebaeudeBaujahr } from "../Verbrauchsausweis/audits/HeizungGebaeudeBaujahr.js";
|
||||||
import { addNotification, deleteNotification } from "#components/Notifications/shared.js";
|
import { addNotification, deleteNotification } from "#components/Notifications/shared.js";
|
||||||
import TagInput from "../TagInput.svelte";
|
import TagInput from "../TagInput.svelte";
|
||||||
@@ -48,7 +46,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
required
|
required
|
||||||
data-cy="ausstellgrund"
|
data-cy="ausstellgrund"
|
||||||
>
|
>
|
||||||
<option disabled selected value>Bitte auswählen</option>
|
<option disabled selected value={null}>Bitte auswählen</option>
|
||||||
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
|
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
|
||||||
<option value={ausstellgrund}>{name}</option>
|
<option value={ausstellgrund}>{name}</option>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -224,7 +222,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
required
|
required
|
||||||
bind:value={aufnahme.saniert}
|
bind:value={aufnahme.saniert}
|
||||||
>
|
>
|
||||||
<option disabled selected value>Bitte auswählen</option>
|
<option disabled selected value={null}>Bitte auswählen</option>
|
||||||
<option value={true}>saniert</option>
|
<option value={true}>saniert</option>
|
||||||
<option value={false}>unsaniert</option>
|
<option value={false}>unsaniert</option>
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
async function spaeterWeitermachen() {
|
async function spaeterWeitermachen() {
|
||||||
loginAction = spaeterWeitermachen;
|
loginAction = spaeterWeitermachen;
|
||||||
if (!await validateAccessTokenClient()) {
|
if (!(await validateAccessTokenClient())) {
|
||||||
loginOverlayHidden = false;
|
loginOverlayHidden = false;
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -120,18 +120,16 @@ sm:grid-cols-[1fr_min-content_min-content_min-content] sm:justify-self-end">
|
|||||||
|
|
||||||
|
|
||||||
{#if showWeiter}
|
{#if showWeiter}
|
||||||
<div>
|
|
||||||
<Overlay bind:hidden={loginOverlayHidden}>
|
|
||||||
<div class="bg-white w-full max-w-screen-sm py-8">
|
|
||||||
<EmbeddedAuthFlowModule onLogin={loginAction} email={""}></EmbeddedAuthFlowModule>
|
|
||||||
</div>
|
|
||||||
</Overlay>
|
|
||||||
|
|
||||||
<button on:click={ausweisAbschicken} type="button" class="button" data-cy="weiter">Weiter</button>
|
<button on:click={ausweisAbschicken} type="button" class="button" data-cy="weiter">Weiter</button>
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Overlay bind:hidden={loginOverlayHidden}>
|
||||||
|
<div class="bg-white w-full max-w-screen-sm py-8">
|
||||||
|
<EmbeddedAuthFlowModule onLogin={loginAction} email={""}></EmbeddedAuthFlowModule>
|
||||||
|
</div>
|
||||||
|
</Overlay>
|
||||||
|
|
||||||
{#if showHelp}
|
{#if showHelp}
|
||||||
<div class="w-full col-start-1 row-start-2 sm:row-start-2 col-span-4 mt-4">
|
<div class="w-full col-start-1 row-start-2 sm:row-start-2 col-span-4 mt-4">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
bind:value={aufnahme.dachgeschoss}
|
bind:value={aufnahme.dachgeschoss}
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option disabled selected value>Bitte auswählen</option>
|
<option disabled selected value={null}>Bitte auswählen</option>
|
||||||
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
||||||
>nicht vorhanden</option
|
>nicht vorhanden</option
|
||||||
>
|
>
|
||||||
@@ -150,7 +150,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
required
|
required
|
||||||
bind:value={aufnahme.keller}
|
bind:value={aufnahme.keller}
|
||||||
>
|
>
|
||||||
<option disabled selected value>Bitte auswählen</option>
|
<option disabled selected value={null}>Bitte auswählen</option>
|
||||||
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
||||||
>nicht vorhanden</option
|
>nicht vorhanden</option
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
required
|
required
|
||||||
bind:value={aufnahme.lueftung}
|
bind:value={aufnahme.lueftung}
|
||||||
>
|
>
|
||||||
<option disabled selected value>Bitte auswählen</option>
|
<option disabled selected value={null}>Bitte auswählen</option>
|
||||||
<option value="Fensterlueftung">Fensterlüftung</option>
|
<option value="Fensterlueftung">Fensterlüftung</option>
|
||||||
<option value="Schachtlueftung">Schachtlüftung</option>
|
<option value="Schachtlueftung">Schachtlüftung</option>
|
||||||
<option value="LueftungsanlageOhneWaermerueckgewinnung"
|
<option value="LueftungsanlageOhneWaermerueckgewinnung"
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ export const BenutzerSchema = z.object({
|
|||||||
rolle: z.nativeEnum(BenutzerRolle),
|
rolle: z.nativeEnum(BenutzerRolle),
|
||||||
firma: z.string().nullish(),
|
firma: z.string().nullish(),
|
||||||
lex_office_id: z.string().nullish(),
|
lex_office_id: z.string().nullish(),
|
||||||
|
verified: z.boolean(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
export enum TokenType {
|
export enum TokenType {
|
||||||
Refresh,
|
Refresh,
|
||||||
Access,
|
Access,
|
||||||
Reset
|
Reset,
|
||||||
|
Verify
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TokenData = { uid: string, typ: TokenType, exp: number }
|
export type TokenData = { uid: string, typ: TokenType, exp: number }
|
||||||
37
src/lib/server/mail/registrierung.ts
Normal file
37
src/lib/server/mail/registrierung.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { BASE_URI } from "#lib/constants.js";
|
||||||
|
import { transport } from "#lib/mail.js";
|
||||||
|
import {
|
||||||
|
Benutzer,
|
||||||
|
} from "#lib/client/prisma.js";
|
||||||
|
import { encodeToken } from "#lib/auth/token.js";
|
||||||
|
import { TokenType } from "#lib/auth/types.js";
|
||||||
|
|
||||||
|
export async function sendRegisterMail(
|
||||||
|
user: Benutzer
|
||||||
|
) {
|
||||||
|
const verificationJwt = encodeToken({
|
||||||
|
typ: TokenType.Verify,
|
||||||
|
exp: Date.now() + (15 * 60 * 1000),
|
||||||
|
uid: user.uid
|
||||||
|
})
|
||||||
|
|
||||||
|
await transport.sendMail({
|
||||||
|
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
||||||
|
to: user.email,
|
||||||
|
subject: `Ihre Registrierung bei IBCornelsen`,
|
||||||
|
bcc: "info@online-energieausweis.org",
|
||||||
|
text: `Hallo ${user.vorname},
|
||||||
|
|
||||||
|
vielen Dank für Ihre Registrierung bei IBCornelsen! Ihr Benutzerkonto wurde erfolgreich erstellt.
|
||||||
|
|
||||||
|
Um Ihre Registrierung abzuschließen, klicken Sie bitte auf den folgenden Link, um Ihre E-Mail-Adresse zu bestätigen:
|
||||||
|
https://${BASE_URI}/auth/verify?t=${verificationJwt}
|
||||||
|
|
||||||
|
Falls Sie diese Registrierung nicht durchgeführt haben, ignorieren Sie bitte diese E-Mail. Bei Fragen oder Problemen steht Ihnen unser Support-Team jederzeit zur Verfügung.
|
||||||
|
|
||||||
|
Wir freuen uns, Sie beim IBC willkommen zu heißen!
|
||||||
|
|
||||||
|
Mit freundlichen Grüßen
|
||||||
|
Ihr IBCornelsen-Team`
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { UUidWithPrefix } from "#components/Ausweis/types.js"
|
import { UUidWithPrefix } from "#components/Ausweis/types.js"
|
||||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js"
|
import { authorizationMiddleware } from "#lib/middleware/authorization.js"
|
||||||
import { AufnahmeSchema, ObjektSchema, prisma } from "#lib/server/prisma"
|
import { AufnahmeSchema, ObjektSchema, prisma } from "#lib/server/prisma.js"
|
||||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server"
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server"
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ export const PUT = defineApiRoute({
|
|||||||
input: ObjektSchema.omit({
|
input: ObjektSchema.omit({
|
||||||
id: true,
|
id: true,
|
||||||
uid: true,
|
uid: true,
|
||||||
benutzer_id: true
|
benutzer_id: true,
|
||||||
|
erstellungsdatum: true
|
||||||
}),
|
}),
|
||||||
output: z.object({
|
output: z.object({
|
||||||
uid: UUidWithPrefix
|
uid: UUidWithPrefix
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { UUidWithPrefix } from "#components/Ausweis/types.js";
|
import { UUidWithPrefix } from "#components/Ausweis/types.js";
|
||||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||||
import { hashPassword } from "#lib/password.js";
|
import { hashPassword } from "#lib/password.js";
|
||||||
|
import { sendRegisterMail } from "#lib/server/mail/registrierung.js";
|
||||||
import { BenutzerSchema, prisma } from "#lib/server/prisma.js";
|
import { BenutzerSchema, prisma } from "#lib/server/prisma.js";
|
||||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -50,20 +51,20 @@ export const PUT = defineApiRoute({
|
|||||||
uid: UUidWithPrefix
|
uid: UUidWithPrefix
|
||||||
}),
|
}),
|
||||||
async fetch(input) {
|
async fetch(input) {
|
||||||
const user = await prisma.benutzer.findUnique({
|
const existingUser = await prisma.benutzer.findUnique({
|
||||||
where: {
|
where: {
|
||||||
email: input.email
|
email: input.email
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (user) {
|
if (existingUser) {
|
||||||
throw new APIError({
|
throw new APIError({
|
||||||
code: "CONFLICT",
|
code: "CONFLICT",
|
||||||
message: "Email Adresse ist bereits vergeben."
|
message: "Email Adresse ist bereits vergeben."
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { uid } = await prisma.benutzer.create({
|
const user = await prisma.benutzer.create({
|
||||||
data: {
|
data: {
|
||||||
email: input.email,
|
email: input.email,
|
||||||
passwort: hashPassword(input.passwort),
|
passwort: hashPassword(input.passwort),
|
||||||
@@ -72,6 +73,8 @@ export const PUT = defineApiRoute({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return { uid }
|
await sendRegisterMail(user)
|
||||||
|
|
||||||
|
return { uid: user.uid }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
32
src/pages/auth/verify.astro
Normal file
32
src/pages/auth/verify.astro
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
import Layout from "#layouts/Layout.astro";
|
||||||
|
import { decodeToken } from "#lib/auth/token";
|
||||||
|
import { TokenType } from "#lib/auth/types";
|
||||||
|
import { prisma } from "#lib/server/prisma";
|
||||||
|
|
||||||
|
const token = Astro.url.searchParams.get("t");
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return Astro.redirect("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = decodeToken(token)
|
||||||
|
|
||||||
|
if (payload.typ !== TokenType.Verify || !payload.uid || !payload.exp || payload.exp < Date.now()) {
|
||||||
|
return Astro.redirect("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.benutzer.update({
|
||||||
|
where: {
|
||||||
|
uid: payload.uid
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
verified: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Bestätigung">
|
||||||
|
<h1>Vielen Dank</h1>
|
||||||
|
<p>Ihre Email Adresse wurde bestätigt, sie können diese Seite nun schließen.</p>
|
||||||
|
</Layout>
|
||||||
@@ -338,6 +338,7 @@ export function fakeBenutzerComplete() {
|
|||||||
rolle: BenutzerRolle.USER,
|
rolle: BenutzerRolle.USER,
|
||||||
firma: undefined,
|
firma: undefined,
|
||||||
lex_office_id: undefined,
|
lex_office_id: undefined,
|
||||||
|
verified: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export function fakeBild() {
|
export function fakeBild() {
|
||||||
|
|||||||
Reference in New Issue
Block a user