Files
Aegis/frontend/src/api/settings.ts
T
kitos 174b7e8d24 fix(jira): always return HTTP 200 from jira-test + strip trailing slash
- jira-test now returns {status: "ok"|"error", message: ...} with
  HTTP 200 so Cloudflare never intercepts the response
- jira_service strips trailing slash from URL before creating Jira
  client (avoids double-slash in REST paths)
- Frontend reads data.status field instead of HTTP status code
2026-05-26 17:42:12 +02:00

191 lines
5.2 KiB
TypeScript

import client from "./client";
// ---------------------------------------------------------------------------
// Email / SMTP config (admin only)
// ---------------------------------------------------------------------------
export interface EmailConfigOut {
enabled: boolean;
host: string;
port: number;
username: string;
from_email: string;
use_tls: boolean;
}
export interface EmailConfigUpdate {
enabled?: boolean;
host?: string;
port?: number;
username?: string;
password?: string;
from_email?: string;
use_tls?: boolean;
}
export async function getEmailConfig(): Promise<EmailConfigOut> {
const { data } = await client.get<EmailConfigOut>("/system/email-config");
return data;
}
export async function updateEmailConfig(payload: EmailConfigUpdate): Promise<EmailConfigOut> {
const { data } = await client.patch<EmailConfigOut>("/system/email-config", payload);
return data;
}
export async function sendTestEmail(to: string): Promise<{ detail: string }> {
const { data } = await client.post<{ detail: string }>("/system/email-test", { to });
return data;
}
// ---------------------------------------------------------------------------
// Webhook config (admin + leads)
// ---------------------------------------------------------------------------
export interface WebhookOut {
id: string;
name: string;
url: string;
secret: string | null;
events: string[];
is_active: boolean;
created_at: string | null;
last_triggered_at: string | null;
failure_count: number;
}
export interface WebhookCreate {
name: string;
url: string;
secret?: string;
events: string[];
is_active?: boolean;
}
export interface WebhookUpdate {
name?: string;
url?: string;
secret?: string;
events?: string[];
is_active?: boolean;
}
export async function getWebhooks(): Promise<WebhookOut[]> {
const { data } = await client.get<WebhookOut[]>("/webhooks");
return data;
}
export async function createWebhook(payload: WebhookCreate): Promise<WebhookOut> {
const { data } = await client.post<WebhookOut>("/webhooks", payload);
return data;
}
export async function updateWebhook(id: string, payload: WebhookUpdate): Promise<WebhookOut> {
const { data } = await client.patch<WebhookOut>(`/webhooks/${id}`, payload);
return data;
}
export async function deleteWebhook(id: string): Promise<void> {
await client.delete(`/webhooks/${id}`);
}
export async function testWebhook(id: string): Promise<{ detail: string }> {
const { data } = await client.post<{ detail: string }>(`/webhooks/${id}/test`);
return data;
}
// ---------------------------------------------------------------------------
// User preferences (all users)
// ---------------------------------------------------------------------------
export interface NotificationPreferences {
// Universal
email_on_test_validated: boolean;
email_on_test_rejected: boolean;
email_on_campaign_completed: boolean;
email_on_new_mitre_techniques: boolean;
email_on_stale_coverage: boolean;
in_app_all: boolean;
// Tech + leads
email_on_assigned_to_campaign?: boolean;
email_on_test_state_change?: boolean;
// Leads only
email_on_all_team_validations?: boolean;
email_on_webhook_failures?: boolean;
// Admin only
email_on_new_users?: boolean;
email_on_system_errors?: boolean;
}
export interface UserPreferencesUpdate {
notification_preferences?: Partial<NotificationPreferences>;
jira_account_id?: string | null;
jira_api_token?: string | null;
/** Atlassian email used for Jira auth. Overrides Aegis account email. Empty string clears it. */
jira_email?: string | null;
}
export interface UserMeOut {
id: string;
username: string;
email: string | null;
role: string;
is_active: boolean;
must_change_password: boolean;
created_at: string | null;
last_login: string | null;
notification_preferences: NotificationPreferences | null;
jira_account_id: string | null;
jira_email: string | null;
jira_token_set: boolean;
}
export async function getMe(): Promise<UserMeOut> {
const { data } = await client.get<UserMeOut>("/users/me");
return data;
}
export async function updateMyPreferences(payload: UserPreferencesUpdate): Promise<UserMeOut> {
const { data } = await client.patch<UserMeOut>("/users/me/preferences", payload);
return data;
}
// ---------------------------------------------------------------------------
// Jira system config (admin only)
// ---------------------------------------------------------------------------
export interface JiraConfigOut {
enabled: boolean;
url: string;
project_key: string;
parent_ticket: string;
}
export interface JiraConfigUpdate {
enabled?: boolean;
url?: string;
project_key?: string;
parent_ticket?: string;
}
export async function getJiraConfig(): Promise<JiraConfigOut> {
const { data } = await client.get<JiraConfigOut>("/system/jira-config");
return data;
}
export async function updateJiraConfig(payload: JiraConfigUpdate): Promise<JiraConfigOut> {
const { data } = await client.patch<JiraConfigOut>("/system/jira-config", payload);
return data;
}
export async function testJiraConnection(): Promise<{
status: "ok" | "error";
connected_as?: string;
jira_url?: string;
message?: string;
}> {
const { data } = await client.post("/system/jira-test");
return data;
}