@consilioweb/payload-support 4.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -35
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/TicketConversation/RewriteDropdown.js +1 -1
- package/dist/components/TicketConversation/components/AISummaryPanel.js +3 -0
- package/dist/components/TicketConversation/components/ActionPanels.js +13 -8
- package/dist/components/TicketConversation/components/ClientHistory.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlock.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlockInserter.js +1 -1
- package/dist/components/TicketConversation/components/QuickActions.js +10 -8
- package/dist/components/TicketConversation/components/TicketHeader.js +2 -0
- package/dist/components/TicketConversation/components/TimeTrackingPanel.js +15 -9
- package/dist/components/TicketConversation/index.d.ts +10 -0
- package/dist/components/TicketConversation/index.js +25 -7
- package/dist/index.cjs +421 -73
- package/dist/index.d.cts +127 -38
- package/dist/index.d.ts +127 -38
- package/dist/index.js +415 -72
- package/dist/styles/BillingView.module.scss +11 -11
- package/dist/styles/ChatView.module.scss +7 -7
- package/dist/styles/CommandPalette.module.scss +1 -1
- package/dist/styles/CrmView.module.scss +9 -9
- package/dist/styles/EmailTracking.module.scss +6 -6
- package/dist/styles/ImportConversation.module.scss +5 -5
- package/dist/styles/Logs.module.scss +5 -5
- package/dist/styles/NewTicket.module.scss +2 -2
- package/dist/styles/PendingEmails.module.scss +13 -13
- package/dist/styles/SupportDashboard.module.scss +24 -8
- package/dist/styles/TicketDetail.module.scss +20 -20
- package/dist/styles/TicketInbox.module.scss +6 -6
- package/dist/styles/TicketingSettings.module.scss +10 -10
- package/dist/styles/TimeDashboard.module.scss +6 -6
- package/dist/styles/_tokens.scss +3 -1
- package/dist/utils/db.d.ts +34 -0
- package/dist/utils/readSettings.d.ts +90 -0
- package/dist/views/BillingView/client.js +15 -8
- package/dist/views/BillingView/index.js +4 -4
- package/dist/views/ChatView/client.js +2 -0
- package/dist/views/ChatView/index.js +4 -4
- package/dist/views/CrmView/client.js +2 -0
- package/dist/views/CrmView/index.js +4 -4
- package/dist/views/EmailTrackingView/client.js +23 -11
- package/dist/views/EmailTrackingView/index.js +4 -4
- package/dist/views/ImportConversationView/client.js +1 -0
- package/dist/views/ImportConversationView/index.js +4 -4
- package/dist/views/LogsView/client.js +1 -1
- package/dist/views/LogsView/index.js +4 -2
- package/dist/views/NewTicketView/client.js +20 -13
- package/dist/views/NewTicketView/index.js +4 -2
- package/dist/views/PendingEmailsView/client.js +9 -3
- package/dist/views/PendingEmailsView/index.js +4 -4
- package/dist/views/SupportDashboardView/client.js +17 -19
- package/dist/views/SupportDashboardView/index.js +4 -4
- package/dist/views/TicketDetailView/client.js +23 -11
- package/dist/views/TicketDetailView/index.js +4 -4
- package/dist/views/TicketInboxView/client.js +52 -26
- package/dist/views/TicketInboxView/index.js +4 -2
- package/dist/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/dist/views/TicketingSettingsView/client.js +44 -26
- package/dist/views/TicketingSettingsView/index.js +4 -4
- package/dist/views/TimeDashboardView/client.js +10 -7
- package/dist/views/TimeDashboardView/index.js +4 -4
- package/dist/views/shared/ErrorBoundary.d.ts +36 -1
- package/dist/views/shared/ErrorBoundary.js +59 -28
- package/dist/views/shared/adminTokens.d.ts +15 -5
- package/dist/views/shared/adminTokens.js +23 -7
- package/dist/views/shared/icons.d.ts +49 -0
- package/dist/views/shared/icons.js +92 -0
- package/dist/views/shared/locales/en.json +15 -1
- package/dist/views/shared/locales/fr.json +15 -1
- package/dist/views/shared/viewAccess.d.ts +29 -0
- package/dist/views/shared/viewAccess.js +24 -0
- package/package.json +31 -21
- package/scripts/uninstall-data.mjs +178 -0
- package/scripts/uninstall.mjs +184 -0
- package/src/collections/Tickets.ts +7 -0
- package/src/collections/TimeEntries.ts +11 -3
- package/src/components/RichTextEditor/index.tsx +1 -1
- package/src/components/TicketConversation/RewriteDropdown.tsx +1 -1
- package/src/components/TicketConversation/components/AISummaryPanel.tsx +3 -0
- package/src/components/TicketConversation/components/ActionPanels.tsx +13 -8
- package/src/components/TicketConversation/components/ClientHistory.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlock.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlockInserter.tsx +1 -1
- package/src/components/TicketConversation/components/QuickActions.tsx +10 -8
- package/src/components/TicketConversation/components/TicketHeader.tsx +2 -0
- package/src/components/TicketConversation/components/TimeTrackingPanel.tsx +17 -9
- package/src/components/TicketConversation/index.tsx +41 -7
- package/src/endpoints/auth-2fa.ts +53 -8
- package/src/endpoints/capabilities.ts +2 -4
- package/src/endpoints/chatbot.ts +2 -2
- package/src/endpoints/delete-account.ts +191 -47
- package/src/endpoints/export-data.ts +104 -4
- package/src/endpoints/import-conversation.ts +2 -2
- package/src/endpoints/login.ts +13 -3
- package/src/endpoints/purge-logs.ts +6 -15
- package/src/endpoints/push.ts +14 -1
- package/src/endpoints/statuses.ts +17 -0
- package/src/index.ts +2 -0
- package/src/plugin.ts +51 -1
- package/src/portal/LiveChat.tsx +1 -1
- package/src/portal/auth/profile/page.tsx +3 -2
- package/src/portal/icons.tsx +91 -0
- package/src/portal/login/page.tsx +14 -4
- package/src/styles/BillingView.module.scss +11 -11
- package/src/styles/ChatView.module.scss +7 -7
- package/src/styles/CommandPalette.module.scss +1 -1
- package/src/styles/CrmView.module.scss +9 -9
- package/src/styles/EmailTracking.module.scss +6 -6
- package/src/styles/ImportConversation.module.scss +5 -5
- package/src/styles/Logs.module.scss +5 -5
- package/src/styles/NewTicket.module.scss +2 -2
- package/src/styles/PendingEmails.module.scss +13 -13
- package/src/styles/SupportDashboard.module.scss +24 -8
- package/src/styles/TicketDetail.module.scss +20 -20
- package/src/styles/TicketInbox.module.scss +6 -6
- package/src/styles/TicketingSettings.module.scss +10 -10
- package/src/styles/TimeDashboard.module.scss +6 -6
- package/src/styles/_tokens.scss +3 -1
- package/src/types.ts +20 -0
- package/src/utils/push.ts +22 -0
- package/src/utils/rateLimiter.ts +98 -0
- package/src/utils/retention.ts +111 -0
- package/src/utils/slugs.ts +15 -0
- package/src/utils/twoFactorChallenge.ts +6 -1
- package/src/utils/urlSafety.ts +36 -1
- package/src/views/BillingView/client.tsx +17 -8
- package/src/views/BillingView/index.tsx +4 -4
- package/src/views/ChatView/client.tsx +2 -0
- package/src/views/ChatView/index.tsx +4 -4
- package/src/views/CrmView/client.tsx +2 -0
- package/src/views/CrmView/index.tsx +4 -4
- package/src/views/EmailTrackingView/client.tsx +18 -7
- package/src/views/EmailTrackingView/index.tsx +4 -4
- package/src/views/ImportConversationView/client.tsx +1 -0
- package/src/views/ImportConversationView/index.tsx +4 -4
- package/src/views/LogsView/client.tsx +1 -1
- package/src/views/LogsView/index.tsx +4 -2
- package/src/views/NewTicketView/client.tsx +22 -13
- package/src/views/NewTicketView/index.tsx +4 -2
- package/src/views/PendingEmailsView/client.tsx +9 -3
- package/src/views/PendingEmailsView/index.tsx +4 -4
- package/src/views/SupportDashboardView/client.tsx +11 -5
- package/src/views/SupportDashboardView/index.tsx +4 -4
- package/src/views/TicketDetailView/client.tsx +25 -11
- package/src/views/TicketDetailView/index.tsx +4 -4
- package/src/views/TicketInboxView/client.tsx +47 -7
- package/src/views/TicketInboxView/index.tsx +4 -2
- package/src/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/src/views/TicketingSettingsView/client.tsx +201 -144
- package/src/views/TicketingSettingsView/index.tsx +4 -4
- package/src/views/TimeDashboardView/client.tsx +10 -7
- package/src/views/TimeDashboardView/index.tsx +4 -4
- package/src/views/shared/ErrorBoundary.tsx +95 -31
- package/src/views/shared/adminTokens.ts +28 -11
- package/src/views/shared/icons.tsx +146 -0
- package/src/views/shared/locales/en.json +15 -1
- package/src/views/shared/locales/fr.json +15 -1
- package/src/views/shared/viewAccess.ts +73 -0
- package/src/types/lucide-react.d.ts +0 -42
package/dist/index.d.cts
CHANGED
|
@@ -11,9 +11,29 @@ interface RateLimitStore {
|
|
|
11
11
|
/**
|
|
12
12
|
* Process-local fallback store. Applications running more than one process
|
|
13
13
|
* should provide a persistent RateLimitStore through the plugin options.
|
|
14
|
+
*
|
|
15
|
+
* BOUNDED, because the keys come from anonymous HTTP traffic: `/support/login`
|
|
16
|
+
* and `/support/chatbot` key their limiter on the client IP, and the IP is read
|
|
17
|
+
* from `x-forwarded-for`. A caller rotating that header wrote one PERMANENT
|
|
18
|
+
* entry per value into a map that had no ceiling, no expiry sweep and no
|
|
19
|
+
* eviction — only `reset()` ever removed anything, and the login path never
|
|
20
|
+
* calls it. Worse, every fresh key opened a fresh window, so the limiter did
|
|
21
|
+
* not even slow down the flood that was exhausting it.
|
|
22
|
+
*
|
|
23
|
+
* Two independent bounds, the same pair `endpoints/typing.ts` already applies
|
|
24
|
+
* to its own module-level map: `clientIpRateKey` caps the SIZE of a key, the
|
|
25
|
+
* ceiling below caps their NUMBER.
|
|
14
26
|
*/
|
|
15
27
|
declare class MemoryRateLimitStore implements RateLimitStore {
|
|
28
|
+
private readonly maxKeys;
|
|
16
29
|
private readonly entries;
|
|
30
|
+
constructor(maxKeys?: number);
|
|
31
|
+
/** Distinct keys currently held. Exposed so the ceiling can be asserted. */
|
|
32
|
+
get size(): number;
|
|
33
|
+
/** Reclaims every window that has already closed. */
|
|
34
|
+
private sweepExpired;
|
|
35
|
+
/** Soonest-closing window first, so the ceiling drops the least useful entry. */
|
|
36
|
+
private evictOldest;
|
|
17
37
|
increment(key: string, windowMs: number): Promise<RateLimitEntry>;
|
|
18
38
|
reset(key: string): Promise<void>;
|
|
19
39
|
}
|
|
@@ -45,6 +65,94 @@ declare class RateLimiter {
|
|
|
45
65
|
reset(key: string, context?: unknown): Promise<void>;
|
|
46
66
|
}
|
|
47
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Default collection slugs used by the support plugin.
|
|
70
|
+
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
71
|
+
*/
|
|
72
|
+
interface CollectionSlugs {
|
|
73
|
+
tickets: string;
|
|
74
|
+
ticketMessages: string;
|
|
75
|
+
supportClients: string;
|
|
76
|
+
timeEntries: string;
|
|
77
|
+
cannedResponses: string;
|
|
78
|
+
ticketActivityLog: string;
|
|
79
|
+
satisfactionSurveys: string;
|
|
80
|
+
knowledgeBase: string;
|
|
81
|
+
chatMessages: string;
|
|
82
|
+
pendingEmails: string;
|
|
83
|
+
emailLogs: string;
|
|
84
|
+
authLogs: string;
|
|
85
|
+
webhookEndpoints: string;
|
|
86
|
+
slaPolicies: string;
|
|
87
|
+
macros: string;
|
|
88
|
+
ticketStatuses: string;
|
|
89
|
+
ticketFeedback: string;
|
|
90
|
+
notificationQueue: string;
|
|
91
|
+
automationRules: string;
|
|
92
|
+
supportTeams: string;
|
|
93
|
+
pushSubscriptions: string;
|
|
94
|
+
rateLimits: string;
|
|
95
|
+
counters: string;
|
|
96
|
+
users: string;
|
|
97
|
+
media: string;
|
|
98
|
+
}
|
|
99
|
+
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve collection slugs merging user overrides with defaults.
|
|
102
|
+
*/
|
|
103
|
+
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* How long the two journals are kept, in days.
|
|
107
|
+
*
|
|
108
|
+
* Defaults follow the CNIL guidance the README documents: six months would be
|
|
109
|
+
* the floor for connection logs, a year is the ceiling usually accepted, and
|
|
110
|
+
* these two values sit inside that range while staying long enough to
|
|
111
|
+
* investigate an intrusion. Set a value to 0 to disable the automatic purge of
|
|
112
|
+
* that journal — never to mean "delete everything", which is what `days=0`
|
|
113
|
+
* means on the manual endpoint.
|
|
114
|
+
*/
|
|
115
|
+
interface RetentionConfig {
|
|
116
|
+
/** Retention of `auth-logs` in days. `0` disables the scheduled purge. */
|
|
117
|
+
authLogsDays?: number;
|
|
118
|
+
/** Retention of `email-logs` in days. `0` disables the scheduled purge. */
|
|
119
|
+
emailLogsDays?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Cron for the scheduled purge. Payload's cron takes an optional leading
|
|
122
|
+
* seconds field. Default: every day at 03:30.
|
|
123
|
+
*/
|
|
124
|
+
cron?: string;
|
|
125
|
+
/** Queue the scheduled job is pushed to. Default: `default`. */
|
|
126
|
+
queue?: string;
|
|
127
|
+
}
|
|
128
|
+
declare const DEFAULT_RETENTION: {
|
|
129
|
+
readonly authLogsDays: 180;
|
|
130
|
+
readonly emailLogsDays: 365;
|
|
131
|
+
readonly cron: "0 30 3 * * *";
|
|
132
|
+
readonly queue: "default";
|
|
133
|
+
};
|
|
134
|
+
declare const PURGE_LOGS_TASK_SLUG = "support-purge-logs";
|
|
135
|
+
/** Journals the purge is allowed to touch, keyed by their public name. */
|
|
136
|
+
declare function purgeableCollections(slugs: CollectionSlugs): Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* Delete rows of `slug` created more than `days` days ago.
|
|
139
|
+
*
|
|
140
|
+
* `days <= 0` means "everything" and is only reachable from the manual
|
|
141
|
+
* admin-only endpoint. The scheduled task refuses it: a misconfigured cron
|
|
142
|
+
* that wipes the whole security journal every night is a far worse outcome
|
|
143
|
+
* than a journal that grows.
|
|
144
|
+
*/
|
|
145
|
+
declare function purgeOlderThan(payload: Payload, slug: string, days: number, req?: PayloadRequest): Promise<number>;
|
|
146
|
+
interface ScheduledPurgeResult {
|
|
147
|
+
purged: Record<string, number>;
|
|
148
|
+
skipped: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The scheduled half of the purge. Never accepts `days <= 0`, and silently
|
|
152
|
+
* skips a journal whose collection is not registered (its feature flag is off).
|
|
153
|
+
*/
|
|
154
|
+
declare function runScheduledPurge(payload: Payload, slugs: CollectionSlugs, retention: RetentionConfig | false | undefined, req?: PayloadRequest): Promise<ScheduledPurgeResult>;
|
|
155
|
+
|
|
48
156
|
interface InboundEmailLimits {
|
|
49
157
|
maxRequestBytes: number;
|
|
50
158
|
maxAttachmentBytes: number;
|
|
@@ -208,6 +316,24 @@ interface SupportPluginConfig {
|
|
|
208
316
|
email?: EmailConfig;
|
|
209
317
|
/** Shared rate-limit storage. Defaults to process-local memory. */
|
|
210
318
|
rateLimitStore?: RateLimitStore | 'payload';
|
|
319
|
+
/**
|
|
320
|
+
* Automatic retention of the two journals the plugin writes.
|
|
321
|
+
*
|
|
322
|
+
* The plugin registers a daily Payload Jobs task that deletes rows older
|
|
323
|
+
* than the configured number of days. Set a value to 0 to keep that journal
|
|
324
|
+
* forever (the manual `DELETE /api/support/purge-logs` endpoint stays
|
|
325
|
+
* available either way).
|
|
326
|
+
*
|
|
327
|
+
* Defaults: auth-logs 180 days, email-logs 365 days, cron `0 30 3 * * *`.
|
|
328
|
+
*
|
|
329
|
+
* `false` registers no task at all. That is the ONLY value that changes the
|
|
330
|
+
* schema footprint: registering a task turns Payload's job queue on, which
|
|
331
|
+
* adds the `payload-jobs` collection and the `payload-jobs-stats` global to
|
|
332
|
+
* an app that had no jobs — two tables you would have to migrate. Pass
|
|
333
|
+
* `false` if you would rather purge from your own cron, calling
|
|
334
|
+
* `DELETE /api/support/purge-logs`.
|
|
335
|
+
*/
|
|
336
|
+
retention?: RetentionConfig | false;
|
|
211
337
|
/** Sequential ticket number formatting. */
|
|
212
338
|
ticketNumber?: {
|
|
213
339
|
prefix?: string;
|
|
@@ -356,43 +482,6 @@ declare const DEFAULT_FEATURES: Required<SupportFeatures>;
|
|
|
356
482
|
*/
|
|
357
483
|
declare function supportPlugin(config?: SupportPluginConfig): Plugin;
|
|
358
484
|
|
|
359
|
-
/**
|
|
360
|
-
* Default collection slugs used by the support plugin.
|
|
361
|
-
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
362
|
-
*/
|
|
363
|
-
interface CollectionSlugs {
|
|
364
|
-
tickets: string;
|
|
365
|
-
ticketMessages: string;
|
|
366
|
-
supportClients: string;
|
|
367
|
-
timeEntries: string;
|
|
368
|
-
cannedResponses: string;
|
|
369
|
-
ticketActivityLog: string;
|
|
370
|
-
satisfactionSurveys: string;
|
|
371
|
-
knowledgeBase: string;
|
|
372
|
-
chatMessages: string;
|
|
373
|
-
pendingEmails: string;
|
|
374
|
-
emailLogs: string;
|
|
375
|
-
authLogs: string;
|
|
376
|
-
webhookEndpoints: string;
|
|
377
|
-
slaPolicies: string;
|
|
378
|
-
macros: string;
|
|
379
|
-
ticketStatuses: string;
|
|
380
|
-
ticketFeedback: string;
|
|
381
|
-
notificationQueue: string;
|
|
382
|
-
automationRules: string;
|
|
383
|
-
supportTeams: string;
|
|
384
|
-
pushSubscriptions: string;
|
|
385
|
-
rateLimits: string;
|
|
386
|
-
counters: string;
|
|
387
|
-
users: string;
|
|
388
|
-
media: string;
|
|
389
|
-
}
|
|
390
|
-
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
391
|
-
/**
|
|
392
|
-
* Resolve collection slugs merging user overrides with defaults.
|
|
393
|
-
*/
|
|
394
|
-
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
395
|
-
|
|
396
485
|
/**
|
|
397
486
|
* Ticketing feature flags — single source of truth (client + server).
|
|
398
487
|
*
|
|
@@ -690,4 +779,4 @@ declare function createTicketStatusesCollection(slugs: CollectionSlugs): Collect
|
|
|
690
779
|
*/
|
|
691
780
|
declare function createTicketCollaboratorsCollection(slugs: CollectionSlugs): CollectionConfig;
|
|
692
781
|
|
|
693
|
-
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type SatisfactionSurveyData, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
|
782
|
+
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_RETENTION, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PURGE_LOGS_TASK_SLUG, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type RetentionConfig, type SatisfactionSurveyData, type ScheduledPurgeResult, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, purgeOlderThan, purgeableCollections, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, runScheduledPurge, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,9 +11,29 @@ interface RateLimitStore {
|
|
|
11
11
|
/**
|
|
12
12
|
* Process-local fallback store. Applications running more than one process
|
|
13
13
|
* should provide a persistent RateLimitStore through the plugin options.
|
|
14
|
+
*
|
|
15
|
+
* BOUNDED, because the keys come from anonymous HTTP traffic: `/support/login`
|
|
16
|
+
* and `/support/chatbot` key their limiter on the client IP, and the IP is read
|
|
17
|
+
* from `x-forwarded-for`. A caller rotating that header wrote one PERMANENT
|
|
18
|
+
* entry per value into a map that had no ceiling, no expiry sweep and no
|
|
19
|
+
* eviction — only `reset()` ever removed anything, and the login path never
|
|
20
|
+
* calls it. Worse, every fresh key opened a fresh window, so the limiter did
|
|
21
|
+
* not even slow down the flood that was exhausting it.
|
|
22
|
+
*
|
|
23
|
+
* Two independent bounds, the same pair `endpoints/typing.ts` already applies
|
|
24
|
+
* to its own module-level map: `clientIpRateKey` caps the SIZE of a key, the
|
|
25
|
+
* ceiling below caps their NUMBER.
|
|
14
26
|
*/
|
|
15
27
|
declare class MemoryRateLimitStore implements RateLimitStore {
|
|
28
|
+
private readonly maxKeys;
|
|
16
29
|
private readonly entries;
|
|
30
|
+
constructor(maxKeys?: number);
|
|
31
|
+
/** Distinct keys currently held. Exposed so the ceiling can be asserted. */
|
|
32
|
+
get size(): number;
|
|
33
|
+
/** Reclaims every window that has already closed. */
|
|
34
|
+
private sweepExpired;
|
|
35
|
+
/** Soonest-closing window first, so the ceiling drops the least useful entry. */
|
|
36
|
+
private evictOldest;
|
|
17
37
|
increment(key: string, windowMs: number): Promise<RateLimitEntry>;
|
|
18
38
|
reset(key: string): Promise<void>;
|
|
19
39
|
}
|
|
@@ -45,6 +65,94 @@ declare class RateLimiter {
|
|
|
45
65
|
reset(key: string, context?: unknown): Promise<void>;
|
|
46
66
|
}
|
|
47
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Default collection slugs used by the support plugin.
|
|
70
|
+
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
71
|
+
*/
|
|
72
|
+
interface CollectionSlugs {
|
|
73
|
+
tickets: string;
|
|
74
|
+
ticketMessages: string;
|
|
75
|
+
supportClients: string;
|
|
76
|
+
timeEntries: string;
|
|
77
|
+
cannedResponses: string;
|
|
78
|
+
ticketActivityLog: string;
|
|
79
|
+
satisfactionSurveys: string;
|
|
80
|
+
knowledgeBase: string;
|
|
81
|
+
chatMessages: string;
|
|
82
|
+
pendingEmails: string;
|
|
83
|
+
emailLogs: string;
|
|
84
|
+
authLogs: string;
|
|
85
|
+
webhookEndpoints: string;
|
|
86
|
+
slaPolicies: string;
|
|
87
|
+
macros: string;
|
|
88
|
+
ticketStatuses: string;
|
|
89
|
+
ticketFeedback: string;
|
|
90
|
+
notificationQueue: string;
|
|
91
|
+
automationRules: string;
|
|
92
|
+
supportTeams: string;
|
|
93
|
+
pushSubscriptions: string;
|
|
94
|
+
rateLimits: string;
|
|
95
|
+
counters: string;
|
|
96
|
+
users: string;
|
|
97
|
+
media: string;
|
|
98
|
+
}
|
|
99
|
+
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve collection slugs merging user overrides with defaults.
|
|
102
|
+
*/
|
|
103
|
+
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* How long the two journals are kept, in days.
|
|
107
|
+
*
|
|
108
|
+
* Defaults follow the CNIL guidance the README documents: six months would be
|
|
109
|
+
* the floor for connection logs, a year is the ceiling usually accepted, and
|
|
110
|
+
* these two values sit inside that range while staying long enough to
|
|
111
|
+
* investigate an intrusion. Set a value to 0 to disable the automatic purge of
|
|
112
|
+
* that journal — never to mean "delete everything", which is what `days=0`
|
|
113
|
+
* means on the manual endpoint.
|
|
114
|
+
*/
|
|
115
|
+
interface RetentionConfig {
|
|
116
|
+
/** Retention of `auth-logs` in days. `0` disables the scheduled purge. */
|
|
117
|
+
authLogsDays?: number;
|
|
118
|
+
/** Retention of `email-logs` in days. `0` disables the scheduled purge. */
|
|
119
|
+
emailLogsDays?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Cron for the scheduled purge. Payload's cron takes an optional leading
|
|
122
|
+
* seconds field. Default: every day at 03:30.
|
|
123
|
+
*/
|
|
124
|
+
cron?: string;
|
|
125
|
+
/** Queue the scheduled job is pushed to. Default: `default`. */
|
|
126
|
+
queue?: string;
|
|
127
|
+
}
|
|
128
|
+
declare const DEFAULT_RETENTION: {
|
|
129
|
+
readonly authLogsDays: 180;
|
|
130
|
+
readonly emailLogsDays: 365;
|
|
131
|
+
readonly cron: "0 30 3 * * *";
|
|
132
|
+
readonly queue: "default";
|
|
133
|
+
};
|
|
134
|
+
declare const PURGE_LOGS_TASK_SLUG = "support-purge-logs";
|
|
135
|
+
/** Journals the purge is allowed to touch, keyed by their public name. */
|
|
136
|
+
declare function purgeableCollections(slugs: CollectionSlugs): Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* Delete rows of `slug` created more than `days` days ago.
|
|
139
|
+
*
|
|
140
|
+
* `days <= 0` means "everything" and is only reachable from the manual
|
|
141
|
+
* admin-only endpoint. The scheduled task refuses it: a misconfigured cron
|
|
142
|
+
* that wipes the whole security journal every night is a far worse outcome
|
|
143
|
+
* than a journal that grows.
|
|
144
|
+
*/
|
|
145
|
+
declare function purgeOlderThan(payload: Payload, slug: string, days: number, req?: PayloadRequest): Promise<number>;
|
|
146
|
+
interface ScheduledPurgeResult {
|
|
147
|
+
purged: Record<string, number>;
|
|
148
|
+
skipped: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The scheduled half of the purge. Never accepts `days <= 0`, and silently
|
|
152
|
+
* skips a journal whose collection is not registered (its feature flag is off).
|
|
153
|
+
*/
|
|
154
|
+
declare function runScheduledPurge(payload: Payload, slugs: CollectionSlugs, retention: RetentionConfig | false | undefined, req?: PayloadRequest): Promise<ScheduledPurgeResult>;
|
|
155
|
+
|
|
48
156
|
interface InboundEmailLimits {
|
|
49
157
|
maxRequestBytes: number;
|
|
50
158
|
maxAttachmentBytes: number;
|
|
@@ -208,6 +316,24 @@ interface SupportPluginConfig {
|
|
|
208
316
|
email?: EmailConfig;
|
|
209
317
|
/** Shared rate-limit storage. Defaults to process-local memory. */
|
|
210
318
|
rateLimitStore?: RateLimitStore | 'payload';
|
|
319
|
+
/**
|
|
320
|
+
* Automatic retention of the two journals the plugin writes.
|
|
321
|
+
*
|
|
322
|
+
* The plugin registers a daily Payload Jobs task that deletes rows older
|
|
323
|
+
* than the configured number of days. Set a value to 0 to keep that journal
|
|
324
|
+
* forever (the manual `DELETE /api/support/purge-logs` endpoint stays
|
|
325
|
+
* available either way).
|
|
326
|
+
*
|
|
327
|
+
* Defaults: auth-logs 180 days, email-logs 365 days, cron `0 30 3 * * *`.
|
|
328
|
+
*
|
|
329
|
+
* `false` registers no task at all. That is the ONLY value that changes the
|
|
330
|
+
* schema footprint: registering a task turns Payload's job queue on, which
|
|
331
|
+
* adds the `payload-jobs` collection and the `payload-jobs-stats` global to
|
|
332
|
+
* an app that had no jobs — two tables you would have to migrate. Pass
|
|
333
|
+
* `false` if you would rather purge from your own cron, calling
|
|
334
|
+
* `DELETE /api/support/purge-logs`.
|
|
335
|
+
*/
|
|
336
|
+
retention?: RetentionConfig | false;
|
|
211
337
|
/** Sequential ticket number formatting. */
|
|
212
338
|
ticketNumber?: {
|
|
213
339
|
prefix?: string;
|
|
@@ -356,43 +482,6 @@ declare const DEFAULT_FEATURES: Required<SupportFeatures>;
|
|
|
356
482
|
*/
|
|
357
483
|
declare function supportPlugin(config?: SupportPluginConfig): Plugin;
|
|
358
484
|
|
|
359
|
-
/**
|
|
360
|
-
* Default collection slugs used by the support plugin.
|
|
361
|
-
* All slugs can be overridden via SupportPluginConfig.collectionSlugs.
|
|
362
|
-
*/
|
|
363
|
-
interface CollectionSlugs {
|
|
364
|
-
tickets: string;
|
|
365
|
-
ticketMessages: string;
|
|
366
|
-
supportClients: string;
|
|
367
|
-
timeEntries: string;
|
|
368
|
-
cannedResponses: string;
|
|
369
|
-
ticketActivityLog: string;
|
|
370
|
-
satisfactionSurveys: string;
|
|
371
|
-
knowledgeBase: string;
|
|
372
|
-
chatMessages: string;
|
|
373
|
-
pendingEmails: string;
|
|
374
|
-
emailLogs: string;
|
|
375
|
-
authLogs: string;
|
|
376
|
-
webhookEndpoints: string;
|
|
377
|
-
slaPolicies: string;
|
|
378
|
-
macros: string;
|
|
379
|
-
ticketStatuses: string;
|
|
380
|
-
ticketFeedback: string;
|
|
381
|
-
notificationQueue: string;
|
|
382
|
-
automationRules: string;
|
|
383
|
-
supportTeams: string;
|
|
384
|
-
pushSubscriptions: string;
|
|
385
|
-
rateLimits: string;
|
|
386
|
-
counters: string;
|
|
387
|
-
users: string;
|
|
388
|
-
media: string;
|
|
389
|
-
}
|
|
390
|
-
declare const DEFAULT_SLUGS: CollectionSlugs;
|
|
391
|
-
/**
|
|
392
|
-
* Resolve collection slugs merging user overrides with defaults.
|
|
393
|
-
*/
|
|
394
|
-
declare function resolveSlugs(overrides?: Partial<CollectionSlugs>): CollectionSlugs;
|
|
395
|
-
|
|
396
485
|
/**
|
|
397
486
|
* Ticketing feature flags — single source of truth (client + server).
|
|
398
487
|
*
|
|
@@ -690,4 +779,4 @@ declare function createTicketStatusesCollection(slugs: CollectionSlugs): Collect
|
|
|
690
779
|
*/
|
|
691
780
|
declare function createTicketCollaboratorsCollection(slugs: CollectionSlugs): CollectionConfig;
|
|
692
781
|
|
|
693
|
-
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type SatisfactionSurveyData, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|
|
782
|
+
export { type AIProviderConfig, type ActivityEntryData, type CannedResponseData, type ClientData, type CollectionSlugs, DEFAULT_FEATURES, DEFAULT_INBOUND_EMAIL_LIMITS, DEFAULT_RETENTION, DEFAULT_SETTINGS, DEFAULT_SLUGS, DEFAULT_TICKETING_FEATURES, DEFAULT_USER_PREFS, type EmailConfig, type InboundEmailInput, type InboundEmailLimits, type InboundEmailValidationError, MemoryRateLimitStore, type MessageData, PURGE_LOGS_TASK_SLUG, PayloadRateLimitStore, type RateLimitEntry, type RateLimitStore, RateLimiter, type RetentionConfig, type SatisfactionSurveyData, type ScheduledPurgeResult, type SupportFeatures, type SupportPluginConfig, type SupportSettings, type SupportSettingsState, type TicketData, type TicketSynthesisResult, type TicketingFeatures, type TimeEntryData, type UserPrefs, calculateBusinessHoursDeadline, createAdminNotification, createAssignSlaDeadlines, createAuthLogsCollection, createCannedResponsesCollection, createChatMessagesCollection, createCheckSlaOnReply, createCheckSlaOnResolve, createEmailLogsCollection, createKnowledgeBaseCollection, createLoginEndpoint, createMacrosCollection, createOAuthGoogleEndpoint, createPendingEmailsCollection, createSatisfactionSurveysCollection, createSlaPoliciesCollection, createSupportClientsCollection, createTicketActivityLogCollection, createTicketCollaboratorsCollection, createTicketMessagesCollection, createTicketStatusEmail, createTicketStatusesCollection, createTicketsCollection, createTimeEntriesCollection, createTrackOpenEndpoint, createWebhookEndpointsCollection, dispatchWebhook, generateTicketSynthesis, normalizeFeatures, projectAutoClose, purgeOlderThan, purgeableCollections, readSupportSettings, readSupportSettingsState, readUserPrefs, resolveSlugs, runScheduledPurge, stripProjectedFeatures, supportPlugin, validateInboundEmailPayload, verifySecret };
|