@strapi/upload 5.60.0 → 5.61.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 (91) hide show
  1. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
  2. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
  3. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
  4. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
  5. package/dist/admin/components/Drawer.js +12 -7
  6. package/dist/admin/components/Drawer.js.map +1 -1
  7. package/dist/admin/components/Drawer.mjs +12 -7
  8. package/dist/admin/components/Drawer.mjs.map +1 -1
  9. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
  10. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
  11. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
  12. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
  13. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +5 -1
  14. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  15. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +5 -1
  16. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  17. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +37 -27
  18. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  19. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +37 -27
  20. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  21. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
  22. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
  23. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
  24. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
  25. package/dist/admin/index.js +10 -1
  26. package/dist/admin/index.js.map +1 -1
  27. package/dist/admin/index.mjs +10 -1
  28. package/dist/admin/index.mjs.map +1 -1
  29. package/dist/admin/pages/Assets/AssetsPage.js +1 -1
  30. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  31. package/dist/admin/pages/Assets/AssetsPage.mjs +2 -2
  32. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  33. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
  34. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
  35. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  36. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
  37. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  38. package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
  39. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
  40. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
  41. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
  42. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
  43. package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
  44. package/dist/admin/src/components/Drawer.d.ts +8 -0
  45. package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
  46. package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
  47. package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
  48. package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
  49. package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
  50. package/dist/admin/translations/en.json.js +4 -0
  51. package/dist/admin/translations/en.json.js.map +1 -1
  52. package/dist/admin/translations/en.json.mjs +4 -0
  53. package/dist/admin/translations/en.json.mjs.map +1 -1
  54. package/dist/server/audit-logs.js +264 -0
  55. package/dist/server/audit-logs.js.map +1 -0
  56. package/dist/server/audit-logs.mjs +255 -0
  57. package/dist/server/audit-logs.mjs.map +1 -0
  58. package/dist/server/bootstrap.js +4 -0
  59. package/dist/server/bootstrap.js.map +1 -1
  60. package/dist/server/bootstrap.mjs +4 -0
  61. package/dist/server/bootstrap.mjs.map +1 -1
  62. package/dist/server/controllers/admin-folder-file.js +23 -1
  63. package/dist/server/controllers/admin-folder-file.js.map +1 -1
  64. package/dist/server/controllers/admin-folder-file.mjs +23 -1
  65. package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
  66. package/dist/server/services/folder.js +48 -1
  67. package/dist/server/services/folder.js.map +1 -1
  68. package/dist/server/services/folder.mjs +48 -1
  69. package/dist/server/services/folder.mjs.map +1 -1
  70. package/dist/server/services/image-manipulation.js +12 -5
  71. package/dist/server/services/image-manipulation.js.map +1 -1
  72. package/dist/server/services/image-manipulation.mjs +12 -5
  73. package/dist/server/services/image-manipulation.mjs.map +1 -1
  74. package/dist/server/services/upload.js +100 -16
  75. package/dist/server/services/upload.js.map +1 -1
  76. package/dist/server/services/upload.mjs +102 -18
  77. package/dist/server/services/upload.mjs.map +1 -1
  78. package/dist/server/src/audit-logs.d.ts +142 -0
  79. package/dist/server/src/audit-logs.d.ts.map +1 -0
  80. package/dist/server/src/bootstrap.d.ts.map +1 -1
  81. package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
  82. package/dist/server/src/index.d.ts +3 -3
  83. package/dist/server/src/index.d.ts.map +1 -1
  84. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  85. package/dist/server/src/services/folder.d.ts.map +1 -1
  86. package/dist/server/src/services/image-manipulation.d.ts +3 -3
  87. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  88. package/dist/server/src/services/index.d.ts +3 -3
  89. package/dist/server/src/services/index.d.ts.map +1 -1
  90. package/dist/server/src/services/upload.d.ts.map +1 -1
  91. package/package.json +9 -16
