API Verbessert - Verbrauchsausweis Funktioniert
This commit is contained in:
@@ -51,7 +51,7 @@
|
|||||||
"trpc-openapi": "^1.2.0",
|
"trpc-openapi": "^1.2.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"vite-tsconfig-paths": "^4.2.0",
|
"vite-tsconfig-paths": "^4.2.0",
|
||||||
"zod": "^3.21.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="energietraeger_einheit_heizquelle_1"
|
name="einheit_1"
|
||||||
required
|
required
|
||||||
bind:value={ausweis.einheit_1}
|
bind:value={ausweis.einheit_1}
|
||||||
>
|
>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<Label>Einheit *</Label>
|
<Label>Einheit *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="energietraeger_einheit_heizquelle_2"
|
name="einheit_2"
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
disabled={!ausweis.zusaetzliche_heizquelle}
|
||||||
bind:value={ausweis.einheit_2}
|
bind:value={ausweis.einheit_2}
|
||||||
required
|
required
|
||||||
|
|||||||
@@ -1,297 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import HorizontalDots from "#components/Icons/HorizontalDots.svelte";
|
|
||||||
import type { Verbrauchsausweis } from "#lib/Ausweis/Verbrauchsausweis";
|
|
||||||
import moment from "moment";
|
|
||||||
import Cross from "#components/Icons/Cross.svelte";
|
|
||||||
import { Dachgeschoss } from "#lib/Ausweis/types";
|
|
||||||
|
|
||||||
interface Service {
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export let ausweis: Verbrauchsausweis;
|
|
||||||
export let services: Service[];
|
|
||||||
export let hidden: boolean;
|
|
||||||
|
|
||||||
export let i: number;
|
|
||||||
|
|
||||||
let left: string = "";
|
|
||||||
$: {
|
|
||||||
if (i == 0 || i % 3 == 0) {
|
|
||||||
left = "0";
|
|
||||||
} else if (i % 2 == 0) {
|
|
||||||
left = "-50%";
|
|
||||||
} else {
|
|
||||||
left = "-100%";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: energieverbrauchDaten = [
|
|
||||||
moment(ausweis.energieverbrauch_zeitraum),
|
|
||||||
moment(ausweis.energieverbrauch_zeitraum).add("1", "year"),
|
|
||||||
moment(ausweis.energieverbrauch_zeitraum).add("2", "years"),
|
|
||||||
moment(ausweis.energieverbrauch_zeitraum).add("3", "years"),
|
|
||||||
];
|
|
||||||
|
|
||||||
let showDropdown: boolean = false;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="rounded-lg bg-white shadow-sm border px-4 py-1 relative">
|
|
||||||
<div class="flex flex-row justify-between items-center cursor-pointer">
|
|
||||||
<h3>
|
|
||||||
{ausweis.objekt_strasse}, {ausweis.objekt_plz}
|
|
||||||
{ausweis.objekt_ort}
|
|
||||||
</h3>
|
|
||||||
<button
|
|
||||||
class="cursor-pointer relative hover:bg-gray-100 rounded-lg p-1"
|
|
||||||
on:click={() => {
|
|
||||||
showDropdown = !showDropdown;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<HorizontalDots width={20} height={20} />
|
|
||||||
<div
|
|
||||||
class="absolute right-0 top-full w-[150px] border shadow-md rounded-lg bg-white z-50"
|
|
||||||
hidden={!showDropdown}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="cursor-pointer hover:bg-gray-100 w-full p-1"
|
|
||||||
on:click={() => {
|
|
||||||
hidden = !hidden;
|
|
||||||
}}>Berechnung</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="cursor-pointer hover:bg-gray-100 w-full p-1"
|
|
||||||
on:click={() => {}}>Gebäudeansicht</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="cursor-pointer hover:bg-gray-100 w-full p-1"
|
|
||||||
on:click={() => {}}>Ausweis Ansehen</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<a href="/ausweis/{ausweis.uid}/cad">Gebäudeansicht</a>
|
|
||||||
<div
|
|
||||||
class="absolute top-[calc(100%+16px)] left-0 w-[200%] rounded-lg z-50 bg-white border p-2"
|
|
||||||
style="left: {left};"
|
|
||||||
{hidden}
|
|
||||||
>
|
|
||||||
<div class="flex flex-row justify-between">
|
|
||||||
<h4 class="px-2 py-1 bg-violet-50 rounded-lg">
|
|
||||||
Datenprüfung Verbrauchsausweis - ID {ausweis.id} - {ausweis.objekt_strasse},
|
|
||||||
{ausweis.objekt_plz}
|
|
||||||
{ausweis.objekt_ort}
|
|
||||||
</h4>
|
|
||||||
<Cross
|
|
||||||
on:click={() => (hidden = true)}
|
|
||||||
className="p-1 hover:bg-gray-100 cursor-pointer w-[25px] h-[25px] rounded-lg"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<h5>Abschnitt A,B,C,D und E</h5>
|
|
||||||
<div class="grid grid-cols-4 gap-4">
|
|
||||||
<div class="border rounded-lg p-1">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>AL</td><td>:</td>
|
|
||||||
<td>{ausweis.ausstellgrund}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>BH</td><td>:</td>
|
|
||||||
<td>{ausweis.baujahr_anlage}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>BG</td><td>:</td>
|
|
||||||
<td>{ausweis.baujahr_gebaeude}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>AW</td><td>:</td>
|
|
||||||
<td>{ausweis.anzahl_einheiten}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ST</td><td>:</td>
|
|
||||||
<td>{ausweis.objekt_saniert}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="border rounded-lg p-1">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>WF</td><td>:</td>
|
|
||||||
<td>{ausweis.wohnflaeche}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>F</td><td>:</td>
|
|
||||||
<td>{ausweis.baujahr_anlage}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>AN</td><td>:</td>
|
|
||||||
<td>{ausweis.baujahr_gebaeude}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>KB</td><td>:</td>
|
|
||||||
<td>{ausweis.keller_beheizt}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>DB</td><td>:</td>
|
|
||||||
<td>{ausweis.dachgeschoss == Dachgeschoss.BEHEIZT ? "Ja" : "Nein"}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="border rounded-lg p-1">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>WWE</td><td>:</td>
|
|
||||||
<td>{ausweis.warmwasser_enthalten}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>WWA</td><td>:</td>
|
|
||||||
<td>{ausweis.anteil_warmwasser_1}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>WWAZH</td><td>:</td>
|
|
||||||
<td>{ausweis.anteil_warmwasser_2}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>AEVS</td><td>:</td>
|
|
||||||
<td />
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>SSWW</td><td>:</td>
|
|
||||||
<td>{ausweis.dachgeschoss}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="border rounded-lg p-1">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>GT</td><td>:</td>
|
|
||||||
<td>{ausweis.objekt_gebaeudeteil}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>GTL</td><td>:</td>
|
|
||||||
<td />
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>L</td><td>:</td>
|
|
||||||
<td>{ausweis.lueftungskonzept}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>AK</td><td>:</td>
|
|
||||||
<td />
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>LS</td><td>:</td>
|
|
||||||
<td>{ausweis.leerstand}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="border rounded-lg p-1 gap-2 grid grid-cols-4 justify-between">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>{energieverbrauchDaten[0].format("MMMM YYYY")}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{energieverbrauchDaten[0].format("MM.YYYY")} - {energieverbrauchDaten[1].format(
|
|
||||||
"MM.YYYY"
|
|
||||||
)}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{energieverbrauchDaten[1].format("MM.YYYY")} - {energieverbrauchDaten[2].format(
|
|
||||||
"MM.YYYY"
|
|
||||||
)}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{energieverbrauchDaten[2].format("MM.YYYY")} - {energieverbrauchDaten[3].format(
|
|
||||||
"MM.YYYY"
|
|
||||||
)}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Faktoren Hi / PF / COE</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Primäre Heizquelle (1)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_1_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_1}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_2_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_1}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_3_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_1}
|
|
||||||
{ausweis.energietraeger_1}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>10 / 1.1 / 2.5</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Sekundäre Heizquelle (2)</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_1_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_2}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_2_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_2}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
>{ausweis.energieverbrauch_3_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_einheit_heizquelle_2}
|
|
||||||
{ausweis.energietraeger_2}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>10 / 1.1 / 2.5</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Klimafaktoren</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>1.12</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>1.15</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>1.12</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>-</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -56,17 +56,17 @@ const loggedIn = isLoggedIn(Astro);
|
|||||||
>Energieausweis erstellen</a
|
>Energieausweis erstellen</a
|
||||||
>
|
>
|
||||||
<a class="headerButton" href="/energieausweis-kontakt.php"
|
<a class="headerButton" href="/energieausweis-kontakt.php"
|
||||||
>{t("header.kontakt")}</a
|
>Kontakt</a
|
||||||
>
|
>
|
||||||
<a class="headerButton" href="/agb">AGB</a>
|
<a class="headerButton" href="/agb">AGB</a>
|
||||||
{
|
{
|
||||||
loggedIn ? (
|
loggedIn ? (
|
||||||
<a class="headerButton" href="/user">
|
<a class="headerButton" href="/user">
|
||||||
{t("header.profil")}
|
Profil
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<a class="headerButton" href="/login">
|
<a class="headerButton" href="/login">
|
||||||
{t("header.login")}
|
Login
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
VerbrauchsausweisWohnen,
|
VerbrauchsausweisWohnen,
|
||||||
} from "@ibcornelsen/database";
|
} from "@ibcornelsen/database";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import trpc from "src/trpc";
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
|
export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
|
||||||
ausweis: VerbrauchsausweisWohnen & {
|
ausweis: VerbrauchsausweisWohnen & {
|
||||||
@@ -28,7 +28,7 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const klimafaktoren = await trpc.klimafaktoren.query({
|
const klimafaktoren = await client.v1.klimafaktoren.query({
|
||||||
plz: ausweis.gebaeude_stammdaten.plz,
|
plz: ausweis.gebaeude_stammdaten.plz,
|
||||||
genauigkeit: "years",
|
genauigkeit: "years",
|
||||||
startdatum: ausweis.startdatum,
|
startdatum: ausweis.startdatum,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
import { getKlimafaktoren } from "#lib/getKlimafaktoren";
|
||||||
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
||||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import jwt from "jwt-simple";
|
import jwt from "jwt-simple";
|
||||||
|
|
||||||
export function encodeToken(data: Record<string, any>) {
|
type TokenData = { uid: string, exp: number }
|
||||||
|
|
||||||
|
export function encodeToken(data: TokenData) {
|
||||||
const token = jwt.encode(data, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4", "HS256");
|
const token = jwt.encode(data, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4", "HS256");
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeToken<T>(token: string): Partial<T> {
|
export function decodeToken(token: string): Partial<TokenData> {
|
||||||
return jwt.decode(token, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4");
|
return jwt.decode(token, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4");
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { memoize } from "./Memoization";
|
import { memoize } from "./Memoization";
|
||||||
import trpc from "src/trpc";
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
export const getKlimafaktoren = memoize(async (date: Date, plz: string) => {
|
export const getKlimafaktoren = memoize(async (date: Date, plz: string) => {
|
||||||
if (!plz || !date) {
|
if (!plz || !date) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await trpc.klimafaktoren.query({
|
const response = await client.v1.klimafaktoren.query({
|
||||||
plz,
|
plz,
|
||||||
genauigkeit: "years",
|
genauigkeit: "years",
|
||||||
startdatum: date,
|
startdatum: date,
|
||||||
|
|||||||
@@ -69,33 +69,4 @@ export class User {
|
|||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async create(user: UserType): Promise<{uid: string, id: number} | null> {
|
|
||||||
if (!user || UserRegisterValidator.safeParse(user).success == false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uid = uuid();
|
|
||||||
const hashedPassword = hashPassword(user.passwort);
|
|
||||||
|
|
||||||
const result = await prisma.benutzer.create({
|
|
||||||
data: {
|
|
||||||
email: user.email,
|
|
||||||
passwort: hashedPassword,
|
|
||||||
uid: uid
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
uid,
|
|
||||||
id: result.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
endEnergieVerbrauchVerbrauchsausweis_2016,
|
endEnergieVerbrauchVerbrauchsausweis_2016,
|
||||||
energetischeNutzflaecheVerbrauchsausweisWohnen_2016,
|
energetischeNutzflaecheVerbrauchsausweisWohnen_2016,
|
||||||
} from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
} from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
import { getKlimafaktoren } from "#lib/getKlimafaktoren";
|
||||||
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
||||||
import {
|
import {
|
||||||
GebaeudeStammdaten,
|
GebaeudeStammdaten,
|
||||||
@@ -28,6 +28,11 @@ export async function xmlVerbrauchsausweisWohnen_2016(
|
|||||||
let postleitzahl = gebaeude.plz?.substring(0, 3) + "XX";
|
let postleitzahl = gebaeude.plz?.substring(0, 3) + "XX";
|
||||||
|
|
||||||
const result = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis);
|
const result = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw new Error("Verbrauchsausweis konnte nicht zur Berechnung verarbeitet werden.");
|
||||||
|
}
|
||||||
|
|
||||||
const berechnungen = new AusweisBerechnungen2016(
|
const berechnungen = new AusweisBerechnungen2016(
|
||||||
ausweis,
|
ausweis,
|
||||||
ausweis.gebaeude_stammdaten,
|
ausweis.gebaeude_stammdaten,
|
||||||
@@ -79,12 +84,12 @@ export async function xmlVerbrauchsausweisWohnen_2016(
|
|||||||
: "true";
|
: "true";
|
||||||
|
|
||||||
let heizwertfaktor_1 = getHeizwertfaktor(
|
let heizwertfaktor_1 = getHeizwertfaktor(
|
||||||
ausweis.brennstoff_1,
|
ausweis.brennstoff_1 as string,
|
||||||
ausweis.einheit_1
|
ausweis.einheit_1 as string
|
||||||
);
|
);
|
||||||
let heizwertfaktor_2 = getHeizwertfaktor(
|
let heizwertfaktor_2 = getHeizwertfaktor(
|
||||||
ausweis.brennstoff_2,
|
ausweis.brennstoff_2 as string,
|
||||||
ausweis.einheit_2
|
ausweis.einheit_2 as string
|
||||||
);
|
);
|
||||||
|
|
||||||
let warmWasserErmittlung =
|
let warmWasserErmittlung =
|
||||||
@@ -158,12 +163,12 @@ export async function xmlVerbrauchsausweisWohnen_2016(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let energieTraeger = berechnungen.getEnergietraegerBezeichnung(
|
let energieTraeger = berechnungen.getEnergietraegerBezeichnung(
|
||||||
ausweis.brennstoff_1,
|
ausweis.brennstoff_1 as string,
|
||||||
ausweis.einheit_1
|
ausweis.einheit_1 as string
|
||||||
);
|
);
|
||||||
let energieTraeger_2 = berechnungen.getEnergietraegerBezeichnung(
|
let energieTraeger_2 = berechnungen.getEnergietraegerBezeichnung(
|
||||||
ausweis.brennstoff_2,
|
ausweis.brennstoff_2 as string,
|
||||||
ausweis.einheit_2
|
ausweis.einheit_2 as string
|
||||||
);
|
);
|
||||||
|
|
||||||
let warmwasserZuschlag = Math.round(result.energieVerbrauchWarmwasser_1);
|
let warmwasserZuschlag = Math.round(result.energieVerbrauchWarmwasser_1);
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
export async function getKlimafaktorenServer(date: Date, zip: string, accuracy: "months" | "years" = "months"): Promise<number[] | null> {
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* Dies ist die Server-Side Implementierung von fetch, die Daten werden direkt vom Server abgerufen.
|
|
||||||
* Dadurch können unnötige Requests vermieden werden.
|
|
||||||
* @date 9/20/2023 - 11:33:30 AM
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @async
|
|
||||||
* @param {string} resourceUri
|
|
||||||
* @param {?RequestInit} [options]
|
|
||||||
* @returns {Promise<any>}
|
|
||||||
*/
|
|
||||||
export async function fetch(resourceUri: string, options?: RequestInit): Promise<any> {
|
|
||||||
const response = await fetch(`http://localhost:3000/api/${resourceUri}`, options);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Fehler beim Abrufen der Daten.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
import { TRPCError, initTRPC } from "@trpc/server";
|
import { initTRPC } from "@trpc/server";
|
||||||
import { ZodError } from "zod";
|
import { ZodError } from "zod";
|
||||||
import { OpenApiMeta } from "trpc-openapi";
|
import { OpenApiMeta } from "trpc-openapi";
|
||||||
|
|
||||||
type Context = { uid?: string };
|
type Context = {
|
||||||
|
authorization: string | null;
|
||||||
|
ip: string;
|
||||||
|
req: Request;
|
||||||
|
}
|
||||||
|
|
||||||
export const t = initTRPC.context<Context>().meta<OpenApiMeta>().create({
|
export const t = initTRPC.context<Context>().meta<OpenApiMeta>().create({
|
||||||
|
|
||||||
errorFormatter(opts) {
|
errorFormatter(opts) {
|
||||||
const { shape, error } = opts;
|
const { shape, error } = opts;
|
||||||
return {
|
return {
|
||||||
@@ -19,16 +24,3 @@ export const t = initTRPC.context<Context>().meta<OpenApiMeta>().create({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const publicProcedure = t.procedure
|
|
||||||
|
|
||||||
export const privateProcedure = t.procedure.use((opts) => {
|
|
||||||
if (!opts.ctx.uid) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: 'FORBIDDEN',
|
|
||||||
message: "Diese Ressource benötigt eine UID, welche im 'Authorization' Header gegeben sein muss.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return opts.next();
|
|
||||||
});
|
|
||||||
0
src/lib/trpc/middlewares/adminProcedure.ts
Normal file
0
src/lib/trpc/middlewares/adminProcedure.ts
Normal file
26
src/lib/trpc/middlewares/loggedProcedure.ts
Normal file
26
src/lib/trpc/middlewares/loggedProcedure.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { prisma } from "@ibcornelsen/database";
|
||||||
|
import { privateProcedure } from "./privateProcedure";
|
||||||
|
|
||||||
|
// NOTE: Muss noch mit der Datenbank eingebunden werden.
|
||||||
|
export const loggedProcedure = privateProcedure.use(async (opts) => {
|
||||||
|
const start = Date.now();
|
||||||
|
|
||||||
|
const result = await opts.next();
|
||||||
|
|
||||||
|
const durationMs = Date.now() - start;
|
||||||
|
|
||||||
|
await prisma.apiRequests.create({
|
||||||
|
data: {
|
||||||
|
ip: opts.ctx.ip,
|
||||||
|
method: opts.type,
|
||||||
|
path: opts.path,
|
||||||
|
responseSize: JSON.stringify(result).length,
|
||||||
|
responseTime: durationMs,
|
||||||
|
userAgent: opts.ctx.req.headers["user-agent"] || "",
|
||||||
|
status: result.ok ? 200 : 500,
|
||||||
|
user_id: opts.ctx.user.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
44
src/lib/trpc/middlewares/privateProcedure.ts
Normal file
44
src/lib/trpc/middlewares/privateProcedure.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { publicProcedure } from "./publicProcedure";
|
||||||
|
import { decodeToken } from "#lib/JsonWebToken";
|
||||||
|
import { User } from "#lib/User";
|
||||||
|
|
||||||
|
export const privateProcedure = publicProcedure.use(async (opts) => {
|
||||||
|
const { ctx } = opts;
|
||||||
|
|
||||||
|
if (!ctx.authorization) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Für diese Action ist ein Bearer Token verpflichtend." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const [authorizationType, value] = ctx.authorization.split(" ");
|
||||||
|
|
||||||
|
if (authorizationType != "Bearer") {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Für diese Action ist ein Bearer Token verpflichtend." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const stringToken = Buffer.from(value, "base64").toString();
|
||||||
|
try {
|
||||||
|
const token = decodeToken(
|
||||||
|
stringToken
|
||||||
|
);
|
||||||
|
const uid = token.uid;
|
||||||
|
|
||||||
|
if (!uid) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await User.fromUID(uid);
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts.next({
|
||||||
|
ctx: {
|
||||||
|
user,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||||
|
}
|
||||||
|
});
|
||||||
3
src/lib/trpc/middlewares/publicProcedure.ts
Normal file
3
src/lib/trpc/middlewares/publicProcedure.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { t } from "#lib/trpc/context";
|
||||||
|
|
||||||
|
export const publicProcedure = t.procedure;
|
||||||
0
src/lib/trpc/procedures/v1/benutzer/entfernen.ts
Normal file
0
src/lib/trpc/procedures/v1/benutzer/entfernen.ts
Normal file
64
src/lib/trpc/procedures/v1/benutzer/erstellen.ts
Normal file
64
src/lib/trpc/procedures/v1/benutzer/erstellen.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import moment from "moment";
|
||||||
|
import { prisma } from "@ibcornelsen/database";
|
||||||
|
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||||
|
import { encodeToken } from "#lib/JsonWebToken";
|
||||||
|
import { hashPassword } from "#lib/Password";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
|
export const tRPC_V1_BenutzerErstellenProcedure = publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
passwort: z.string().min(8).max(100),
|
||||||
|
vorname: z.string().min(1).max(100),
|
||||||
|
name: z.string().min(1).max(100),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
z.object({
|
||||||
|
uid: z.string().uuid(),
|
||||||
|
token: z.string(),
|
||||||
|
exp: z.number(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.query(async (opts) => {
|
||||||
|
const hashedPassword = hashPassword(opts.input.passwort);
|
||||||
|
|
||||||
|
// Vielleicht existiert der Benutzer ja schon?
|
||||||
|
const existingUser = await prisma.benutzer.findUnique({
|
||||||
|
where: {
|
||||||
|
email: opts.input.email
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (existingUser) {
|
||||||
|
throw new TRPCError({ code: "CONFLICT", message: "Der Benutzer existiert bereits." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.benutzer.create({
|
||||||
|
data: {
|
||||||
|
email: opts.input.email,
|
||||||
|
passwort: hashedPassword,
|
||||||
|
vorname: opts.input.vorname,
|
||||||
|
name: opts.input.name
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
uid: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Der Benutzer konnte nicht erstellt werden." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const expiry = moment().add(2, "days").unix();
|
||||||
|
const token = encodeToken({ uid: user.uid, exp: expiry })
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: user.uid,
|
||||||
|
token: token,
|
||||||
|
exp: expiry
|
||||||
|
}
|
||||||
|
});
|
||||||
31
src/lib/trpc/procedures/v1/benutzer/fromPrivateId.ts
Normal file
31
src/lib/trpc/procedures/v1/benutzer/fromPrivateId.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import { BenutzerSchema, prisma } from "@ibcornelsen/database";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { loggedProcedure } from "#lib/trpc/middlewares/loggedProcedure";
|
||||||
|
|
||||||
|
export const tRPC_V1_BenutzerFromPrivateIdProcedure = loggedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
id: z.number(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
BenutzerSchema
|
||||||
|
)
|
||||||
|
.query(async (opts) => {
|
||||||
|
if (opts.ctx.user.id !== opts.input.id) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Sie sind nicht dazu authorisiert die Daten dieses Benutzers einzusehen." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.benutzer.findUnique({
|
||||||
|
where: {
|
||||||
|
id: opts.input.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht." });
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
});
|
||||||
31
src/lib/trpc/procedures/v1/benutzer/fromPublicId.ts
Normal file
31
src/lib/trpc/procedures/v1/benutzer/fromPublicId.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import { BenutzerSchema, prisma } from "@ibcornelsen/database";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { loggedProcedure } from "#lib/trpc/middlewares/loggedProcedure";
|
||||||
|
|
||||||
|
export const tRPC_V1_BenutzerFromPublicIdProcedure = loggedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
uid: z.string().uuid(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
BenutzerSchema
|
||||||
|
)
|
||||||
|
.query(async (opts) => {
|
||||||
|
if (opts.ctx.user.uid !== opts.input.uid) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Sie sind nicht dazu authorisiert die Daten dieses Benutzers einzusehen." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.benutzer.findUnique({
|
||||||
|
where: {
|
||||||
|
uid: opts.input.uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht." });
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
});
|
||||||
50
src/lib/trpc/procedures/v1/benutzer/tokenErneuern.ts
Normal file
50
src/lib/trpc/procedures/v1/benutzer/tokenErneuern.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import moment from "moment";
|
||||||
|
import { prisma } from "@ibcornelsen/database";
|
||||||
|
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||||
|
import { encodeToken } from "#lib/JsonWebToken";
|
||||||
|
import { hashPassword } from "#lib/Password";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
|
export const tRPC_V1_BenutzerTokenErneuernProcedure = publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
passwort: z.string().min(8).max(100),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
z.object({
|
||||||
|
uid: z.string().uuid(),
|
||||||
|
token: z.string(),
|
||||||
|
exp: z.number(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.query(async (opts) => {
|
||||||
|
const hashedPassword = hashPassword(opts.input.passwort);
|
||||||
|
|
||||||
|
// Falls der Nutzer nicht existiert, wird eine Fehlermeldung zurückgegeben.
|
||||||
|
const user = await prisma.benutzer.findUnique({
|
||||||
|
where: {
|
||||||
|
email: opts.input.email
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht oder das Password ist falsch." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Falls das Passwort nicht stimmt, wird eine Fehlermeldung zurückgegeben.
|
||||||
|
if (user.passwort !== hashedPassword) {
|
||||||
|
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht oder das Password ist falsch." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const expiry = moment().add(2, "days").unix();
|
||||||
|
const token = encodeToken({ uid: user.uid, exp: expiry })
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: user.uid,
|
||||||
|
token: token,
|
||||||
|
exp: expiry
|
||||||
|
}
|
||||||
|
});
|
||||||
49
src/lib/trpc/procedures/v1/benutzer/tokenValidieren.ts
Normal file
49
src/lib/trpc/procedures/v1/benutzer/tokenValidieren.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import { prisma } from "@ibcornelsen/database";
|
||||||
|
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||||
|
import { decodeToken } from "#lib/JsonWebToken";
|
||||||
|
|
||||||
|
export const tRPC_V1_BenutzerTokenValidierenProcedure = publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
token: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
z.object({
|
||||||
|
uid: z.string().uuid(),
|
||||||
|
valid: z.boolean(),
|
||||||
|
exp: z.number()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.query(async (opts) => {
|
||||||
|
const decodedToken = decodeToken(opts.input.token);
|
||||||
|
|
||||||
|
if (!decodedToken || !decodedToken.uid || !decodedToken.exp) {
|
||||||
|
return {
|
||||||
|
uid: "",
|
||||||
|
valid: false,
|
||||||
|
exp: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.benutzer.findUnique({
|
||||||
|
where: {
|
||||||
|
uid: decodedToken.uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
uid: "",
|
||||||
|
valid: false,
|
||||||
|
exp: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: decodedToken.uid,
|
||||||
|
valid: true,
|
||||||
|
exp: decodedToken.exp
|
||||||
|
};
|
||||||
|
});
|
||||||
45
src/lib/trpc/procedures/v1/index.ts
Normal file
45
src/lib/trpc/procedures/v1/index.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { t } from "#lib/trpc/context";
|
||||||
|
import { tRPC_V1_KlimafaktorenProcedure } from "./klimafaktoren";
|
||||||
|
import { VerbrauchsausweisWohnen2016Erstellen } from "./verbrauchsausweis-wohnen/2016/erstellen";
|
||||||
|
import { tRPC_V1_BenutzerErstellenProcedure } from "./benutzer/erstellen";
|
||||||
|
import { tRPC_V1_BenutzerTokenErneuernProcedure } from "./benutzer/tokenErneuern";
|
||||||
|
import { tRPC_V1_BenutzerTokenValidierenProcedure } from "./benutzer/tokenValidieren";
|
||||||
|
import { tRPC_V1_BenutzerFromPublicIdProcedure } from "./benutzer/fromPublicId";
|
||||||
|
import { tRPC_V1_BenutzerFromPrivateIdProcedure } from "./benutzer/fromPrivateId";
|
||||||
|
|
||||||
|
const router = t.router;
|
||||||
|
|
||||||
|
export const v1Router = router({
|
||||||
|
verbrauchsausweisWohnen: router({
|
||||||
|
2016: router({
|
||||||
|
erstellen: VerbrauchsausweisWohnen2016Erstellen
|
||||||
|
}),
|
||||||
|
2023: router({
|
||||||
|
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
verbrauchsausweisGewerbe: router({
|
||||||
|
2016: router({
|
||||||
|
|
||||||
|
}),
|
||||||
|
2023: router({
|
||||||
|
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
bedarfsausweisWohen: router({
|
||||||
|
2016: router({
|
||||||
|
|
||||||
|
}),
|
||||||
|
2023: router({
|
||||||
|
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
klimafaktoren: tRPC_V1_KlimafaktorenProcedure,
|
||||||
|
benutzer: router({
|
||||||
|
erstellen: tRPC_V1_BenutzerErstellenProcedure,
|
||||||
|
tokenErneuern: tRPC_V1_BenutzerTokenErneuernProcedure,
|
||||||
|
tokenValidieren: tRPC_V1_BenutzerTokenValidierenProcedure,
|
||||||
|
fromPublicId: tRPC_V1_BenutzerFromPublicIdProcedure,
|
||||||
|
fromPrivateId: tRPC_V1_BenutzerFromPrivateIdProcedure
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { t } from "../../context";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { prisma } from "@ibcornelsen/database";
|
import { prisma } from "@ibcornelsen/database";
|
||||||
|
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||||
|
|
||||||
export const tRPCKlimafaktorenProcedure = t.procedure
|
export const tRPC_V1_KlimafaktorenProcedure = publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
plz: z.string().min(4).max(5),
|
plz: z.string().min(4).max(5),
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ZodSchema, z } from "zod";
|
import { z } from "zod";
|
||||||
import { publicProcedure } from "../../../../context";
|
import { prisma } from "@ibcornelsen/database";
|
||||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen, prisma } from "@ibcornelsen/database";
|
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||||
|
|
||||||
export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
||||||
.meta({
|
.meta({
|
||||||
@@ -16,11 +16,11 @@ export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
|||||||
baujahr_heizung: z.array(z.number()).optional(),
|
baujahr_heizung: z.array(z.number()).optional(),
|
||||||
zusaetzliche_heizquelle: z.boolean().optional(),
|
zusaetzliche_heizquelle: z.boolean().optional(),
|
||||||
brennstoff_1: z.string().max(50).optional(),
|
brennstoff_1: z.string().max(50).optional(),
|
||||||
einheit_1: z.string().max(10).optional(),
|
einheit_1: z.string().max(50).optional(),
|
||||||
brennstoff_2: z.string().max(50).optional(),
|
brennstoff_2: z.string().max(50).optional(),
|
||||||
einheit_2: z.string().max(10).optional(),
|
einheit_2: z.string().max(50).optional(),
|
||||||
startdatum: z.date().optional(),
|
startdatum: z.coerce.date().optional(),
|
||||||
enddatum: z.date().optional(),
|
enddatum: z.coerce.date().optional(),
|
||||||
verbrauch_1: z.number().optional(),
|
verbrauch_1: z.number().optional(),
|
||||||
verbrauch_2: z.number().optional(),
|
verbrauch_2: z.number().optional(),
|
||||||
verbrauch_3: z.number().optional(),
|
verbrauch_3: z.number().optional(),
|
||||||
@@ -86,8 +86,8 @@ export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
|||||||
aussenwand_min_12cm_gedaemmt: z.boolean().optional(),
|
aussenwand_min_12cm_gedaemmt: z.boolean().optional(),
|
||||||
dachgeschoss_min_12cm_gedaemmt: z.boolean().optional(),
|
dachgeschoss_min_12cm_gedaemmt: z.boolean().optional(),
|
||||||
oberste_geschossdecke_min_12cm_gedaemmt: z.boolean().optional(),
|
oberste_geschossdecke_min_12cm_gedaemmt: z.boolean().optional(),
|
||||||
} satisfies ZodSchema<GebaeudeStammdaten>))
|
}))
|
||||||
} satisfies ZodSchema<VerbrauchsausweisWohnen>))
|
}))
|
||||||
.output(
|
.output(
|
||||||
z.object({
|
z.object({
|
||||||
uid: z.string().uuid(),
|
uid: z.string().uuid(),
|
||||||
@@ -121,7 +121,23 @@ export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
|||||||
});
|
});
|
||||||
|
|
||||||
return { uid: verbrauchsausweis.uid };
|
return { uid: verbrauchsausweis.uid };
|
||||||
}
|
} else {
|
||||||
|
// Gebäude existiert noch nicht
|
||||||
|
const gebaeude = await prisma.gebaeudeStammdaten.create({
|
||||||
|
data: opts.input.gebaeude_stammdaten
|
||||||
|
});
|
||||||
|
|
||||||
return { uid: "" };
|
const verbrauchsausweis = await prisma.verbrauchsausweisWohnen.create({
|
||||||
|
data: {
|
||||||
|
...opts.input,
|
||||||
|
gebaeude_stammdaten: {
|
||||||
|
connect: {
|
||||||
|
uid: gebaeude.uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { uid: verbrauchsausweis.uid };
|
||||||
|
}
|
||||||
});
|
});
|
||||||
@@ -15,13 +15,14 @@
|
|||||||
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
|
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
|
||||||
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
|
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
|
||||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||||
import trpc from "src/trpc";
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
export let uid: string = "";
|
export let uid: string = "";
|
||||||
|
|
||||||
let gebaeude: GebaeudeStammdaten = {} as GebaeudeStammdaten;
|
let gebaeude: GebaeudeStammdaten = {} as GebaeudeStammdaten;
|
||||||
let ausweis: VerbrauchsausweisWohnen = {} as VerbrauchsausweisWohnen;
|
let ausweis: VerbrauchsausweisWohnen = {} as VerbrauchsausweisWohnen;
|
||||||
if (uid) {
|
if (uid) {
|
||||||
|
// NOTE: Funktioniert nicht mehr
|
||||||
async () => {
|
async () => {
|
||||||
const result = await fetch(`/api/verbrauchsausweis?uid=${uid}`, {
|
const result = await fetch(`/api/verbrauchsausweis?uid=${uid}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@@ -62,11 +63,16 @@
|
|||||||
|
|
||||||
|
|
||||||
async function ausweisAbschicken() {
|
async function ausweisAbschicken() {
|
||||||
|
console.log(ausweis);
|
||||||
|
|
||||||
overlay.ariaHidden = "false";
|
overlay.ariaHidden = "false";
|
||||||
const response = await trpc.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
|
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
|
||||||
...ausweis,
|
...ausweis,
|
||||||
gebaeude_stammdaten: gebaeude
|
gebaeude_stammdaten: gebaeude
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(response.uid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let overlay: HTMLDivElement;
|
let overlay: HTMLDivElement;
|
||||||
|
|||||||
@@ -1,34 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie"
|
||||||
import { addNotification } from "@ibcornelsen/ui";
|
import { addNotification } from "@ibcornelsen/ui";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
let email: string;
|
let email: string;
|
||||||
let password: string;
|
let passwort: string;
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
const response = await fetch("/api/login", {
|
const response = await client.v1.benutzer.tokenErneuern.query({
|
||||||
method: "POST",
|
email,
|
||||||
body: JSON.stringify({
|
passwort
|
||||||
email,
|
})
|
||||||
password,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const json = await response.json();
|
|
||||||
|
|
||||||
if (json.success == true) {
|
|
||||||
const options = {
|
|
||||||
domain: `.${window.location.hostname}`,
|
|
||||||
path: "/",
|
|
||||||
expires: json.data.expires
|
|
||||||
}
|
|
||||||
Cookies.set("token", json.data.token, options);
|
|
||||||
Cookies.set("expires", json.data.expires, options);
|
|
||||||
localStorage.setItem("token", json.data.token);
|
|
||||||
localStorage.setItem("expires", json.data.expires);
|
|
||||||
window.location.href = "/user";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
if (!response.token || !response.exp) {
|
||||||
addNotification({
|
addNotification({
|
||||||
message: "Ups...",
|
message: "Ups...",
|
||||||
subtext: "Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
|
subtext: "Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
|
||||||
@@ -36,7 +20,16 @@
|
|||||||
timeout: 6000,
|
timeout: 6000,
|
||||||
dismissable: true
|
dismissable: true
|
||||||
})
|
})
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
domain: `.${window.location.hostname}`,
|
||||||
|
path: "/",
|
||||||
|
expires: response.exp
|
||||||
|
}
|
||||||
|
Cookies.set("token", response.token, options);
|
||||||
|
window.location.href = "/user";
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -61,7 +54,7 @@
|
|||||||
type="password"
|
type="password"
|
||||||
placeholder="********"
|
placeholder="********"
|
||||||
name="password"
|
name="password"
|
||||||
bind:value={password}
|
bind:value={passwort}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { addNotification } from "@ibcornelsen/ui";
|
import { addNotification } from "@ibcornelsen/ui";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import {client} from "src/trpc";
|
||||||
|
|
||||||
let passwort: string;
|
let passwort: string;
|
||||||
let email: string;
|
let email: string;
|
||||||
|
let vorname: string;
|
||||||
|
let name: string;
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
const response = await fetch("/api/user", {
|
const response = await client.v1.benutzer.erstellen.query({
|
||||||
method: "PUT",
|
email,
|
||||||
body: JSON.stringify({
|
passwort,
|
||||||
passwort, email
|
vorname,
|
||||||
})
|
name
|
||||||
})
|
})
|
||||||
|
|
||||||
const json = await response.json()
|
if (response.token) {
|
||||||
|
const options = {
|
||||||
if (json.success == true) {
|
domain: `.${window.location.hostname}`,
|
||||||
|
path: "/",
|
||||||
|
expires: response.exp
|
||||||
|
}
|
||||||
|
Cookies.set("token", response.token, options);
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
} else {
|
} else {
|
||||||
addNotification({
|
addNotification({
|
||||||
@@ -31,6 +39,28 @@
|
|||||||
<div style="width:50%;margin: 0 auto">
|
<div style="width:50%;margin: 0 auto">
|
||||||
<h1>Registrieren:</h1>
|
<h1>Registrieren:</h1>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex flex-row gap-4 w-full">
|
||||||
|
<div class="w-1/2">
|
||||||
|
<h4>Vorname</h4>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Vorname"
|
||||||
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
|
bind:value={vorname}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2">
|
||||||
|
<h4>Nachname</h4>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Nachname"
|
||||||
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
|
bind:value={name}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>Email</h4>
|
<h4>Email</h4>
|
||||||
<input
|
<input
|
||||||
|
|||||||
42
src/pages/api/[trpc].ts
Normal file
42
src/pages/api/[trpc].ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// NOTE: Öffentliche API benötigt OpenApiMeta. Das Package bräuchte momentan noch einen extra Server, deshalb nehmen wir es momentan noch nicht mit rein.
|
||||||
|
//import { OpenApiMeta } from "trpc-openapi";
|
||||||
|
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
||||||
|
import { APIRoute } from "astro";
|
||||||
|
import { t } from "../../lib/trpc/context";
|
||||||
|
import { v1Router } from "#lib/trpc/procedures/v1";
|
||||||
|
|
||||||
|
export const appRouter = t.router({
|
||||||
|
v1: v1Router,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const all: APIRoute = ({ request }) => {
|
||||||
|
return fetchRequestHandler({
|
||||||
|
req: request,
|
||||||
|
endpoint: "/api",
|
||||||
|
router: appRouter,
|
||||||
|
createContext: async ({ req }) => {
|
||||||
|
const ip = req.headers.get("x-forwarded-for");
|
||||||
|
const authorization = req.headers.get("authorization") || null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
authorization,
|
||||||
|
ip: ip?.toString() || "",
|
||||||
|
req: req,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function tRPCCaller(request: Request) {
|
||||||
|
const { authorization } = {
|
||||||
|
authorization: request.headers.get("authorization") || "",
|
||||||
|
};
|
||||||
|
const createCaller = t.createCallerFactory(appRouter);
|
||||||
|
return createCaller({
|
||||||
|
authorization,
|
||||||
|
req: request,
|
||||||
|
ip: request.headers.get("x-forwarded-for") || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppRouter = typeof appRouter;
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import type { APIRoute } from "astro";
|
|
||||||
import { success, MissingPropertyError, error } from "../../lib/APIResponse";
|
|
||||||
import { validatePassword } from "../../lib/Password";
|
|
||||||
import { User } from "../../lib/User";
|
|
||||||
import moment from "moment";
|
|
||||||
import { encodeToken } from "../../lib/JsonWebToken";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
|
||||||
* @param param0 Die Request mit dem request body. Dieser enthält entweder eine uid mit der der Benutzer identifiziert werden kann.
|
|
||||||
*/
|
|
||||||
export const post: APIRoute = async ({ request }) => {
|
|
||||||
const body = await request.json();
|
|
||||||
|
|
||||||
if (!body.hasOwnProperty("email") || !body.hasOwnProperty("password")) {
|
|
||||||
return MissingPropertyError(["email", "password"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await User.fromEmail(body.email);
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return error(["Invalid email or password."]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate Password
|
|
||||||
if (!validatePassword(user.passwort, body.password)) {
|
|
||||||
return error(["Invalid email or password."]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const expiry = moment().add(2, "days").unix();
|
|
||||||
const token = encodeToken({ id: user.id, uid: user.uid, exp: expiry })
|
|
||||||
|
|
||||||
return success({ token, expires: expiry });
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import type { APIRoute } from "astro";
|
|
||||||
import { success, MissingPropertyError, error } from "../../lib/APIResponse";
|
|
||||||
import { validatePassword, hashPassword } from "../../lib/Password";
|
|
||||||
import { User } from "../../lib/User";
|
|
||||||
import moment from "moment";
|
|
||||||
import { encodeToken } from "../../lib/JsonWebToken";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
|
||||||
* @param param0 Die Request mit dem request body. Dieser enthält entweder eine uid mit der der Benutzer identifiziert werden kann.
|
|
||||||
*/
|
|
||||||
export const post: APIRoute = async ({ request }) => {
|
|
||||||
const body = await request.json();
|
|
||||||
|
|
||||||
if (!body.hasOwnProperty("email") || !body.hasOwnProperty("password")) {
|
|
||||||
return MissingPropertyError(["email", "password"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await User.fromEmail(body.email);
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return error(["Invalid email or password."]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate Password
|
|
||||||
if (!validatePassword(user.passwort, body.password)) {
|
|
||||||
return error(["Invalid email or password."]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const expiry = moment().add(2, "days").unix();
|
|
||||||
const token = encodeToken({ id: user.id, uid: user.uid, exp: expiry })
|
|
||||||
|
|
||||||
return success({ token, expires: expiry });
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// NOTE: Öffentliche API benötigt OpenApiMeta. Das Package bräuchte momentan noch einen extra Server, deshalb nehmen wir es momentan noch nicht mit rein.
|
|
||||||
//import { OpenApiMeta } from "trpc-openapi";
|
|
||||||
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
|
||||||
import { APIRoute } from "astro";
|
|
||||||
import { t } from "./context";
|
|
||||||
import { v1Router } from "./procedures/v1";
|
|
||||||
|
|
||||||
export const AppRouter = t.router({
|
|
||||||
v1: v1Router,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const all: APIRoute = ({ request }) => {
|
|
||||||
console.log(request);
|
|
||||||
|
|
||||||
return fetchRequestHandler({
|
|
||||||
req: request,
|
|
||||||
endpoint: "/api/trpc",
|
|
||||||
router: AppRouter,
|
|
||||||
createContext: async ({ req }) => {
|
|
||||||
return { uid: req.headers.get("X-Session") ?? undefined };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function tRPCCaller(request: Request) {
|
|
||||||
const { uid } = { uid: request.headers.get("Authorization") || "" };
|
|
||||||
const createCaller = t.createCallerFactory(AppRouter);
|
|
||||||
return createCaller({ uid });
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AppRouter = typeof AppRouter;
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { z } from "zod";
|
|
||||||
import { t } from "../../context";
|
|
||||||
import { tRPCKlimafaktorenProcedure } from "./klimafaktoren";
|
|
||||||
import { VerbrauchsausweisWohnen2016Erstellen } from "./verbrauchsausweis-wohnen/2016/erstellen";
|
|
||||||
|
|
||||||
const router = t.router;
|
|
||||||
|
|
||||||
export const v1Router = router({
|
|
||||||
verbrauchsausweisWohnen: router({
|
|
||||||
2016: router({
|
|
||||||
erstellen: VerbrauchsausweisWohnen2016Erstellen
|
|
||||||
}),
|
|
||||||
2023: router({
|
|
||||||
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
verbrauchsausweisGewerbe: router({
|
|
||||||
2016: router({
|
|
||||||
|
|
||||||
}),
|
|
||||||
2023: router({
|
|
||||||
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
bedarfsausweisWohen: router({
|
|
||||||
2016: router({
|
|
||||||
|
|
||||||
}),
|
|
||||||
2023: router({
|
|
||||||
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
klimafaktoren: tRPCKlimafaktorenProcedure,
|
|
||||||
test: t.procedure.meta({
|
|
||||||
openapi: {
|
|
||||||
method: "GET",
|
|
||||||
path: "/v1/test",
|
|
||||||
}
|
|
||||||
}).input(z.void({})).output(z.string()).query(async (opts) => {
|
|
||||||
return "Hello World!";
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
import type { APIRoute } from "astro";
|
|
||||||
import { success, MissingPropertyError, MissingEntityError, ActionFailedError, InvalidDataError, error } from "../../lib/APIResponse";
|
|
||||||
import { User } from "../../lib/User";
|
|
||||||
import { UserRegisterValidator, UserType } from "../../lib/User/type";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
|
||||||
* @param param0 Die Request mit dem request body. Dieser enthält entweder eine uid mit der der Benutzer identifiziert werden kann.
|
|
||||||
*/
|
|
||||||
export const get: APIRoute = async ({ request }) => {
|
|
||||||
const body = await request.json();
|
|
||||||
|
|
||||||
if (!body.hasOwnProperty("uid")) {
|
|
||||||
return MissingPropertyError(["uid"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = User.fromUID(body.uid);
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return MissingEntityError("user");
|
|
||||||
}
|
|
||||||
|
|
||||||
return success(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const put: APIRoute = async ({ request }) => {
|
|
||||||
const body: z.infer<typeof UserRegisterValidator> = await request.json();
|
|
||||||
|
|
||||||
const validate = UserRegisterValidator.safeParse(body);
|
|
||||||
|
|
||||||
if (validate.success == false) {
|
|
||||||
return InvalidDataError(validate.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await User.fromEmail(body.email);
|
|
||||||
|
|
||||||
if (user) {
|
|
||||||
return error(["Diese Email Adresse wird bereits verwendet."]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await User.create(body as UserType);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
return ActionFailedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success({ uid: result.uid, id: result.id });
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import type { APIRoute } from "astro";
|
|
||||||
import { success, MissingPropertyError, MissingEntityError, error } from "../../lib/APIResponse";
|
|
||||||
import { validateAuthorizationHeader } from "src/lib/server/Authorization";
|
|
||||||
import { prisma } from "@ibcornelsen/database";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
|
||||||
* @param param0 Die Request mit dem request body. Dieser enthält entweder eine uid mit der der Benutzer identifiziert werden kann.
|
|
||||||
*/
|
|
||||||
export const get: APIRoute = async ({ request }) => {
|
|
||||||
const user = await validateAuthorizationHeader(request, ["Bearer", "Basic"]);
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return error(["Invalid authentication credentials!"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const body = Object.fromEntries(new URLSearchParams(request.url.split("?")[1]))
|
|
||||||
|
|
||||||
let result;
|
|
||||||
if (body.zip) {
|
|
||||||
result = await prisma.postleitzahlen.findUnique({
|
|
||||||
where: {
|
|
||||||
plz: body.zip,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else if (body.city) {
|
|
||||||
result = await prisma.postleitzahlen.findMany({
|
|
||||||
where: {
|
|
||||||
stadt: body.city,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else if (body.state) {
|
|
||||||
result = await prisma.postleitzahlen.findMany({
|
|
||||||
where: {
|
|
||||||
bundesland: body.state,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return MissingPropertyError(["Either 'state', 'city' or 'zip' have to exist in request body."])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
return MissingEntityError("zip info")
|
|
||||||
}
|
|
||||||
|
|
||||||
return success(result);
|
|
||||||
}
|
|
||||||
@@ -1,28 +1,27 @@
|
|||||||
---
|
---
|
||||||
import { changeLanguage } from "i18next";
|
|
||||||
import moment from "moment";
|
|
||||||
import { decodeToken } from "#lib/JsonWebToken";
|
|
||||||
import { User } from "#lib/User";
|
|
||||||
import UserLayout from "#layouts/UserLayout.astro";
|
import UserLayout from "#layouts/UserLayout.astro";
|
||||||
import AusweisCard from "#components/AusweisCard.svelte";
|
import { User } from "#lib/User";
|
||||||
import { Verbrauchsausweis } from "#lib/Ausweis/Verbrauchsausweis";
|
import { tRPCCaller } from "../api/[trpc]";
|
||||||
|
|
||||||
changeLanguage("de");
|
|
||||||
|
|
||||||
const token = Astro.cookies.get("token").value;
|
const token = Astro.cookies.get("token").value;
|
||||||
const expires = Astro.cookies.get("expires").number();
|
|
||||||
const now = moment().unix();
|
if (!token) {
|
||||||
if (!token || now > expires) {
|
Astro.cookies.delete("token");
|
||||||
Astro.cookies.delete("token");
|
return Astro.redirect(`/login`);
|
||||||
Astro.cookies.delete("expires");
|
|
||||||
return Astro.redirect(`/login`);
|
|
||||||
}
|
}
|
||||||
const parsed = decodeToken(token);
|
|
||||||
const user = await User.fromUID(parsed.uid);
|
const response = await tRPCCaller(Astro.request).v1.benutzer.tokenValidieren({ token });
|
||||||
|
|
||||||
|
if (!response.valid) {
|
||||||
|
Astro.cookies.delete("token");
|
||||||
|
return Astro.redirect(`/login`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await User.fromUID(response.uid);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
Astro.cookies.delete("token");
|
Astro.cookies.delete("token");
|
||||||
Astro.cookies.delete("expires");
|
return Astro.redirect(`/login`);
|
||||||
return Astro.redirect(`/login`);
|
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -31,8 +30,5 @@ if (!user) {
|
|||||||
|
|
||||||
<h2>Ihre Ausweise</h2>
|
<h2>Ihre Ausweise</h2>
|
||||||
<div class="grid grid-flow-row grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
<div class="grid grid-flow-row grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||||
<AusweisCard client:load hidden={true} i={0} ausweis={new Verbrauchsausweis()}></AusweisCard>
|
|
||||||
<AusweisCard client:load hidden={true} i={1} ausweis={new Verbrauchsausweis()}></AusweisCard>
|
|
||||||
<AusweisCard client:load hidden={true} i={2} ausweis={new Verbrauchsausweis()}></AusweisCard>
|
|
||||||
</div>
|
</div>
|
||||||
</UserLayout>
|
</UserLayout>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
||||||
import cookies from 'js-cookie';
|
import cookies from 'js-cookie';
|
||||||
import type { AppRouter } from 'src/pages/api/trpc/[trpc]';
|
import type { AppRouter } from 'src/pages/api/[trpc]';
|
||||||
|
|
||||||
export default createTRPCProxyClient<AppRouter>({
|
export const client = createTRPCProxyClient<AppRouter>({
|
||||||
links: [
|
links: [
|
||||||
httpBatchLink({
|
httpBatchLink({
|
||||||
url: 'http://localhost:3000/api/trpc',
|
url: 'http://localhost:3000/api',
|
||||||
headers() {
|
headers() {
|
||||||
return {
|
return {
|
||||||
'Authorization': `Bearer ${cookies.get('uid')}`,
|
'Authorization': `Bearer ${cookies.get('uid')}`,
|
||||||
|
|||||||
2
test.ts
2
test.ts
@@ -1,4 +1,4 @@
|
|||||||
import { AppRouter } from "src/pages/api/trpc/[trpc]"
|
import { AppRouter } from "src/pages/api/[trpc]"
|
||||||
import { createOpenApiExpressMiddleware } from "trpc-openapi"
|
import { createOpenApiExpressMiddleware } from "trpc-openapi"
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user