diff --git a/src/modules/ImpersonateUserModule.svelte b/src/modules/ImpersonateUserModule.svelte
new file mode 100644
index 00000000..8b623303
--- /dev/null
+++ b/src/modules/ImpersonateUserModule.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+{#await userRequest}
+
+{:then users}
+
+ {#each users as user}
+
+
+ {user.vorname} {user.name}
+ {user.email}
+
+
Einloggen
+
+ {/each}
+
+{/await}
\ No newline at end of file
diff --git a/src/pages/api/user/index.ts b/src/pages/api/user/index.ts
index b33241eb..143cda6a 100644
--- a/src/pages/api/user/index.ts
+++ b/src/pages/api/user/index.ts
@@ -1,9 +1,10 @@
import { UUidWithPrefix } from "#components/Ausweis/types.js";
-import { authorizationMiddleware } from "#lib/middleware/authorization.js";
+import { adminMiddleware, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { hashPassword } from "#lib/password.js";
import { sendRegisterMail } from "#lib/server/mail/registrierung.js";
-import { BenutzerSchema, prisma } from "#lib/server/prisma.js";
+import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
+import { BenutzerSchema } from "src/generated/zod/benutzer.js";
import { z } from "zod";
export const POST = defineApiRoute({
@@ -40,6 +41,39 @@ export const POST = defineApiRoute({
},
})
+export const GET = defineApiRoute({
+ input: z.object({
+ uid: UUidWithPrefix
+ }).or(z.object({
+ take: z.number(),
+ email: z.string()
+ })),
+ output: z.array(BenutzerSchema),
+ middleware: adminMiddleware,
+ async fetch(input, context, admin) {
+ if ("uid" in input) {
+ const user = await prisma.benutzer.findUnique({
+ where: {
+ uid: input.uid
+ }
+ })
+
+ return [user];
+ } else {
+ const users = await prisma.benutzer.findMany({
+ where: {
+ email: {
+ startsWith: input.email
+ }
+ },
+ take: input.take
+ })
+
+ return users;
+ }
+ },
+})
+
export const PUT = defineApiRoute({
input: z.object({
email: z.string().email(),
diff --git a/src/pages/dashboard/admin/impersonate-user.astro b/src/pages/dashboard/admin/impersonate-user.astro
new file mode 100644
index 00000000..871346c1
--- /dev/null
+++ b/src/pages/dashboard/admin/impersonate-user.astro
@@ -0,0 +1,33 @@
+---
+import DashboardLayout from "#layouts/DashboardLayout.astro";
+import UserLayout from "#layouts/DashboardLayout.astro";
+import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
+import { Enums, prisma } from "#lib/server/prisma";
+import { createCaller } from "src/astro-typesafe-api-caller";
+import DashboardModule from "#modules/Dashboard/DashboardModule.svelte";
+import ImpersonateUserModule from "#modules/ImpersonateUserModule.svelte";
+
+const caller = createCaller(Astro)
+
+const params = Astro.params;
+const page = Number(params.page)
+
+const user = await caller.user.self.GET.fetch(undefined, {
+ headers: {
+ "Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
+ }
+});
+
+if (!user) {
+ return Astro.redirect("/auth/login")
+}
+
+if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
+ return Astro.redirect("/dashboard")
+}
+
+---
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/dashboard/admin/impersonate.astro b/src/pages/dashboard/admin/impersonate.astro
new file mode 100644
index 00000000..62c2617c
--- /dev/null
+++ b/src/pages/dashboard/admin/impersonate.astro
@@ -0,0 +1,66 @@
+---
+import { encodeToken } from "#lib/auth/token";
+import { TokenType } from "#lib/auth/types";
+import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants";
+import { Enums, prisma } from "#lib/server/prisma";
+import moment from "moment";
+import { createCaller } from "src/astro-typesafe-api-caller";
+
+const caller = createCaller(Astro)
+
+const user = await caller.user.self.GET.fetch(undefined, {
+ headers: {
+ "Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
+ }
+});
+
+if (!user) {
+ return Astro.redirect("/auth/login")
+}
+
+if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
+ return Astro.redirect("/dashboard")
+}
+
+const uid = Astro.url.searchParams.get("uid")
+
+if (!uid) {
+ return Astro.redirect("/404")
+}
+
+const searchedUser = await prisma.benutzer.findUnique({
+ where: {
+ uid
+ }
+})
+
+if (!searchedUser) {
+ return Astro.redirect("/dashboard/impersonate-user")
+}
+
+const refreshTokenExpiry = moment().add(30, "days");
+const accessToken = encodeToken({
+ uid: searchedUser.uid,
+ typ: TokenType.Access,
+ exp: moment().add(30, "minutes").valueOf(),
+});
+const refreshToken = encodeToken({
+ uid: searchedUser.uid,
+ typ: TokenType.Refresh,
+ exp: refreshTokenExpiry.valueOf(),
+});
+
+Astro.cookies.set(API_REFRESH_TOKEN_COOKIE_NAME, refreshToken, {
+ domain: `.${Astro.url.hostname}`,
+ path: "/",
+ expires: refreshTokenExpiry.toDate()
+})
+Astro.cookies.set(API_ACCESS_TOKEN_COOKIE_NAME, accessToken, {
+ domain: `.${Astro.url.hostname}`,
+ path: "/",
+ expires: moment().add(30, "minutes").toDate()
+})
+Astro.cookies.set("uid", searchedUser.uid)
+
+return Astro.redirect("/dashboard")
+---
\ No newline at end of file
diff --git a/src/pages/dashboard/objekte/[page].astro b/src/pages/dashboard/objekte/[page].astro
index 4e60590e..74d81b60 100644
--- a/src/pages/dashboard/objekte/[page].astro
+++ b/src/pages/dashboard/objekte/[page].astro
@@ -10,6 +10,9 @@ const caller = createCaller(Astro)
const params = Astro.params;
const page = Number(params.page)
+const id = parseInt(Astro.url.searchParams.get("id") || "")
+
+
const user = await caller.user.self.GET.fetch(undefined, {
headers: {
"Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
@@ -32,8 +35,76 @@ const objekte = await prisma.objekt.findMany({
where: user.rolle === Enums.BenutzerRolle.USER ? {
benutzer: {
uid: user.uid
- }
- } : {},
+ },
+ } : {
+ OR: [
+ {
+ aufnahmen: {
+ some: {
+ verbrauchsausweise_gewerbe: {
+ some: {
+ alte_ausweis_id: id
+ }
+ },
+ }
+ }
+ },
+ {
+ aufnahmen: {
+ some: {
+ verbrauchsausweise_wohnen: {
+ some: {
+ alte_ausweis_id: id
+ }
+ },
+ }
+ }
+ },
+ {
+ aufnahmen: {
+ some: {
+ bedarfsausweise_wohnen: {
+ some: {
+ alte_ausweis_id: id
+ }
+ },
+ }
+ }
+ },
+ {
+ aufnahmen: {
+ some: {
+ verbrauchsausweise_gewerbe: {
+ some: {
+ id: id
+ }
+ },
+ }
+ }
+ },
+ {
+ aufnahmen: {
+ some: {
+ verbrauchsausweise_wohnen: {
+ some: {
+ id: id
+ }
+ },
+ }
+ }
+ },
+ {
+ aufnahmen: {
+ some: {
+ bedarfsausweise_wohnen: {
+ some: {
+ id: id
+ }
+ },
+ }
+ }
+ },]
+ },
orderBy: {
erstellungsdatum: "desc"
},
@@ -53,6 +124,6 @@ const objekte = await prisma.objekt.findMany({
})
---
-
-
+
+
\ No newline at end of file
diff --git a/src/pages/pdf/ansichtsausweis.ts b/src/pages/pdf/ansichtsausweis.ts
index ba9694e4..028eb9bd 100644
--- a/src/pages/pdf/ansichtsausweis.ts
+++ b/src/pages/pdf/ansichtsausweis.ts
@@ -11,7 +11,7 @@ export const GET: APIRoute = async (Astro) => {
const uidAusweis = Astro.url.searchParams.get("uid");
if (!uidAusweis) {
- return Astro.redirect("/404")
+ return new Response(null, { status: 404 });
}
const ausweisart = getAusweisartFromUUID(uidAusweis)
@@ -46,7 +46,7 @@ export const GET: APIRoute = async (Astro) => {
if (!ausweis) {
- return Astro.redirect("/");
+ return new Response(null, { status: 404 });
}
aufnahme = await caller.aufnahme._uid.GET.fetch(undefined, {
diff --git a/src/pages/pdf/datenblatt.ts b/src/pages/pdf/datenblatt.ts
index ae1d5a0e..345a6516 100644
--- a/src/pages/pdf/datenblatt.ts
+++ b/src/pages/pdf/datenblatt.ts
@@ -13,7 +13,7 @@ export const GET: APIRoute = async (Astro) => {
const uidAusweis = Astro.url.searchParams.get("uid");
if (!uidAusweis) {
- return Astro.redirect("/404")
+ return new Response(null, { status: 404 });
}
const ausweisart = getAusweisartFromUUID(uidAusweis)
@@ -48,7 +48,7 @@ export const GET: APIRoute = async (Astro) => {
if (!ausweis) {
- return Astro.redirect("/");
+ return new Response(null, { status: 404 });
}
aufnahme = await caller.aufnahme._uid.GET.fetch(undefined, {