@strapi/admin 5.52.3 → 5.54.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/dist/admin/admin/src/App.js +1 -1
- package/dist/admin/admin/src/App.js.map +1 -1
- package/dist/admin/admin/src/App.mjs +1 -1
- package/dist/admin/admin/src/App.mjs.map +1 -1
- package/dist/admin/admin/src/components/DismissibleBanner.js +60 -0
- package/dist/admin/admin/src/components/DismissibleBanner.js.map +1 -0
- package/dist/admin/admin/src/components/DismissibleBanner.mjs +58 -0
- package/dist/admin/admin/src/components/DismissibleBanner.mjs.map +1 -0
- package/dist/admin/admin/src/components/Form.js +11 -2
- package/dist/admin/admin/src/components/Form.js.map +1 -1
- package/dist/admin/admin/src/components/Form.mjs +11 -2
- package/dist/admin/admin/src/components/Form.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/DateTime.js +1 -1
- package/dist/admin/admin/src/components/FormInputs/DateTime.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/DateTime.mjs +1 -1
- package/dist/admin/admin/src/components/FormInputs/DateTime.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Time.js +1 -1
- package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Time.mjs +1 -1
- package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavUser.js +1 -2
- package/dist/admin/admin/src/components/MainNav/NavUser.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavUser.mjs +1 -2
- package/dist/admin/admin/src/components/MainNav/NavUser.mjs.map +1 -1
- package/dist/admin/admin/src/components/MediaLibraryBanner.js +85 -0
- package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -0
- package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +83 -0
- package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -0
- package/dist/admin/admin/src/components/Providers.js +6 -6
- package/dist/admin/admin/src/components/Providers.js.map +1 -1
- package/dist/admin/admin/src/components/Providers.mjs +6 -6
- package/dist/admin/admin/src/components/Providers.mjs.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.js +56 -86
- package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.mjs +58 -88
- package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
- package/dist/admin/admin/src/core/store/configure.js +14 -2
- package/dist/admin/admin/src/core/store/configure.js.map +1 -1
- package/dist/admin/admin/src/core/store/configure.mjs +14 -2
- package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
- package/dist/admin/admin/src/core/store/hooks.mjs +1 -1
- package/dist/admin/admin/src/features/Auth.js +162 -46
- package/dist/admin/admin/src/features/Auth.js.map +1 -1
- package/dist/admin/admin/src/features/Auth.mjs +164 -48
- package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js +19 -0
- package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js.map +1 -0
- package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs +17 -0
- package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs.map +1 -0
- package/dist/admin/admin/src/hooks/{useIdleSessionLogout.js → useSessionKeepalive.js} +34 -27
- package/dist/admin/admin/src/hooks/useSessionKeepalive.js.map +1 -0
- package/dist/admin/admin/src/hooks/{useIdleSessionLogout.mjs → useSessionKeepalive.mjs} +34 -27
- package/dist/admin/admin/src/hooks/useSessionKeepalive.mjs.map +1 -0
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +2 -0
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +2 -0
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
- package/dist/admin/admin/src/pages/SessionsPage.js +2 -5
- package/dist/admin/admin/src/pages/SessionsPage.js.map +1 -1
- package/dist/admin/admin/src/pages/SessionsPage.mjs +2 -5
- package/dist/admin/admin/src/pages/SessionsPage.mjs.map +1 -1
- package/dist/admin/admin/src/render.js +5 -0
- package/dist/admin/admin/src/render.js.map +1 -1
- package/dist/admin/admin/src/render.mjs +5 -0
- package/dist/admin/admin/src/render.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +30 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +30 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.js +3 -13
- package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.mjs +3 -13
- package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +152 -48
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +151 -50
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/admin/src/utils/unsavedChangesRegistry.js +25 -0
- package/dist/admin/admin/src/utils/unsavedChangesRegistry.js.map +1 -0
- package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs +22 -0
- package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs.map +1 -0
- package/dist/admin/admin/tests/utils.js +14 -14
- package/dist/admin/admin/tests/utils.js.map +1 -1
- package/dist/admin/admin/tests/utils.mjs +14 -14
- package/dist/admin/admin/tests/utils.mjs.map +1 -1
- package/dist/admin/ee/admin/src/constants.js +6 -0
- package/dist/admin/ee/admin/src/constants.js.map +1 -1
- package/dist/admin/ee/admin/src/constants.mjs +6 -0
- package/dist/admin/ee/admin/src/constants.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +31 -3
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +33 -5
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js +177 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs +175 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +173 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +151 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +14 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +14 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/index.js +3 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/shared/utils/audit-log-export.js +16 -0
- package/dist/admin/shared/utils/audit-log-export.js.map +1 -0
- package/dist/admin/shared/utils/audit-log-export.mjs +9 -0
- package/dist/admin/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/admin/src/components/DismissibleBanner.d.ts +8 -0
- package/dist/admin/src/components/MediaLibraryBanner.d.ts +2 -0
- package/dist/admin/src/hooks/useRegisterUnsavedChanges.d.ts +6 -0
- package/dist/admin/src/hooks/useSessionKeepalive.d.ts +88 -0
- package/dist/admin/src/utils/getFetchClient.d.ts +22 -7
- package/dist/admin/src/utils/unsavedChangesRegistry.d.ts +11 -0
- package/dist/admin/tests/store.d.ts +4 -0
- package/dist/admin/tests/utils.d.ts +4 -0
- package/dist/ee/admin/src/constants.d.ts +4 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.d.ts +10 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.d.ts +18 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +13 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts +1 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +24 -3
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +8 -2
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts +10 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +1 -0
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js +50 -0
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs +51 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js +201 -7
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs +201 -8
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.js +14 -0
- package/dist/server/ee/server/src/audit-logs/utils.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs +12 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js +11 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs +11 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.js +8 -0
- package/dist/server/ee/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.mjs +8 -0
- package/dist/server/ee/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/ee/server/src/index.js +10 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +10 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/shared/utils/audit-log-export.js +22 -0
- package/dist/server/shared/utils/audit-log-export.js.map +1 -0
- package/dist/server/shared/utils/audit-log-export.mjs +12 -0
- package/dist/server/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/shared/contracts/audit-logs.d.ts +15 -1
- package/dist/shared/contracts/audit-logs.d.ts.map +1 -1
- package/dist/shared/contracts/shared.d.ts +1 -0
- package/dist/shared/contracts/shared.d.ts.map +1 -1
- package/dist/shared/utils/audit-log-export.d.ts +9 -0
- package/dist/shared/utils/audit-log-export.d.ts.map +1 -0
- package/package.json +7 -7
- package/dist/admin/admin/src/hooks/useIdleSessionLogout.js.map +0 -1
- package/dist/admin/admin/src/hooks/useIdleSessionLogout.mjs.map +0 -1
- package/dist/admin/src/hooks/useIdleSessionLogout.d.ts +0 -87
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
declare const SESSION_EXPIRY_BUFFER_MS = 1000;
|
|
2
|
+
/**
|
|
3
|
+
* How long before the access token's `exp` an active tab renews. Renewing
|
|
4
|
+
* ahead of expiry (rather than at it) means the refreshed token is already in
|
|
5
|
+
* shared storage by the time any *other* tab's post-expiry timer fires — so an
|
|
6
|
+
* idle sibling re-syncs instead of racing the refresh.
|
|
7
|
+
*/
|
|
8
|
+
declare const SESSION_RENEW_MARGIN_MS = 10000;
|
|
9
|
+
interface UseSessionKeepaliveOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The current admin access JWT (from Redux), or `null` when logged out.
|
|
12
|
+
*/
|
|
13
|
+
token: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Called when a renewal attempt is rejected by the server (the session is
|
|
16
|
+
* truly over: refresh token idle/max window elapsed). This is a
|
|
17
|
+
* server-confirmed end of session, so it SHOULD broadcast a global logout to
|
|
18
|
+
* every tab.
|
|
19
|
+
*/
|
|
20
|
+
onSessionDead?: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Read the access token currently in shared storage (localStorage/cookie).
|
|
23
|
+
* Because every open tab shares the same refresh cookie, an active tab that
|
|
24
|
+
* refreshes writes a newer access token here. When omitted, the hook never
|
|
25
|
+
* re-syncs across tabs.
|
|
26
|
+
*/
|
|
27
|
+
getStoredToken?: () => string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Adopt a newer shared token instead of treating this tab's token as stale.
|
|
30
|
+
* Typically dispatches `setToken`, which updates Redux and causes this hook
|
|
31
|
+
* to re-arm against the later `exp`. Only called when `getStoredToken`
|
|
32
|
+
* returns a token whose `exp` is later than the in-memory one.
|
|
33
|
+
*/
|
|
34
|
+
onResync?: (token: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Epoch ms of the user's last interaction (pointer, key, scroll, …). Used to
|
|
37
|
+
* decide whether to silently renew when the access token is about to expire.
|
|
38
|
+
* Idle tabs must NOT renew — that would defeat the server's
|
|
39
|
+
* `idleSessionLifespan` / `idleRefreshTokenLifespan`. When omitted, the hook
|
|
40
|
+
* never treats the tab as active.
|
|
41
|
+
*/
|
|
42
|
+
getLastActivityAt?: () => number;
|
|
43
|
+
/**
|
|
44
|
+
* Silently renew the session (rotate the refresh token + mint a new access
|
|
45
|
+
* token). Resolves `true` on success — the resulting `setToken` re-arms this
|
|
46
|
+
* hook against the new `exp` — or `false` when the server rejects it. Only
|
|
47
|
+
* called when the user was active during the current token's lifetime.
|
|
48
|
+
*/
|
|
49
|
+
renewSession?: () => Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Escape hatch for tests / dev environments where we don't want the
|
|
52
|
+
* automatic renew / re-sync behavior. Mirrors the existing `_disableRenewToken`
|
|
53
|
+
* prop on `<AuthProvider>`.
|
|
54
|
+
*/
|
|
55
|
+
disabled?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Keep the admin session alive while the user is active — without one tab
|
|
59
|
+
* tearing down another, and without logging anyone out because a short-lived
|
|
60
|
+
* access token aged out.
|
|
61
|
+
*
|
|
62
|
+
* The access token (`accessTokenLifespan`, e.g. 30 min) is transport plumbing,
|
|
63
|
+
* not the session length; the refresh token's idle/max window is the session.
|
|
64
|
+
* So expiry of the access JWT must never clear auth state or unmount the page:
|
|
65
|
+
* the next user-initiated request 401s, `withTokenRefresh` refreshes and
|
|
66
|
+
* retries, and only a *rejected* refresh ends the session (`onSessionDead`).
|
|
67
|
+
* Two timers are armed per token:
|
|
68
|
+
*
|
|
69
|
+
* - Renew (at `exp` minus a margin): if the user interacted during this token's
|
|
70
|
+
* lifetime, silently renew *ahead* of expiry. The new `setToken` re-arms the
|
|
71
|
+
* hook; a server rejection (`onSessionDead`) ends the session globally.
|
|
72
|
+
* Renewing early guarantees the refreshed token reaches shared storage before
|
|
73
|
+
* any sibling tab's post-expiry timer fires.
|
|
74
|
+
* - Post-expiry (just after `exp`): the fallback when this tab did not renew.
|
|
75
|
+
* It first re-syncs from a token another tab refreshed (so an idle tab rides
|
|
76
|
+
* on an active sibling), then renews if activity arrived late. If the tab is
|
|
77
|
+
* still idle, it does nothing destructive — the stale access token stays in
|
|
78
|
+
* place so form state survives until the next request.
|
|
79
|
+
*
|
|
80
|
+
* Idle tabs must not renew: a tab left open forever must not keep the session
|
|
81
|
+
* alive past the server's idle/max window.
|
|
82
|
+
*
|
|
83
|
+
* If the JWT can't be decoded (malformed, missing `exp`), the timers are skipped
|
|
84
|
+
* silently — the 401 refresh path still covers the next user-initiated request.
|
|
85
|
+
*/
|
|
86
|
+
declare const useSessionKeepalive: ({ token, onSessionDead, getStoredToken, onResync, getLastActivityAt, renewSession, disabled, }: UseSessionKeepaliveOptions) => void;
|
|
87
|
+
export { useSessionKeepalive, SESSION_EXPIRY_BUFFER_MS, SESSION_RENEW_MARGIN_MS };
|
|
88
|
+
export type { UseSessionKeepaliveOptions };
|
|
@@ -15,18 +15,26 @@ export type ApiError = errors.ApplicationError | errors.ForbiddenError | errors.
|
|
|
15
15
|
declare const setOnTokenUpdate: (callback: ((token: string) => void) | null) => void;
|
|
16
16
|
/**
|
|
17
17
|
* Set the callback that will be called when the active session is no longer
|
|
18
|
-
* valid
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* valid — i.e. the server rejected the refresh token, not merely that the
|
|
19
|
+
* short-lived access token expired. This lets the tab redirect to /auth/login
|
|
20
|
+
* (after any unsaved-changes guard) rather than sitting on a dead session.
|
|
21
21
|
*
|
|
22
22
|
* @param callback - Function to call when the session ends, or null to clear
|
|
23
23
|
*/
|
|
24
24
|
declare const setOnSessionExpired: (callback: (() => void) | null) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Re-arm session-expired notifications after a new access token is stored
|
|
27
|
+
* (silent refresh) or after a successful login.
|
|
28
|
+
*/
|
|
29
|
+
declare const resetSessionExpiredNotification: () => void;
|
|
25
30
|
/**
|
|
26
31
|
* Trigger the registered session-expired callback, if any. Safe to call from
|
|
27
|
-
* non-React code (e.g., the RTK Query baseQuery 401 handler).
|
|
32
|
+
* non-React code (e.g., the RTK Query baseQuery 401 handler). Returns `false`
|
|
33
|
+
* when nothing is listening, so callers can fall back to a hard redirect
|
|
34
|
+
* instead of leaving the user on a dead page. Subsequent calls during the same
|
|
35
|
+
* dead session return `true` without invoking the handler again.
|
|
28
36
|
*/
|
|
29
|
-
declare const triggerSessionExpired: () =>
|
|
37
|
+
declare const triggerSessionExpired: () => boolean;
|
|
30
38
|
/**
|
|
31
39
|
* Store the new token in the appropriate storage (localStorage or cookie)
|
|
32
40
|
* and notify the app to update its state.
|
|
@@ -38,6 +46,13 @@ declare const triggerSessionExpired: () => void;
|
|
|
38
46
|
* @internal Exported for testing purposes
|
|
39
47
|
*/
|
|
40
48
|
declare const storeToken: (token: string) => void;
|
|
49
|
+
declare const ADMIN_REFRESH_LOCK = "strapi-admin-access-token";
|
|
50
|
+
/**
|
|
51
|
+
* Refresh the access token by calling the /admin/access-token endpoint.
|
|
52
|
+
* This uses a low-level fetch to avoid recursion through the interceptor.
|
|
53
|
+
* Returns the new token on success, or null on failure.
|
|
54
|
+
*/
|
|
55
|
+
declare const refreshAccessToken: (tokenUsedByFailedRequest?: string | null) => Promise<string | null>;
|
|
41
56
|
/**
|
|
42
57
|
* Attempt to refresh the token if not already refreshing.
|
|
43
58
|
* Uses a module-level promise to prevent concurrent refresh requests.
|
|
@@ -46,7 +61,7 @@ declare const storeToken: (token: string) => void;
|
|
|
46
61
|
* @throws {Error} If the token refresh fails (e.g., refresh token expired)
|
|
47
62
|
* @internal Exported for testing purposes
|
|
48
63
|
*/
|
|
49
|
-
declare const attemptTokenRefresh: () => Promise<string>;
|
|
64
|
+
declare const attemptTokenRefresh: (tokenUsedByFailedRequest?: string | null) => Promise<string>;
|
|
50
65
|
type FetchResponse<TData = unknown> = {
|
|
51
66
|
data: TData;
|
|
52
67
|
status?: number;
|
|
@@ -117,5 +132,5 @@ type FetchClient = {
|
|
|
117
132
|
* ```
|
|
118
133
|
*/
|
|
119
134
|
declare const getFetchClient: (defaultOptions?: FetchConfig) => FetchClient;
|
|
120
|
-
export { getFetchClient, isFetchError, FetchError, attemptTokenRefresh, storeToken, setOnTokenUpdate, setOnSessionExpired, triggerSessionExpired, };
|
|
135
|
+
export { getFetchClient, isFetchError, FetchError, attemptTokenRefresh, refreshAccessToken, storeToken, setOnTokenUpdate, setOnSessionExpired, triggerSessionExpired, resetSessionExpiredNotification, ADMIN_REFRESH_LOCK, };
|
|
121
136
|
export type { FetchOptions, FetchResponse, FetchConfig, FetchClient, ErrorResponse };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type UnsavedChangesCheck = () => boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Register a callback that reports whether a form (or other surface) has unsaved
|
|
4
|
+
* edits. Used by the auth layer to warn before session-expiry logout discards
|
|
5
|
+
* in-memory state that route blockers never see (token clear unmounts the form).
|
|
6
|
+
*/
|
|
7
|
+
declare const registerUnsavedChangesCheck: (id: string, check: UnsavedChangesCheck) => (() => void);
|
|
8
|
+
declare const hasUnsavedChanges: () => boolean;
|
|
9
|
+
declare const clearUnsavedChangesChecks: () => void;
|
|
10
|
+
export { registerUnsavedChangesCheck, hasUnsavedChanges, clearUnsavedChangesChecks };
|
|
11
|
+
export type { UnsavedChangesCheck };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ExportProgress, ExportResult } from '../hooks/useExportAuditLogs';
|
|
2
|
+
interface ExportCardProps {
|
|
3
|
+
progress: ExportProgress | null;
|
|
4
|
+
exportResult: ExportResult | null;
|
|
5
|
+
onDownload: () => void;
|
|
6
|
+
onDismiss: () => void;
|
|
7
|
+
}
|
|
8
|
+
declare const ExportCard: ({ progress, exportResult, onDownload, onDismiss }: ExportCardProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
export { ExportCard };
|
|
10
|
+
export type { ExportCardProps };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface ExportProgress {
|
|
2
|
+
fetched: number;
|
|
3
|
+
total: number;
|
|
4
|
+
}
|
|
5
|
+
interface ExportResult {
|
|
6
|
+
blob: Blob;
|
|
7
|
+
fileName: string;
|
|
8
|
+
}
|
|
9
|
+
declare const useExportAuditLogs: () => {
|
|
10
|
+
exportAuditLogs: (filters: unknown, totalEntries: number) => Promise<void>;
|
|
11
|
+
downloadExport: () => void;
|
|
12
|
+
dismissExport: () => void;
|
|
13
|
+
isExporting: boolean;
|
|
14
|
+
progress: ExportProgress | null;
|
|
15
|
+
exportResult: ExportResult | null;
|
|
16
|
+
};
|
|
17
|
+
export { useExportAuditLogs };
|
|
18
|
+
export type { ExportProgress, ExportResult };
|
|
@@ -27,5 +27,18 @@ export declare const actionTypes: {
|
|
|
27
27
|
'permission.create': string;
|
|
28
28
|
'permission.update': string;
|
|
29
29
|
'permission.delete': string;
|
|
30
|
+
'release.create': string;
|
|
31
|
+
'release.update': string;
|
|
32
|
+
'release.delete': string;
|
|
33
|
+
'release.trigger': string;
|
|
34
|
+
'release.entry.add': string;
|
|
35
|
+
'release.entry.update': string;
|
|
36
|
+
'release.entry.remove': string;
|
|
37
|
+
'release.settings.update': string;
|
|
38
|
+
'audit-log.export': string;
|
|
39
|
+
'locale.create': string;
|
|
40
|
+
'locale.update': string;
|
|
41
|
+
'locale.delete': string;
|
|
42
|
+
'locale.default.update': string;
|
|
30
43
|
};
|
|
31
44
|
export declare const getDefaultMessage: (value: keyof typeof actionTypes) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;;kBAkBb,OAAO;uBAUF,OAAO;iBAUb,OAAO;gBAWR,OAAO;;AAhC3B,wBA2FE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/routes/audit-logs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAeA,
|
|
1
|
+
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/routes/audit-logs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAeA,wBA4BE"}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { Readable } from 'stream';
|
|
1
2
|
import type { Core } from '@strapi/types';
|
|
2
3
|
interface Event {
|
|
3
4
|
action: string;
|
|
4
5
|
date: Date;
|
|
5
|
-
userId: string | number;
|
|
6
|
+
userId: string | number | null;
|
|
6
7
|
payload: Record<string, unknown>;
|
|
7
8
|
}
|
|
9
|
+
interface ExportQuery {
|
|
10
|
+
cursor?: number;
|
|
11
|
+
pageSize?: number;
|
|
12
|
+
until?: number;
|
|
13
|
+
token?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
declare const toCsvLine: (row: any) => string;
|
|
8
17
|
/**
|
|
9
18
|
* @description
|
|
10
19
|
* Manages audit logs interaction with the database. Accessible via strapi.get('audit-logs')
|
|
@@ -20,6 +29,18 @@ declare const createAuditLogsService: (strapi: Core.Strapi) => {
|
|
|
20
29
|
total: number;
|
|
21
30
|
};
|
|
22
31
|
}>;
|
|
32
|
+
isExportTooLarge(query: {
|
|
33
|
+
filters?: unknown;
|
|
34
|
+
}): Promise<boolean>;
|
|
35
|
+
isTrustedContinuation(query: ExportQuery): boolean;
|
|
36
|
+
createExportStream(query: ExportQuery): Promise<{
|
|
37
|
+
stream: Readable;
|
|
38
|
+
nextCursor: number | null;
|
|
39
|
+
until: number;
|
|
40
|
+
isNewExport: boolean;
|
|
41
|
+
partSize: number;
|
|
42
|
+
exportToken: string;
|
|
43
|
+
}>;
|
|
23
44
|
findManyUsers(query: {
|
|
24
45
|
page?: number | string;
|
|
25
46
|
pageSize?: number | string;
|
|
@@ -27,7 +48,7 @@ declare const createAuditLogsService: (strapi: Core.Strapi) => {
|
|
|
27
48
|
results: {
|
|
28
49
|
id: any;
|
|
29
50
|
email: any;
|
|
30
|
-
displayName:
|
|
51
|
+
displayName: string;
|
|
31
52
|
}[];
|
|
32
53
|
pagination: {
|
|
33
54
|
page: number;
|
|
@@ -39,5 +60,5 @@ declare const createAuditLogsService: (strapi: Core.Strapi) => {
|
|
|
39
60
|
findOne(id: unknown): Promise<any>;
|
|
40
61
|
deleteExpiredEvents(expirationDate: Date): Promise<import("@strapi/database/dist/types").CountResult>;
|
|
41
62
|
};
|
|
42
|
-
export { createAuditLogsService };
|
|
63
|
+
export { createAuditLogsService, toCsvLine };
|
|
43
64
|
//# sourceMappingURL=audit-logs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/audit-logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/audit-logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAyB1C,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IAEX,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAkCD,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA8BD,QAAA,MAAM,SAAS,GAAI,KAAK,GAAG,WAc1B,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,sBAAsB,GAAI,QAAQ,IAAI,CAAC,MAAM;qBAExB,KAAK;oBAWN,OAAO;;;;;;;;;4BAiCC;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;iCAoBtB,WAAW;8BAIR,WAAW;;;;;;;;yBA2GhB;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE;;;;;;;;;;;;;gBAmC/D,OAAO;wCAkBW,IAAI;CAU3C,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import type { Core } from '@strapi/types';
|
|
1
|
+
import type { Core, Modules } from '@strapi/types';
|
|
2
2
|
/**
|
|
3
3
|
* @description
|
|
4
|
-
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-
|
|
4
|
+
* Manages the lifecycle of audit logs. Accessible via strapi.get('audit-logs-lifecycle')
|
|
5
5
|
*/
|
|
6
6
|
declare const createAuditLogsLifecycleService: (strapi: Core.Strapi) => {
|
|
7
|
+
/**
|
|
8
|
+
* Adds an event to the list of audited events. Plugins register their own from
|
|
9
|
+
* their bootstrap; the transformer builds the audited shape
|
|
10
|
+
* ({resource, details, outcome}) from the arguments passed to eventHub.emit().
|
|
11
|
+
*/
|
|
12
|
+
registerEvent<TDetails = unknown>(name: string, transform: Modules.AuditLogs.EventTransformer<TDetails>): void;
|
|
7
13
|
register(): Promise</*elided*/ any>;
|
|
8
14
|
unsubscribe(): /*elided*/ any;
|
|
9
15
|
destroy(): /*elided*/ any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"lifecycles.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/services/lifecycles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAgFnD;;;GAGG;AACH,QAAA,MAAM,+BAA+B,GAAI,QAAQ,IAAI,CAAC,MAAM;IAiHxD;;;;OAIG;kBACW,QAAQ,kBACd,MAAM,aACD,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;;;CAyF5D,CAAC;AAEF,OAAO,EAAE,+BAA+B,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/utils/csv.ts"],"names":[],"mappings":"AACA,QAAA,MAAM,OAAO,WAAW,CAAC;AAGzB,QAAA,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,MAgBxC,CAAC;AAEF,QAAA,MAAM,gBAAgB,GAAI,QAAQ,OAAO,EAAE,KAAG,MAE7C,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare const EXPORT_TOKEN_TTL_MS: number;
|
|
2
|
+
declare const signExportToken: (secret: string, until: number, filters: unknown, issuedAt?: number) => string;
|
|
3
|
+
declare const verifyExportToken: (secret: string, token: unknown, until: number, filters: unknown, now?: number) => boolean;
|
|
4
|
+
export { signExportToken, verifyExportToken, EXPORT_TOKEN_TTL_MS };
|
|
5
|
+
//# sourceMappingURL=export-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-token.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/utils/export-token.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,mBAAmB,QAAiB,CAAC;AAW3C,QAAA,MAAM,eAAe,GACnB,QAAQ,MAAM,EACd,OAAO,MAAM,EACb,SAAS,OAAO,EAChB,iBAAqB,KACpB,MAA6E,CAAC;AAEjF,QAAA,MAAM,iBAAiB,GACrB,QAAQ,MAAM,EACd,OAAO,OAAO,EACd,OAAO,MAAM,EACb,SAAS,OAAO,EAChB,YAAgB,KACf,OAyBF,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface AdminUserLike {
|
|
2
|
+
username?: string | null;
|
|
3
|
+
firstname?: string | null;
|
|
4
|
+
lastname?: string | null;
|
|
5
|
+
email: string;
|
|
6
|
+
}
|
|
7
|
+
/** How an admin user is named across audit logs */
|
|
8
|
+
declare const getDisplayName: (user: AdminUserLike) => string;
|
|
9
|
+
export { getDisplayName };
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/audit-logs/utils.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mDAAmD;AACnD,QAAA,MAAM,cAAc,GAAI,MAAM,aAAa,KAAG,MAU7C,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export declare const validateFindMany: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
2
2
|
export declare const validateFindManyUsers: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
3
|
+
export declare const validateExport: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
3
4
|
declare const _default: {
|
|
4
5
|
validateFindMany: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
5
6
|
validateFindManyUsers: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
7
|
+
validateExport: (body: unknown, errorMessage?: string) => Promise<any>;
|
|
6
8
|
};
|
|
7
9
|
export default _default;
|
|
8
10
|
//# sourceMappingURL=audit-logs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/validation/audit-logs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../../../../../ee/server/src/audit-logs/validation/audit-logs.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,gBAAgB,wDAA+D,CAAC;AAC7F,eAAO,MAAM,qBAAqB,wDAEhC,CAAC;AACH,eAAO,MAAM,cAAc,wDAA6D,CAAC;;;;;;AAEzF,wBAIE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-actions.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/config/admin-actions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"admin-actions.d.ts","sourceRoot":"","sources":["../../../../../ee/server/src/config/admin-actions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,wBAqCE"}
|
|
@@ -5,6 +5,7 @@ declare const getAdminEE: () => {
|
|
|
5
5
|
findMany(ctx: import("koa").Context): Promise<void>;
|
|
6
6
|
findManyUsers(ctx: import("koa").Context): Promise<void>;
|
|
7
7
|
findOne(ctx: import("koa").Context): Promise<void>;
|
|
8
|
+
export(ctx: import("koa").Context): Promise<void>;
|
|
8
9
|
} | undefined;
|
|
9
10
|
authentication: {
|
|
10
11
|
getProviders(ctx: import("koa").Context): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../ee/server/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../ee/server/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAe1C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBA4Be;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;wBAsBxB;QAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOpD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var zlib = require('zlib');
|
|
4
|
+
var utils = require('@strapi/utils');
|
|
5
|
+
var auditLogExport = require('../../../../../shared/utils/audit-log-export.js');
|
|
3
6
|
var auditLogs = require('../validation/audit-logs.js');
|
|
4
7
|
|
|
8
|
+
const EXPORT_INVALID_CONTINUATION_MESSAGE = 'The export continuation is invalid or has expired. Restart the export.';
|
|
9
|
+
const EXPORT_TOO_LARGE_MESSAGE = 'The export matches more entries than the configured limit. Add filters to reduce it.';
|
|
5
10
|
var auditLogsController = {
|
|
6
11
|
async findMany (ctx) {
|
|
7
12
|
const { query } = ctx.request;
|
|
@@ -26,6 +31,51 @@ var auditLogsController = {
|
|
|
26
31
|
const body = await auditLogs.findOne(id);
|
|
27
32
|
ctx.body = body;
|
|
28
33
|
strapi.telemetry.send('didWatchAnAuditLog');
|
|
34
|
+
},
|
|
35
|
+
async export (ctx) {
|
|
36
|
+
const { query } = ctx.request;
|
|
37
|
+
const validatedQuery = await auditLogs.validateExport(query);
|
|
38
|
+
const auditLogs$1 = strapi.get('audit-logs');
|
|
39
|
+
const isContinuation = validatedQuery.cursor !== undefined;
|
|
40
|
+
if (isContinuation && !auditLogs$1.isTrustedContinuation(validatedQuery)) {
|
|
41
|
+
throw new utils.errors.ValidationError(EXPORT_INVALID_CONTINUATION_MESSAGE);
|
|
42
|
+
}
|
|
43
|
+
if (!isContinuation) {
|
|
44
|
+
if (await auditLogs$1.isExportTooLarge({
|
|
45
|
+
filters: validatedQuery.filters ?? null
|
|
46
|
+
})) {
|
|
47
|
+
throw new utils.errors.PayloadTooLargeError(EXPORT_TOO_LARGE_MESSAGE);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const { stream, nextCursor, until, isNewExport, partSize, exportToken } = await auditLogs$1.createExportStream(validatedQuery);
|
|
51
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
52
|
+
ctx.set('Content-Type', 'text/csv; charset=utf-8');
|
|
53
|
+
ctx.set('Content-Disposition', `attachment; filename="audit-logs-${date}.csv"`);
|
|
54
|
+
ctx.set(auditLogExport.AUDIT_LOGS_EXPORT_UNTIL_HEADER, String(until));
|
|
55
|
+
ctx.set(auditLogExport.AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, String(partSize));
|
|
56
|
+
ctx.set(auditLogExport.AUDIT_LOGS_EXPORT_TOKEN_HEADER, exportToken);
|
|
57
|
+
ctx.set(auditLogExport.AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER, nextCursor !== null ? String(nextCursor) : auditLogExport.AUDIT_LOGS_EXPORT_CURSOR_DONE);
|
|
58
|
+
const exposedHeaders = [
|
|
59
|
+
ctx.response.get('Access-Control-Expose-Headers'),
|
|
60
|
+
auditLogExport.AUDIT_LOGS_EXPORT_UNTIL_HEADER,
|
|
61
|
+
auditLogExport.AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,
|
|
62
|
+
auditLogExport.AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,
|
|
63
|
+
auditLogExport.AUDIT_LOGS_EXPORT_TOKEN_HEADER,
|
|
64
|
+
'Content-Disposition'
|
|
65
|
+
].filter(Boolean).join(', ');
|
|
66
|
+
ctx.set('Access-Control-Expose-Headers', exposedHeaders);
|
|
67
|
+
ctx.vary('Accept-Encoding');
|
|
68
|
+
if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip') {
|
|
69
|
+
ctx.set('Content-Encoding', 'gzip');
|
|
70
|
+
const gzip = zlib.createGzip();
|
|
71
|
+
stream.on('error', (error)=>gzip.destroy(error));
|
|
72
|
+
ctx.body = stream.pipe(gzip);
|
|
73
|
+
} else {
|
|
74
|
+
ctx.body = stream;
|
|
75
|
+
}
|
|
76
|
+
if (isNewExport) {
|
|
77
|
+
strapi.telemetry.send('didExportAuditLogs');
|
|
78
|
+
}
|
|
29
79
|
}
|
|
30
80
|
};
|
|
31
81
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.js","sources":["../../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { validateFindMany, validateFindManyUsers } from '../validation/audit-logs';\n\nexport default {\n async findMany(ctx: Context) {\n const { query } = ctx.request;\n await validateFindMany(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findMany(query);\n\n ctx.body = body;\n },\n\n async findManyUsers(ctx: Context) {\n const { query } = ctx.request;\n const { page, pageSize } = await validateFindManyUsers(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findManyUsers({ page, pageSize });\n\n ctx.body = body;\n },\n\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findOne(id);\n\n ctx.body = body;\n\n strapi.telemetry.send('didWatchAnAuditLog');\n },\n};\n"],"names":["findMany","ctx","query","request","validateFindMany","auditLogs","strapi","get","body","findManyUsers","page","pageSize","validateFindManyUsers","findOne","id","params","telemetry","send"],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit-logs.js","sources":["../../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"sourcesContent":["import { createGzip } from 'zlib';\n\nimport type { Context } from 'koa';\nimport { errors } from '@strapi/utils';\n\nimport {\n AUDIT_LOGS_EXPORT_CURSOR_DONE,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n} from '../../../../../shared/utils/audit-log-export';\nimport { validateExport, validateFindMany, validateFindManyUsers } from '../validation/audit-logs';\n\nconst EXPORT_INVALID_CONTINUATION_MESSAGE =\n 'The export continuation is invalid or has expired. Restart the export.';\nconst EXPORT_TOO_LARGE_MESSAGE =\n 'The export matches more entries than the configured limit. Add filters to reduce it.';\n\nexport default {\n async findMany(ctx: Context) {\n const { query } = ctx.request;\n await validateFindMany(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findMany(query);\n\n ctx.body = body;\n },\n\n async findManyUsers(ctx: Context) {\n const { query } = ctx.request;\n const { page, pageSize } = await validateFindManyUsers(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findManyUsers({ page, pageSize });\n\n ctx.body = body;\n },\n\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findOne(id);\n\n ctx.body = body;\n\n strapi.telemetry.send('didWatchAnAuditLog');\n },\n\n async export(ctx: Context) {\n const { query } = ctx.request;\n const validatedQuery = await validateExport(query);\n\n const auditLogs = strapi.get('audit-logs');\n\n const isContinuation = validatedQuery.cursor !== undefined;\n\n if (isContinuation && !auditLogs.isTrustedContinuation(validatedQuery)) {\n throw new errors.ValidationError(EXPORT_INVALID_CONTINUATION_MESSAGE);\n }\n\n if (!isContinuation) {\n if (await auditLogs.isExportTooLarge({ filters: validatedQuery.filters ?? null })) {\n throw new errors.PayloadTooLargeError(EXPORT_TOO_LARGE_MESSAGE);\n }\n }\n\n const { stream, nextCursor, until, isNewExport, partSize, exportToken } =\n await auditLogs.createExportStream(validatedQuery);\n\n const date = new Date().toISOString().slice(0, 10);\n\n ctx.set('Content-Type', 'text/csv; charset=utf-8');\n ctx.set('Content-Disposition', `attachment; filename=\"audit-logs-${date}.csv\"`);\n ctx.set(AUDIT_LOGS_EXPORT_UNTIL_HEADER, String(until));\n ctx.set(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, String(partSize));\n ctx.set(AUDIT_LOGS_EXPORT_TOKEN_HEADER, exportToken);\n ctx.set(\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n nextCursor !== null ? String(nextCursor) : AUDIT_LOGS_EXPORT_CURSOR_DONE\n );\n\n const exposedHeaders = [\n ctx.response.get('Access-Control-Expose-Headers'),\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n 'Content-Disposition',\n ]\n .filter(Boolean)\n .join(', ');\n ctx.set('Access-Control-Expose-Headers', exposedHeaders);\n\n ctx.vary('Accept-Encoding');\n if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip') {\n ctx.set('Content-Encoding', 'gzip');\n const gzip = createGzip();\n stream.on('error', (error: Error) => gzip.destroy(error));\n ctx.body = stream.pipe(gzip);\n } else {\n ctx.body = stream;\n }\n\n if (isNewExport) {\n strapi.telemetry.send('didExportAuditLogs');\n }\n },\n};\n"],"names":["EXPORT_INVALID_CONTINUATION_MESSAGE","EXPORT_TOO_LARGE_MESSAGE","findMany","ctx","query","request","validateFindMany","auditLogs","strapi","get","body","findManyUsers","page","pageSize","validateFindManyUsers","findOne","id","params","telemetry","send","export","validatedQuery","validateExport","isContinuation","cursor","undefined","isTrustedContinuation","errors","ValidationError","isExportTooLarge","filters","PayloadTooLargeError","stream","nextCursor","until","isNewExport","partSize","exportToken","createExportStream","date","Date","toISOString","slice","set","AUDIT_LOGS_EXPORT_UNTIL_HEADER","String","AUDIT_LOGS_EXPORT_PART_SIZE_HEADER","AUDIT_LOGS_EXPORT_TOKEN_HEADER","AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER","AUDIT_LOGS_EXPORT_CURSOR_DONE","exposedHeaders","response","filter","Boolean","join","vary","acceptsEncodings","gzip","createGzip","on","error","destroy","pipe"],"mappings":"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"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createGzip } from 'zlib';
|
|
2
|
+
import { errors } from '@strapi/utils';
|
|
3
|
+
import { AUDIT_LOGS_EXPORT_UNTIL_HEADER, AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, AUDIT_LOGS_EXPORT_TOKEN_HEADER, AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER, AUDIT_LOGS_EXPORT_CURSOR_DONE } from '../../../../../shared/utils/audit-log-export.mjs';
|
|
4
|
+
import { validateExport, validateFindManyUsers, validateFindMany } from '../validation/audit-logs.mjs';
|
|
2
5
|
|
|
6
|
+
const EXPORT_INVALID_CONTINUATION_MESSAGE = 'The export continuation is invalid or has expired. Restart the export.';
|
|
7
|
+
const EXPORT_TOO_LARGE_MESSAGE = 'The export matches more entries than the configured limit. Add filters to reduce it.';
|
|
3
8
|
var auditLogsController = {
|
|
4
9
|
async findMany (ctx) {
|
|
5
10
|
const { query } = ctx.request;
|
|
@@ -24,6 +29,51 @@ var auditLogsController = {
|
|
|
24
29
|
const body = await auditLogs.findOne(id);
|
|
25
30
|
ctx.body = body;
|
|
26
31
|
strapi.telemetry.send('didWatchAnAuditLog');
|
|
32
|
+
},
|
|
33
|
+
async export (ctx) {
|
|
34
|
+
const { query } = ctx.request;
|
|
35
|
+
const validatedQuery = await validateExport(query);
|
|
36
|
+
const auditLogs = strapi.get('audit-logs');
|
|
37
|
+
const isContinuation = validatedQuery.cursor !== undefined;
|
|
38
|
+
if (isContinuation && !auditLogs.isTrustedContinuation(validatedQuery)) {
|
|
39
|
+
throw new errors.ValidationError(EXPORT_INVALID_CONTINUATION_MESSAGE);
|
|
40
|
+
}
|
|
41
|
+
if (!isContinuation) {
|
|
42
|
+
if (await auditLogs.isExportTooLarge({
|
|
43
|
+
filters: validatedQuery.filters ?? null
|
|
44
|
+
})) {
|
|
45
|
+
throw new errors.PayloadTooLargeError(EXPORT_TOO_LARGE_MESSAGE);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const { stream, nextCursor, until, isNewExport, partSize, exportToken } = await auditLogs.createExportStream(validatedQuery);
|
|
49
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
50
|
+
ctx.set('Content-Type', 'text/csv; charset=utf-8');
|
|
51
|
+
ctx.set('Content-Disposition', `attachment; filename="audit-logs-${date}.csv"`);
|
|
52
|
+
ctx.set(AUDIT_LOGS_EXPORT_UNTIL_HEADER, String(until));
|
|
53
|
+
ctx.set(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, String(partSize));
|
|
54
|
+
ctx.set(AUDIT_LOGS_EXPORT_TOKEN_HEADER, exportToken);
|
|
55
|
+
ctx.set(AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER, nextCursor !== null ? String(nextCursor) : AUDIT_LOGS_EXPORT_CURSOR_DONE);
|
|
56
|
+
const exposedHeaders = [
|
|
57
|
+
ctx.response.get('Access-Control-Expose-Headers'),
|
|
58
|
+
AUDIT_LOGS_EXPORT_UNTIL_HEADER,
|
|
59
|
+
AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,
|
|
60
|
+
AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,
|
|
61
|
+
AUDIT_LOGS_EXPORT_TOKEN_HEADER,
|
|
62
|
+
'Content-Disposition'
|
|
63
|
+
].filter(Boolean).join(', ');
|
|
64
|
+
ctx.set('Access-Control-Expose-Headers', exposedHeaders);
|
|
65
|
+
ctx.vary('Accept-Encoding');
|
|
66
|
+
if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip') {
|
|
67
|
+
ctx.set('Content-Encoding', 'gzip');
|
|
68
|
+
const gzip = createGzip();
|
|
69
|
+
stream.on('error', (error)=>gzip.destroy(error));
|
|
70
|
+
ctx.body = stream.pipe(gzip);
|
|
71
|
+
} else {
|
|
72
|
+
ctx.body = stream;
|
|
73
|
+
}
|
|
74
|
+
if (isNewExport) {
|
|
75
|
+
strapi.telemetry.send('didExportAuditLogs');
|
|
76
|
+
}
|
|
27
77
|
}
|
|
28
78
|
};
|
|
29
79
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-logs.mjs","sources":["../../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { validateFindMany, validateFindManyUsers } from '../validation/audit-logs';\n\nexport default {\n async findMany(ctx: Context) {\n const { query } = ctx.request;\n await validateFindMany(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findMany(query);\n\n ctx.body = body;\n },\n\n async findManyUsers(ctx: Context) {\n const { query } = ctx.request;\n const { page, pageSize } = await validateFindManyUsers(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findManyUsers({ page, pageSize });\n\n ctx.body = body;\n },\n\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findOne(id);\n\n ctx.body = body;\n\n strapi.telemetry.send('didWatchAnAuditLog');\n },\n};\n"],"names":["findMany","ctx","query","request","validateFindMany","auditLogs","strapi","get","body","findManyUsers","page","pageSize","validateFindManyUsers","findOne","id","params","telemetry","send"],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit-logs.mjs","sources":["../../../../../../../ee/server/src/audit-logs/controllers/audit-logs.ts"],"sourcesContent":["import { createGzip } from 'zlib';\n\nimport type { Context } from 'koa';\nimport { errors } from '@strapi/utils';\n\nimport {\n AUDIT_LOGS_EXPORT_CURSOR_DONE,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n} from '../../../../../shared/utils/audit-log-export';\nimport { validateExport, validateFindMany, validateFindManyUsers } from '../validation/audit-logs';\n\nconst EXPORT_INVALID_CONTINUATION_MESSAGE =\n 'The export continuation is invalid or has expired. Restart the export.';\nconst EXPORT_TOO_LARGE_MESSAGE =\n 'The export matches more entries than the configured limit. Add filters to reduce it.';\n\nexport default {\n async findMany(ctx: Context) {\n const { query } = ctx.request;\n await validateFindMany(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findMany(query);\n\n ctx.body = body;\n },\n\n async findManyUsers(ctx: Context) {\n const { query } = ctx.request;\n const { page, pageSize } = await validateFindManyUsers(query);\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findManyUsers({ page, pageSize });\n\n ctx.body = body;\n },\n\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const auditLogs = strapi.get('audit-logs');\n const body = await auditLogs.findOne(id);\n\n ctx.body = body;\n\n strapi.telemetry.send('didWatchAnAuditLog');\n },\n\n async export(ctx: Context) {\n const { query } = ctx.request;\n const validatedQuery = await validateExport(query);\n\n const auditLogs = strapi.get('audit-logs');\n\n const isContinuation = validatedQuery.cursor !== undefined;\n\n if (isContinuation && !auditLogs.isTrustedContinuation(validatedQuery)) {\n throw new errors.ValidationError(EXPORT_INVALID_CONTINUATION_MESSAGE);\n }\n\n if (!isContinuation) {\n if (await auditLogs.isExportTooLarge({ filters: validatedQuery.filters ?? null })) {\n throw new errors.PayloadTooLargeError(EXPORT_TOO_LARGE_MESSAGE);\n }\n }\n\n const { stream, nextCursor, until, isNewExport, partSize, exportToken } =\n await auditLogs.createExportStream(validatedQuery);\n\n const date = new Date().toISOString().slice(0, 10);\n\n ctx.set('Content-Type', 'text/csv; charset=utf-8');\n ctx.set('Content-Disposition', `attachment; filename=\"audit-logs-${date}.csv\"`);\n ctx.set(AUDIT_LOGS_EXPORT_UNTIL_HEADER, String(until));\n ctx.set(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, String(partSize));\n ctx.set(AUDIT_LOGS_EXPORT_TOKEN_HEADER, exportToken);\n ctx.set(\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n nextCursor !== null ? String(nextCursor) : AUDIT_LOGS_EXPORT_CURSOR_DONE\n );\n\n const exposedHeaders = [\n ctx.response.get('Access-Control-Expose-Headers'),\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n 'Content-Disposition',\n ]\n .filter(Boolean)\n .join(', ');\n ctx.set('Access-Control-Expose-Headers', exposedHeaders);\n\n ctx.vary('Accept-Encoding');\n if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip') {\n ctx.set('Content-Encoding', 'gzip');\n const gzip = createGzip();\n stream.on('error', (error: Error) => gzip.destroy(error));\n ctx.body = stream.pipe(gzip);\n } else {\n ctx.body = stream;\n }\n\n if (isNewExport) {\n strapi.telemetry.send('didExportAuditLogs');\n }\n },\n};\n"],"names":["EXPORT_INVALID_CONTINUATION_MESSAGE","EXPORT_TOO_LARGE_MESSAGE","findMany","ctx","query","request","validateFindMany","auditLogs","strapi","get","body","findManyUsers","page","pageSize","validateFindManyUsers","findOne","id","params","telemetry","send","export","validatedQuery","validateExport","isContinuation","cursor","undefined","isTrustedContinuation","errors","ValidationError","isExportTooLarge","filters","PayloadTooLargeError","stream","nextCursor","until","isNewExport","partSize","exportToken","createExportStream","date","Date","toISOString","slice","set","AUDIT_LOGS_EXPORT_UNTIL_HEADER","String","AUDIT_LOGS_EXPORT_PART_SIZE_HEADER","AUDIT_LOGS_EXPORT_TOKEN_HEADER","AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER","AUDIT_LOGS_EXPORT_CURSOR_DONE","exposedHeaders","response","filter","Boolean","join","vary","acceptsEncodings","gzip","createGzip","on","error","destroy","pipe"],"mappings":"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"}
|