@strapi/content-releases 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/server/audit-logs.js +169 -0
- package/dist/server/audit-logs.js.map +1 -0
- package/dist/server/audit-logs.mjs +163 -0
- package/dist/server/audit-logs.mjs.map +1 -0
- package/dist/server/bootstrap.js +6 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +6 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/constants.js +20 -0
- package/dist/server/constants.js.map +1 -1
- package/dist/server/constants.mjs +20 -1
- package/dist/server/constants.mjs.map +1 -1
- package/dist/server/controllers/release.js +9 -21
- package/dist/server/controllers/release.js.map +1 -1
- package/dist/server/controllers/release.mjs +9 -21
- package/dist/server/controllers/release.mjs.map +1 -1
- package/dist/server/controllers/settings.js +0 -1
- package/dist/server/controllers/settings.js.map +1 -1
- package/dist/server/controllers/settings.mjs +0 -1
- package/dist/server/controllers/settings.mjs.map +1 -1
- package/dist/server/services/release-action.js +59 -3
- package/dist/server/services/release-action.js.map +1 -1
- package/dist/server/services/release-action.mjs +60 -4
- package/dist/server/services/release-action.mjs.map +1 -1
- package/dist/server/services/release.js +110 -10
- package/dist/server/services/release.js.map +1 -1
- package/dist/server/services/release.mjs +112 -12
- package/dist/server/services/release.mjs.map +1 -1
- package/dist/server/services/scheduling.js +12 -5
- package/dist/server/services/scheduling.js.map +1 -1
- package/dist/server/services/scheduling.mjs +12 -5
- package/dist/server/services/scheduling.mjs.map +1 -1
- package/dist/server/services/settings.js +29 -1
- package/dist/server/services/settings.js.map +1 -1
- package/dist/server/services/settings.mjs +29 -1
- package/dist/server/services/settings.mjs.map +1 -1
- package/dist/server/src/audit-logs.d.ts +87 -0
- package/dist/server/src/audit-logs.d.ts.map +1 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +20 -0
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/controllers/release.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +8 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +8 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/release-action.d.ts.map +1 -1
- package/dist/server/src/services/release.d.ts +8 -1
- package/dist/server/src/services/release.d.ts.map +1 -1
- package/dist/server/src/services/scheduling.d.ts.map +1 -1
- package/dist/server/src/services/settings.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@strapi/utils');
|
|
4
|
+
var constants = require('./constants.js');
|
|
5
|
+
|
|
6
|
+
const RELEASE_EDITABLE_FIELDS = [
|
|
7
|
+
'name',
|
|
8
|
+
'scheduledAt',
|
|
9
|
+
'timezone'
|
|
10
|
+
];
|
|
11
|
+
/** Audit rows are never pruned by size, so the failure reason is capped */ const MAX_REASON_LENGTH = 100;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the fields that changed in a release update.
|
|
14
|
+
* `isScheduled` is included when the release changes between scheduled and unscheduled.
|
|
15
|
+
*/ const getReleaseChanges = (previous, next)=>{
|
|
16
|
+
const changes = {};
|
|
17
|
+
for (const field of RELEASE_EDITABLE_FIELDS){
|
|
18
|
+
const hasChanged = (previous?.[field] ?? null) !== (next[field] ?? null);
|
|
19
|
+
if (hasChanged) {
|
|
20
|
+
changes[field] = {
|
|
21
|
+
before: previous?.[field] ?? null,
|
|
22
|
+
after: next[field] ?? null
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (field === 'scheduledAt' && changes.scheduledAt) {
|
|
26
|
+
const wasScheduled = previous?.scheduledAt != null;
|
|
27
|
+
const isScheduled = next.scheduledAt != null;
|
|
28
|
+
if (wasScheduled !== isScheduled) {
|
|
29
|
+
changes.isScheduled = {
|
|
30
|
+
before: wasScheduled,
|
|
31
|
+
after: isScheduled
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return changes;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Emits an audit event for a write that may be part of a bulk transaction.
|
|
40
|
+
* Inside one, the event waits for its commit, so a rollback leaves no rows for
|
|
41
|
+
* entries that were never added. Standalone, it is emitted right away.
|
|
42
|
+
*/ const emitAuditOnCommit = async ({ strapi }, event, payload)=>{
|
|
43
|
+
if (!strapi.db.inTransaction()) {
|
|
44
|
+
await utils.emitAudit({
|
|
45
|
+
strapi
|
|
46
|
+
}, event, payload);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await strapi.db.transaction(({ onCommit })=>onCommit(()=>utils.emitAudit({
|
|
50
|
+
strapi
|
|
51
|
+
}, event, payload)));
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Runs work as a system principal so events emitted during the operation
|
|
55
|
+
* are recorded with a system actor.
|
|
56
|
+
*/ const runAsSystem = async ({ strapi }, origin, work)=>{
|
|
57
|
+
let result;
|
|
58
|
+
await strapi.requestContext.run({
|
|
59
|
+
state: {
|
|
60
|
+
auditSource: origin
|
|
61
|
+
},
|
|
62
|
+
request: {
|
|
63
|
+
url: ''
|
|
64
|
+
}
|
|
65
|
+
}, async ()=>{
|
|
66
|
+
result = await work();
|
|
67
|
+
});
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
const registerAuditEvents = (auditLogsLifecycle)=>{
|
|
71
|
+
const releaseResource = (event)=>({
|
|
72
|
+
type: 'release',
|
|
73
|
+
id: event.releaseId,
|
|
74
|
+
name: event.name
|
|
75
|
+
});
|
|
76
|
+
const entryRef = (event)=>({
|
|
77
|
+
contentType: event.contentType,
|
|
78
|
+
documentId: event.entryDocumentId,
|
|
79
|
+
locale: event.locale ?? null
|
|
80
|
+
});
|
|
81
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_CREATE, (event)=>({
|
|
82
|
+
resource: releaseResource(event),
|
|
83
|
+
details: {
|
|
84
|
+
isScheduled: event.scheduledAt != null,
|
|
85
|
+
...event.scheduledAt && {
|
|
86
|
+
scheduledAt: event.scheduledAt,
|
|
87
|
+
timezone: event.timezone
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}));
|
|
91
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_UPDATE, (event)=>({
|
|
92
|
+
resource: releaseResource(event),
|
|
93
|
+
details: {
|
|
94
|
+
changes: event.changes
|
|
95
|
+
}
|
|
96
|
+
}));
|
|
97
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_DELETE, (event)=>({
|
|
98
|
+
resource: releaseResource(event)
|
|
99
|
+
}));
|
|
100
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_TRIGGER, (event)=>{
|
|
101
|
+
const base = {
|
|
102
|
+
resource: releaseResource(event),
|
|
103
|
+
outcome: event.outcome
|
|
104
|
+
};
|
|
105
|
+
if (event.outcome === 'failure') {
|
|
106
|
+
return {
|
|
107
|
+
...base,
|
|
108
|
+
details: {
|
|
109
|
+
reason: event.reason?.slice(0, MAX_REASON_LENGTH),
|
|
110
|
+
// Only when the emitter can attribute the counts.
|
|
111
|
+
...event.published != null && {
|
|
112
|
+
published: event.published,
|
|
113
|
+
unpublished: event.unpublished,
|
|
114
|
+
failed: event.failed
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (event.published != null && event.unpublished != null) {
|
|
120
|
+
return {
|
|
121
|
+
...base,
|
|
122
|
+
details: {
|
|
123
|
+
published: event.published,
|
|
124
|
+
unpublished: event.unpublished,
|
|
125
|
+
failed: 0
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return base;
|
|
130
|
+
});
|
|
131
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_ENTRY_ADD, (event)=>({
|
|
132
|
+
resource: releaseResource(event),
|
|
133
|
+
details: {
|
|
134
|
+
entry: entryRef(event),
|
|
135
|
+
actionType: event.type
|
|
136
|
+
}
|
|
137
|
+
}));
|
|
138
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_ENTRY_UPDATE, (event)=>({
|
|
139
|
+
resource: releaseResource(event),
|
|
140
|
+
details: {
|
|
141
|
+
entry: entryRef(event),
|
|
142
|
+
actionType: {
|
|
143
|
+
before: event.from,
|
|
144
|
+
after: event.to
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}));
|
|
148
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_ENTRY_REMOVE, (event)=>({
|
|
149
|
+
resource: releaseResource(event),
|
|
150
|
+
details: {
|
|
151
|
+
entry: entryRef(event)
|
|
152
|
+
}
|
|
153
|
+
}));
|
|
154
|
+
auditLogsLifecycle.registerEvent(constants.AUDITED_EVENTS.RELEASE_SETTINGS_UPDATE, (event)=>({
|
|
155
|
+
resource: {
|
|
156
|
+
type: 'release'
|
|
157
|
+
},
|
|
158
|
+
details: {
|
|
159
|
+
changes: event.changes
|
|
160
|
+
}
|
|
161
|
+
}));
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
exports.RELEASE_EDITABLE_FIELDS = RELEASE_EDITABLE_FIELDS;
|
|
165
|
+
exports.emitAuditOnCommit = emitAuditOnCommit;
|
|
166
|
+
exports.getReleaseChanges = getReleaseChanges;
|
|
167
|
+
exports.registerAuditEvents = registerAuditEvents;
|
|
168
|
+
exports.runAsSystem = runAsSystem;
|
|
169
|
+
//# sourceMappingURL=audit-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logs.js","sources":["../../server/src/audit-logs.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { emitAudit } from '@strapi/utils';\n\nimport { AUDITED_EVENTS } from './constants';\n\n/**\n * Transformers for the release audit events.\n * Each builds {resource, details, outcome} from its emitted event.\n */\n\ninterface ReleaseEvent {\n releaseId: number;\n name?: string;\n scheduledAt?: string | null;\n timezone?: string | null;\n}\n\ninterface ReleaseEntryEvent {\n releaseId: number;\n name?: string;\n contentType: string;\n entryDocumentId: string;\n locale: string | null;\n}\n\nexport interface CreateDetails {\n isScheduled: boolean;\n scheduledAt?: string | null;\n timezone?: string | null;\n}\n\nexport const RELEASE_EDITABLE_FIELDS = ['name', 'scheduledAt', 'timezone'] as const;\n\n/** Audit rows are never pruned by size, so the failure reason is capped */\nconst MAX_REASON_LENGTH = 100;\n\ntype ReleaseChangedField = (typeof RELEASE_EDITABLE_FIELDS)[number] | 'isScheduled';\n\nexport interface UpdateDetails {\n changes: Partial<Record<ReleaseChangedField, Modules.AuditLogs.FieldChange>>;\n}\n\n/**\n * Returns the fields that changed in a release update.\n * `isScheduled` is included when the release changes between scheduled and unscheduled.\n */\nexport const getReleaseChanges = (\n previous: { name?: string; scheduledAt?: string | null; timezone?: string | null } | null,\n next: { name?: string; scheduledAt?: string | null; timezone?: string | null }\n) => {\n const changes: Partial<Record<ReleaseChangedField, Modules.AuditLogs.FieldChange>> = {};\n\n for (const field of RELEASE_EDITABLE_FIELDS) {\n const hasChanged = (previous?.[field] ?? null) !== (next[field] ?? null);\n\n if (hasChanged) {\n changes[field] = { before: previous?.[field] ?? null, after: next[field] ?? null };\n }\n\n if (field === 'scheduledAt' && changes.scheduledAt) {\n const wasScheduled = previous?.scheduledAt != null;\n const isScheduled = next.scheduledAt != null;\n\n if (wasScheduled !== isScheduled) {\n changes.isScheduled = { before: wasScheduled, after: isScheduled };\n }\n }\n }\n\n return changes;\n};\n\nexport interface TriggerDetails {\n published: number;\n unpublished: number;\n failed: number;\n}\n\nexport interface TriggerFailureDetails {\n /**\n * Only the error name is stored, capped in length. Error objects may contain\n * sensitive data such as database error details, and a custom error class can put\n * arbitrary text in its name.\n */\n reason: string;\n // A failed run is not atomic, so counts are not reported. Reserved for partial releases.\n published?: number;\n unpublished?: number;\n failed?: number;\n}\n\ntype TriggerEvent = ReleaseEvent &\n (\n | { outcome: 'success'; published?: number; unpublished?: number }\n | {\n outcome: 'failure';\n reason: string;\n published?: number;\n unpublished?: number;\n failed?: number;\n }\n );\n\nexport interface SettingsUpdateDetails {\n changes: Partial<Record<'defaultTimezone', Modules.AuditLogs.FieldChange>>;\n}\n\ninterface EntryRef {\n contentType: string;\n documentId: string;\n locale: string | null;\n}\n\nexport interface EntryAddDetails {\n entry: EntryRef;\n actionType: 'publish' | 'unpublish';\n}\n\nexport interface EntryUpdateDetails {\n entry: EntryRef;\n actionType: { before: 'publish' | 'unpublish'; after: 'publish' | 'unpublish' };\n}\n\nexport interface EntryRemoveDetails {\n entry: EntryRef;\n}\n\n/**\n * Emits an audit event for a write that may be part of a bulk transaction.\n * Inside one, the event waits for its commit, so a rollback leaves no rows for\n * entries that were never added. Standalone, it is emitted right away.\n */\nexport const emitAuditOnCommit = async (\n { strapi }: { strapi: Core.Strapi },\n event: string,\n payload: unknown\n): Promise<void> => {\n if (!strapi.db.inTransaction()) {\n await emitAudit({ strapi }, event, payload);\n return;\n }\n\n await strapi.db.transaction(({ onCommit }) =>\n onCommit(() => emitAudit({ strapi }, event, payload))\n );\n};\n\n/**\n * Runs work as a system principal so events emitted during the operation\n * are recorded with a system actor.\n */\nexport const runAsSystem = async <T>(\n { strapi }: { strapi: Core.Strapi },\n origin: Modules.AuditLogs.SystemOrigin,\n work: () => Promise<T>\n): Promise<T> => {\n let result: T;\n\n await strapi.requestContext.run(\n { state: { auditSource: origin }, request: { url: '' } } as any,\n async () => {\n result = await work();\n }\n );\n\n return result!;\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 ): void;\n}\n\nexport const registerAuditEvents = (auditLogsLifecycle: AuditLogsLifecycle) => {\n const releaseResource = (event: ReleaseEvent): Modules.AuditLogs.Resource => ({\n type: 'release',\n id: event.releaseId,\n name: event.name,\n });\n\n const entryRef = (event: ReleaseEntryEvent): EntryRef => ({\n contentType: event.contentType,\n documentId: event.entryDocumentId,\n locale: event.locale ?? null,\n });\n\n auditLogsLifecycle.registerEvent<CreateDetails>(\n AUDITED_EVENTS.RELEASE_CREATE,\n (event: ReleaseEvent) => ({\n resource: releaseResource(event),\n details: {\n isScheduled: event.scheduledAt != null,\n ...(event.scheduledAt && { scheduledAt: event.scheduledAt, timezone: event.timezone }),\n },\n })\n );\n\n auditLogsLifecycle.registerEvent<UpdateDetails>(\n AUDITED_EVENTS.RELEASE_UPDATE,\n (event: ReleaseEvent & UpdateDetails) => ({\n resource: releaseResource(event),\n details: { changes: event.changes },\n })\n );\n\n auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_DELETE, (event: ReleaseEvent) => ({\n resource: releaseResource(event),\n }));\n\n auditLogsLifecycle.registerEvent<TriggerDetails | TriggerFailureDetails>(\n AUDITED_EVENTS.RELEASE_TRIGGER,\n (event: TriggerEvent) => {\n const base = { resource: releaseResource(event), outcome: event.outcome };\n\n if (event.outcome === 'failure') {\n return {\n ...base,\n details: {\n reason: event.reason?.slice(0, MAX_REASON_LENGTH),\n // Only when the emitter can attribute the counts.\n ...(event.published != null && {\n published: event.published,\n unpublished: event.unpublished,\n failed: event.failed,\n }),\n },\n };\n }\n\n if (event.published != null && event.unpublished != null) {\n return {\n ...base,\n details: { published: event.published, unpublished: event.unpublished, failed: 0 },\n };\n }\n\n return base;\n }\n );\n\n auditLogsLifecycle.registerEvent<EntryAddDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_ADD,\n (event: ReleaseEntryEvent & { type: 'publish' | 'unpublish' }) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event), actionType: event.type },\n })\n );\n\n auditLogsLifecycle.registerEvent<EntryUpdateDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_UPDATE,\n (\n event: ReleaseEntryEvent & {\n from: 'publish' | 'unpublish';\n to: 'publish' | 'unpublish';\n }\n ) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event), actionType: { before: event.from, after: event.to } },\n })\n );\n\n auditLogsLifecycle.registerEvent<EntryRemoveDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_REMOVE,\n (event: ReleaseEntryEvent) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event) },\n })\n );\n\n auditLogsLifecycle.registerEvent<SettingsUpdateDetails>(\n AUDITED_EVENTS.RELEASE_SETTINGS_UPDATE,\n (event: SettingsUpdateDetails) => ({\n resource: { type: 'release' },\n details: { changes: event.changes },\n })\n );\n};\n"],"names":["RELEASE_EDITABLE_FIELDS","MAX_REASON_LENGTH","getReleaseChanges","previous","next","changes","field","hasChanged","before","after","scheduledAt","wasScheduled","isScheduled","emitAuditOnCommit","strapi","event","payload","db","inTransaction","emitAudit","transaction","onCommit","runAsSystem","origin","work","result","requestContext","run","state","auditSource","request","url","registerAuditEvents","auditLogsLifecycle","releaseResource","type","id","releaseId","name","entryRef","contentType","documentId","entryDocumentId","locale","registerEvent","AUDITED_EVENTS","RELEASE_CREATE","resource","details","timezone","RELEASE_UPDATE","RELEASE_DELETE","RELEASE_TRIGGER","base","outcome","reason","slice","published","unpublished","failed","RELEASE_ENTRY_ADD","entry","actionType","RELEASE_ENTRY_UPDATE","from","to","RELEASE_ENTRY_REMOVE","RELEASE_SETTINGS_UPDATE"],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { emitAudit } from '@strapi/utils';
|
|
2
|
+
import { AUDITED_EVENTS } from './constants.mjs';
|
|
3
|
+
|
|
4
|
+
const RELEASE_EDITABLE_FIELDS = [
|
|
5
|
+
'name',
|
|
6
|
+
'scheduledAt',
|
|
7
|
+
'timezone'
|
|
8
|
+
];
|
|
9
|
+
/** Audit rows are never pruned by size, so the failure reason is capped */ const MAX_REASON_LENGTH = 100;
|
|
10
|
+
/**
|
|
11
|
+
* Returns the fields that changed in a release update.
|
|
12
|
+
* `isScheduled` is included when the release changes between scheduled and unscheduled.
|
|
13
|
+
*/ const getReleaseChanges = (previous, next)=>{
|
|
14
|
+
const changes = {};
|
|
15
|
+
for (const field of RELEASE_EDITABLE_FIELDS){
|
|
16
|
+
const hasChanged = (previous?.[field] ?? null) !== (next[field] ?? null);
|
|
17
|
+
if (hasChanged) {
|
|
18
|
+
changes[field] = {
|
|
19
|
+
before: previous?.[field] ?? null,
|
|
20
|
+
after: next[field] ?? null
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (field === 'scheduledAt' && changes.scheduledAt) {
|
|
24
|
+
const wasScheduled = previous?.scheduledAt != null;
|
|
25
|
+
const isScheduled = next.scheduledAt != null;
|
|
26
|
+
if (wasScheduled !== isScheduled) {
|
|
27
|
+
changes.isScheduled = {
|
|
28
|
+
before: wasScheduled,
|
|
29
|
+
after: isScheduled
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return changes;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Emits an audit event for a write that may be part of a bulk transaction.
|
|
38
|
+
* Inside one, the event waits for its commit, so a rollback leaves no rows for
|
|
39
|
+
* entries that were never added. Standalone, it is emitted right away.
|
|
40
|
+
*/ const emitAuditOnCommit = async ({ strapi }, event, payload)=>{
|
|
41
|
+
if (!strapi.db.inTransaction()) {
|
|
42
|
+
await emitAudit({
|
|
43
|
+
strapi
|
|
44
|
+
}, event, payload);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await strapi.db.transaction(({ onCommit })=>onCommit(()=>emitAudit({
|
|
48
|
+
strapi
|
|
49
|
+
}, event, payload)));
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Runs work as a system principal so events emitted during the operation
|
|
53
|
+
* are recorded with a system actor.
|
|
54
|
+
*/ const runAsSystem = async ({ strapi }, origin, work)=>{
|
|
55
|
+
let result;
|
|
56
|
+
await strapi.requestContext.run({
|
|
57
|
+
state: {
|
|
58
|
+
auditSource: origin
|
|
59
|
+
},
|
|
60
|
+
request: {
|
|
61
|
+
url: ''
|
|
62
|
+
}
|
|
63
|
+
}, async ()=>{
|
|
64
|
+
result = await work();
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
const registerAuditEvents = (auditLogsLifecycle)=>{
|
|
69
|
+
const releaseResource = (event)=>({
|
|
70
|
+
type: 'release',
|
|
71
|
+
id: event.releaseId,
|
|
72
|
+
name: event.name
|
|
73
|
+
});
|
|
74
|
+
const entryRef = (event)=>({
|
|
75
|
+
contentType: event.contentType,
|
|
76
|
+
documentId: event.entryDocumentId,
|
|
77
|
+
locale: event.locale ?? null
|
|
78
|
+
});
|
|
79
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_CREATE, (event)=>({
|
|
80
|
+
resource: releaseResource(event),
|
|
81
|
+
details: {
|
|
82
|
+
isScheduled: event.scheduledAt != null,
|
|
83
|
+
...event.scheduledAt && {
|
|
84
|
+
scheduledAt: event.scheduledAt,
|
|
85
|
+
timezone: event.timezone
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_UPDATE, (event)=>({
|
|
90
|
+
resource: releaseResource(event),
|
|
91
|
+
details: {
|
|
92
|
+
changes: event.changes
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_DELETE, (event)=>({
|
|
96
|
+
resource: releaseResource(event)
|
|
97
|
+
}));
|
|
98
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_TRIGGER, (event)=>{
|
|
99
|
+
const base = {
|
|
100
|
+
resource: releaseResource(event),
|
|
101
|
+
outcome: event.outcome
|
|
102
|
+
};
|
|
103
|
+
if (event.outcome === 'failure') {
|
|
104
|
+
return {
|
|
105
|
+
...base,
|
|
106
|
+
details: {
|
|
107
|
+
reason: event.reason?.slice(0, MAX_REASON_LENGTH),
|
|
108
|
+
// Only when the emitter can attribute the counts.
|
|
109
|
+
...event.published != null && {
|
|
110
|
+
published: event.published,
|
|
111
|
+
unpublished: event.unpublished,
|
|
112
|
+
failed: event.failed
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (event.published != null && event.unpublished != null) {
|
|
118
|
+
return {
|
|
119
|
+
...base,
|
|
120
|
+
details: {
|
|
121
|
+
published: event.published,
|
|
122
|
+
unpublished: event.unpublished,
|
|
123
|
+
failed: 0
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return base;
|
|
128
|
+
});
|
|
129
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_ENTRY_ADD, (event)=>({
|
|
130
|
+
resource: releaseResource(event),
|
|
131
|
+
details: {
|
|
132
|
+
entry: entryRef(event),
|
|
133
|
+
actionType: event.type
|
|
134
|
+
}
|
|
135
|
+
}));
|
|
136
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_ENTRY_UPDATE, (event)=>({
|
|
137
|
+
resource: releaseResource(event),
|
|
138
|
+
details: {
|
|
139
|
+
entry: entryRef(event),
|
|
140
|
+
actionType: {
|
|
141
|
+
before: event.from,
|
|
142
|
+
after: event.to
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}));
|
|
146
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_ENTRY_REMOVE, (event)=>({
|
|
147
|
+
resource: releaseResource(event),
|
|
148
|
+
details: {
|
|
149
|
+
entry: entryRef(event)
|
|
150
|
+
}
|
|
151
|
+
}));
|
|
152
|
+
auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_SETTINGS_UPDATE, (event)=>({
|
|
153
|
+
resource: {
|
|
154
|
+
type: 'release'
|
|
155
|
+
},
|
|
156
|
+
details: {
|
|
157
|
+
changes: event.changes
|
|
158
|
+
}
|
|
159
|
+
}));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export { RELEASE_EDITABLE_FIELDS, emitAuditOnCommit, getReleaseChanges, registerAuditEvents, runAsSystem };
|
|
163
|
+
//# sourceMappingURL=audit-logs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logs.mjs","sources":["../../server/src/audit-logs.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { emitAudit } from '@strapi/utils';\n\nimport { AUDITED_EVENTS } from './constants';\n\n/**\n * Transformers for the release audit events.\n * Each builds {resource, details, outcome} from its emitted event.\n */\n\ninterface ReleaseEvent {\n releaseId: number;\n name?: string;\n scheduledAt?: string | null;\n timezone?: string | null;\n}\n\ninterface ReleaseEntryEvent {\n releaseId: number;\n name?: string;\n contentType: string;\n entryDocumentId: string;\n locale: string | null;\n}\n\nexport interface CreateDetails {\n isScheduled: boolean;\n scheduledAt?: string | null;\n timezone?: string | null;\n}\n\nexport const RELEASE_EDITABLE_FIELDS = ['name', 'scheduledAt', 'timezone'] as const;\n\n/** Audit rows are never pruned by size, so the failure reason is capped */\nconst MAX_REASON_LENGTH = 100;\n\ntype ReleaseChangedField = (typeof RELEASE_EDITABLE_FIELDS)[number] | 'isScheduled';\n\nexport interface UpdateDetails {\n changes: Partial<Record<ReleaseChangedField, Modules.AuditLogs.FieldChange>>;\n}\n\n/**\n * Returns the fields that changed in a release update.\n * `isScheduled` is included when the release changes between scheduled and unscheduled.\n */\nexport const getReleaseChanges = (\n previous: { name?: string; scheduledAt?: string | null; timezone?: string | null } | null,\n next: { name?: string; scheduledAt?: string | null; timezone?: string | null }\n) => {\n const changes: Partial<Record<ReleaseChangedField, Modules.AuditLogs.FieldChange>> = {};\n\n for (const field of RELEASE_EDITABLE_FIELDS) {\n const hasChanged = (previous?.[field] ?? null) !== (next[field] ?? null);\n\n if (hasChanged) {\n changes[field] = { before: previous?.[field] ?? null, after: next[field] ?? null };\n }\n\n if (field === 'scheduledAt' && changes.scheduledAt) {\n const wasScheduled = previous?.scheduledAt != null;\n const isScheduled = next.scheduledAt != null;\n\n if (wasScheduled !== isScheduled) {\n changes.isScheduled = { before: wasScheduled, after: isScheduled };\n }\n }\n }\n\n return changes;\n};\n\nexport interface TriggerDetails {\n published: number;\n unpublished: number;\n failed: number;\n}\n\nexport interface TriggerFailureDetails {\n /**\n * Only the error name is stored, capped in length. Error objects may contain\n * sensitive data such as database error details, and a custom error class can put\n * arbitrary text in its name.\n */\n reason: string;\n // A failed run is not atomic, so counts are not reported. Reserved for partial releases.\n published?: number;\n unpublished?: number;\n failed?: number;\n}\n\ntype TriggerEvent = ReleaseEvent &\n (\n | { outcome: 'success'; published?: number; unpublished?: number }\n | {\n outcome: 'failure';\n reason: string;\n published?: number;\n unpublished?: number;\n failed?: number;\n }\n );\n\nexport interface SettingsUpdateDetails {\n changes: Partial<Record<'defaultTimezone', Modules.AuditLogs.FieldChange>>;\n}\n\ninterface EntryRef {\n contentType: string;\n documentId: string;\n locale: string | null;\n}\n\nexport interface EntryAddDetails {\n entry: EntryRef;\n actionType: 'publish' | 'unpublish';\n}\n\nexport interface EntryUpdateDetails {\n entry: EntryRef;\n actionType: { before: 'publish' | 'unpublish'; after: 'publish' | 'unpublish' };\n}\n\nexport interface EntryRemoveDetails {\n entry: EntryRef;\n}\n\n/**\n * Emits an audit event for a write that may be part of a bulk transaction.\n * Inside one, the event waits for its commit, so a rollback leaves no rows for\n * entries that were never added. Standalone, it is emitted right away.\n */\nexport const emitAuditOnCommit = async (\n { strapi }: { strapi: Core.Strapi },\n event: string,\n payload: unknown\n): Promise<void> => {\n if (!strapi.db.inTransaction()) {\n await emitAudit({ strapi }, event, payload);\n return;\n }\n\n await strapi.db.transaction(({ onCommit }) =>\n onCommit(() => emitAudit({ strapi }, event, payload))\n );\n};\n\n/**\n * Runs work as a system principal so events emitted during the operation\n * are recorded with a system actor.\n */\nexport const runAsSystem = async <T>(\n { strapi }: { strapi: Core.Strapi },\n origin: Modules.AuditLogs.SystemOrigin,\n work: () => Promise<T>\n): Promise<T> => {\n let result: T;\n\n await strapi.requestContext.run(\n { state: { auditSource: origin }, request: { url: '' } } as any,\n async () => {\n result = await work();\n }\n );\n\n return result!;\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 ): void;\n}\n\nexport const registerAuditEvents = (auditLogsLifecycle: AuditLogsLifecycle) => {\n const releaseResource = (event: ReleaseEvent): Modules.AuditLogs.Resource => ({\n type: 'release',\n id: event.releaseId,\n name: event.name,\n });\n\n const entryRef = (event: ReleaseEntryEvent): EntryRef => ({\n contentType: event.contentType,\n documentId: event.entryDocumentId,\n locale: event.locale ?? null,\n });\n\n auditLogsLifecycle.registerEvent<CreateDetails>(\n AUDITED_EVENTS.RELEASE_CREATE,\n (event: ReleaseEvent) => ({\n resource: releaseResource(event),\n details: {\n isScheduled: event.scheduledAt != null,\n ...(event.scheduledAt && { scheduledAt: event.scheduledAt, timezone: event.timezone }),\n },\n })\n );\n\n auditLogsLifecycle.registerEvent<UpdateDetails>(\n AUDITED_EVENTS.RELEASE_UPDATE,\n (event: ReleaseEvent & UpdateDetails) => ({\n resource: releaseResource(event),\n details: { changes: event.changes },\n })\n );\n\n auditLogsLifecycle.registerEvent(AUDITED_EVENTS.RELEASE_DELETE, (event: ReleaseEvent) => ({\n resource: releaseResource(event),\n }));\n\n auditLogsLifecycle.registerEvent<TriggerDetails | TriggerFailureDetails>(\n AUDITED_EVENTS.RELEASE_TRIGGER,\n (event: TriggerEvent) => {\n const base = { resource: releaseResource(event), outcome: event.outcome };\n\n if (event.outcome === 'failure') {\n return {\n ...base,\n details: {\n reason: event.reason?.slice(0, MAX_REASON_LENGTH),\n // Only when the emitter can attribute the counts.\n ...(event.published != null && {\n published: event.published,\n unpublished: event.unpublished,\n failed: event.failed,\n }),\n },\n };\n }\n\n if (event.published != null && event.unpublished != null) {\n return {\n ...base,\n details: { published: event.published, unpublished: event.unpublished, failed: 0 },\n };\n }\n\n return base;\n }\n );\n\n auditLogsLifecycle.registerEvent<EntryAddDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_ADD,\n (event: ReleaseEntryEvent & { type: 'publish' | 'unpublish' }) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event), actionType: event.type },\n })\n );\n\n auditLogsLifecycle.registerEvent<EntryUpdateDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_UPDATE,\n (\n event: ReleaseEntryEvent & {\n from: 'publish' | 'unpublish';\n to: 'publish' | 'unpublish';\n }\n ) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event), actionType: { before: event.from, after: event.to } },\n })\n );\n\n auditLogsLifecycle.registerEvent<EntryRemoveDetails>(\n AUDITED_EVENTS.RELEASE_ENTRY_REMOVE,\n (event: ReleaseEntryEvent) => ({\n resource: releaseResource(event),\n details: { entry: entryRef(event) },\n })\n );\n\n auditLogsLifecycle.registerEvent<SettingsUpdateDetails>(\n AUDITED_EVENTS.RELEASE_SETTINGS_UPDATE,\n (event: SettingsUpdateDetails) => ({\n resource: { type: 'release' },\n details: { changes: event.changes },\n })\n );\n};\n"],"names":["RELEASE_EDITABLE_FIELDS","MAX_REASON_LENGTH","getReleaseChanges","previous","next","changes","field","hasChanged","before","after","scheduledAt","wasScheduled","isScheduled","emitAuditOnCommit","strapi","event","payload","db","inTransaction","emitAudit","transaction","onCommit","runAsSystem","origin","work","result","requestContext","run","state","auditSource","request","url","registerAuditEvents","auditLogsLifecycle","releaseResource","type","id","releaseId","name","entryRef","contentType","documentId","entryDocumentId","locale","registerEvent","AUDITED_EVENTS","RELEASE_CREATE","resource","details","timezone","RELEASE_UPDATE","RELEASE_DELETE","RELEASE_TRIGGER","base","outcome","reason","slice","published","unpublished","failed","RELEASE_ENTRY_ADD","entry","actionType","RELEASE_ENTRY_UPDATE","from","to","RELEASE_ENTRY_REMOVE","RELEASE_SETTINGS_UPDATE"],"mappings":"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"}
|
package/dist/server/bootstrap.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var constants = require('./constants.js');
|
|
4
|
+
var auditLogs = require('./audit-logs.js');
|
|
4
5
|
var index = require('./utils/index.js');
|
|
5
6
|
var documents = require('./middlewares/documents.js');
|
|
6
7
|
|
|
@@ -61,6 +62,11 @@ const bootstrap = async ({ strapi: strapi1 })=>{
|
|
|
61
62
|
Object.entries(constants.ALLOWED_WEBHOOK_EVENTS).forEach(([key, value])=>{
|
|
62
63
|
strapi1.get('webhookStore').addAllowedEvent(key, value);
|
|
63
64
|
});
|
|
65
|
+
// Absent in CE, without the audit-logs license, or when disabled by config;
|
|
66
|
+
// get() throws for services that were never added, so probe first.
|
|
67
|
+
if (strapi1.has('audit-logs-lifecycle')) {
|
|
68
|
+
auditLogs.registerAuditEvents(strapi1.get('audit-logs-lifecycle'));
|
|
69
|
+
}
|
|
64
70
|
}
|
|
65
71
|
};
|
|
66
72
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { getService } from './utils';\nimport { deleteActionsOnDelete, updateActionsOnUpdate } from './middlewares/documents';\n\ninterface DeleteManyParams {\n contentType: UID.ContentType;\n locale: string | null;\n entryDocumentId?: Modules.Documents.ID;\n}\n\nconst deleteReleasesActionsAndUpdateReleaseStatus = async (params: DeleteManyParams) => {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: params,\n },\n });\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: params,\n });\n\n // We update the status of each release after delete the actions\n for (const release of releases) {\n getService('release', { strapi }).updateReleaseStatus(release.id);\n }\n};\n\nexport const bootstrap = async ({ strapi }: { strapi: Core.Strapi }) => {\n if (strapi.ee.features.isEnabled('cms-content-releases')) {\n const contentTypesWithDraftAndPublish = Object.keys(strapi.contentTypes).filter(\n (uid: any) => strapi.contentTypes[uid]?.options?.draftAndPublish\n );\n\n strapi.db.lifecycles.subscribe({\n models: contentTypesWithDraftAndPublish,\n\n /**\n * deleteMany is still used outside documents service, for example when deleting a locale\n */\n async afterDeleteMany(event) {\n try {\n const model = strapi.getModel(event.model.uid as UID.Schema);\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = event.params;\n\n deleteReleasesActionsAndUpdateReleaseStatus({\n contentType: model.uid,\n locale: where?.locale ?? null,\n ...(where?.documentId && { entryDocumentId: where.documentId }),\n });\n }\n } catch (error) {\n // If an error happens we don't want to block the delete entry flow, but we log the error\n strapi.log.error('Error while deleting release actions after entry deleteMany', {\n error,\n });\n }\n },\n });\n\n // We register middleware to handle ReleaseActions when changes on documents are made\n strapi.documents.use(deleteActionsOnDelete);\n strapi.documents.use(updateActionsOnUpdate);\n\n getService('scheduling', { strapi })\n .syncFromDatabase()\n .catch((err: Error) => {\n strapi.log.error(\n 'Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling.'\n );\n\n throw err;\n });\n\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n }\n};\n"],"names":["deleteReleasesActionsAndUpdateReleaseStatus","params","releases","strapi","db","query","RELEASE_MODEL_UID","findMany","where","actions","RELEASE_ACTION_MODEL_UID","deleteMany","release","getService","updateReleaseStatus","id","bootstrap","ee","features","isEnabled","contentTypesWithDraftAndPublish","Object","keys","contentTypes","filter","uid","options","draftAndPublish","lifecycles","subscribe","models","afterDeleteMany","event","model","getModel","kind","contentType","locale","documentId","entryDocumentId","error","log","documents","use","deleteActionsOnDelete","updateActionsOnUpdate","syncFromDatabase","catch","err","entries","ALLOWED_WEBHOOK_EVENTS","forEach","key","value","get","addAllowedEvent"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { registerAuditEvents } from './audit-logs';\nimport { getService } from './utils';\nimport { deleteActionsOnDelete, updateActionsOnUpdate } from './middlewares/documents';\n\ninterface DeleteManyParams {\n contentType: UID.ContentType;\n locale: string | null;\n entryDocumentId?: Modules.Documents.ID;\n}\n\nconst deleteReleasesActionsAndUpdateReleaseStatus = async (params: DeleteManyParams) => {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: params,\n },\n });\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: params,\n });\n\n // We update the status of each release after delete the actions\n for (const release of releases) {\n getService('release', { strapi }).updateReleaseStatus(release.id);\n }\n};\n\nexport const bootstrap = async ({ strapi }: { strapi: Core.Strapi }) => {\n if (strapi.ee.features.isEnabled('cms-content-releases')) {\n const contentTypesWithDraftAndPublish = Object.keys(strapi.contentTypes).filter(\n (uid: any) => strapi.contentTypes[uid]?.options?.draftAndPublish\n );\n\n strapi.db.lifecycles.subscribe({\n models: contentTypesWithDraftAndPublish,\n\n /**\n * deleteMany is still used outside documents service, for example when deleting a locale\n */\n async afterDeleteMany(event) {\n try {\n const model = strapi.getModel(event.model.uid as UID.Schema);\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = event.params;\n\n deleteReleasesActionsAndUpdateReleaseStatus({\n contentType: model.uid,\n locale: where?.locale ?? null,\n ...(where?.documentId && { entryDocumentId: where.documentId }),\n });\n }\n } catch (error) {\n // If an error happens we don't want to block the delete entry flow, but we log the error\n strapi.log.error('Error while deleting release actions after entry deleteMany', {\n error,\n });\n }\n },\n });\n\n // We register middleware to handle ReleaseActions when changes on documents are made\n strapi.documents.use(deleteActionsOnDelete);\n strapi.documents.use(updateActionsOnUpdate);\n\n getService('scheduling', { strapi })\n .syncFromDatabase()\n .catch((err: Error) => {\n strapi.log.error(\n 'Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling.'\n );\n\n throw err;\n });\n\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\n // Absent in CE, without the audit-logs license, or when disabled by config;\n // get() throws for services that were never added, so probe first.\n if (strapi.has('audit-logs-lifecycle')) {\n registerAuditEvents(strapi.get('audit-logs-lifecycle'));\n }\n }\n};\n"],"names":["deleteReleasesActionsAndUpdateReleaseStatus","params","releases","strapi","db","query","RELEASE_MODEL_UID","findMany","where","actions","RELEASE_ACTION_MODEL_UID","deleteMany","release","getService","updateReleaseStatus","id","bootstrap","ee","features","isEnabled","contentTypesWithDraftAndPublish","Object","keys","contentTypes","filter","uid","options","draftAndPublish","lifecycles","subscribe","models","afterDeleteMany","event","model","getModel","kind","contentType","locale","documentId","entryDocumentId","error","log","documents","use","deleteActionsOnDelete","updateActionsOnUpdate","syncFromDatabase","catch","err","entries","ALLOWED_WEBHOOK_EVENTS","forEach","key","value","get","addAllowedEvent","has","registerAuditEvents"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ALLOWED_WEBHOOK_EVENTS, RELEASE_MODEL_UID, RELEASE_ACTION_MODEL_UID } from './constants.mjs';
|
|
2
|
+
import { registerAuditEvents } from './audit-logs.mjs';
|
|
2
3
|
import { getService } from './utils/index.mjs';
|
|
3
4
|
import { deleteActionsOnDelete, updateActionsOnUpdate } from './middlewares/documents.mjs';
|
|
4
5
|
|
|
@@ -59,6 +60,11 @@ const bootstrap = async ({ strapi: strapi1 })=>{
|
|
|
59
60
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value])=>{
|
|
60
61
|
strapi1.get('webhookStore').addAllowedEvent(key, value);
|
|
61
62
|
});
|
|
63
|
+
// Absent in CE, without the audit-logs license, or when disabled by config;
|
|
64
|
+
// get() throws for services that were never added, so probe first.
|
|
65
|
+
if (strapi1.has('audit-logs-lifecycle')) {
|
|
66
|
+
registerAuditEvents(strapi1.get('audit-logs-lifecycle'));
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
69
|
};
|
|
64
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { getService } from './utils';\nimport { deleteActionsOnDelete, updateActionsOnUpdate } from './middlewares/documents';\n\ninterface DeleteManyParams {\n contentType: UID.ContentType;\n locale: string | null;\n entryDocumentId?: Modules.Documents.ID;\n}\n\nconst deleteReleasesActionsAndUpdateReleaseStatus = async (params: DeleteManyParams) => {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: params,\n },\n });\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: params,\n });\n\n // We update the status of each release after delete the actions\n for (const release of releases) {\n getService('release', { strapi }).updateReleaseStatus(release.id);\n }\n};\n\nexport const bootstrap = async ({ strapi }: { strapi: Core.Strapi }) => {\n if (strapi.ee.features.isEnabled('cms-content-releases')) {\n const contentTypesWithDraftAndPublish = Object.keys(strapi.contentTypes).filter(\n (uid: any) => strapi.contentTypes[uid]?.options?.draftAndPublish\n );\n\n strapi.db.lifecycles.subscribe({\n models: contentTypesWithDraftAndPublish,\n\n /**\n * deleteMany is still used outside documents service, for example when deleting a locale\n */\n async afterDeleteMany(event) {\n try {\n const model = strapi.getModel(event.model.uid as UID.Schema);\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = event.params;\n\n deleteReleasesActionsAndUpdateReleaseStatus({\n contentType: model.uid,\n locale: where?.locale ?? null,\n ...(where?.documentId && { entryDocumentId: where.documentId }),\n });\n }\n } catch (error) {\n // If an error happens we don't want to block the delete entry flow, but we log the error\n strapi.log.error('Error while deleting release actions after entry deleteMany', {\n error,\n });\n }\n },\n });\n\n // We register middleware to handle ReleaseActions when changes on documents are made\n strapi.documents.use(deleteActionsOnDelete);\n strapi.documents.use(updateActionsOnUpdate);\n\n getService('scheduling', { strapi })\n .syncFromDatabase()\n .catch((err: Error) => {\n strapi.log.error(\n 'Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling.'\n );\n\n throw err;\n });\n\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n }\n};\n"],"names":["deleteReleasesActionsAndUpdateReleaseStatus","params","releases","strapi","db","query","RELEASE_MODEL_UID","findMany","where","actions","RELEASE_ACTION_MODEL_UID","deleteMany","release","getService","updateReleaseStatus","id","bootstrap","ee","features","isEnabled","contentTypesWithDraftAndPublish","Object","keys","contentTypes","filter","uid","options","draftAndPublish","lifecycles","subscribe","models","afterDeleteMany","event","model","getModel","kind","contentType","locale","documentId","entryDocumentId","error","log","documents","use","deleteActionsOnDelete","updateActionsOnUpdate","syncFromDatabase","catch","err","entries","ALLOWED_WEBHOOK_EVENTS","forEach","key","value","get","addAllowedEvent"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { Core, UID, Modules } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { registerAuditEvents } from './audit-logs';\nimport { getService } from './utils';\nimport { deleteActionsOnDelete, updateActionsOnUpdate } from './middlewares/documents';\n\ninterface DeleteManyParams {\n contentType: UID.ContentType;\n locale: string | null;\n entryDocumentId?: Modules.Documents.ID;\n}\n\nconst deleteReleasesActionsAndUpdateReleaseStatus = async (params: DeleteManyParams) => {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: params,\n },\n });\n\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: params,\n });\n\n // We update the status of each release after delete the actions\n for (const release of releases) {\n getService('release', { strapi }).updateReleaseStatus(release.id);\n }\n};\n\nexport const bootstrap = async ({ strapi }: { strapi: Core.Strapi }) => {\n if (strapi.ee.features.isEnabled('cms-content-releases')) {\n const contentTypesWithDraftAndPublish = Object.keys(strapi.contentTypes).filter(\n (uid: any) => strapi.contentTypes[uid]?.options?.draftAndPublish\n );\n\n strapi.db.lifecycles.subscribe({\n models: contentTypesWithDraftAndPublish,\n\n /**\n * deleteMany is still used outside documents service, for example when deleting a locale\n */\n async afterDeleteMany(event) {\n try {\n const model = strapi.getModel(event.model.uid as UID.Schema);\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = event.params;\n\n deleteReleasesActionsAndUpdateReleaseStatus({\n contentType: model.uid,\n locale: where?.locale ?? null,\n ...(where?.documentId && { entryDocumentId: where.documentId }),\n });\n }\n } catch (error) {\n // If an error happens we don't want to block the delete entry flow, but we log the error\n strapi.log.error('Error while deleting release actions after entry deleteMany', {\n error,\n });\n }\n },\n });\n\n // We register middleware to handle ReleaseActions when changes on documents are made\n strapi.documents.use(deleteActionsOnDelete);\n strapi.documents.use(updateActionsOnUpdate);\n\n getService('scheduling', { strapi })\n .syncFromDatabase()\n .catch((err: Error) => {\n strapi.log.error(\n 'Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling.'\n );\n\n throw err;\n });\n\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\n // Absent in CE, without the audit-logs license, or when disabled by config;\n // get() throws for services that were never added, so probe first.\n if (strapi.has('audit-logs-lifecycle')) {\n registerAuditEvents(strapi.get('audit-logs-lifecycle'));\n }\n }\n};\n"],"names":["deleteReleasesActionsAndUpdateReleaseStatus","params","releases","strapi","db","query","RELEASE_MODEL_UID","findMany","where","actions","RELEASE_ACTION_MODEL_UID","deleteMany","release","getService","updateReleaseStatus","id","bootstrap","ee","features","isEnabled","contentTypesWithDraftAndPublish","Object","keys","contentTypes","filter","uid","options","draftAndPublish","lifecycles","subscribe","models","afterDeleteMany","event","model","getModel","kind","contentType","locale","documentId","entryDocumentId","error","log","documents","use","deleteActionsOnDelete","updateActionsOnUpdate","syncFromDatabase","catch","err","entries","ALLOWED_WEBHOOK_EVENTS","forEach","key","value","get","addAllowedEvent","has","registerAuditEvents"],"mappings":"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"}
|
package/dist/server/constants.js
CHANGED
|
@@ -66,9 +66,29 @@ const ACTIONS = [
|
|
|
66
66
|
const ALLOWED_WEBHOOK_EVENTS = {
|
|
67
67
|
RELEASES_PUBLISH: 'releases.publish'
|
|
68
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* Audit Log events, transformed in audit-logs.ts and registered during bootstrap.
|
|
71
|
+
*
|
|
72
|
+
* RELEASE_TRIGGER is different from the releases.publish webhook.
|
|
73
|
+
* The webhook has its own payload format, which is already a public contract.
|
|
74
|
+
*
|
|
75
|
+
* TODO: Decide whether these should eventually converge when the
|
|
76
|
+
* releases.publish payload is revised: replace it with release.trigger,
|
|
77
|
+
* or keep both formats permanently.
|
|
78
|
+
*/ const AUDITED_EVENTS = {
|
|
79
|
+
RELEASE_CREATE: 'release.create',
|
|
80
|
+
RELEASE_UPDATE: 'release.update',
|
|
81
|
+
RELEASE_DELETE: 'release.delete',
|
|
82
|
+
RELEASE_TRIGGER: 'release.trigger',
|
|
83
|
+
RELEASE_ENTRY_ADD: 'release.entry.add',
|
|
84
|
+
RELEASE_ENTRY_UPDATE: 'release.entry.update',
|
|
85
|
+
RELEASE_ENTRY_REMOVE: 'release.entry.remove',
|
|
86
|
+
RELEASE_SETTINGS_UPDATE: 'release.settings.update'
|
|
87
|
+
};
|
|
69
88
|
|
|
70
89
|
exports.ACTIONS = ACTIONS;
|
|
71
90
|
exports.ALLOWED_WEBHOOK_EVENTS = ALLOWED_WEBHOOK_EVENTS;
|
|
91
|
+
exports.AUDITED_EVENTS = AUDITED_EVENTS;
|
|
72
92
|
exports.RELEASE_ACTION_MODEL_UID = RELEASE_ACTION_MODEL_UID;
|
|
73
93
|
exports.RELEASE_MODEL_UID = RELEASE_MODEL_UID;
|
|
74
94
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../server/src/constants.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n\n // Settings\n {\n uid: 'settings.read',\n section: 'settings',\n displayName: 'Read',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n\n {\n uid: 'settings.update',\n section: 'settings',\n displayName: 'Edit',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n];\n\nexport const ALLOWED_WEBHOOK_EVENTS = {\n RELEASES_PUBLISH: 'releases.publish',\n};\n"],"names":["RELEASE_MODEL_UID","RELEASE_ACTION_MODEL_UID","ACTIONS","section","displayName","uid","pluginName","category","subCategory","ALLOWED_WEBHOOK_EVENTS","RELEASES_PUBLISH"],"mappings":";;AAAO,MAAMA,oBAAoB;AAC1B,MAAMC,2BAA2B;MAE3BC,OAAAA,GAAU;AACrB,IAAA;QACEC,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,MAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,SAAA;QACbC,GAAAA,EAAK,SAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,gCAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,2BAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;;AAGA,IAAA;QACED,GAAAA,EAAK,eAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd,KAAA;AAEA,IAAA;QACED,GAAAA,EAAK,iBAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd;;MAGWG,sBAAAA,GAAyB;IACpCC,gBAAAA,EAAkB;AACpB
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../server/src/constants.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n\n // Settings\n {\n uid: 'settings.read',\n section: 'settings',\n displayName: 'Read',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n\n {\n uid: 'settings.update',\n section: 'settings',\n displayName: 'Edit',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n];\n\nexport const ALLOWED_WEBHOOK_EVENTS = {\n RELEASES_PUBLISH: 'releases.publish',\n};\n\n/**\n * Audit Log events, transformed in audit-logs.ts and registered during bootstrap.\n *\n * RELEASE_TRIGGER is different from the releases.publish webhook.\n * The webhook has its own payload format, which is already a public contract.\n *\n * TODO: Decide whether these should eventually converge when the\n * releases.publish payload is revised: replace it with release.trigger,\n * or keep both formats permanently.\n */\nexport const AUDITED_EVENTS = {\n RELEASE_CREATE: 'release.create',\n RELEASE_UPDATE: 'release.update',\n RELEASE_DELETE: 'release.delete',\n RELEASE_TRIGGER: 'release.trigger',\n RELEASE_ENTRY_ADD: 'release.entry.add',\n RELEASE_ENTRY_UPDATE: 'release.entry.update',\n RELEASE_ENTRY_REMOVE: 'release.entry.remove',\n RELEASE_SETTINGS_UPDATE: 'release.settings.update',\n} as const;\n"],"names":["RELEASE_MODEL_UID","RELEASE_ACTION_MODEL_UID","ACTIONS","section","displayName","uid","pluginName","category","subCategory","ALLOWED_WEBHOOK_EVENTS","RELEASES_PUBLISH","AUDITED_EVENTS","RELEASE_CREATE","RELEASE_UPDATE","RELEASE_DELETE","RELEASE_TRIGGER","RELEASE_ENTRY_ADD","RELEASE_ENTRY_UPDATE","RELEASE_ENTRY_REMOVE","RELEASE_SETTINGS_UPDATE"],"mappings":";;AAAO,MAAMA,oBAAoB;AAC1B,MAAMC,2BAA2B;MAE3BC,OAAAA,GAAU;AACrB,IAAA;QACEC,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,MAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,SAAA;QACbC,GAAAA,EAAK,SAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,gCAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,2BAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;;AAGA,IAAA;QACED,GAAAA,EAAK,eAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd,KAAA;AAEA,IAAA;QACED,GAAAA,EAAK,iBAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd;;MAGWG,sBAAAA,GAAyB;IACpCC,gBAAAA,EAAkB;AACpB;AAEA;;;;;;;;;UAUaC,cAAAA,GAAiB;IAC5BC,cAAAA,EAAgB,gBAAA;IAChBC,cAAAA,EAAgB,gBAAA;IAChBC,cAAAA,EAAgB,gBAAA;IAChBC,eAAAA,EAAiB,iBAAA;IACjBC,iBAAAA,EAAmB,mBAAA;IACnBC,oBAAAA,EAAsB,sBAAA;IACtBC,oBAAAA,EAAsB,sBAAA;IACtBC,uBAAAA,EAAyB;AAC3B;;;;;;;;"}
|
|
@@ -64,6 +64,25 @@ const ACTIONS = [
|
|
|
64
64
|
const ALLOWED_WEBHOOK_EVENTS = {
|
|
65
65
|
RELEASES_PUBLISH: 'releases.publish'
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Audit Log events, transformed in audit-logs.ts and registered during bootstrap.
|
|
69
|
+
*
|
|
70
|
+
* RELEASE_TRIGGER is different from the releases.publish webhook.
|
|
71
|
+
* The webhook has its own payload format, which is already a public contract.
|
|
72
|
+
*
|
|
73
|
+
* TODO: Decide whether these should eventually converge when the
|
|
74
|
+
* releases.publish payload is revised: replace it with release.trigger,
|
|
75
|
+
* or keep both formats permanently.
|
|
76
|
+
*/ const AUDITED_EVENTS = {
|
|
77
|
+
RELEASE_CREATE: 'release.create',
|
|
78
|
+
RELEASE_UPDATE: 'release.update',
|
|
79
|
+
RELEASE_DELETE: 'release.delete',
|
|
80
|
+
RELEASE_TRIGGER: 'release.trigger',
|
|
81
|
+
RELEASE_ENTRY_ADD: 'release.entry.add',
|
|
82
|
+
RELEASE_ENTRY_UPDATE: 'release.entry.update',
|
|
83
|
+
RELEASE_ENTRY_REMOVE: 'release.entry.remove',
|
|
84
|
+
RELEASE_SETTINGS_UPDATE: 'release.settings.update'
|
|
85
|
+
};
|
|
67
86
|
|
|
68
|
-
export { ACTIONS, ALLOWED_WEBHOOK_EVENTS, RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID };
|
|
87
|
+
export { ACTIONS, ALLOWED_WEBHOOK_EVENTS, AUDITED_EVENTS, RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID };
|
|
69
88
|
//# sourceMappingURL=constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sources":["../../server/src/constants.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n\n // Settings\n {\n uid: 'settings.read',\n section: 'settings',\n displayName: 'Read',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n\n {\n uid: 'settings.update',\n section: 'settings',\n displayName: 'Edit',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n];\n\nexport const ALLOWED_WEBHOOK_EVENTS = {\n RELEASES_PUBLISH: 'releases.publish',\n};\n"],"names":["RELEASE_MODEL_UID","RELEASE_ACTION_MODEL_UID","ACTIONS","section","displayName","uid","pluginName","category","subCategory","ALLOWED_WEBHOOK_EVENTS","RELEASES_PUBLISH"],"mappings":"AAAO,MAAMA,oBAAoB;AAC1B,MAAMC,2BAA2B;MAE3BC,OAAAA,GAAU;AACrB,IAAA;QACEC,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,MAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,SAAA;QACbC,GAAAA,EAAK,SAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,gCAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,2BAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;;AAGA,IAAA;QACED,GAAAA,EAAK,eAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd,KAAA;AAEA,IAAA;QACED,GAAAA,EAAK,iBAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd;;MAGWG,sBAAAA,GAAyB;IACpCC,gBAAAA,EAAkB;AACpB;;;;"}
|
|
1
|
+
{"version":3,"file":"constants.mjs","sources":["../../server/src/constants.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n\n // Settings\n {\n uid: 'settings.read',\n section: 'settings',\n displayName: 'Read',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n\n {\n uid: 'settings.update',\n section: 'settings',\n displayName: 'Edit',\n category: 'content releases',\n subCategory: 'options',\n pluginName: 'content-releases',\n },\n];\n\nexport const ALLOWED_WEBHOOK_EVENTS = {\n RELEASES_PUBLISH: 'releases.publish',\n};\n\n/**\n * Audit Log events, transformed in audit-logs.ts and registered during bootstrap.\n *\n * RELEASE_TRIGGER is different from the releases.publish webhook.\n * The webhook has its own payload format, which is already a public contract.\n *\n * TODO: Decide whether these should eventually converge when the\n * releases.publish payload is revised: replace it with release.trigger,\n * or keep both formats permanently.\n */\nexport const AUDITED_EVENTS = {\n RELEASE_CREATE: 'release.create',\n RELEASE_UPDATE: 'release.update',\n RELEASE_DELETE: 'release.delete',\n RELEASE_TRIGGER: 'release.trigger',\n RELEASE_ENTRY_ADD: 'release.entry.add',\n RELEASE_ENTRY_UPDATE: 'release.entry.update',\n RELEASE_ENTRY_REMOVE: 'release.entry.remove',\n RELEASE_SETTINGS_UPDATE: 'release.settings.update',\n} as const;\n"],"names":["RELEASE_MODEL_UID","RELEASE_ACTION_MODEL_UID","ACTIONS","section","displayName","uid","pluginName","category","subCategory","ALLOWED_WEBHOOK_EVENTS","RELEASES_PUBLISH","AUDITED_EVENTS","RELEASE_CREATE","RELEASE_UPDATE","RELEASE_DELETE","RELEASE_TRIGGER","RELEASE_ENTRY_ADD","RELEASE_ENTRY_UPDATE","RELEASE_ENTRY_REMOVE","RELEASE_SETTINGS_UPDATE"],"mappings":"AAAO,MAAMA,oBAAoB;AAC1B,MAAMC,2BAA2B;MAE3BC,OAAAA,GAAU;AACrB,IAAA;QACEC,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,MAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,MAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,QAAA;QACbC,GAAAA,EAAK,QAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,SAAA;QACbC,GAAAA,EAAK,SAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,gCAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;AACA,IAAA;QACEH,OAAAA,EAAS,SAAA;QACTC,WAAAA,EAAa,2BAAA;QACbC,GAAAA,EAAK,eAAA;QACLC,UAAAA,EAAY;AACd,KAAA;;AAGA,IAAA;QACED,GAAAA,EAAK,eAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd,KAAA;AAEA,IAAA;QACED,GAAAA,EAAK,iBAAA;QACLF,OAAAA,EAAS,UAAA;QACTC,WAAAA,EAAa,MAAA;QACbG,QAAAA,EAAU,kBAAA;QACVC,WAAAA,EAAa,SAAA;QACbF,UAAAA,EAAY;AACd;;MAGWG,sBAAAA,GAAyB;IACpCC,gBAAAA,EAAkB;AACpB;AAEA;;;;;;;;;UAUaC,cAAAA,GAAiB;IAC5BC,cAAAA,EAAgB,gBAAA;IAChBC,cAAAA,EAAgB,gBAAA;IAChBC,cAAAA,EAAgB,gBAAA;IAChBC,eAAAA,EAAiB,iBAAA;IACjBC,iBAAAA,EAAmB,mBAAA;IACnBC,oBAAAA,EAAsB,sBAAA;IACtBC,oBAAAA,EAAsB,sBAAA;IACtBC,uBAAAA,EAAyB;AAC3B;;;;"}
|