This commit is contained in:
Baobhan Sith
2025-04-26 20:04:01 +08:00
parent e025c4f7a1
commit 38248cfc1d
14 changed files with 149 additions and 115 deletions
-2
View File
@@ -26,8 +26,6 @@
"CONNECTION_UPDATED": "Connection Updated",
"CONNECTION_DELETED": "Connection Deleted",
"CONNECTION_TESTED": "Connection Tested",
"CONNECTIONS_IMPORTED": "Connections Imported",
"CONNECTIONS_EXPORTED": "Connections Exported",
"PROXY_CREATED": "Proxy Created",
"PROXY_UPDATED": "Proxy Updated",
"PROXY_DELETED": "Proxy Deleted",
-2
View File
@@ -26,8 +26,6 @@
"CONNECTION_UPDATED": "接続を更新しました",
"CONNECTION_DELETED": "接続を削除しました",
"CONNECTION_TESTED": "接続をテストしました",
"CONNECTIONS_IMPORTED": "接続をインポートしました",
"CONNECTIONS_EXPORTED": "接続をエクスポートしました",
"PROXY_CREATED": "プロキシを作成しました",
"PROXY_UPDATED": "プロキシを更新しました",
"PROXY_DELETED": "プロキシを削除しました",
-2
View File
@@ -12,8 +12,6 @@
"CONNECTION_UPDATED": "连接已更新",
"CONNECTION_DELETED": "连接已删除",
"CONNECTION_TESTED": "连接已测试",
"CONNECTIONS_IMPORTED": "连接已导入",
"CONNECTIONS_EXPORTED": "连接已导出",
"PROXY_CREATED": "代理已创建",
"PROXY_UPDATED": "代理已更新",
"PROXY_DELETED": "代理已删除",
@@ -1,8 +1,9 @@
import { Request, Response } from 'express';
import { NotificationSettingsRepository } from '../repositories/notification.repository'; // Use repository
import { NotificationSetting, NotificationChannelType, NotificationChannelConfig, WebhookConfig, EmailConfig, TelegramConfig, NotificationEvent } from '../types/notification.types';
import { AuditLogService } from '../services/audit.service'; // Keep for now if other parts use it
// import { AuditLogService } from '../services/audit.service'; // Keep for now if other parts use it - Removed as eventService is used
import { AppEventType, default as eventService } from '../services/event.service'; // Import event service
import i18next from '../i18n'; // Import the i18next instance
// Remove sender imports as they are no longer called directly for testing
// import telegramSenderService from '../services/senders/telegram.sender.service';
@@ -12,7 +13,7 @@ import { AppEventType, default as eventService } from '../services/event.service
// Removed escapeTelegramMarkdownV2 helper function
const auditLogService = new AuditLogService(); // Keep for now if other parts use it, but prefer eventService
// const auditLogService = new AuditLogService(); // Removed as eventService is used
export class NotificationController {
private repository: NotificationSettingsRepository; // Use repository
@@ -27,18 +28,20 @@ export class NotificationController {
const settings = await this.repository.getAll(); // Use repository
res.status(200).json(settings);
} catch (error: any) {
res.status(500).json({ message: '获取通知设置失败', error: error.message });
}
};
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorFetchSettings'), error: error.message });
}
};
// POST /api/v1/notifications
create = async (req: Request, res: Response): Promise<void> => {
const settingData: Omit<NotificationSetting, 'id' | 'created_at' | 'updated_at'> = req.body;
if (!settingData.channel_type || !settingData.name || !settingData.config) {
res.status(400).json({ message: '缺少必要的通知设置字段 (channel_type, name, config)' });
return;
}
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorMissingFields') });
return;
}
try {
const newSettingId = await this.repository.create(settingData); // Use repository
@@ -52,9 +55,10 @@ export class NotificationController {
}
res.status(201).json(newSetting);
} catch (error: any) {
res.status(500).json({ message: '创建通知设置失败', error: error.message });
}
};
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorCreateSetting'), error: error.message });
}
};
// PUT /api/v1/notifications/:id
update = async (req: Request, res: Response): Promise<void> => {
@@ -62,13 +66,15 @@ export class NotificationController {
const settingData: Partial<Omit<NotificationSetting, 'id' | 'created_at' | 'updated_at'>> = req.body;
if (isNaN(id)) {
res.status(400).json({ message: '无效的通知设置 ID' });
return;
}
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorInvalidId') });
return;
}
if (Object.keys(settingData).length === 0) {
res.status(400).json({ message: '没有提供要更新的数据' });
return;
}
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorNoUpdateData') });
return;
}
try {
const success = await this.repository.update(id, settingData); // Use repository
@@ -81,28 +87,32 @@ export class NotificationController {
});
res.status(200).json(updatedSetting);
} else {
res.status(404).json({ message: `未找到 ID 为 ${id} 的通知设置` });
}
} catch (error: any) {
res.status(500).json({ message: '更新通知设置失败', error: error.message });
}
};
// Use i18next.t for i18n with interpolation
res.status(404).json({ message: i18next.t('notificationController.errorNotFound', { id }) });
}
} catch (error: any) {
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorUpdateSetting'), error: error.message });
}
};
// DELETE /api/v1/notifications/:id
delete = async (req: Request, res: Response): Promise<void> => {
const id = parseInt(req.params.id, 10);
if (isNaN(id)) {
res.status(400).json({ message: '无效的通知设置 ID' });
return;
}
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorInvalidId') });
return;
}
try {
const settingToDelete = await this.repository.getById(id); // Get details before deleting for audit log
if (!settingToDelete) {
res.status(404).json({ message: `未找到 ID 为 ${id} 的通知设置` });
return;
}
// Use i18next.t for i18n with interpolation
res.status(404).json({ message: i18next.t('notificationController.errorNotFound', { id }) });
return;
}
const success = await this.repository.delete(id); // Use repository
if (success) {
// 记录审计日志 (Use event service)
@@ -112,13 +122,15 @@ export class NotificationController {
});
res.status(204).send(); // No Content
} else {
// Should not happen if getById succeeded, but handle defensively
res.status(404).json({ message: `删除 ID 为 ${id} 的通知设置失败,可能已被删除` });
}
} catch (error: any) {
res.status(500).json({ message: '删除通知设置失败', error: error.message });
}
};
// Should not happen if getById succeeded, but handle defensively
// Use i18next.t for i18n with interpolation
res.status(404).json({ message: i18next.t('notificationController.errorDeleteNotFound', { id }) });
}
} catch (error: any) {
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorDeleteSetting'), error: error.message });
}
};
// --- Refactored Test Endpoints ---
@@ -130,68 +142,78 @@ export class NotificationController {
const id = parseInt(req.params.id, 10);
if (isNaN(id)) {
res.status(400).json({ message: '无效的通知设置 ID' });
return;
}
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorInvalidId') });
return;
}
try {
const settingToTest = await this.repository.getById(id);
if (!settingToTest) {
res.status(404).json({ message: `未找到 ID 为 ${id} 的通知设置` });
return;
}
// Use i18next.t for i18n with interpolation
res.status(404).json({ message: i18next.t('notificationController.errorNotFound', { id }) });
return;
}
// Trigger the standard test event, passing the config to be used by the processor
eventService.emitEvent(AppEventType.TestNotification, {
userId: (req.session as any).userId, // Optional: associate test with user
details: {
message: `为设置 ID ${id} (${settingToTest.name}) 触发的测试`,
testTargetConfig: settingToTest.config, // Pass the config to use
testTargetChannelType: settingToTest.channel_type // Pass the channel type
details: {
// Use i18next.t for i18n with interpolation
message: i18next.t('notificationController.testMessageSaved', { id, name: settingToTest.name }),
testTargetConfig: settingToTest.config, // Pass the config to use
testTargetChannelType: settingToTest.channel_type // Pass the channel type
}
});
// Respond immediately confirming the event was triggered
res.status(200).json({ message: '测试通知事件已触发。请检查对应渠道的接收情况。' });
// Respond immediately confirming the event was triggered
// Use i18next.t for i18n
res.status(200).json({ message: i18next.t('notificationController.testEventTriggered') });
} catch (error: any) {
console.error(`[NotificationController] Error triggering test for setting ${id}:`, error);
res.status(500).json({ message: '触发测试通知时发生内部错误', error: error.message });
}
};
} catch (error: any) {
console.error(`[NotificationController] Error triggering test for setting ${id}:`, error);
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorTriggerTest'), error: error.message });
}
};
// POST /api/v1/notifications/test-unsaved
// Tests configuration data provided in the request body by triggering a test event
testUnsavedSetting = async (req: Request, res: Response): Promise<void> => {
const { channel_type, config } = req.body as { channel_type: NotificationChannelType, config: NotificationChannelConfig };
if (!channel_type || !config) {
res.status(400).json({ message: '缺少必要的测试信息 (channel_type, config)' });
return;
}
if (!channel_type || !config) {
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorMissingTestInfo') });
return;
}
if (!['webhook', 'email', 'telegram'].includes(channel_type)) {
res.status(400).json({ message: '无效的渠道类型' });
return;
}
if (!['webhook', 'email', 'telegram'].includes(channel_type)) {
// Use i18next.t for i18n
res.status(400).json({ message: i18next.t('notificationController.errorInvalidChannelType') });
return;
}
try {
// Trigger the standard test event, passing the unsaved config to be used by the processor
eventService.emitEvent(AppEventType.TestNotification, {
userId: (req.session as any).userId,
details: {
message: `为未保存的 ${channel_type} 配置触发的测试`,
testTargetConfig: config, // Pass the unsaved config to use
testTargetChannelType: channel_type // Pass the channel type
details: {
// Use i18next.t for i18n with interpolation
message: i18next.t('notificationController.testMessageUnsaved', { channelType: channel_type }),
testTargetConfig: config, // Pass the unsaved config to use
testTargetChannelType: channel_type // Pass the channel type
}
});
// Respond immediately confirming the event was triggered
res.status(200).json({ message: '测试通知事件已触发。请检查对应渠道的接收情况。' });
// Respond immediately confirming the event was triggered
// Use i18next.t for i18n
res.status(200).json({ message: i18next.t('notificationController.testEventTriggered') });
} catch (error: any) {
console.error(`[NotificationController] Error triggering test for unsaved ${channel_type}:`, error);
res.status(500).json({ message: '触发测试通知时发生内部错误', error: error.message });
}
};
} catch (error: any) {
console.error(`[NotificationController] Error triggering test for unsaved ${channel_type}:`, error);
// Use i18next.t for i18n
res.status(500).json({ message: i18next.t('notificationController.errorTriggerTest'), error: error.message });
}
};
} // End of class NotificationController
@@ -16,8 +16,6 @@ export enum AppEventType {
ConnectionUpdated = 'CONNECTION_UPDATED',
ConnectionDeleted = 'CONNECTION_DELETED',
ConnectionTested = 'CONNECTION_TESTED',
ConnectionsImported = 'CONNECTIONS_IMPORTED',
ConnectionsExported = 'CONNECTIONS_EXPORTED',
ProxyCreated = 'PROXY_CREATED',
ProxyUpdated = 'PROXY_UPDATED',
ProxyDeleted = 'PROXY_DELETED',
@@ -15,8 +15,6 @@ export type AuditLogActionType =
| 'CONNECTION_UPDATED'
| 'CONNECTION_DELETED'
| 'CONNECTION_TESTED'
| 'CONNECTIONS_IMPORTED'
| 'CONNECTIONS_EXPORTED'
// Proxies
| 'PROXY_CREATED'
@@ -39,9 +37,6 @@ export type AuditLogActionType =
| 'NOTIFICATION_SETTING_UPDATED'
| 'NOTIFICATION_SETTING_DELETED'
// API Keys (Removed from audit log types)
// | 'API_KEY_CREATED'
// | 'API_KEY_DELETED'
// SFTP (Consider logging specific actions if needed, e.g., UPLOAD, DOWNLOAD, DELETE_FILE)
| 'SFTP_ACTION' // Generic SFTP action for now
@@ -5,7 +5,6 @@ export type NotificationEvent =
| 'LOGIN_SUCCESS' | 'LOGIN_FAILURE' | 'LOGOUT' | 'PASSWORD_CHANGED'
| '2FA_ENABLED' | '2FA_DISABLED' | 'PASSKEY_REGISTERED' | 'PASSKEY_DELETED'
| 'CONNECTION_CREATED' | 'CONNECTION_UPDATED' | 'CONNECTION_DELETED' | 'CONNECTION_TESTED'
| 'CONNECTIONS_IMPORTED' | 'CONNECTIONS_EXPORTED'
| 'PROXY_CREATED' | 'PROXY_UPDATED' | 'PROXY_DELETED'
| 'TAG_CREATED' | 'TAG_UPDATED' | 'TAG_DELETED'
| 'SETTINGS_UPDATED' | 'IP_WHITELIST_UPDATED' | 'IP_BLOCKED'
@@ -272,7 +272,6 @@ const allNotificationEvents: NotificationEvent[] = [
'LOGIN_SUCCESS', 'LOGIN_FAILURE', 'LOGOUT', 'PASSWORD_CHANGED', // Added LOGOUT, PASSWORD_CHANGED
'2FA_ENABLED', '2FA_DISABLED', 'PASSKEY_REGISTERED', 'PASSKEY_DELETED', // Added 2FA, changed PASSKEY_ADDED
'CONNECTION_CREATED', 'CONNECTION_UPDATED', 'CONNECTION_DELETED', 'CONNECTION_TESTED', // Changed _ADDED, added _TESTED
'CONNECTIONS_IMPORTED', 'CONNECTIONS_EXPORTED', // Added IMPORT/EXPORT
'PROXY_CREATED', 'PROXY_UPDATED', 'PROXY_DELETED', // Changed _ADDED
'TAG_CREATED', 'TAG_UPDATED', 'TAG_DELETED', // Changed _ADDED
'SETTINGS_UPDATED', 'IP_WHITELIST_UPDATED', // Added IP_WHITELIST_UPDATED
@@ -487,9 +486,10 @@ const handleTestNotification = async () => {
// Test unsaved setting
result = await store.testUnsavedSetting(formData.channel_type, testConfig);
}
testResult.value = { success: true, message: result.message || t('settings.notifications.form.testSuccess') };
} catch (error: any) {
console.error("Test notification error:", error);
// Translate the message received from the backend using t()
testResult.value = { success: true, message: t(result.message || 'settings.notifications.form.testSuccess') };
} catch (error: any) {
console.error("Test notification error:", error);
const message = error?.response?.data?.message || error.message || t('settings.notifications.form.testFailed');
testResult.value = { success: false, message: message };
// Optionally set testError if you want a separate display area for errors vs results
+17 -6
View File
@@ -502,8 +502,6 @@
"CONNECTION_UPDATED": "Connection Updated",
"CONNECTION_DELETED": "Connection Deleted",
"CONNECTION_TESTED": "Connection Tested",
"CONNECTIONS_IMPORTED": "Connections Imported",
"CONNECTIONS_EXPORTED": "Connections Exported",
"PROXY_CREATED": "Proxy Created",
"PROXY_UPDATED": "Proxy Updated",
"PROXY_DELETED": "Proxy Deleted",
@@ -644,6 +642,23 @@
}
}
},
"notificationController": {
"errorFetchSettings": "Failed to fetch notification settings",
"errorMissingFields": "Missing required notification setting fields (channel_type, name, config)",
"errorCreateSetting": "Failed to create notification setting",
"errorInvalidId": "Invalid notification setting ID",
"errorNoUpdateData": "No data provided for update",
"errorNotFound": "Notification setting with ID {id} not found",
"errorUpdateSetting": "Failed to update notification setting",
"errorDeleteNotFound": "Failed to delete notification setting with ID {id}, it might have already been deleted",
"errorDeleteSetting": "Failed to delete notification setting",
"testMessageSaved": "Test triggered for setting ID {id} ({name})",
"testEventTriggered": "Test notification event triggered. Please check the corresponding channel for reception.",
"errorTriggerTest": "Internal error occurred while triggering test notification",
"errorMissingTestInfo": "Missing required test information (channel_type, config)",
"errorInvalidChannelType": "Invalid channel type",
"testMessageUnsaved": "Test triggered for unsaved {channelType} configuration"
},
"common": {
"loading": "Loading...",
"cancel": "Cancel",
@@ -711,8 +726,6 @@
"CONNECTION_UPDATED": "Connection Updated",
"CONNECTION_DELETED": "Connection Deleted",
"CONNECTION_TESTED": "Connection Tested",
"CONNECTIONS_IMPORTED": "Connections Imported",
"CONNECTIONS_EXPORTED": "Connections Exported",
"PROXY_CREATED": "Proxy Created",
"PROXY_UPDATED": "Proxy Updated",
"PROXY_DELETED": "Proxy Deleted",
@@ -724,8 +737,6 @@
"NOTIFICATION_SETTING_CREATED": "Notification Setting Created",
"NOTIFICATION_SETTING_UPDATED": "Notification Setting Updated",
"NOTIFICATION_SETTING_DELETED": "Notification Setting Deleted",
"API_KEY_CREATED": "API Key Created",
"API_KEY_DELETED": "API Key Deleted",
"SFTP_ACTION": "SFTP Action",
"SSH_CONNECT_SUCCESS": "SSH Connection Successful",
"SSH_CONNECT_FAILURE": "SSH Connection Failed",
+17 -6
View File
@@ -502,8 +502,6 @@
"CONNECTION_UPDATED": "接続更新",
"CONNECTION_DELETED": "接続削除",
"CONNECTION_TESTED": "接続テスト",
"CONNECTIONS_IMPORTED": "接続インポート",
"CONNECTIONS_EXPORTED": "接続エクスポート",
"PROXY_CREATED": "プロキシ作成",
"PROXY_UPDATED": "プロキシ更新",
"PROXY_DELETED": "プロキシ削除",
@@ -644,6 +642,23 @@
}
}
},
"notificationController": {
"errorFetchSettings": "通知設定の取得に失敗しました",
"errorMissingFields": "必須の通知設定フィールドが不足しています (channel_type, name, config)",
"errorCreateSetting": "通知設定の作成に失敗しました",
"errorInvalidId": "無効な通知設定 ID",
"errorNoUpdateData": "更新するデータが提供されていません",
"errorNotFound": "ID {id} の通知設定が見つかりません",
"errorUpdateSetting": "通知設定の更新に失敗しました",
"errorDeleteNotFound": "ID {id} の通知設定の削除に失敗しました。すでに削除されている可能性があります",
"errorDeleteSetting": "通知設定の削除に失敗しました",
"testMessageSaved": "設定 ID {id} ({name}) のテストがトリガーされました",
"testEventTriggered": "テスト通知イベントがトリガーされました。対応するチャネルで受信を確認してください。",
"errorTriggerTest": "テスト通知のトリガー中に内部エラーが発生しました",
"errorMissingTestInfo": "必須のテスト情報が不足しています (channel_type, config)",
"errorInvalidChannelType": "無効なチャネルタイプ",
"testMessageUnsaved": "未保存の {channelType} 設定のテストがトリガーされました"
},
"common": {
"loading": "ロード中...",
"cancel": "キャンセル",
@@ -713,8 +728,6 @@
"CONNECTION_UPDATED": "接続更新",
"CONNECTION_DELETED": "接続削除",
"CONNECTION_TESTED": "接続テスト",
"CONNECTIONS_IMPORTED": "接続インポート",
"CONNECTIONS_EXPORTED": "接続エクスポート",
"PROXY_CREATED": "プロキシ作成",
"PROXY_UPDATED": "プロキシ更新",
"PROXY_DELETED": "プロキシ削除",
@@ -726,8 +739,6 @@
"NOTIFICATION_SETTING_CREATED": "通知設定作成",
"NOTIFICATION_SETTING_UPDATED": "通知設定更新",
"NOTIFICATION_SETTING_DELETED": "通知設定削除",
"API_KEY_CREATED": "APIキー作成",
"API_KEY_DELETED": "APIキー削除",
"SFTP_ACTION": "SFTP 操作",
"SSH_CONNECT_SUCCESS": "SSH 接続成功",
"SSH_CONNECT_FAILURE": "SSH 接続失敗",
+17 -6
View File
@@ -501,8 +501,6 @@
"CONNECTION_CREATED": "连接已创建",
"CONNECTION_UPDATED": "连接已更新",
"CONNECTION_DELETED": "连接已删除",
"CONNECTION_TESTED": "连接已测试",
"CONNECTIONS_IMPORTED": "连接已导入",
"CONNECTIONS_EXPORTED": "连接已导出",
"PROXY_CREATED": "代理已创建",
"PROXY_UPDATED": "代理已更新",
@@ -644,6 +642,23 @@
}
}
},
"notificationController": {
"errorFetchSettings": "获取通知设置失败",
"errorMissingFields": "缺少必要的通知设置字段 (channel_type, name, config)",
"errorCreateSetting": "创建通知设置失败",
"errorInvalidId": "无效的通知设置 ID",
"errorNoUpdateData": "没有提供要更新的数据",
"errorNotFound": "未找到 ID 为 {id} 的通知设置",
"errorUpdateSetting": "更新通知设置失败",
"errorDeleteNotFound": "删除 ID 为 {id} 的通知设置失败,可能已被删除",
"errorDeleteSetting": "删除通知设置失败",
"testMessageSaved": "为设置 ID {id} ({name}) 触发的测试",
"testEventTriggered": "测试通知事件已触发。请检查对应渠道的接收情况。",
"errorTriggerTest": "触发测试通知时发生内部错误",
"errorMissingTestInfo": "缺少必要的测试信息 (channel_type, config)",
"errorInvalidChannelType": "无效的渠道类型",
"testMessageUnsaved": "为未保存的 {channelType} 配置触发的测试"
},
"common": {
"loading": "加载中...",
"cancel": "取消",
@@ -713,8 +728,6 @@
"CONNECTION_UPDATED": "连接已更新",
"CONNECTION_DELETED": "连接已删除",
"CONNECTION_TESTED": "连接已测试",
"CONNECTIONS_IMPORTED": "连接已导入",
"CONNECTIONS_EXPORTED": "连接已导出",
"PROXY_CREATED": "代理已创建",
"PROXY_UPDATED": "代理已更新",
"PROXY_DELETED": "代理已删除",
@@ -726,8 +739,6 @@
"NOTIFICATION_SETTING_CREATED": "通知设置已创建",
"NOTIFICATION_SETTING_UPDATED": "通知设置已更新",
"NOTIFICATION_SETTING_DELETED": "通知设置已删除",
"API_KEY_CREATED": "API 密钥已创建",
"API_KEY_DELETED": "API 密钥已删除",
"SFTP_ACTION": "SFTP 操作",
"SSH_CONNECT_SUCCESS": "SSH 连接成功",
"SSH_CONNECT_FAILURE": "SSH 连接失败",
@@ -16,8 +16,6 @@ export type AuditLogActionType =
| 'CONNECTION_UPDATED'
| 'CONNECTION_DELETED'
| 'CONNECTION_TESTED'
| 'CONNECTIONS_IMPORTED'
| 'CONNECTIONS_EXPORTED'
// Proxies
| 'PROXY_CREATED'
| 'PROXY_UPDATED'
@@ -23,7 +23,6 @@ export type NotificationEvent =
| 'LOGIN_SUCCESS' | 'LOGIN_FAILURE' | 'LOGOUT' | 'PASSWORD_CHANGED'
| '2FA_ENABLED' | '2FA_DISABLED' | 'PASSKEY_REGISTERED' | 'PASSKEY_DELETED'
| 'CONNECTION_CREATED' | 'CONNECTION_UPDATED' | 'CONNECTION_DELETED' | 'CONNECTION_TESTED'
| 'CONNECTIONS_IMPORTED' | 'CONNECTIONS_EXPORTED'
| 'PROXY_CREATED' | 'PROXY_UPDATED' | 'PROXY_DELETED'
| 'TAG_CREATED' | 'TAG_UPDATED' | 'TAG_DELETED'
| 'SETTINGS_UPDATED' | 'IP_WHITELIST_UPDATED'
@@ -78,12 +77,10 @@ export type AuditLogActionType =
| 'LOGIN_SUCCESS' | 'LOGIN_FAILURE' | 'LOGOUT' | 'PASSWORD_CHANGED'
| '2FA_ENABLED' | '2FA_DISABLED' | 'PASSKEY_REGISTERED' | 'PASSKEY_DELETED'
| 'CONNECTION_CREATED' | 'CONNECTION_UPDATED' | 'CONNECTION_DELETED' | 'CONNECTION_TESTED'
| 'CONNECTIONS_IMPORTED' | 'CONNECTIONS_EXPORTED'
| 'PROXY_CREATED' | 'PROXY_UPDATED' | 'PROXY_DELETED'
| 'TAG_CREATED' | 'TAG_UPDATED' | 'TAG_DELETED'
| 'SETTINGS_UPDATED' | 'IP_WHITELIST_UPDATED'
| 'NOTIFICATION_SETTING_CREATED' | 'NOTIFICATION_SETTING_UPDATED' | 'NOTIFICATION_SETTING_DELETED'
// | 'API_KEY_CREATED' | 'API_KEY_DELETED' // Removed API Key types
| 'SFTP_ACTION'
// SSH Actions
| 'SSH_CONNECT_SUCCESS' | 'SSH_CONNECT_FAILURE' | 'SSH_SHELL_FAILURE'
@@ -120,12 +120,10 @@ const allActionTypes: AuditLogActionType[] = [
'LOGIN_SUCCESS', 'LOGIN_FAILURE', 'LOGOUT', 'PASSWORD_CHANGED',
'2FA_ENABLED', '2FA_DISABLED', 'PASSKEY_REGISTERED', 'PASSKEY_DELETED',
'CONNECTION_CREATED', 'CONNECTION_UPDATED', 'CONNECTION_DELETED', 'CONNECTION_TESTED',
'CONNECTIONS_IMPORTED', 'CONNECTIONS_EXPORTED',
'PROXY_CREATED', 'PROXY_UPDATED', 'PROXY_DELETED',
'TAG_CREATED', 'TAG_UPDATED', 'TAG_DELETED',
'SETTINGS_UPDATED', 'IP_WHITELIST_UPDATED',
'NOTIFICATION_SETTING_CREATED', 'NOTIFICATION_SETTING_UPDATED', 'NOTIFICATION_SETTING_DELETED',
// 'API_KEY_CREATED', 'API_KEY_DELETED', // Removed API Key types from dropdown
'SFTP_ACTION',
// SSH Actions
'SSH_CONNECT_SUCCESS', 'SSH_CONNECT_FAILURE', 'SSH_SHELL_FAILURE',