@sap/cds 9.3.0 → 9.3.1
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
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
- The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
- This project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## Version 9.3.1 - 2025-09-03
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- In messaging services, propagated headers (e.g. `x-correlation-id`) will not be automatically propagated for `format: 'cloudevents'`
|
|
12
|
+
- Avoid deprecation warning for `cds.context.user.tokenInfo`
|
|
13
|
+
- Consider `@Capabilities.ExpandRestrictions.NonExpandableProperties` annotation and ignore fields referenced by the annotation, when rewriting asterisk expand into columns
|
|
14
|
+
|
|
7
15
|
## Version 9.3.0 - 2025-08-29
|
|
8
16
|
|
|
9
17
|
### Added
|
|
@@ -113,14 +113,17 @@ function get_user_factory(credentials, skipped_attrs) {
|
|
|
113
113
|
if (Array.isArray(payload.ias_apis)) payload.ias_apis.forEach(r => (roles[r] = 1))
|
|
114
114
|
if (clientid === credentials.clientid) roles['internal-user'] = 1
|
|
115
115
|
else delete roles['internal-user']
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
|
|
117
|
+
const user = new cds.User({ id: 'system', roles, authInfo: securityContext })
|
|
118
|
+
// REVISIT: remove compat in cds^10
|
|
119
|
+
Object.defineProperty(user, 'tokenInfo', {
|
|
120
|
+
get() {
|
|
121
|
+
// prettier-ignore
|
|
120
122
|
cds.utils.deprecated({ kind: 'API', old: 'cds.context.user.tokenInfo', use: 'cds.context.user.authInfo.token' })
|
|
121
123
|
return securityContext.token
|
|
122
124
|
}
|
|
123
125
|
})
|
|
126
|
+
return user
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
// add all unknown attributes to req.user.attr in order to keep public API small
|
|
@@ -138,14 +141,15 @@ function get_user_factory(credentials, skipped_attrs) {
|
|
|
138
141
|
if (attr.given_name) attr.givenName = attr.given_name
|
|
139
142
|
if (attr.family_name) attr.familyName = attr.family_name
|
|
140
143
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
get
|
|
144
|
+
const user = new cds.User({ id: payload.sub, attr, authInfo: securityContext })
|
|
145
|
+
// REVISIT: remove compat in cds^10
|
|
146
|
+
Object.defineProperty(user, 'tokenInfo', {
|
|
147
|
+
get() {
|
|
145
148
|
cds.utils.deprecated({ kind: 'API', old: 'cds.context.user.tokenInfo', use: 'cds.context.user.authInfo.token' })
|
|
146
149
|
return securityContext.token
|
|
147
150
|
}
|
|
148
151
|
})
|
|
152
|
+
return user
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
155
|
|
|
@@ -87,14 +87,15 @@ function get_user_factory(credentials, xsappname, kind) {
|
|
|
87
87
|
attr.email = payload.email
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
get
|
|
90
|
+
const user = new cds.User({ id, roles, attr, authInfo: securityContext })
|
|
91
|
+
// REVISIT: remove compat in cds^10
|
|
92
|
+
Object.defineProperty(user, 'tokenInfo', {
|
|
93
|
+
get() {
|
|
94
94
|
cds.utils.deprecated({ kind: 'API', old: 'cds.context.user.tokenInfo', use: 'cds.context.user.authInfo.token' })
|
|
95
95
|
return securityContext.token
|
|
96
96
|
}
|
|
97
97
|
})
|
|
98
|
+
return user
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -89,11 +89,17 @@ const rewriteExpandAsterisk = (columns, target) => {
|
|
|
89
89
|
})
|
|
90
90
|
if (expandAllColIdx > -1) {
|
|
91
91
|
const { expand } = columns.splice(expandAllColIdx, 1)[0]
|
|
92
|
+
|
|
93
|
+
const annotation = target['@Capabilities.ExpandRestrictions.NonExpandableProperties']
|
|
94
|
+
const restrictions = annotation?.map(element => element['=']) ?? []
|
|
95
|
+
|
|
92
96
|
for (const elName in target.elements) {
|
|
93
|
-
if (target.elements[elName]._target
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
if (!target.elements[elName]._target) continue
|
|
98
|
+
if (restrictions.includes(elName)) continue
|
|
99
|
+
if (elName === 'SiblingEntity') continue
|
|
100
|
+
if (columns.find(col => col.expand && col.ref && col.ref[0] === elName)) continue
|
|
101
|
+
|
|
102
|
+
columns.push({ ref: [elName], expand: [...expand] })
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
105
|
}
|
|
@@ -103,6 +103,13 @@ module.exports = class MessagingService extends cds.Service {
|
|
|
103
103
|
|
|
104
104
|
prepareHeaders(headers, event) {
|
|
105
105
|
if (this.options.format === 'cloudevents') {
|
|
106
|
+
for (const propagatedHeader of cds.EventContext.propagateHeaders) {
|
|
107
|
+
if (headers[propagatedHeader] && !Object.hasOwn(propagatedHeader, headers)) {
|
|
108
|
+
// For propagated headers, e.g. `x-correlation-id` (from inbound HTTP request), we don't want to set the
|
|
109
|
+
// respective header. It's incompatible to the cloudevents spec, allowed is only [a-zA-Z0-9].
|
|
110
|
+
Object.defineProperty(headers, propagatedHeader, { value: undefined, enumerable: false })
|
|
111
|
+
}
|
|
112
|
+
}
|
|
106
113
|
if (!('id' in headers)) headers.id = cds.utils.uuid()
|
|
107
114
|
if (!('type' in headers)) headers.type = event
|
|
108
115
|
if (!('source' in headers)) headers.source = `/default/sap.cap/${process.pid}`
|