@consilioweb/payload-support 3.0.0 → 4.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.
Files changed (43) hide show
  1. package/README.md +36 -2
  2. package/dist/index.cjs +558 -94
  3. package/dist/index.d.cts +20 -5
  4. package/dist/index.d.ts +20 -5
  5. package/dist/index.js +558 -94
  6. package/package.json +1 -1
  7. package/src/collections/ChatMessages.ts +59 -2
  8. package/src/collections/ClientSummaries.ts +10 -4
  9. package/src/collections/TicketMessages.ts +4 -1
  10. package/src/collections/WebhookEndpoints.ts +44 -2
  11. package/src/endpoints/admin-chat.ts +3 -3
  12. package/src/endpoints/ai-agent.ts +3 -3
  13. package/src/endpoints/ai.ts +3 -3
  14. package/src/endpoints/auth-2fa.ts +16 -4
  15. package/src/endpoints/capabilities.ts +6 -6
  16. package/src/endpoints/chat.ts +7 -5
  17. package/src/endpoints/chatbot.ts +48 -2
  18. package/src/endpoints/client-intelligence.ts +4 -4
  19. package/src/endpoints/email-stats.ts +19 -3
  20. package/src/endpoints/import-conversation.ts +1 -1
  21. package/src/endpoints/index.ts +1 -1
  22. package/src/endpoints/invite-collaborator.ts +29 -3
  23. package/src/endpoints/login.ts +15 -2
  24. package/src/endpoints/oauth-google.ts +130 -8
  25. package/src/endpoints/resend-notification.ts +3 -3
  26. package/src/endpoints/send-reminder.ts +3 -3
  27. package/src/endpoints/signature.ts +9 -2
  28. package/src/endpoints/ticket-synthesis.ts +3 -3
  29. package/src/endpoints/transfer-ticket.ts +28 -3
  30. package/src/endpoints/typing.ts +117 -14
  31. package/src/endpoints/user-prefs.ts +5 -2
  32. package/src/plugin.ts +12 -0
  33. package/src/portal/auth/layout.tsx +19 -1
  34. package/src/portal/auth/tickets/detail/MessageBody.tsx +88 -0
  35. package/src/portal/auth/tickets/detail/page.tsx +2 -6
  36. package/src/portal/login/page.tsx +11 -3
  37. package/src/utils/fireWebhooks.ts +4 -1
  38. package/src/utils/rateLimiter.ts +39 -5
  39. package/src/utils/readSettings.ts +124 -14
  40. package/src/utils/ticketAccess.ts +16 -1
  41. package/src/utils/twoFactorChallenge.ts +80 -0
  42. package/src/utils/urlSafety.ts +230 -0
  43. package/src/utils/webhookDispatcher.ts +5 -1
package/dist/index.d.cts CHANGED
@@ -28,7 +28,19 @@ declare class RateLimiter {
28
28
  private readonly windowMs;
29
29
  private readonly maxRequests;
30
30
  private readonly store;
31
- constructor(windowMs: number, maxRequests: number, store?: RateLimitStore);
31
+ private readonly prefix;
32
+ /**
33
+ * @param namespace Endpoint-scoped prefix for every key this limiter writes.
34
+ * The store is SHARED (`rateLimitStore: 'payload'` builds one instance for
35
+ * all endpoints), and the raw keys collide across endpoints: `ip` was used
36
+ * by both the login and the chatbot limiter — 10 forged chatbot requests
37
+ * locked a victim out of the portal for 15 minutes — and `String(user.id)`
38
+ * by five different endpoints. Always pass one; it is optional only because
39
+ * `RateLimiter` is part of the published API surface.
40
+ */
41
+ constructor(windowMs: number, maxRequests: number, store?: RateLimitStore, namespace?: string);
42
+ /** The key actually written to the store. Exposed for assertions in tests. */
43
+ scopedKey(key: string): string;
32
44
  check(key: string, context?: unknown): Promise<boolean>;
33
45
  reset(key: string, context?: unknown): Promise<void>;
34
46
  }
