Filtern nach ID
This commit is contained in:
@@ -70,7 +70,7 @@
|
||||
</ul>
|
||||
</details></li> -->
|
||||
{#if benutzer.rolle === "ADMIN"}
|
||||
<li><details class="[&_.caret]:open:rotate-180">
|
||||
<li><details class="[&_.caret]:open:rotate-180" open>
|
||||
<summary class="button-tab w-full outline-0 hover:outline-0 cursor-pointer">
|
||||
<LockClosed width={22} height={22} />
|
||||
Admin <CaretDown size={24} class="caret ml-auto transition-transform"></CaretDown></summary>
|
||||
@@ -80,6 +80,11 @@
|
||||
Ausweise Prüfen
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard/admin/impersonate-user">
|
||||
Impersonate User
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</details></li>
|
||||
{/if}
|
||||
|
||||
@@ -93,6 +93,8 @@
|
||||
objekte = objekte
|
||||
}
|
||||
let filters: { name: keyof z.infer<typeof filterAusweise>, type: ZodTypeAny, value: any }[] = []
|
||||
|
||||
export let id: string = "";
|
||||
</script>
|
||||
|
||||
<h1>Gebäudeübersicht</h1>
|
||||
@@ -100,9 +102,13 @@
|
||||
<hr />
|
||||
|
||||
{#if user.rolle === Enums.BenutzerRolle.ADMIN}
|
||||
<div class="flex flex-col mb-4">
|
||||
<!-- <div class="flex flex-col mb-4">
|
||||
<AusweisePruefenFilter bind:filters={filters}></AusweisePruefenFilter>
|
||||
</div>
|
||||
</div> -->
|
||||
<form action="" class="flex flex-row gap-2 my-2">
|
||||
<input type="text" bind:value={id} name="id" placeholder="ID">
|
||||
<button class="button text-sm">Suchen</button>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
<div class="relative mb-6">
|
||||
|
||||
34
src/modules/ImpersonateUserModule.svelte
Normal file
34
src/modules/ImpersonateUserModule.svelte
Normal file
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
|
||||
import { api } from "astro-typesafe-api/client";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
$: userRequest = api.user.GET.fetch({
|
||||
email,
|
||||
take: 25
|
||||
}, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||
}
|
||||
})
|
||||
|
||||
let email: string = "";
|
||||
</script>
|
||||
|
||||
<input type="email" bind:value={email}>
|
||||
|
||||
{#await userRequest}
|
||||
|
||||
{:then users}
|
||||
<div class="flex flex-col gap-2 my-2">
|
||||
{#each users as user}
|
||||
<div class="flex flex-row justify-between border p-2 rounded-sm">
|
||||
<div class="flex flex-col">
|
||||
<span>{user.vorname} {user.name}</span>
|
||||
<span class="text-xs">{user.email}</span>
|
||||
</div>
|
||||
<a href="/dashboard/admin/impersonate?uid={user.uid}" class="button text-sm">Einloggen</a>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/await}
|
||||
@@ -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(),
|
||||
|
||||
33
src/pages/dashboard/admin/impersonate-user.astro
Normal file
33
src/pages/dashboard/admin/impersonate-user.astro
Normal file
@@ -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")
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
<DashboardLayout title="Impersonate User" {user}>
|
||||
<ImpersonateUserModule client:load></ImpersonateUserModule>
|
||||
</DashboardLayout>
|
||||
66
src/pages/dashboard/admin/impersonate.astro
Normal file
66
src/pages/dashboard/admin/impersonate.astro
Normal file
@@ -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")
|
||||
---
|
||||
@@ -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({
|
||||
})
|
||||
---
|
||||
|
||||
<UserLayout title="Ausweise Prüfen" {user}>
|
||||
<DashboardModule {user} {objekte} totalPages={Math.ceil(totalPages / 25)} page={page} client:load />
|
||||
<UserLayout title="Objekte" {user}>
|
||||
<DashboardModule {user} {objekte} totalPages={Math.ceil(totalPages / 25)} page={page} {id} client:load />
|
||||
</UserLayout>
|
||||
@@ -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, {
|
||||
|
||||
@@ -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, {
|
||||
|
||||
Reference in New Issue
Block a user