41 lines
1.5 KiB
TypeScript
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>;
|