@@ -0,0 +1,255 @@
1
+ import { emitAudit } from '@strapi/utils';
2
+
3
+ const AUDITED_EVENTS = {
4
+ UPLOAD_SETTINGS_UPDATE: 'upload-settings.update',
5
+ MEDIA_CREATE: 'media.create',
6
+ MEDIA_UPDATE: 'media.update',
7
+ MEDIA_DELETE: 'media.delete',
8
+ MEDIA_MOVE: 'media.move',
9
+ FOLDER_CREATE: 'media-folder.create',
10
+ FOLDER_UPDATE: 'media-folder.update',
11
+ // Audit-only events. media.update is a webhook event that carries neither the file as it was
12
+ // nor its folder; media-folder.delete carries every deleted folder in one event.
13
+ MEDIA_UPDATE_AUDIT: 'media.update.audit',
14
+ FOLDER_DELETE_AUDIT: 'media-folder.delete.audit'
15
+ };
16
+ const AUDITED_SETTINGS = [
17
+ 'sizeOptimization',
18
+ 'responsiveDimensions',
19
+ 'autoOrientation',
20
+ 'aiMetadata'
21
+ ];
22
+ // The store replaces the whole value, so an option missing from the request is removed and recorded as null.
23
+ const getUploadSettingsChanges = (previous, next)=>{
24
+ const changes = {};
25
+ for (const setting of AUDITED_SETTINGS){
26
+ const before = previous?.[setting] ?? null;
27
+ const after = next[setting] ?? null;
28
+ if (before !== after) {
29
+ changes[setting] = {
30
+ before,
31
+ after
32
+ };
33
+ }
34
+ }
35
+ return changes;
36
+ };
37
+ const toFolderRef = (folder)=>folder ? {
38
+ id: Number(folder.id),
39
+ name: folder.name ?? null
40
+ } : null;
41
+ /** Picks the fields the audit log compares. */ const toAuditedFile = (file)=>({
42
+ id: Number(file.id),
43
+ name: file.name,
44
+ mime: file.mime,
45
+ size: file.size,
46
+ alternativeText: file.alternativeText ?? null,
47
+ caption: file.caption ?? null,
48
+ focalPoint: file.focalPoint ?? null,
49
+ folder: toFolderRef(file.folder)
50
+ });
51
+ const summarizeFile = (file)=>({
52
+ name: file.name,
53
+ mime: file.mime ?? null,
54
+ size: file.size ?? null
55
+ });
56
+ const getMediaChanges = ({ file: media, previous, replaced })=>{
57
+ const changes = {};
58
+ if (previous.name !== media.name) {
59
+ changes.name = {
60
+ before: previous.name,
61
+ after: media.name
62
+ };
63
+ }
64
+ // The admin sends '' for an empty field that is stored as null
65
+ const blankAsNull = (value)=>value || null;
66
+ for (const field of [
67
+ 'alternativeText',
68
+ 'caption'
69
+ ]){
70
+ const before = previous[field] ?? null;
71
+ const after = media[field] ?? null;
72
+ if (blankAsNull(before) !== blankAsNull(after)) {
73
+ changes[field] = {
74
+ before,
75
+ after
76
+ };
77
+ }
78
+ }
79
+ const focalBefore = previous.focalPoint ?? null;
80
+ const focalAfter = media.focalPoint ?? null;
81
+ if (JSON.stringify(focalBefore) !== JSON.stringify(focalAfter)) {
82
+ changes.focalPoint = {
83
+ before: focalBefore,
84
+ after: focalAfter
85
+ };
86
+ }
87
+ const folderBefore = toFolderRef(previous.folder);
88
+ const folderAfter = toFolderRef(media.folder);
89
+ if ((folderBefore?.id ?? null) !== (folderAfter?.id ?? null)) {
90
+ changes.folder = {
91
+ before: folderBefore,
92
+ after: folderAfter
93
+ };
94
+ }
95
+ if (replaced) {
96
+ changes.file = {
97
+ before: summarizeFile(previous),
98
+ after: summarizeFile(media)
99
+ };
100
+ }
101
+ return changes;
102
+ };
103
+ const getFolderChanges = ({ folder, previous })=>{
104
+ if (!previous) {
105
+ return {};
106
+ }
107
+ const changes = {};
108
+ if (previous.name !== folder.name) {
109
+ changes.name = {
110
+ before: previous.name,
111
+ after: folder.name
112
+ };
113
+ }
114
+ const parentBefore = toFolderRef(previous.parent);
115
+ const parentAfter = toFolderRef(folder.parent);
116
+ if ((parentBefore?.id ?? null) !== (parentAfter?.id ?? null)) {
117
+ changes.parent = {
118
+ before: parentBefore,
119
+ after: parentAfter
120
+ };
121
+ }
122
+ return changes;
123
+ };
124
+ const readParents = async (read, joinTable, ids)=>{
125
+ if (ids.length === 0) {
126
+ return new Map();
127
+ }
128
+ const { joinColumn, inverseJoinColumn } = joinTable;
129
+ const rows = await read(joinTable.name).select(joinColumn.name, inverseJoinColumn.name).whereIn(joinColumn.name, ids);
130
+ return new Map(rows.map((row)=>[
131
+ Number(row[joinColumn.name]),
132
+ Number(row[inverseJoinColumn.name])
133
+ ]));
134
+ };
135
+ const readMediaMoves = async (read, { files, folders, destinationFolderId, fileFolderJoinTable, folderParentJoinTable, folderTable })=>{
136
+ const fileParents = await readParents(read, fileFolderJoinTable, files.map((file)=>Number(file.id)));
137
+ const folderParents = await readParents(read, folderParentJoinTable, folders.map((folder)=>Number(folder.id)));
138
+ const destinationId = destinationFolderId === null ? null : Number(destinationFolderId);
139
+ const referencedIds = new Set([
140
+ ...fileParents.values(),
141
+ ...folderParents.values()
142
+ ]);
143
+ if (destinationId !== null) {
144
+ referencedIds.add(destinationId);
145
+ }
146
+ const folderNames = new Map();
147
+ if (referencedIds.size > 0) {
148
+ const rows = await read(folderTable).select('id', 'name').whereIn('id', [
149
+ ...referencedIds
150
+ ]);
151
+ rows.forEach((row)=>folderNames.set(Number(row.id), row.name ?? null));
152
+ }
153
+ const toRef = (id)=>id == null ? null : {
154
+ id,
155
+ name: folderNames.get(id) ?? null
156
+ };
157
+ const to = toRef(destinationId);
158
+ return [
159
+ ...files.map((file)=>({
160
+ kind: 'file',
161
+ id: Number(file.id),
162
+ name: file.name,
163
+ from: toRef(fileParents.get(Number(file.id))),
164
+ to
165
+ })),
166
+ ...folders.map((folder)=>({
167
+ kind: 'folder',
168
+ id: Number(folder.id),
169
+ name: folder.name,
170
+ from: toRef(folderParents.get(Number(folder.id))),
171
+ to
172
+ }))
173
+ ];
174
+ };
175
+ const emitMediaMoves = async ({ strapi }, moves)=>{
176
+ for (const move of moves){
177
+ if ((move.from?.id ?? null) !== (move.to?.id ?? null)) {
178
+ await emitAudit({
179
+ strapi
180
+ }, AUDITED_EVENTS.MEDIA_MOVE, move);
181
+ }
182
+ }
183
+ };
184
+ const registerAuditEvents = (auditLogsLifecycle)=>{
185
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.UPLOAD_SETTINGS_UPDATE, (event)=>({
186
+ resource: {
187
+ type: 'upload-settings'
188
+ },
189
+ details: {
190
+ changes: event.changes
191
+ }
192
+ }));
193
+ const fileResource = (file)=>({
194
+ type: 'media',
195
+ id: Number(file.id),
196
+ name: file.name
197
+ });
198
+ const folderResource = (folder)=>({
199
+ type: 'media-folder',
200
+ id: Number(folder.id),
201
+ name: folder.name
202
+ });
203
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.MEDIA_CREATE, ({ media })=>({
204
+ resource: fileResource(media),
205
+ details: {
206
+ mime: media.mime ?? null,
207
+ size: media.size ?? null
208
+ }
209
+ }));
210
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.MEDIA_UPDATE_AUDIT, (event)=>({
211
+ resource: fileResource(event.file),
212
+ details: {
213
+ changes: getMediaChanges(event)
214
+ }
215
+ }), {
216
+ action: AUDITED_EVENTS.MEDIA_UPDATE,
217
+ shouldRecord: (event)=>Object.keys(getMediaChanges(event)).length > 0
218
+ });
219
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.MEDIA_DELETE, ({ media })=>({
220
+ resource: fileResource(media)
221
+ }));
222
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.FOLDER_CREATE, ({ folder })=>({
223
+ resource: folderResource(folder)
224
+ }), {
225
+ action: AUDITED_EVENTS.MEDIA_CREATE
226
+ });
227
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.FOLDER_UPDATE, (event)=>({
228
+ resource: folderResource(event.folder),
229
+ details: {
230
+ changes: getFolderChanges(event)
231
+ }
232
+ }), {
233
+ action: AUDITED_EVENTS.MEDIA_UPDATE,
234
+ shouldRecord: (event)=>Object.keys(getFolderChanges(event)).length > 0
235
+ });
236
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.FOLDER_DELETE_AUDIT, ({ folder })=>({
237
+ resource: folderResource(folder)
238
+ }), {
239
+ action: AUDITED_EVENTS.MEDIA_DELETE
240
+ });
241
+ auditLogsLifecycle.registerEvent(AUDITED_EVENTS.MEDIA_MOVE, (event)=>({
242
+ resource: {
243
+ type: event.kind === 'file' ? 'media' : 'media-folder',
244
+ id: event.id,
245
+ name: event.name
246
+ },
247
+ details: {
248
+ from: event.from,
249
+ to: event.to
250
+ }
251
+ }));
252
+ };
253
+
254
+ export { AUDITED_EVENTS, emitMediaMoves, getFolderChanges, getMediaChanges, getUploadSettingsChanges, readMediaMoves, registerAuditEvents, toAuditedFile };
255
+ //# sourceMappingURL=audit-logs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logs.mjs","sources":["../../server/src/audit-logs.ts"],"sourcesContent":["import { emitAudit } from '@strapi/utils';\nimport type { Core, Modules } from '@strapi/types';\n\nimport type { Settings } from './controllers/validation/admin/settings';\n\nexport const AUDITED_EVENTS = {\n UPLOAD_SETTINGS_UPDATE: 'upload-settings.update',\n MEDIA_CREATE: 'media.create',\n MEDIA_UPDATE: 'media.update',\n MEDIA_DELETE: 'media.delete',\n MEDIA_MOVE: 'media.move',\n FOLDER_CREATE: 'media-folder.create',\n FOLDER_UPDATE: 'media-folder.update',\n // Audit-only events. media.update is a webhook event that carries neither the file as it was\n // nor its folder; media-folder.delete carries every deleted folder in one event.\n MEDIA_UPDATE_AUDIT: 'media.update.audit',\n FOLDER_DELETE_AUDIT: 'media-folder.delete.audit',\n} as const;\n\nconst AUDITED_SETTINGS = [\n 'sizeOptimization',\n 'responsiveDimensions',\n 'autoOrientation',\n 'aiMetadata',\n] as const;\n\nexport type UploadSettingsChanges = Partial<\n Record<(typeof AUDITED_SETTINGS)[number], Modules.AuditLogs.FieldChange<boolean | null>>\n>;\n\nexport interface SettingsUpdateDetails {\n changes: UploadSettingsChanges;\n}\n\n// The store replaces the whole value, so an option missing from the request is removed and recorded as null.\nexport const getUploadSettingsChanges = (\n previous: Partial<Settings> | null,\n next: Partial<Settings>\n): UploadSettingsChanges => {\n const changes: UploadSettingsChanges = {};\n\n for (const setting of AUDITED_SETTINGS) {\n const before = previous?.[setting] ?? null;\n const after = next[setting] ?? null;\n\n if (before !== after) {\n changes[setting] = { before, after };\n }\n }\n\n return changes;\n};\n\ninterface FolderRef {\n id: number;\n name: string | null;\n}\n\nexport interface MediaMoveEvent {\n kind: 'file' | 'folder';\n id: number;\n name: string;\n from: FolderRef | null;\n to: FolderRef | null;\n}\n\nexport interface MoveDetails {\n from: FolderRef | null;\n to: FolderRef | null;\n}\n\nconst toFolderRef = (folder: { id: number | string; name?: string | null } | null | undefined) =>\n folder ? { id: Number(folder.id), name: folder.name ?? null } : null;\n\ninterface MediaFile {\n id: number;\n name: string;\n mime?: string;\n size?: number;\n alternativeText?: string | null;\n caption?: string | null;\n focalPoint?: { x: number; y: number } | null;\n folder?: { id: number; name: string | null } | null;\n}\n\n/** The payload of media.create and media.delete, which are also webhook events. */\nexport interface MediaEvent {\n media: MediaFile;\n}\n\nexport interface MediaUpdateEvent {\n file: MediaFile;\n previous: MediaFile;\n /** The file's content was replaced. It keeps its hash and url, so no field shows it. */\n replaced?: boolean;\n}\n\n/** Picks the fields the audit log compares. */\nexport const toAuditedFile = (file: Record<string, any>): MediaFile => ({\n id: Number(file.id),\n name: file.name,\n mime: file.mime,\n size: file.size,\n alternativeText: file.alternativeText ?? null,\n caption: file.caption ?? null,\n focalPoint: file.focalPoint ?? null,\n folder: toFolderRef(file.folder),\n});\n\ninterface FileSummary {\n name: string;\n mime: string | null;\n size: number | null;\n}\n\nexport interface MediaChanges {\n name?: Modules.AuditLogs.FieldChange<string>;\n alternativeText?: Modules.AuditLogs.FieldChange<string | null>;\n caption?: Modules.AuditLogs.FieldChange<string | null>;\n focalPoint?: Modules.AuditLogs.FieldChange<{ x: number; y: number } | null>;\n folder?: Modules.AuditLogs.FieldChange<FolderRef | null>;\n file?: Modules.AuditLogs.FieldChange<FileSummary>;\n}\n\nconst summarizeFile = (file: MediaFile): FileSummary => ({\n name: file.name,\n mime: file.mime ?? null,\n size: file.size ?? null,\n});\n\nexport const getMediaChanges = ({\n file: media,\n previous,\n replaced,\n}: MediaUpdateEvent): MediaChanges => {\n const changes: MediaChanges = {};\n\n if (previous.name !== media.name) {\n changes.name = { before: previous.name, after: media.name };\n }\n\n // The admin sends '' for an empty field that is stored as null\n const blankAsNull = (value: string | null | undefined) => value || null;\n for (const field of ['alternativeText', 'caption'] as const) {\n const before = previous[field] ?? null;\n const after = media[field] ?? null;\n if (blankAsNull(before) !== blankAsNull(after)) {\n changes[field] = { before, after };\n }\n }\n\n const focalBefore = previous.focalPoint ?? null;\n const focalAfter = media.focalPoint ?? null;\n if (JSON.stringify(focalBefore) !== JSON.stringify(focalAfter)) {\n changes.focalPoint = { before: focalBefore, after: focalAfter };\n }\n\n const folderBefore = toFolderRef(previous.folder);\n const folderAfter = toFolderRef(media.folder);\n if ((folderBefore?.id ?? null) !== (folderAfter?.id ?? null)) {\n changes.folder = { before: folderBefore, after: folderAfter };\n }\n\n if (replaced) {\n changes.file = { before: summarizeFile(previous), after: summarizeFile(media) };\n }\n\n return changes;\n};\n\ninterface MediaFolder {\n id: number;\n name: string;\n parent?: { id: number; name: string | null } | null;\n}\n\n/** The payload of the media-folder.* events. They are not webhook events. */\nexport interface FolderEvent {\n folder: MediaFolder;\n previous?: MediaFolder;\n}\n\nexport interface FolderChanges {\n name?: Modules.AuditLogs.FieldChange<string>;\n parent?: Modules.AuditLogs.FieldChange<FolderRef | null>;\n}\n\nexport const getFolderChanges = ({ folder, previous }: FolderEvent): FolderChanges => {\n if (!previous) {\n return {};\n }\n\n const changes: FolderChanges = {};\n\n if (previous.name !== folder.name) {\n changes.name = { before: previous.name, after: folder.name };\n }\n\n const parentBefore = toFolderRef(previous.parent);\n const parentAfter = toFolderRef(folder.parent);\n if ((parentBefore?.id ?? null) !== (parentAfter?.id ?? null)) {\n changes.parent = { before: parentBefore, after: parentAfter };\n }\n\n return changes;\n};\n\ninterface JoinTable {\n name: string;\n joinColumn: { name: string };\n inverseJoinColumn: { name: string };\n}\n\n/** Reads rows of a table inside the move transaction. */\ntype ReadTable = (table: string | undefined) => {\n select(...columns: string[]): {\n whereIn(column: string, values: readonly number[]): PromiseLike<Record<string, any>[]>;\n };\n};\n\nconst readParents = async (read: ReadTable, joinTable: JoinTable, ids: number[]) => {\n if (ids.length === 0) {\n return new Map<number, number>();\n }\n\n const { joinColumn, inverseJoinColumn } = joinTable;\n const rows = await read(joinTable.name)\n .select(joinColumn.name, inverseJoinColumn.name)\n .whereIn(joinColumn.name, ids);\n\n return new Map(\n rows.map((row) => [Number(row[joinColumn.name]), Number(row[inverseJoinColumn.name])])\n );\n};\n\nexport const readMediaMoves = async (\n read: ReadTable,\n {\n files,\n folders,\n destinationFolderId,\n fileFolderJoinTable,\n folderParentJoinTable,\n folderTable,\n }: {\n files: Array<{ id: number | string; name: string }>;\n folders: Array<{ id: number | string; name: string }>;\n destinationFolderId: number | string | null;\n fileFolderJoinTable: JoinTable;\n folderParentJoinTable: JoinTable;\n folderTable: string | undefined;\n }\n): Promise<MediaMoveEvent[]> => {\n const fileParents = await readParents(\n read,\n fileFolderJoinTable,\n files.map((file) => Number(file.id))\n );\n const folderParents = await readParents(\n read,\n folderParentJoinTable,\n folders.map((folder) => Number(folder.id))\n );\n\n const destinationId = destinationFolderId === null ? null : Number(destinationFolderId);\n const referencedIds = new Set([...fileParents.values(), ...folderParents.values()]);\n if (destinationId !== null) {\n referencedIds.add(destinationId);\n }\n\n const folderNames = new Map<number, string | null>();\n if (referencedIds.size > 0) {\n const rows = await read(folderTable)\n .select('id', 'name')\n .whereIn('id', [...referencedIds]);\n rows.forEach((row) => folderNames.set(Number(row.id), row.name ?? null));\n }\n\n const toRef = (id: number | null | undefined): FolderRef | null =>\n id == null ? null : { id, name: folderNames.get(id) ?? null };\n\n const to = toRef(destinationId);\n\n return [\n ...files.map((file) => ({\n kind: 'file' as const,\n id: Number(file.id),\n name: file.name,\n from: toRef(fileParents.get(Number(file.id))),\n to,\n })),\n ...folders.map((folder) => ({\n kind: 'folder' as const,\n id: Number(folder.id),\n name: folder.name,\n from: toRef(folderParents.get(Number(folder.id))),\n to,\n })),\n ];\n};\n\nexport const emitMediaMoves = async (\n { strapi }: { strapi: Core.Strapi },\n moves: MediaMoveEvent[]\n) => {\n for (const move of moves) {\n if ((move.from?.id ?? null) !== (move.to?.id ?? null)) {\n await emitAudit({ strapi }, AUDITED_EVENTS.MEDIA_MOVE, move);\n }\n }\n};\n\n/**\n * The part of the audit-logs lifecycle service used by this plugin.\n * The full service type lives in the Admin EE package and cannot be imported here.\n */\ninterface AuditLogsLifecycle {\n registerEvent<TDetails>(\n name: string,\n transform: Modules.AuditLogs.EventTransformer<TDetails>,\n options?: { action?: string; shouldRecord?: (...args: any[]) => boolean }\n ): void;\n}\n\nexport const registerAuditEvents = (auditLogsLifecycle: AuditLogsLifecycle) => {\n auditLogsLifecycle.registerEvent<SettingsUpdateDetails>(\n AUDITED_EVENTS.UPLOAD_SETTINGS_UPDATE,\n (event: SettingsUpdateDetails) => ({\n resource: { type: 'upload-settings' },\n details: { changes: event.changes },\n })\n );\n\n const fileResource = (file: MediaFile) => ({\n type: 'media',\n id: Number(file.id),\n name: file.name,\n });\n const folderResource = (folder: MediaFolder) => ({\n type: 'media-folder',\n id: Number(folder.id),\n name: folder.name,\n });\n\n auditLogsLifecycle.registerEvent<{ mime: string | null; size: number | null }>(\n AUDITED_EVENTS.MEDIA_CREATE,\n ({ media }: MediaEvent) => ({\n resource: fileResource(media),\n details: { mime: media.mime ?? null, size: media.size ?? null },\n })\n );\n\n auditLogsLifecycle.registerEvent<{ changes: MediaChanges }>(\n AUDITED_EVENTS.MEDIA_UPDATE_AUDIT,\n (event: MediaUpdateEvent) => ({\n resource: fileResource(event.file),\n details: { changes: getMediaChanges(event) },\n }),\n {\n action: AUDITED_EVENTS.MEDIA_UPDATE,\n shouldRecord: (event: MediaUpdateEvent) => Object.keys(getMediaChanges(event)).length > 0,\n }\n );\n\n auditLogsLifecycle.registerEvent(AUDITED_EVENTS.MEDIA_DELETE, ({ media }: MediaEvent) => ({\n resource: fileResource(media),\n }));\n\n auditLogsLifecycle.registerEvent(\n AUDITED_EVENTS.FOLDER_CREATE,\n ({ folder }: FolderEvent) => ({ resource: folderResource(folder) }),\n { action: AUDITED_EVENTS.MEDIA_CREATE }\n );\n\n auditLogsLifecycle.registerEvent<{ changes: FolderChanges }>(\n AUDITED_EVENTS.FOLDER_UPDATE,\n (event: FolderEvent) => ({\n resource: folderResource(event.folder),\n details: { changes: getFolderChanges(event) },\n }),\n {\n action: AUDITED_EVENTS.MEDIA_UPDATE,\n shouldRecord: (event: FolderEvent) => Object.keys(getFolderChanges(event)).length > 0,\n }\n );\n\n auditLogsLifecycle.registerEvent(\n AUDITED_EVENTS.FOLDER_DELETE_AUDIT,\n ({ folder }: FolderEvent) => ({ resource: folderResource(folder) }),\n { action: AUDITED_EVENTS.MEDIA_DELETE }\n );\n\n auditLogsLifecycle.registerEvent<MoveDetails>(\n AUDITED_EVENTS.MEDIA_MOVE,\n (event: MediaMoveEvent) => ({\n resource: {\n type: event.kind === 'file' ? 'media' : 'media-folder',\n id: event.id,\n name: event.name,\n },\n details: { from: event.from, to: event.to },\n })\n );\n};\n"],"names":["AUDITED_EVENTS","UPLOAD_SETTINGS_UPDATE","MEDIA_CREATE","MEDIA_UPDATE","MEDIA_DELETE","MEDIA_MOVE","FOLDER_CREATE","FOLDER_UPDATE","MEDIA_UPDATE_AUDIT","FOLDER_DELETE_AUDIT","AUDITED_SETTINGS","getUploadSettingsChanges","previous","next","changes","setting","before","after","toFolderRef","folder","id","Number","name","toAuditedFile","file","mime","size","alternativeText","caption","focalPoint","summarizeFile","getMediaChanges","media","replaced","blankAsNull","value","field","focalBefore","focalAfter","JSON","stringify","folderBefore","folderAfter","getFolderChanges","parentBefore","parent","parentAfter","readParents","read","joinTable","ids","length","Map","joinColumn","inverseJoinColumn","rows","select","whereIn","map","row","readMediaMoves","files","folders","destinationFolderId","fileFolderJoinTable","folderParentJoinTable","folderTable","fileParents","folderParents","destinationId","referencedIds","Set","values","add","folderNames","forEach","set","toRef","get","to","kind","from","emitMediaMoves","strapi","moves","move","emitAudit","registerAuditEvents","auditLogsLifecycle","registerEvent","event","resource","type","details","fileResource","folderResource","action","shouldRecord","Object","keys"],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  var index = require('./utils/index.js');
4
4
  var constants = require('./constants.js');
