@consilioweb/payload-support 3.0.0 → 5.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 +58 -14
- package/dist/index.cjs +673 -107
- package/dist/index.d.cts +40 -5
- package/dist/index.d.ts +40 -5
- package/dist/index.js +673 -107
- package/dist/utils/db.d.ts +34 -0
- package/dist/utils/readSettings.d.ts +90 -0
- package/dist/views/BillingView/index.js +4 -4
- package/dist/views/ChatView/index.js +4 -4
- package/dist/views/CrmView/index.js +4 -4
- package/dist/views/EmailTrackingView/index.js +4 -4
- package/dist/views/ImportConversationView/index.js +4 -4
- package/dist/views/LogsView/index.js +4 -2
- package/dist/views/NewTicketView/index.js +4 -2
- package/dist/views/PendingEmailsView/index.js +4 -4
- package/dist/views/SupportDashboardView/index.js +4 -4
- package/dist/views/TicketDetailView/index.js +4 -4
- package/dist/views/TicketInboxView/index.js +4 -2
- package/dist/views/TicketingSettingsView/index.js +4 -4
- package/dist/views/TimeDashboardView/index.js +4 -4
- package/dist/views/shared/viewAccess.d.ts +29 -0
- package/dist/views/shared/viewAccess.js +24 -0
- package/package.json +26 -20
- package/src/collections/ChatMessages.ts +59 -2
- package/src/collections/ClientSummaries.ts +10 -4
- package/src/collections/TicketMessages.ts +4 -1
- package/src/collections/WebhookEndpoints.ts +44 -2
- package/src/endpoints/admin-chat.ts +3 -3
- package/src/endpoints/ai-agent.ts +3 -3
- package/src/endpoints/ai.ts +3 -3
- package/src/endpoints/auth-2fa.ts +68 -11
- package/src/endpoints/capabilities.ts +7 -9
- package/src/endpoints/chat.ts +7 -5
- package/src/endpoints/chatbot.ts +50 -4
- package/src/endpoints/client-intelligence.ts +4 -4
- package/src/endpoints/email-stats.ts +19 -3
- package/src/endpoints/import-conversation.ts +3 -3
- package/src/endpoints/index.ts +1 -1
- package/src/endpoints/invite-collaborator.ts +29 -3
- package/src/endpoints/login.ts +28 -5
- package/src/endpoints/oauth-google.ts +130 -8
- package/src/endpoints/push.ts +14 -1
- package/src/endpoints/resend-notification.ts +3 -3
- package/src/endpoints/send-reminder.ts +3 -3
- package/src/endpoints/signature.ts +9 -2
- package/src/endpoints/statuses.ts +17 -0
- package/src/endpoints/ticket-synthesis.ts +3 -3
- package/src/endpoints/transfer-ticket.ts +28 -3
- package/src/endpoints/typing.ts +117 -14
- package/src/endpoints/user-prefs.ts +5 -2
- package/src/plugin.ts +12 -0
- package/src/portal/auth/layout.tsx +19 -1
- package/src/portal/auth/tickets/detail/MessageBody.tsx +88 -0
- package/src/portal/auth/tickets/detail/page.tsx +2 -6
- package/src/portal/login/page.tsx +23 -5
- package/src/utils/fireWebhooks.ts +4 -1
- package/src/utils/push.ts +22 -0
- package/src/utils/rateLimiter.ts +136 -4
- package/src/utils/readSettings.ts +124 -14
- package/src/utils/ticketAccess.ts +16 -1
- package/src/utils/twoFactorChallenge.ts +85 -0
- package/src/utils/urlSafety.ts +265 -0
- package/src/utils/webhookDispatcher.ts +5 -1
- package/src/views/BillingView/index.tsx +4 -4
- package/src/views/ChatView/index.tsx +4 -4
- package/src/views/CrmView/index.tsx +4 -4
- package/src/views/EmailTrackingView/index.tsx +4 -4
- package/src/views/ImportConversationView/index.tsx +4 -4
- package/src/views/LogsView/index.tsx +4 -2
- package/src/views/NewTicketView/index.tsx +4 -2
- package/src/views/PendingEmailsView/index.tsx +4 -4
- package/src/views/SupportDashboardView/index.tsx +4 -4
- package/src/views/TicketDetailView/index.tsx +4 -4
- package/src/views/TicketInboxView/index.tsx +4 -2
- package/src/views/TicketingSettingsView/index.tsx +4 -4
- package/src/views/TimeDashboardView/index.tsx +4 -4
- package/src/views/shared/viewAccess.ts +73 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { AdminViewServerProps } from 'payload'
|
|
2
|
+
import { formatAdminURL } from 'payload/shared'
|
|
3
|
+
import { SUPPORT_STAFF_SLUG_CONFIG_KEY } from '../../utils/readSettings.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Where a custom admin view must send a caller it refuses, or `null` to render.
|
|
7
|
+
*
|
|
8
|
+
* Payload does NOT gate custom admin views. `RootPage` skips its own
|
|
9
|
+
* `canAccessAdmin` redirect as soon as `isCustomAdminView()` matches, and that
|
|
10
|
+
* helper only compares the request path against the registered `view.path` —
|
|
11
|
+
* it reads no visibility flag, despite what its docblock claims. Authorising a
|
|
12
|
+
* custom view is therefore the view's own job, and every view registered by
|
|
13
|
+
* this plugin sits at a custom path (`/support/inbox`, `/support/ticket`, …).
|
|
14
|
+
*
|
|
15
|
+
* `!req.user` alone is not that check. A single `payload-token` cookie serves
|
|
16
|
+
* every auth collection of the host app, so an ordinary front-office account —
|
|
17
|
+
* a `customers`, `members` or `subscribers` signup — carries one on `/admin`
|
|
18
|
+
* routes too. Such a caller reached `DefaultTemplate` and received the admin
|
|
19
|
+
* chrome together with the client config Payload builds for any authenticated
|
|
20
|
+
* request: the field schema of every collection and global, `admin.hidden`
|
|
21
|
+
* ones included, plus an unfiltered `visibleEntities`.
|
|
22
|
+
*
|
|
23
|
+
* The ticket data itself never travelled — the client components fetch through
|
|
24
|
+
* `/api/support/*`, which `requireAdmin` has guarded all along — but the shape
|
|
25
|
+
* of the whole CMS did.
|
|
26
|
+
*
|
|
27
|
+
* The gate mirrors `requireAdmin` (utils/auth.ts): membership of the staff
|
|
28
|
+
* collection. It additionally honours `canAccessAdmin`, so an account the host
|
|
29
|
+
* disabled through its own `access.admin` is refused here too, and it fails
|
|
30
|
+
* closed on anything it cannot resolve.
|
|
31
|
+
*/
|
|
32
|
+
export function supportViewRedirectTarget(
|
|
33
|
+
initPageResult: AdminViewServerProps['initPageResult'],
|
|
34
|
+
): string | null {
|
|
35
|
+
const req = initPageResult?.req
|
|
36
|
+
const config = req?.payload?.config
|
|
37
|
+
const adminRoute = config?.routes?.admin ?? '/admin'
|
|
38
|
+
const routes = config?.admin?.routes
|
|
39
|
+
|
|
40
|
+
const to = (route: string | undefined, fallback: string) =>
|
|
41
|
+
formatAdminURL({ adminRoute, path: (route ?? fallback) as `/${string}` })
|
|
42
|
+
|
|
43
|
+
if (!req?.user) return to(routes?.login, '/login')
|
|
44
|
+
|
|
45
|
+
// `sanitizePermissions` deletes the key when it is false, so an explicit
|
|
46
|
+
// `false` is a denial while `undefined` simply means "not computed here".
|
|
47
|
+
if (initPageResult?.permissions?.canAccessAdmin === false) {
|
|
48
|
+
return to(routes?.unauthorized, '/unauthorized')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Same source of truth as the write path: the slug `plugin.ts` publishes on
|
|
52
|
+
// `config.custom`, NOT `config.admin.user` — Payload defaults the latter to
|
|
53
|
+
// the app's first auth collection, which on a host declaring a front office
|
|
54
|
+
// first is precisely the collection we are trying to keep out.
|
|
55
|
+
//
|
|
56
|
+
// `resolveStaffPrefSlug` is deliberately NOT used here. Its last-resort
|
|
57
|
+
// fallback is the literal `'users'`, which is the right call on a read path
|
|
58
|
+
// (a wrong scope returns no settings) and the wrong one on an authorisation
|
|
59
|
+
// path: it would admit whoever happens to sit in a collection named `users`
|
|
60
|
+
// on a host where neither source resolved. A gate with nothing to compare
|
|
61
|
+
// against refuses.
|
|
62
|
+
const custom = config?.custom as Record<string, unknown> | undefined
|
|
63
|
+
const registered = custom?.[SUPPORT_STAFF_SLUG_CONFIG_KEY]
|
|
64
|
+
const staffSlug =
|
|
65
|
+
(typeof registered === 'string' && registered) || config?.admin?.user || null
|
|
66
|
+
|
|
67
|
+
const collection = (req.user as { collection?: string }).collection
|
|
68
|
+
if (!staffSlug || !collection || collection !== staffSlug) {
|
|
69
|
+
return to(routes?.unauthorized, '/unauthorized')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return null
|
|
73
|
+
}
|