Files
d4rk_tablet/packages/shared/src/dto/auth.ts
T
2026-07-16 09:35:32 +02:00

41 lines
1.5 KiB
TypeScript

import { z } from 'zod';
import { citizenId } from './common';
import { ROLES, DEPARTMENTS } from '../rbac';
import { permissionSchema } from './rank';
/** JWT-Payload (in Web-App aus Token dekodiert). */
export const authUserSchema = z.object({
sub: z.string(), // interne mdt_users id
citizenid: citizenId.nullable(),
discordId: z.string().nullable(),
name: z.string(),
roles: z.array(z.enum(ROLES)),
/** Effektive Rechte (server-seitig aus Rang-Matrix + Overrides berechnet). */
permissions: z.array(permissionSchema),
/** Behörde + Rang (aus QBox-Job), für Branding & Anzeige. */
department: z.enum(DEPARTMENTS).nullable(),
grade: z.number().int().nullable(),
/** Behörden-Keys, denen der User angehört (aus QBox-Job über die Registry). */
authorities: z.array(z.string()),
});
export type AuthUser = z.infer<typeof authUserSchema>;
/** Body von /auth/fivem — von der fivem-bridge (Server) gesendet, HMAC-signiert. */
export const fivemAuthRequestSchema = z.object({
license: z.string().min(1),
citizenid: citizenId,
name: z.string(),
job: z.string(),
jobGrade: z.string().optional(), // Rang-Bezeichnung (Anzeige)
gradeLevel: z.coerce.number().int().min(0).default(0), // QBox job.grade.level
callsign: z.string().nullable().optional(),
});
export type FivemAuthRequest = z.infer<typeof fivemAuthRequestSchema>;
export const authTokenResponseSchema = z.object({
token: z.string(),
refreshToken: z.string(),
user: authUserSchema,
});
export type AuthTokenResponse = z.infer<typeof authTokenResponseSchema>;