feat(frontend): add config types and API client for file-config endpoints

- types/config.ts: TypeScript interfaces for ActionConfig, FilterConfig,
  JailFileConfig, ConfFileContent, and related request/response shapes
- api/config.ts: typed API functions for reading and writing conf files
- api/endpoints.ts: add /config/file/* endpoint constants
This commit is contained in:
2026-03-13 13:47:45 +01:00
parent f5c3635258
commit 8bdad3529f
3 changed files with 201 additions and 0 deletions

View File

@@ -5,11 +5,15 @@
import { del, get, post, put } from "./client";
import { ENDPOINTS } from "./endpoints";
import type {
ActionConfig,
ActionConfigUpdate,
AddLogPathRequest,
ConfFileContent,
ConfFileCreateRequest,
ConfFilesResponse,
ConfFileUpdateRequest,
FilterConfig,
FilterConfigUpdate,
GlobalConfig,
GlobalConfigUpdate,
JailConfigFileContent,
@@ -26,6 +30,8 @@ import type {
RegexTestResponse,
ServerSettingsResponse,
ServerSettingsUpdate,
JailFileConfig,
JailFileConfigUpdate,
} from "../types/config";
// ---------------------------------------------------------------------------
@@ -164,6 +170,12 @@ export async function fetchJailConfigFiles(): Promise<JailConfigFilesResponse> {
return get<JailConfigFilesResponse>(ENDPOINTS.configJailFiles);
}
export async function createJailConfigFile(
req: ConfFileCreateRequest
): Promise<ConfFileContent> {
return post<ConfFileContent>(ENDPOINTS.configJailFiles, req);
}
export async function fetchJailConfigFileContent(
filename: string
): Promise<JailConfigFileContent> {
@@ -226,3 +238,48 @@ export async function createActionFile(
): Promise<ConfFileContent> {
return post<ConfFileContent>(ENDPOINTS.configActions, req);
}
// ---------------------------------------------------------------------------
// Parsed filter config (Task 2.2)
// ---------------------------------------------------------------------------
export async function fetchParsedFilter(name: string): Promise<FilterConfig> {
return get<FilterConfig>(ENDPOINTS.configFilterParsed(name));
}
export async function updateParsedFilter(
name: string,
update: FilterConfigUpdate
): Promise<void> {
await put<undefined>(ENDPOINTS.configFilterParsed(name), update);
}
// ---------------------------------------------------------------------------
// Parsed action config (Task 3.2)
// ---------------------------------------------------------------------------
export async function fetchParsedAction(name: string): Promise<ActionConfig> {
return get<ActionConfig>(ENDPOINTS.configActionParsed(name));
}
export async function updateParsedAction(
name: string,
update: ActionConfigUpdate
): Promise<void> {
await put<undefined>(ENDPOINTS.configActionParsed(name), update);
}
// ---------------------------------------------------------------------------
// Parsed jail file config (Task 6.1 / 6.2)
// ---------------------------------------------------------------------------
export async function fetchParsedJailFile(filename: string): Promise<JailFileConfig> {
return get<JailFileConfig>(ENDPOINTS.configJailFileParsed(filename));
}
export async function updateParsedJailFile(
filename: string,
update: JailFileConfigUpdate
): Promise<void> {
await put<undefined>(ENDPOINTS.configJailFileParsed(filename), update);
}

View File

@@ -76,10 +76,16 @@ export const ENDPOINTS = {
`/config/jail-files/${encodeURIComponent(filename)}`,
configJailFileEnabled: (filename: string): string =>
`/config/jail-files/${encodeURIComponent(filename)}/enabled`,
configJailFileParsed: (filename: string): string =>
`/config/jail-files/${encodeURIComponent(filename)}/parsed`,
configFilters: "/config/filters",
configFilter: (name: string): string => `/config/filters/${encodeURIComponent(name)}`,
configFilterParsed: (name: string): string =>
`/config/filters/${encodeURIComponent(name)}/parsed`,
configActions: "/config/actions",
configAction: (name: string): string => `/config/actions/${encodeURIComponent(name)}`,
configActionParsed: (name: string): string =>
`/config/actions/${encodeURIComponent(name)}/parsed`,
// -------------------------------------------------------------------------
// Server settings

View File

@@ -242,3 +242,141 @@ export interface ConfFileCreateRequest {
name: string;
content: string;
}
// ---------------------------------------------------------------------------
// Parsed filter config (Task 2.1 / 2.2)
// ---------------------------------------------------------------------------
/**
* Structured representation of a ``filter.d/*.conf`` file.
* Maps 1-to-1 with the backend ``FilterConfig`` Pydantic model.
*/
export interface FilterConfig {
/** Base name without extension, e.g. "sshd". */
name: string;
/** Actual filename, e.g. "sshd.conf". */
filename: string;
/** [INCLUDES] before directive, or null. */
before: string | null;
/** [INCLUDES] after directive, or null. */
after: string | null;
/** [DEFAULT] section key-value pairs (e.g. _daemon, __prefix). */
variables: Record<string, string>;
/** prefregex line, or null. */
prefregex: string | null;
/** failregex patterns (one per entry). */
failregex: string[];
/** ignoreregex patterns (one per entry). */
ignoreregex: string[];
/** maxlines, or null. */
maxlines: number | null;
/** datepattern, or null. */
datepattern: string | null;
/** journalmatch, or null. */
journalmatch: string | null;
}
/**
* Partial update payload for a filter config.
* All fields are optional; ``null`` means leave unchanged.
*/
export interface FilterConfigUpdate {
before?: string | null;
after?: string | null;
variables?: Record<string, string> | null;
prefregex?: string | null;
failregex?: string[] | null;
ignoreregex?: string[] | null;
maxlines?: number | null;
datepattern?: string | null;
journalmatch?: string | null;
}
// ---------------------------------------------------------------------------
// Parsed action config (Task 3.1 / 3.2)
// ---------------------------------------------------------------------------
/**
* Structured representation of an ``action.d/*.conf`` file.
* Maps 1-to-1 with the backend ``ActionConfig`` Pydantic model.
*/
export interface ActionConfig {
/** Base name without extension, e.g. "iptables". */
name: string;
/** Actual filename, e.g. "iptables.conf". */
filename: string;
/** [INCLUDES] before directive, or null. */
before: string | null;
/** [INCLUDES] after directive, or null. */
after: string | null;
/** actionstart command, or null. */
actionstart: string | null;
/** actionstop command, or null. */
actionstop: string | null;
/** actioncheck command, or null. */
actioncheck: string | null;
/** actionban command, or null. */
actionban: string | null;
/** actionunban command, or null. */
actionunban: string | null;
/** actionflush command, or null. */
actionflush: string | null;
/** [Definition] key-value pairs that are not lifecycle commands. */
definition_vars: Record<string, string>;
/** [Init] section key-value pairs. */
init_vars: Record<string, string>;
}
/**
* Partial update payload for an action config.
* All fields are optional; ``null`` means leave unchanged.
*/
export interface ActionConfigUpdate {
before?: string | null;
after?: string | null;
actionstart?: string | null;
actionstop?: string | null;
actioncheck?: string | null;
actionban?: string | null;
actionunban?: string | null;
actionflush?: string | null;
definition_vars?: Record<string, string> | null;
init_vars?: Record<string, string> | null;
}
// ---------------------------------------------------------------------------
// Parsed jail file config (Task 6.1 / 6.2)
// ---------------------------------------------------------------------------
/**
* Settings within a single [jailname] section of a jail.d/*.conf file.
* Maps 1-to-1 with the backend ``JailSectionConfig`` Pydantic model.
*/
export interface JailSectionConfig {
enabled: boolean | null;
port: string | null;
filter: string | null;
logpath: string[];
maxretry: number | null;
findtime: number | null;
bantime: number | null;
action: string[];
backend: string | null;
extra: Record<string, string>;
}
/**
* Structured representation of a ``jail.d/*.conf`` file.
* Maps 1-to-1 with the backend ``JailFileConfig`` Pydantic model.
*/
export interface JailFileConfig {
filename: string;
jails: Record<string, JailSectionConfig>;
}
/**
* Partial update payload for a jail file config.
*/
export interface JailFileConfigUpdate {
jails?: Record<string, JailSectionConfig> | null;
}