Files
Epicnabbo-Catalogus-Updated…/src/features/housekeeping/domains/system/commands/system-commands.ts
T

316 lines
9.6 KiB
TypeScript

import "server-only";
import { z } from "zod";
import { PERMS } from "@/lib/permission-slugs";
import type { HousekeepingCommand } from "../../../foundation/commands/registry";
import { anyCapability } from "../../../foundation/contracts";
import {
type SystemMutationOperation,
type SystemMutationService,
systemMutationService,
} from "../services/mutations";
export const SYSTEM_COMMAND_IDS = [
"system.access.rank.create",
"system.access.rank.delete",
"system.access.rank.update",
"system.access.permissions.update",
"system.access.permissions.repair",
"system.configuration.settings.save",
"system.configuration.setting.create",
"system.configuration.setting.update",
"system.configuration.setting.delete",
"system.configuration.emulator-setting.update",
"system.configuration.emulator-text.update",
"system.operations.alerts.mark-read",
"system.operations.alert.broadcast",
"system.operations.rcon.update-catalog",
"system.operations.rcon.update-word-filter",
"system.operations.rcon.update-navigator",
"system.operations.rcon.hotel-alert",
"system.operations.rcon.disconnect-user",
"system.operations.rcon.alert-user",
"system.operations.rcon.forward-user",
"system.operations.rcon.give-credits",
"system.operations.rcon.give-duckets",
"system.operations.rcon.give-diamonds",
"system.operations.rcon.give-badge",
"system.operations.rcon.set-motto",
"system.operations.rcon.set-rank",
"system.operations.rcon.execute-command",
"system.operations.rcon.send-gift",
"system.operations.maintenance.update",
] as const;
interface CommandOptions<I> {
readonly id: (typeof SYSTEM_COMMAND_IDS)[number];
readonly operation: SystemMutationOperation;
readonly capability: string;
readonly input: z.ZodType<I>;
readonly requiresReason: boolean;
readonly attempts?: number;
}
function systemCommand<I>(
service: Pick<SystemMutationService, "execute">,
options: CommandOptions<I>,
): HousekeepingCommand<I, unknown> {
return {
id: options.id,
owner: "system",
risk: "sensitive",
capability: anyCapability(options.capability),
input: options.input,
requiresReason: options.requiresReason,
rateLimit: { attempts: options.attempts ?? 10, windowMs: 60_000 },
execute: (context, input) =>
service.execute(
{
capability: context.capability,
correlationId: context.correlationId,
},
options.operation,
input,
),
};
}
const empty = z.object({});
const positiveId = z.number().int().positive();
const requiredText = (max: number) => z.string().min(1).max(max).regex(/\S/u);
const settingInput = z.object({
key: requiredText(255),
value: z.string().max(65_535),
});
export function createSystemCommands(
service: Pick<SystemMutationService, "execute">,
) {
return [
systemCommand(service, {
id: "system.access.rank.create",
operation: "access.rank.create",
capability: PERMS.PERMISSIONS_MANAGE,
input: z.object({ name: requiredText(25), level: positiveId }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.access.rank.delete",
operation: "access.rank.delete",
capability: PERMS.PERMISSIONS_MANAGE,
input: z.object({ id: positiveId }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.access.rank.update",
operation: "access.rank.update",
capability: PERMS.PERMISSIONS_MANAGE,
input: z.object({
id: positiveId,
fields: z.record(z.string(), z.union([z.string(), z.number()])),
}),
requiresReason: true,
}),
systemCommand(service, {
id: "system.access.permissions.update",
operation: "access.permissions.update",
capability: PERMS.PERMISSIONS_MANAGE,
input: z.object({
roleId: positiveId,
permissionSlugs: z.array(requiredText(160)).max(500),
}),
requiresReason: true,
}),
systemCommand(service, {
id: "system.access.permissions.repair",
operation: "access.permissions.repair",
capability: PERMS.PERMISSIONS_MANAGE,
input: empty,
requiresReason: true,
}),
systemCommand(service, {
id: "system.configuration.settings.save",
operation: "configuration.settings.save",
capability: PERMS.SETTINGS_EDIT,
input: z.object({ settings: z.record(z.string(), z.string()) }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.configuration.setting.create",
operation: "configuration.setting.create",
capability: PERMS.SETTINGS_EDIT,
input: settingInput.extend({ comment: z.string().max(255).optional() }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.configuration.setting.update",
operation: "configuration.setting.update",
capability: PERMS.SETTINGS_EDIT,
input: settingInput,
requiresReason: true,
}),
systemCommand(service, {
id: "system.configuration.setting.delete",
operation: "configuration.setting.delete",
capability: PERMS.SETTINGS_EDIT,
input: z.object({ key: requiredText(255) }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.configuration.emulator-setting.update",
operation: "configuration.emulator-setting.update",
capability: PERMS.SETTINGS_EDIT,
input: z.object({ key: requiredText(100), value: z.string().max(512) }),
requiresReason: false,
}),
systemCommand(service, {
id: "system.configuration.emulator-text.update",
operation: "configuration.emulator-text.update",
capability: PERMS.SETTINGS_EDIT,
input: z.object({ key: requiredText(100), value: z.string().max(4096) }),
requiresReason: false,
}),
systemCommand(service, {
id: "system.operations.alerts.mark-read",
operation: "operations.alerts.mark-read",
capability: PERMS.NOTIFICATIONS_VIEW,
input: empty,
requiresReason: false,
}),
systemCommand(service, {
id: "system.operations.alert.broadcast",
operation: "operations.alert.broadcast",
capability: PERMS.NOTIFICATIONS_EDIT,
input: z.object({ message: requiredText(1000) }),
requiresReason: true,
}),
systemCommand(service, {
id: "system.operations.rcon.update-catalog",
operation: "rcon.update-catalog",
capability: PERMS.RCON_EXECUTE,
input: empty,
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.update-word-filter",
operation: "rcon.update-word-filter",
capability: PERMS.RCON_EXECUTE,
input: empty,
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.update-navigator",
operation: "rcon.update-navigator",
capability: PERMS.RCON_EXECUTE,
input: empty,
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.hotel-alert",
operation: "rcon.hotel-alert",
capability: PERMS.RCON_EXECUTE,
input: z.object({ message: requiredText(512) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.disconnect-user",
operation: "rcon.disconnect-user",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, username: requiredText(255) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.alert-user",
operation: "rcon.alert-user",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, message: requiredText(512) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.forward-user",
operation: "rcon.forward-user",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, roomId: positiveId }),
requiresReason: true,
attempts: 5,
}),
...[
["give-credits", "rcon.give-credits"],
["give-duckets", "rcon.give-duckets"],
["give-diamonds", "rcon.give-diamonds"],
].map(([suffix, operation]) =>
systemCommand(service, {
id: `system.operations.rcon.${suffix}` as (typeof SYSTEM_COMMAND_IDS)[number],
operation: operation as SystemMutationOperation,
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, amount: positiveId }),
requiresReason: true,
attempts: 5,
}),
),
systemCommand(service, {
id: "system.operations.rcon.give-badge",
operation: "rcon.give-badge",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, badge: requiredText(32) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.set-motto",
operation: "rcon.set-motto",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, motto: requiredText(127) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.set-rank",
operation: "rcon.set-rank",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, rank: positiveId.max(9999) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.execute-command",
operation: "rcon.execute-command",
capability: PERMS.RCON_EXECUTE,
input: z.object({ userId: positiveId, command: requiredText(100) }),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.rcon.send-gift",
operation: "rcon.send-gift",
capability: PERMS.RCON_EXECUTE,
input: z.object({
userId: positiveId,
itemId: positiveId,
message: z.string().max(255).optional(),
}),
requiresReason: true,
attempts: 5,
}),
systemCommand(service, {
id: "system.operations.maintenance.update",
operation: "operations.maintenance.update",
capability: PERMS.SETTINGS_EDIT,
input: z.object({
enabled: z.boolean(),
message: z.string().max(65_535),
minimumLoginRank: z.number().int().min(0),
}),
requiresReason: true,
}),
] as const;
}
export const SYSTEM_COMMANDS = createSystemCommands(systemMutationService);