5
5
  var mediaLibraryDefaultNotice = require('./media-library-default-notice.js');
6
+ var auditLogs = require('./audit-logs.js');
6
7
 
7
8
  async function bootstrap({ strapi: strapi1 }) {
8
9
  const defaultConfig = {
@@ -46,6 +47,9 @@ async function bootstrap({ strapi: strapi1 }) {
46
47
  });
47
48
  await registerPermissionActions();
48
49
  await registerWebhookEvents();
50
+ if (strapi1.has('audit-logs-lifecycle')) {
51
+ auditLogs.registerAuditEvents(strapi1.get('audit-logs-lifecycle'));
52
+ }
49
53
  await index.getService('weeklyMetrics').registerCron();
50
54
  // AI metadata
51
55
  if (strapi1.ai.admin.isAvailable()) {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n // AI metadata\n if (strapi.ai.admin.isAvailable()) {\n const aiMetadataProvider = getService('aiMetadataProvider');\n\n if (!aiMetadataProvider.hasProvider() && strapi.ai.admin.isStrapiManagedAiEnabled()) {\n aiMetadataProvider.registerStrapiManagedProvider();\n }\n }\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","ai","admin","isAvailable","aiMetadataProvider","hasProvider","isStrapiManagedAiEnabled","registerStrapiManagedProvider","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\nimport { registerAuditEvents } from './audit-logs';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n if (strapi.has('audit-logs-lifecycle')) {\n registerAuditEvents(strapi.get('audit-logs-lifecycle'));\n }\n\n await getService('weeklyMetrics').registerCron();\n\n // AI metadata\n if (strapi.ai.admin.isAvailable()) {\n const aiMetadataProvider = getService('aiMetadataProvider');\n\n if (!aiMetadataProvider.hasProvider() && strapi.ai.admin.isStrapiManagedAiEnabled()) {\n aiMetadataProvider.registerStrapiManagedProvider();\n }\n }\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","has","registerAuditEvents","getService","registerCron","ai","admin","isAvailable","aiMetadataProvider","hasProvider","isStrapiManagedAiEnabled","registerStrapiManagedProvider","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { getService } from './utils/index.mjs';
2
2
  import { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants.mjs';
3
3
  import { notifyMediaLibraryDefault } from './media-library-default-notice.mjs';
4
+ import { registerAuditEvents } from './audit-logs.mjs';
4
5
 
5
6
  async function bootstrap({ strapi: strapi1 }) {
6
7
  const defaultConfig = {
@@ -44,6 +45,9 @@ async function bootstrap({ strapi: strapi1 }) {
44
45
  });
45
46
  await registerPermissionActions();
46
47
  await registerWebhookEvents();
48
+ if (strapi1.has('audit-logs-lifecycle')) {
49
+ registerAuditEvents(strapi1.get('audit-logs-lifecycle'));
50
+ }
47
51
  await getService('weeklyMetrics').registerCron();
48
52
  // AI metadata
49
53
  if (strapi1.ai.admin.isAvailable()) {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n // AI metadata\n if (strapi.ai.admin.isAvailable()) {\n const aiMetadataProvider = getService('aiMetadataProvider');\n\n if (!aiMetadataProvider.hasProvider() && strapi.ai.admin.isStrapiManagedAiEnabled()) {\n aiMetadataProvider.registerStrapiManagedProvider();\n }\n }\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","ai","admin","isAvailable","aiMetadataProvider","hasProvider","isStrapiManagedAiEnabled","registerStrapiManagedProvider","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\nimport { registerAuditEvents } from './audit-logs';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n if (strapi.has('audit-logs-lifecycle')) {\n registerAuditEvents(strapi.get('audit-logs-lifecycle'));\n }\n\n await getService('weeklyMetrics').registerCron();\n\n // AI metadata\n if (strapi.ai.admin.isAvailable()) {\n const aiMetadataProvider = getService('aiMetadataProvider');\n\n if (!aiMetadataProvider.hasProvider() && strapi.ai.admin.isStrapiManagedAiEnabled()) {\n aiMetadataProvider.registerStrapiManagedProvider();\n }\n }\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","has","registerAuditEvents","getService","registerCron","ai","admin","isAvailable","aiMetadataProvider","hasProvider","isStrapiManagedAiEnabled","registerStrapiManagedProvider","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
@@ -5,6 +5,7 @@ var index = require('../utils/index.js');
5
5
  var constants = require('../constants.js');
6
6
  var errors = require('../errors.js');
7
7
  var folderFile = require('./validation/admin/folder-file.js');
8
+ var auditLogs = require('../audit-logs.js');
8
9
 
9
10
  var adminFolderFile = {
10
11
  async deleteMany (ctx) {
@@ -103,11 +104,13 @@ var adminFolderFile = {
103
104
  const { folderIds = [], fileIds = [], destinationFolderId } = body;
104
105
  let totalFolderNumber = 0;
105
106
  let totalFileNumber = 0;
107
+ let moves = [];
106
108
  const trx = await strapi.db.transaction();
107
109
  try {
108
110
  // fetch folders
109
111
  const existingFolders = await strapi.db.queryBuilder(constants.FOLDER_MODEL_UID).select([
110
112
  'id',
113
+ 'name',
111
114
  'pathId',
112
115
  'path'
113
116
  ]).where({
@@ -117,7 +120,8 @@ var adminFolderFile = {
117
120
  }).transacting(trx.get()).forUpdate().execute();
118
121
  // fetch files
119
122
  const existingFiles = await strapi.db.queryBuilder(constants.FILE_MODEL_UID).select([
120
- 'id'
123
+ 'id',
124
+ 'name'
121
125
  ]).where({
122
126
  id: {
123
127
  $in: fileIds
@@ -137,6 +141,19 @@ var adminFolderFile = {
137
141
  strapi.db.metadata.get(constants.FILE_MODEL_UID).attributes.folderPath.columnName;
138
142
  // @ts-expect-error - no dynamic typings for the models
139
143
  const pathColName = strapi.db.metadata.get(constants.FOLDER_MODEL_UID).attributes.path.columnName;
144
+ // Read before the write: the audit log records where each item was.
145
+ const fileFolderAttribute = strapi.db.metadata.get(constants.FILE_MODEL_UID).attributes.folder;
146
+ const folderParentAttribute = strapi.db.metadata.get(constants.FOLDER_MODEL_UID).attributes.parent;
147
+ moves = await auditLogs.readMediaMoves((table)=>strapi.db.getConnection(table).transacting(trx.get()), {
148
+ files: existingFiles,
149
+ folders: existingFolders,
150
+ destinationFolderId,
151
+ // @ts-expect-error - no dynamic typings for the models
152
+ fileFolderJoinTable: fileFolderAttribute.joinTable,
153
+ // @ts-expect-error - no dynamic typings for the models
154
+ folderParentJoinTable: folderParentAttribute.joinTable,
155
+ folderTable
156
+ });
140
157
  if (existingFolders.length > 0) {
141
158
  // update folders' parent relation
142
159
  // @ts-expect-error - no dynamic typings for the models
@@ -201,6 +218,11 @@ var adminFolderFile = {
201
218
  await trx.rollback();
202
219
  throw e;
203
220
  }
221
+ auditLogs.emitMediaMoves({
222
+ strapi
223
+ }, moves).catch((error)=>{
224
+ strapi.log.error(`Could not record media moves in audit logs: ${error?.message ?? error}`);
225
+ });
204
226
  const updatedFolders = await strapi.db.query(constants.FOLDER_MODEL_UID).findMany({
205
227
  where: {
206
228
  id: {
@@ -1 +1 @@
1
- {"version":3,"file":"admin-folder-file.js","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { errors, strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { FolderContainsUnauthorizedAssetsError } from '../errors';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const { fileIds = [], folderIds = [] } = body;\n\n const canDeleteFiles = async (files: File[]) => {\n const ids = [...new Set(files.map(({ id }) => id))];\n\n if (ids.length === 0) {\n return true;\n }\n\n const query = pmFile.addPermissionsQueryTo({ filters: { id: { $in: ids } } });\n const permittedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n select: ['id'],\n where: query.filters,\n });\n\n return permittedFiles.length === ids.length;\n };\n\n // https://github.com/strapi/strapi/issues/27649\n // Validate explicitly selected files before deleting a folder. Otherwise a mixed request\n // could delete permitted files first and only then discover a forbidden file in the folder.\n if (fileIds.length > 0) {\n const selectedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n if (!(await canDeleteFiles(selectedFiles))) {\n throw new errors.ForbiddenError();\n }\n }\n\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(folderIds, {\n async validateFiles(files) {\n if (!(await canDeleteFiles(files))) {\n throw new FolderContainsUnauthorizedAssetsError();\n }\n },\n });\n const deletedFiles = await fileService.deleteByIds(fileIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles, { action: ACTIONS.read }),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","update","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","fileIds","folderIds","canDeleteFiles","files","ids","Set","map","id","length","query","addPermissionsQueryTo","filters","$in","permittedFiles","db","findMany","select","where","selectedFiles","errors","ForbiddenError","folders","deletedFolders","totalFolderNumber","totalFileNumber","deleteByIds","validateFiles","FolderContainsUnauthorizedAssetsError","deletedFiles","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","sanitizeOutput","read","moveMany","validateMoveManyFoldersFiles","destinationFolderId","trx","transaction","existingFolders","queryBuilder","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","joinTable","parent","name","delete","joinColumn","insert","folder","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","getConnection","orWhere","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","updatedFolders","updatedFiles"],"mappings":"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"}
1
+ {"version":3,"file":"admin-folder-file.js","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { errors, strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { FolderContainsUnauthorizedAssetsError } from '../errors';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\nimport { emitMediaMoves, readMediaMoves, type MediaMoveEvent } from '../audit-logs';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const { fileIds = [], folderIds = [] } = body;\n\n const canDeleteFiles = async (files: File[]) => {\n const ids = [...new Set(files.map(({ id }) => id))];\n\n if (ids.length === 0) {\n return true;\n }\n\n const query = pmFile.addPermissionsQueryTo({ filters: { id: { $in: ids } } });\n const permittedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n select: ['id'],\n where: query.filters,\n });\n\n return permittedFiles.length === ids.length;\n };\n\n // https://github.com/strapi/strapi/issues/27649\n // Validate explicitly selected files before deleting a folder. Otherwise a mixed request\n // could delete permitted files first and only then discover a forbidden file in the folder.\n if (fileIds.length > 0) {\n const selectedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n if (!(await canDeleteFiles(selectedFiles))) {\n throw new errors.ForbiddenError();\n }\n }\n\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(folderIds, {\n async validateFiles(files) {\n if (!(await canDeleteFiles(files))) {\n throw new FolderContainsUnauthorizedAssetsError();\n }\n },\n });\n const deletedFiles = await fileService.deleteByIds(fileIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles, { action: ACTIONS.read }),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n let moves: MediaMoveEvent[] = [];\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'name', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id', 'name'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // Read before the write: the audit log records where each item was.\n const fileFolderAttribute = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder;\n const folderParentAttribute = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n moves = await readMediaMoves(\n (table) => strapi.db.getConnection(table).transacting(trx.get()),\n {\n files: existingFiles,\n folders: existingFolders,\n destinationFolderId,\n // @ts-expect-error - no dynamic typings for the models\n fileFolderJoinTable: fileFolderAttribute.joinTable,\n // @ts-expect-error - no dynamic typings for the models\n folderParentJoinTable: folderParentAttribute.joinTable,\n folderTable,\n }\n );\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n emitMediaMoves({ strapi }, moves).catch((error) => {\n strapi.log.error(`Could not record media moves in audit logs: ${error?.message ?? error}`);\n });\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","update","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","fileIds","folderIds","canDeleteFiles","files","ids","Set","map","id","length","query","addPermissionsQueryTo","filters","$in","permittedFiles","db","findMany","select","where","selectedFiles","errors","ForbiddenError","folders","deletedFolders","totalFolderNumber","totalFileNumber","deleteByIds","validateFiles","FolderContainsUnauthorizedAssetsError","deletedFiles","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","sanitizeOutput","read","moveMany","validateMoveManyFoldersFiles","destinationFolderId","moves","trx","transaction","existingFolders","queryBuilder","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","fileFolderAttribute","folder","folderParentAttribute","parent","readMediaMoves","table","getConnection","fileFolderJoinTable","joinTable","folderParentJoinTable","name","delete","joinColumn","insert","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","orWhere","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","emitMediaMoves","catch","error","log","message","updatedFolders","updatedFiles"],"mappings":"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"}