@cap-js/audit-logging 0.3.1 → 0.3.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
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 0.3.2 - 2023-10-11
8
+
9
+ ### Fixed
10
+
11
+ - If the request has no tenant (e.g., Unauthorized), the audit log shall be sent to the provider account
12
+
13
+ ## Version 0.3.1 - 2023-09-25
14
+
15
+ ### Fixed
16
+
17
+ - Defaulting of `@PersonalData.DataSubjectRole` to entity name
18
+ - Overriding service configuration
19
+
20
+ ## Version 0.3.0 - 2023-09-05
21
+
22
+ ### Changed
23
+
24
+ - Default value for `cds.requires['audit-log'].handle` changed to `['READ', 'WRITE']`, i.e., accessing sensitive data is now logged by default.
25
+
26
+ ## Version 0.2.0 - 2023-09-01
27
+
28
+ ### Added
29
+
30
+ - Export class `AuditLogService` for extending in custom implementations as follows:
31
+ ```js
32
+ const { AuditLogService } = require('@cap-js/audit-logging')
33
+ class MyAuditLogService extends AuditLogService {
34
+ async init() {
35
+ [...]
36
+ // call AuditLogService's init
37
+ await super.init()
38
+ }
39
+ }
40
+ module.exports = MyAuditLogService
41
+ ```
42
+
43
+ ## Version 0.1.0 - 2023-08-18
44
+
45
+ ### Added
46
+
47
+ - New API:
48
+ - `await audit.log('<event>', <data>)` for asynchronous logs (cf. `emit`)
49
+ - `await audit.logSync('<event>', <data>)` for synchronous logs (cf. `send`)
50
+ - New REST API-based schema with auto-filled `LogEntry` aspect
51
+ - New events `SensitiveDataRead`, `PersonalDataModified`, `ConfigurationModified`, and `SecurityEvent`
52
+ - Full support for OAuth2 plan of SAP Audit Log Service
53
+
54
+ ### Changed
55
+
56
+ - Whether reading sensitive data and modifying personal data is logged is determined by `cds.requires['audit-log'].handle: [...]`.
57
+ Possible values in the array are `READ` and/ or `WRITE`, with `WRITE` as the sole default entry.
58
+ Hence, accessing sensitive data is not logged by default.
59
+ - Integration with SAP Audit Log Service via REST API instead of client library (`@sap/audit-logging`)
60
+
61
+ ### Fixed
62
+
63
+ - Various glitches in log calculation
64
+
65
+ ### Removed
66
+
67
+ - Old events `dataAccessLog`, `dataModificationLog`, `configChangeLog`, and `securityLog`
68
+ - `@AuditLog.Operation` annotations are ignored. Having the plugin as dependency signals the intent to audit log.
69
+ - `cds.features.audit_personal_data: true` is no longer necessary. Instead, simply add the plugin as a dependency.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  ## About this project
5
5
 
6
- `@cap-js/audit-logging` is a CDS plugin providing integration to the SAP BTP Audit Logging Service as well as out-of-the-box personal data-related audit logging based on annotations.
6
+ `@cap-js/audit-logging` is a 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.
7
7
 
8
8
  Documentation can be found at [cap.cloud.sap](https://cap.cloud.sap/docs/guides/data-privacy).
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/audit-logging",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
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,7 +9,8 @@
9
9
  "main": "cds-plugin.js",
10
10
  "files": [
11
11
  "lib",
12
- "srv"
12
+ "srv",
13
+ "CHANGELOG.md"
13
14
  ],
14
15
  "scripts": {
15
16
  "lint": "npx eslint .",
@@ -21,7 +22,6 @@
21
22
  "devDependencies": {
22
23
  "@cap-js/sqlite": "^1",
23
24
  "axios": "^1",
24
- "better-sqlite3": "8.5.2",
25
25
  "eslint": "^8",
26
26
  "express": "^4",
27
27
  "jest": "^29"
package/srv/log2restv2.js CHANGED
@@ -69,6 +69,7 @@ module.exports = class AuditLog2RESTv2 extends AuditLogService {
69
69
  setTimeout(() => tokens.delete(tenant), (expires_in - 60) * 1000)
70
70
  return access_token
71
71
  } catch (err) {
72
+ LOG._trace && LOG.trace('error during token fetch:', err)
72
73
  // 401 could also mean x-zid is not valid
73
74
  if (String(err.response?.statusCode).match(/^4\d\d$/)) err.unrecoverable = true
74
75
  throw err
@@ -76,25 +77,30 @@ module.exports = class AuditLog2RESTv2 extends AuditLogService {
76
77
  }
77
78
 
78
79
  async _send(data, path) {
79
- let url
80
80
  const headers = { 'content-type': 'application/json' }
81
- // TODO: what are these for?
82
81
  if (this._vcap) {
83
82
  headers.XS_AUDIT_ORG = this._vcap.organization_name
84
83
  headers.XS_AUDIT_SPACE = this._vcap.space_name
85
84
  headers.XS_AUDIT_APP = this._vcap.application_name
86
85
  }
86
+ let url
87
87
  if (this._oauth2) {
88
88
  url = this.options.credentials.url + PATHS.OAUTH2[path]
89
+ data.tenant ??= this._providerTenant //> if request has no tenant, stay in provider account
89
90
  headers.authorization = 'Bearer ' + (await this._getToken(data.tenant))
90
91
  data.tenant = data.tenant === this._providerTenant ? '$PROVIDER' : '$SUBSCRIBER'
91
92
  } else {
92
93
  url = this.options.credentials.url + PATHS.STANDARD[path]
93
94
  headers.authorization = this._auth
94
95
  }
96
+ if (LOG._debug) {
97
+ const _headers = Object.assign({}, headers, { authorization: headers.authorization.split(' ')[0] + ' ***' })
98
+ LOG.debug(`sending audit log to ${url} with tenant "${data.tenant}", user "${data.user}", and headers`, _headers)
99
+ }
95
100
  try {
96
101
  await _post(url, data, headers)
97
102
  } catch (err) {
103
+ LOG._trace && LOG.trace('error during log send:', err)
98
104
  // 429 (rate limit) is not unrecoverable
99
105
  if (String(err.response?.statusCode).match(/^4\d\d$/) && err.response?.statusCode !== 429)
100
106
  err.unrecoverable = true