Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
230 lines
6.0 KiB
TypeScript
230 lines
6.0 KiB
TypeScript
// Email provider interfaces for inbound email processing
|
|
|
|
export interface EmailProviderConfig {
|
|
id: string;
|
|
tenant: string;
|
|
name: string;
|
|
provider_type: 'microsoft' | 'google' | 'imap';
|
|
mailbox: string;
|
|
folder_to_monitor: string; // Defaults to 'Inbox'
|
|
active: boolean;
|
|
// Common webhook fields as real columns
|
|
webhook_notification_url: string;
|
|
webhook_subscription_id?: string;
|
|
webhook_verification_token?: string;
|
|
webhook_expires_at?: string; // ISO date
|
|
last_subscription_renewal?: string; // ISO date
|
|
// Connection status fields
|
|
connection_status: 'connected' | 'disconnected' | 'error';
|
|
last_connection_test?: string; // ISO date
|
|
connection_error_message?: string;
|
|
// Provider-specific configuration (OAuth scopes, etc.)
|
|
provider_config?: {
|
|
// Microsoft-specific
|
|
tenantId?: string;
|
|
scopes?: string[];
|
|
// Google-specific (camelCase for interface compatibility)
|
|
projectId?: string;
|
|
pubsubTopic?: string;
|
|
// Common OAuth settings
|
|
clientId?: string; // Usually from environment, but could be per-provider
|
|
|
|
// Database field names (snake_case) - for Gmail adapter compatibility
|
|
project_id?: string;
|
|
pubsub_topic_name?: string;
|
|
pubsub_subscription_name?: string;
|
|
client_id?: string;
|
|
client_secret?: string;
|
|
access_token?: string;
|
|
refresh_token?: string;
|
|
token_expires_at?: string;
|
|
history_id?: string;
|
|
watch_expiration?: string;
|
|
customScopes?: string[];
|
|
// Gmail-specific processing configuration
|
|
label_filters?: string[]; // names of labels to include (user-defined)
|
|
auto_process_emails?: boolean;
|
|
max_emails_per_sync?: number;
|
|
|
|
// IMAP-specific configuration
|
|
host?: string;
|
|
port?: number;
|
|
secure?: boolean;
|
|
allow_starttls?: boolean;
|
|
auth_type?: 'password' | 'oauth2';
|
|
username?: string;
|
|
password?: string;
|
|
folder_filters?: string[];
|
|
oauth_authorize_url?: string;
|
|
oauth_token_url?: string;
|
|
oauth_client_id?: string;
|
|
oauth_client_secret?: string;
|
|
oauth_scopes?: string;
|
|
// Note: access_token, refresh_token, token_expires_at are defined above (shared with Gmail OAuth)
|
|
uid_validity?: string;
|
|
last_uid?: string;
|
|
folder_state?: Record<string, { uid_validity?: string; last_uid?: string; last_seen_at?: string }>;
|
|
last_processed_message_id?: string;
|
|
server_capabilities?: string;
|
|
lease_owner?: string;
|
|
lease_expires_at?: string;
|
|
connection_timeout_ms?: number;
|
|
socket_keepalive?: boolean;
|
|
last_seen_at?: string;
|
|
last_sync_at?: string;
|
|
last_error?: string;
|
|
};
|
|
created_at: string; // ISO date
|
|
updated_at: string; // ISO date
|
|
}
|
|
|
|
export interface EmailIngressSkipReason {
|
|
type: 'attachment' | 'raw_mime';
|
|
reason:
|
|
| 'attachment_over_max_bytes'
|
|
| 'attachment_count_exceeded'
|
|
| 'attachment_total_bytes_exceeded'
|
|
| 'raw_mime_over_max_bytes';
|
|
attachmentId?: string;
|
|
attachmentName?: string;
|
|
size: number;
|
|
cap: number;
|
|
}
|
|
|
|
export interface EmailMessage {
|
|
id: string;
|
|
provider: 'microsoft' | 'google' | 'imap';
|
|
providerId: string;
|
|
tenant: string;
|
|
receivedAt: string;
|
|
from: {
|
|
email: string;
|
|
name?: string;
|
|
};
|
|
to: Array<{
|
|
email: string;
|
|
name?: string;
|
|
}>;
|
|
cc?: Array<{
|
|
email: string;
|
|
name?: string;
|
|
}>;
|
|
subject: string;
|
|
body: {
|
|
text: string;
|
|
html?: string;
|
|
};
|
|
attachments?: Array<{
|
|
id: string;
|
|
name: string;
|
|
contentType: string;
|
|
size: number;
|
|
contentId?: string;
|
|
isInline?: boolean;
|
|
content?: string;
|
|
}>;
|
|
threadId?: string;
|
|
references?: string[];
|
|
inReplyTo?: string;
|
|
rawMime?: string;
|
|
rawMimeBase64?: string;
|
|
sourceMimeBase64?: string;
|
|
rawSourceBase64?: string;
|
|
ingressSkipReasons?: EmailIngressSkipReason[];
|
|
}
|
|
|
|
export interface EmailMessageDetails extends EmailMessage {
|
|
// Additional details that might be available when fetching full message
|
|
headers?: Record<string, string>;
|
|
messageSize?: number;
|
|
importance?: 'low' | 'normal' | 'high';
|
|
sensitivity?: 'normal' | 'personal' | 'private' | 'confidential';
|
|
}
|
|
|
|
export interface InboundEmailEvent {
|
|
event_type: 'INBOUND_EMAIL_RECEIVED';
|
|
payload: {
|
|
emailId: string;
|
|
tenant: string;
|
|
providerId: string;
|
|
emailData: EmailMessage;
|
|
matchedClient?: {
|
|
clientId: string;
|
|
clientName: string;
|
|
contactId?: string;
|
|
contactName?: string;
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface EmailConnectionStatus {
|
|
connected: boolean;
|
|
status: 'connected' | 'disconnected' | 'error';
|
|
clientName?: string;
|
|
providerId?: string;
|
|
errorMessage?: string;
|
|
lastConnectionTest?: string;
|
|
}
|
|
|
|
export type UnifiedInboundEmailProvider = 'microsoft' | 'google' | 'imap';
|
|
|
|
export interface UnifiedInboundQueueJobBase {
|
|
jobId: string;
|
|
schemaVersion: 1;
|
|
tenantId: string;
|
|
providerId: string;
|
|
provider: UnifiedInboundEmailProvider;
|
|
enqueuedAt: string;
|
|
attempt: number;
|
|
maxAttempts: number;
|
|
}
|
|
|
|
export interface MicrosoftInboundEmailPointer {
|
|
subscriptionId: string;
|
|
messageId: string;
|
|
resource?: string;
|
|
changeType?: string;
|
|
}
|
|
|
|
export interface GoogleInboundEmailPointer {
|
|
historyId: string;
|
|
emailAddress: string;
|
|
pubsubMessageId?: string;
|
|
discoveredMessageIds?: string[];
|
|
}
|
|
|
|
export interface ImapInboundEmailPointer {
|
|
mailbox: string;
|
|
uid: string;
|
|
uidValidity?: string;
|
|
messageId?: string;
|
|
}
|
|
|
|
export type UnifiedInboundEmailQueueJob =
|
|
| (UnifiedInboundQueueJobBase & {
|
|
provider: 'microsoft';
|
|
pointer: MicrosoftInboundEmailPointer;
|
|
})
|
|
| (UnifiedInboundQueueJobBase & {
|
|
provider: 'google';
|
|
pointer: GoogleInboundEmailPointer;
|
|
})
|
|
| (UnifiedInboundQueueJobBase & {
|
|
provider: 'imap';
|
|
pointer: ImapInboundEmailPointer;
|
|
});
|
|
|
|
export interface EmailQueueJob {
|
|
id: string;
|
|
tenant: string;
|
|
provider: 'microsoft' | 'google' | 'imap' | 'mailhog-test-provider';
|
|
messageId: string;
|
|
providerId: string;
|
|
webhookData: any;
|
|
attempt: number;
|
|
maxRetries: number;
|
|
createdAt: string;
|
|
// Optional email data for cases where we already have the email content (e.g., MailHog)
|
|
emailData?: EmailMessage;
|
|
}
|