174b7e8d24
- 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
191 lines
5.2 KiB
TypeScript
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;
|
|
}
|
|
|