@@ -505,14 +517,17 @@ interface SupportSettingsState {
505
517
  */
506
518
  featuresConfigured: boolean;
507
519
  }
508
- declare function readSupportSettingsState(payload: Payload): Promise<SupportSettingsState>;
509
- declare function readSupportSettings(payload: Payload): Promise<SupportSettings>;
510
- declare function readUserPrefs(payload: Payload, userId: string | number): Promise<UserPrefs>;
520
+ declare function readSupportSettingsState(payload: Payload, staffSlug?: string): Promise<SupportSettingsState>;
521
+ declare function readSupportSettings(payload: Payload, staffSlug?: string): Promise<SupportSettings>;
522
+ declare function readUserPrefs(payload: Payload, userId: string | number, staffSlug?: string): Promise<UserPrefs>;
511
523
 
512
524
  /**
513
525
  * POST /api/support/oauth/google
514
526
  * Google OAuth — handles both login redirect and callback.
515
- * Body: { action: 'login' } or { code: string, state: string, cookieState: string }
527
+ * Body: { action: 'login' } or { code: string, state: string }
528
+ *
529
+ * The CSRF state is NOT taken from the body: `action: 'login'` issues it as an
530
+ * HttpOnly cookie and the callback reads it back from the `Cookie` header.
516
531
  */
517
532
  interface OAuthGoogleOptions {
518
533
  allowedEmailDomains?: string[];
package/dist/index.d.ts CHANGED
@@ -28,7 +28,19 @@ declare class RateLimiter {
28
28
  private readonly windowMs;
29
29
  private readonly maxRequests;
30
30
  private readonly store;
31
- constructor(windowMs: number, maxRequests: number, store?: RateLimitStore);
31
+ private readonly prefix;
32
+ /**
33
+ * @param namespace Endpoint-scoped prefix for every key this limiter writes.
34
+ * The store is SHARED (`rateLimitStore: 'payload'` builds one instance for
35
+ * all endpoints), and the raw keys collide across endpoints: `ip` was used
36
+ * by both the login and the chatbot limiter — 10 forged chatbot requests
37
+ * locked a victim out of the portal for 15 minutes — and `String(user.id)`
38
+ * by five different endpoints. Always pass one; it is optional only because
39
+ * `RateLimiter` is part of the published API surface.
40
+ */
41
+ constructor(windowMs: number, maxRequests: number, store?: RateLimitStore, namespace?: string);
42
+ /** The key actually written to the store. Exposed for assertions in tests. */
43
+ scopedKey(key: string): string;
32
44
  check(key: string, context?: unknown): Promise<boolean>;
33
45
  reset(key: string, context?: unknown): Promise<void>;
34
46
  }
@@ -505,14 +517,17 @@ interface SupportSettingsState {
505
517
  */
506
518
  featuresConfigured: boolean;
507
519
  }
508
- declare function readSupportSettingsState(payload: Payload): Promise<SupportSettingsState>;
509
- declare function readSupportSettings(payload: Payload): Promise<SupportSettings>;
510
- declare function readUserPrefs(payload: Payload, userId: string | number): Promise<UserPrefs>;
520
+ declare function readSupportSettingsState(payload: Payload, staffSlug?: string): Promise<SupportSettingsState>;
521
+ declare function readSupportSettings(payload: Payload, staffSlug?: string): Promise<SupportSettings>;
522
+ declare function readUserPrefs(payload: Payload, userId: string | number, staffSlug?: string): Promise<UserPrefs>;
511
523
 
512
524
  /**
513
525
  * POST /api/support/oauth/google
514
526
  * Google OAuth — handles both login redirect and callback.
515
- * Body: { action: 'login' } or { code: string, state: string, cookieState: string }
527
+ * Body: { action: 'login' } or { code: string, state: string }
528
+ *
529
+ * The CSRF state is NOT taken from the body: `action: 'login'` issues it as an
530
+ * HttpOnly cookie and the callback reads it back from the `Cookie` header.
516
531
  */
517
532
  interface OAuthGoogleOptions {
518
533
  allowedEmailDomains?: string[];