@cap-js/audit-logging 1.0.1 → 1.1.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/package.json +6 -8
- package/srv/log2alsng.js +37 -12
- package/CHANGELOG.md +0 -170
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js/audit-logging",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "CDS plugin providing integration to the SAP Audit Log service as well as out-of-the-box personal data-related audit logging based on annotations.",
|
|
5
5
|
"repository": "cap-js/audit-logging",
|
|
6
6
|
"author": "SAP SE (https://www.sap.com)",
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
"main": "cds-plugin.js",
|
|
10
10
|
"files": [
|
|
11
11
|
"lib",
|
|
12
|
-
"srv"
|
|
13
|
-
"CHANGELOG.md"
|
|
12
|
+
"srv"
|
|
14
13
|
],
|
|
15
14
|
"scripts": {
|
|
16
|
-
"lint": "npx eslint .",
|
|
15
|
+
"lint": "npx eslint . --max-warnings=0",
|
|
17
16
|
"test": "npx jest --silent"
|
|
18
17
|
},
|
|
19
18
|
"peerDependencies": {
|
|
@@ -26,13 +25,12 @@
|
|
|
26
25
|
"axios": "^1",
|
|
27
26
|
"eslint": "^9",
|
|
28
27
|
"express": "^4",
|
|
29
|
-
"jest": "^29"
|
|
28
|
+
"jest": "^29",
|
|
29
|
+
"pretty-quick": "^4.2.2",
|
|
30
|
+
"simple-git-hooks": "^2.13.1"
|
|
30
31
|
},
|
|
31
32
|
"cds": {
|
|
32
33
|
"requires": {
|
|
33
|
-
"[test]": {
|
|
34
|
-
"outbox": "persistent-outbox"
|
|
35
|
-
},
|
|
36
34
|
"audit-log": {
|
|
37
35
|
"handle": [
|
|
38
36
|
"READ",
|
package/srv/log2alsng.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const cds = require('@sap/cds')
|
|
2
|
-
|
|
3
2
|
const LOG = cds.log('audit-log')
|
|
4
3
|
|
|
5
4
|
const https = require('https')
|
|
@@ -12,7 +11,7 @@ module.exports = class AuditLog2ALSNG extends AuditLogService {
|
|
|
12
11
|
this._vcap = JSON.parse(process.env.VCAP_SERVICES || '{}')
|
|
13
12
|
this._userProvided = this._vcap['user-provided']?.find(obj => obj.tags.includes('auditlog-ng')) || {}
|
|
14
13
|
if (!this._userProvided.credentials) throw new Error('No credentials found for SAP Audit Log Service NG')
|
|
15
|
-
this._vcapApplication =
|
|
14
|
+
this._vcapApplication = JSON.parse(process.env.VCAP_APPLICATION || '{}')
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
async init() {
|
|
@@ -24,12 +23,14 @@ module.exports = class AuditLog2ALSNG extends AuditLogService {
|
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
eventMapper(event, data) {
|
|
27
|
-
|
|
26
|
+
const known = {
|
|
28
27
|
PersonalDataModified: () => this.logEvent('dppDataModification', data),
|
|
29
28
|
SensitiveDataRead: () => this.logEvent('dppDataAccess', data),
|
|
30
29
|
ConfigurationModified: () => this.logEvent('configurationChange', data),
|
|
31
30
|
SecurityEvent: () => this.logEvent('legacySecurityWrapper', data)
|
|
32
|
-
}
|
|
31
|
+
}
|
|
32
|
+
const dfault = () => this.logEvent(event, data)
|
|
33
|
+
return (known[event] ?? dfault)()
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
flattenAndSortIdObject(id) {
|
|
@@ -49,7 +50,8 @@ module.exports = class AuditLog2ALSNG extends AuditLogService {
|
|
|
49
50
|
const oldValue = attributes[0]['old'] ?? ''
|
|
50
51
|
const newValue = attributes[0]['new'] ?? ''
|
|
51
52
|
const dataSubjectId = this.flattenAndSortIdObject(subject['id'])
|
|
52
|
-
|
|
53
|
+
|
|
54
|
+
const known = {
|
|
53
55
|
dppDataModification: {
|
|
54
56
|
objectType: object['type'],
|
|
55
57
|
objectId: objectId,
|
|
@@ -84,7 +86,26 @@ module.exports = class AuditLog2ALSNG extends AuditLogService {
|
|
|
84
86
|
: data.data
|
|
85
87
|
})
|
|
86
88
|
}
|
|
87
|
-
}
|
|
89
|
+
}
|
|
90
|
+
if (event in known) return known[event]
|
|
91
|
+
|
|
92
|
+
// For unknown events, remove common audit log entry fields from the event payload
|
|
93
|
+
if (typeof data === 'object' && data !== null) {
|
|
94
|
+
const rest = this.removeCommonAuditLogFields(data)
|
|
95
|
+
return rest
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return data
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
removeCommonAuditLogFields(obj) {
|
|
102
|
+
if (typeof obj !== 'object' || obj === null) return obj
|
|
103
|
+
const { ...rest } = obj
|
|
104
|
+
delete rest.uuid
|
|
105
|
+
delete rest.user
|
|
106
|
+
delete rest.time
|
|
107
|
+
delete rest.tenant
|
|
108
|
+
return rest
|
|
88
109
|
}
|
|
89
110
|
|
|
90
111
|
eventPayload(event, data) {
|
|
@@ -126,14 +147,18 @@ module.exports = class AuditLog2ALSNG extends AuditLogService {
|
|
|
126
147
|
return JSON.stringify([this.eventPayload(event, data)])
|
|
127
148
|
}
|
|
128
149
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
150
|
+
if (event in { dppDataModification: 1, dppDataAccess: 1, configurationChange: 1 }) {
|
|
151
|
+
const eventData = data['attributes']?.map(attr => {
|
|
152
|
+
return this.eventPayload(event, {
|
|
153
|
+
...data,
|
|
154
|
+
attributes: [attr]
|
|
155
|
+
})
|
|
133
156
|
})
|
|
134
|
-
|
|
157
|
+
return JSON.stringify(eventData || [])
|
|
158
|
+
}
|
|
135
159
|
|
|
136
|
-
|
|
160
|
+
// Always wrap event in an envelope for custom events
|
|
161
|
+
return JSON.stringify([this.eventPayload(event, data)])
|
|
137
162
|
}
|
|
138
163
|
|
|
139
164
|
logEvent(event, data) {
|
package/CHANGELOG.md
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
|
-
The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|
6
|
-
|
|
7
|
-
## Version 1.0.1 - 2025-08-05
|
|
8
|
-
|
|
9
|
-
### Fixed
|
|
10
|
-
|
|
11
|
-
- `audit-log-to-alsng`: EventDataPayload to Support Multi-Key Object and DataSubject IDs
|
|
12
|
-
|
|
13
|
-
## Version 1.0.0 - 2025-07-11
|
|
14
|
-
|
|
15
|
-
### Added
|
|
16
|
-
|
|
17
|
-
- Beta support for next generation SAP Audit Log Service
|
|
18
|
-
- Use explicit kind `audit-log-to-alsng` or alpha auto-detect kind `audit-log-to-als`
|
|
19
|
-
|
|
20
|
-
## Version 0.9.0 - 2025-06-05
|
|
21
|
-
|
|
22
|
-
### Added
|
|
23
|
-
|
|
24
|
-
- Support for `@sap/cds^9`
|
|
25
|
-
|
|
26
|
-
## Version 0.8.3 - 2025-04-09
|
|
27
|
-
|
|
28
|
-
### Fixed
|
|
29
|
-
|
|
30
|
-
- Preperation for `@sap/cds^9`
|
|
31
|
-
|
|
32
|
-
## Version 0.8.2 - 2024-11-27
|
|
33
|
-
|
|
34
|
-
### Fixed
|
|
35
|
-
|
|
36
|
-
- Erroneous modification log for non-updated key properties
|
|
37
|
-
- Error during non-modifying queries on database level
|
|
38
|
-
- Specify charset UTF-8 for requests to SAP Audit Log Service
|
|
39
|
-
|
|
40
|
-
## Version 0.8.1 - 2024-09-13
|
|
41
|
-
|
|
42
|
-
### Fixed
|
|
43
|
-
|
|
44
|
-
- Support for `@sap/cds^8.2`
|
|
45
|
-
- Reduce clutter in error raised for outbound requests
|
|
46
|
-
|
|
47
|
-
## Version 0.8.0 - 2024-05-24
|
|
48
|
-
|
|
49
|
-
### Added
|
|
50
|
-
|
|
51
|
-
- Allow to specify undefined tenant in order to log to provider account in multi-tenant scenarios
|
|
52
|
-
|
|
53
|
-
### Changed
|
|
54
|
-
|
|
55
|
-
- Use kind `audit-log-to-restv2` in profile `hybrid`
|
|
56
|
-
|
|
57
|
-
## Version 0.7.0 - 2024-05-15
|
|
58
|
-
|
|
59
|
-
### Added
|
|
60
|
-
|
|
61
|
-
- Automatically promote entities that are associated with data subjects
|
|
62
|
-
|
|
63
|
-
## Version 0.6.0 - 2024-02-05
|
|
64
|
-
|
|
65
|
-
### Added
|
|
66
|
-
|
|
67
|
-
- Support for `@sap/cds^7.5`
|
|
68
|
-
|
|
69
|
-
### Fixed
|
|
70
|
-
|
|
71
|
-
- Automatic personal data modification logging for data subject details with renamed keys
|
|
72
|
-
- Data subject resolution in circular models
|
|
73
|
-
|
|
74
|
-
## Version 0.5.2 - 2023-12-08
|
|
75
|
-
|
|
76
|
-
### Fixed
|
|
77
|
-
|
|
78
|
-
- Automatic personal data modification logging for deep data structures with renamings
|
|
79
|
-
|
|
80
|
-
## Version 0.5.1 - 2023-11-30
|
|
81
|
-
|
|
82
|
-
### Fixed
|
|
83
|
-
|
|
84
|
-
- Falsy early exit during bootstrapping in case a service does not contain personal data
|
|
85
|
-
|
|
86
|
-
## Version 0.5.0 - 2023-11-22
|
|
87
|
-
|
|
88
|
-
### Added
|
|
89
|
-
|
|
90
|
-
- Common log entry fields `uuid`, `tenant`, `user` and `time` can be provided manually
|
|
91
|
-
|
|
92
|
-
## Version 0.4.0 - 2023-10-24
|
|
93
|
-
|
|
94
|
-
### Added
|
|
95
|
-
|
|
96
|
-
- Support for Premium plan of SAP Audit Log Service
|
|
97
|
-
- Support for XSUAA credential type `x509`
|
|
98
|
-
- Support for generic outbox
|
|
99
|
-
|
|
100
|
-
### Changed
|
|
101
|
-
|
|
102
|
-
- Always use outbox (as configured in project)
|
|
103
|
-
|
|
104
|
-
### Fixed
|
|
105
|
-
|
|
106
|
-
- Avoid dangling `SELECT`s to resolve data subject IDs, which resulted in "Transaction already closed" errors
|
|
107
|
-
|
|
108
|
-
## Version 0.3.2 - 2023-10-11
|
|
109
|
-
|
|
110
|
-
### Fixed
|
|
111
|
-
|
|
112
|
-
- If the request has no tenant (e.g., Unauthorized), the audit log shall be sent to the provider account
|
|
113
|
-
|
|
114
|
-
## Version 0.3.1 - 2023-09-25
|
|
115
|
-
|
|
116
|
-
### Fixed
|
|
117
|
-
|
|
118
|
-
- Defaulting of `@PersonalData.DataSubjectRole` to entity name
|
|
119
|
-
- Overriding service configuration
|
|
120
|
-
|
|
121
|
-
## Version 0.3.0 - 2023-09-05
|
|
122
|
-
|
|
123
|
-
### Changed
|
|
124
|
-
|
|
125
|
-
- Default value for `cds.requires['audit-log'].handle` changed to `['READ', 'WRITE']`, i.e., accessing sensitive data is now logged by default.
|
|
126
|
-
|
|
127
|
-
## Version 0.2.0 - 2023-09-01
|
|
128
|
-
|
|
129
|
-
### Added
|
|
130
|
-
|
|
131
|
-
- Export class `AuditLogService` for extending in custom implementations as follows:
|
|
132
|
-
```js
|
|
133
|
-
const { AuditLogService } = require('@cap-js/audit-logging')
|
|
134
|
-
class MyAuditLogService extends AuditLogService {
|
|
135
|
-
async init() {
|
|
136
|
-
[...]
|
|
137
|
-
// call AuditLogService's init
|
|
138
|
-
await super.init()
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
module.exports = MyAuditLogService
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Version 0.1.0 - 2023-08-18
|
|
145
|
-
|
|
146
|
-
### Added
|
|
147
|
-
|
|
148
|
-
- New API:
|
|
149
|
-
- `await audit.log('<event>', <data>)` for asynchronous logs (cf. `emit`)
|
|
150
|
-
- `await audit.logSync('<event>', <data>)` for synchronous logs (cf. `send`)
|
|
151
|
-
- New REST API-based schema with auto-filled `LogEntry` aspect
|
|
152
|
-
- New events `SensitiveDataRead`, `PersonalDataModified`, `ConfigurationModified`, and `SecurityEvent`
|
|
153
|
-
- Full support for OAuth2 plan of SAP Audit Log Service
|
|
154
|
-
|
|
155
|
-
### Changed
|
|
156
|
-
|
|
157
|
-
- Whether reading sensitive data and modifying personal data is logged is determined by `cds.requires['audit-log'].handle: [...]`.
|
|
158
|
-
Possible values in the array are `READ` and/ or `WRITE`, with `WRITE` as the sole default entry.
|
|
159
|
-
Hence, accessing sensitive data is not logged by default.
|
|
160
|
-
- Integration with SAP Audit Log Service via REST API instead of client library (`@sap/audit-logging`)
|
|
161
|
-
|
|
162
|
-
### Fixed
|
|
163
|
-
|
|
164
|
-
- Various glitches in log calculation
|
|
165
|
-
|
|
166
|
-
### Removed
|
|
167
|
-
|
|
168
|
-
- Old events `dataAccessLog`, `dataModificationLog`, `configChangeLog`, and `securityLog`
|
|
169
|
-
- `@AuditLog.Operation` annotations are ignored. Having the plugin as dependency signals the intent to audit log.
|
|
170
|
-
- `cds.features.audit_personal_data: true` is no longer necessary. Instead, simply add the plugin as a dependency.
|