import * as plugins from '../plugins.js'; import * as interfaces from '../../ts_interfaces/index.js'; import { appState } from './shared.js'; import { getActionContext } from './login.js'; // ============================================================================ // SMTP Accounts State // ============================================================================ export interface ISmtpAccountsState { accounts: interfaces.data.ISmtpAccountInfo[]; isLoading: boolean; error: string | null; lastUpdated: number; } export const smtpAccountsStatePart = await appState.getStatePart( 'smtpAccounts', { accounts: [], isLoading: false, error: null, lastUpdated: 0, }, 'soft', ); export const fetchSmtpAccountsAction = smtpAccountsStatePart.createAction( async (statePartArg): Promise => { const context = getActionContext(); const currentState = statePartArg.getState()!; if (!context.identity) return currentState; try { const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_GetSmtpAccounts >('/typedrequest', 'getSmtpAccounts'); const response = await request.fire({ identity: context.identity }); return { ...statePartArg.getState()!, accounts: response.accounts, isLoading: false, error: null, lastUpdated: Date.now(), }; } catch (error: unknown) { return { ...statePartArg.getState()!, isLoading: false, error: error instanceof Error ? error.message : 'Failed to fetch SMTP accounts', }; } }, ); export const toggleSmtpAccountAction = smtpAccountsStatePart.createAction<{ id: string; enabled: boolean; }>(async (statePartArg, dataArg, actionContext): Promise => { const context = getActionContext(); const currentState = statePartArg.getState()!; try { const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_ToggleSmtpAccount >('/typedrequest', 'toggleSmtpAccount'); const response = await request.fire({ identity: context.identity!, id: dataArg.id, enabled: dataArg.enabled, }); if (!response.success) { return { ...currentState, error: response.message || 'Failed to toggle SMTP account' }; } return await actionContext!.dispatch(fetchSmtpAccountsAction, null); } catch (error: unknown) { return { ...currentState, error: error instanceof Error ? error.message : 'Failed to toggle SMTP account', }; } }); export const deleteSmtpAccountAction = smtpAccountsStatePart.createAction( async (statePartArg, id, actionContext): Promise => { const context = getActionContext(); const currentState = statePartArg.getState()!; try { const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_DeleteSmtpAccount >('/typedrequest', 'deleteSmtpAccount'); const response = await request.fire({ identity: context.identity!, id }); if (!response.success) { return { ...currentState, error: response.message || 'Failed to delete SMTP account' }; } return await actionContext!.dispatch(fetchSmtpAccountsAction, null); } catch (error: unknown) { return { ...currentState, error: error instanceof Error ? error.message : 'Failed to delete SMTP account', }; } }, ); // ============================================================================ // Secret-returning calls — standalone functions, deliberately NOT actions: // the one-time password must never enter (persisted) app state. // ============================================================================ export async function createSmtpAccount(options: { username: string; description?: string; senderScope?: interfaces.data.ISmtpAccountSenderScope; recipientScope?: interfaces.data.ISmtpAccountRecipientScope; mailPolicy?: interfaces.data.ISmtpAccountMailPolicy; }) { const context = getActionContext(); const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_CreateSmtpAccount >('/typedrequest', 'createSmtpAccount'); return request.fire({ identity: context.identity!, ...options }); } export async function rotateSmtpAccountPassword(id: string) { const context = getActionContext(); const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_RotateSmtpAccountPassword >('/typedrequest', 'rotateSmtpAccountPassword'); return request.fire({ identity: context.identity!, id }); } export async function updateSmtpAccount(options: { id: string; description?: string; senderScope?: interfaces.data.ISmtpAccountSenderScope; recipientScope?: interfaces.data.ISmtpAccountRecipientScope; mailPolicy?: interfaces.data.ISmtpAccountMailPolicy; }) { const context = getActionContext(); const request = new plugins.domtools.plugins.typedrequest.TypedRequest< interfaces.requests.IReq_UpdateSmtpAccount >('/typedrequest', 'updateSmtpAccount'); return request.fire({ identity: context.identity!, ...options }); }