@sap/cds 7.1.2 → 7.2.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/CHANGELOG.md +55 -4
- package/apis/cds.d.ts +10 -6
- package/apis/connect.d.ts +0 -1
- package/apis/core.d.ts +54 -5
- package/apis/log.d.ts +19 -6
- package/apis/models.d.ts +0 -18
- package/apis/ql.d.ts +23 -23
- package/apis/serve.d.ts +17 -14
- package/apis/services.d.ts +40 -29
- package/apis/test.d.ts +1 -2
- package/bin/serve.js +4 -4
- package/lib/auth/basic-auth.js +1 -1
- package/lib/auth/dummy-auth.js +2 -1
- package/lib/auth/ias-auth.js +68 -2
- package/lib/auth/index.js +5 -5
- package/lib/auth/jwt-auth.js +40 -24
- package/lib/auth/mocked-users.js +0 -13
- package/lib/auth/passport-basic.js +2 -0
- package/lib/auth/passport-digest.js +2 -0
- package/lib/compile/etc/_localized.js +0 -1
- package/lib/compile/extend.js +16 -0
- package/lib/compile/for/lean_drafts.js +38 -6
- package/lib/compile/resolve.js +7 -5
- package/lib/compile/to/json.js +6 -2
- package/lib/dbs/cds-deploy.js +3 -3
- package/lib/env/cds-env.js +3 -3
- package/lib/env/cds-requires.js +1 -0
- package/lib/env/defaults.js +8 -1
- package/lib/env/schemas/cds-rc.json +27 -3
- package/lib/i18n/localize.js +3 -3
- package/lib/index.js +4 -0
- package/lib/log/cds-log.js +10 -1
- package/lib/ql/Whereable.js +7 -3
- package/lib/req/user.js +18 -16
- package/lib/srv/middlewares/sap-statistics.js +3 -3
- package/lib/srv/middlewares/trace.js +5 -4
- package/lib/srv/srv-dispatch.js +10 -9
- package/lib/utils/axios.js +3 -0
- package/lib/utils/cds-test.js +3 -0
- package/lib/utils/cds-utils.js +2 -0
- package/libx/_runtime/auth/index.js +8 -32
- package/libx/_runtime/auth/strategies/ias-auth.js +1 -77
- package/libx/_runtime/auth/strategies/mock.js +1 -12
- package/libx/_runtime/auth/strategies/xssecUtils.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +5 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +5 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +4 -0
- package/libx/_runtime/common/composition/data.js +5 -3
- package/libx/_runtime/common/composition/insert.js +6 -3
- package/libx/_runtime/common/composition/update.js +12 -8
- package/libx/_runtime/common/error/constants.js +6 -1
- package/libx/_runtime/common/generic/auth/requires.js +11 -3
- package/libx/_runtime/common/generic/auth/restrict.js +21 -15
- package/libx/_runtime/common/generic/auth/restrictions.js +5 -2
- package/libx/_runtime/common/generic/crud.js +6 -0
- package/libx/_runtime/common/generic/paging.js +2 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +3 -5
- package/libx/_runtime/common/utils/resolveView.js +3 -1
- package/libx/_runtime/common/utils/restrictions.js +47 -0
- package/libx/_runtime/db/data-conversion/post-processing.js +3 -3
- package/libx/_runtime/db/generic/input.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +0 -17
- package/libx/_runtime/fiori/lean-draft.js +6 -3
- package/libx/_runtime/hana/driver.js +2 -4
- package/libx/_runtime/hana/pool.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
- package/libx/_runtime/messaging/outbox/utils.js +1 -2
- package/libx/_runtime/remote/utils/client.js +1 -1
- package/libx/_runtime/sqlite/Service.js +0 -4
- package/libx/_runtime/sqlite/customBuilder/CustomFunctionBuilder.js +2 -1
- package/libx/odata/afterburner.js +5 -3
- package/libx/odata/cqn2odata.js +7 -7
- package/libx/odata/utils.js +4 -1
- package/libx/rest/RestAdapter.js +15 -16
- package/package.json +1 -1
- package/lib/auth/xsuaa-auth.js +0 -2
- package/libx/_runtime/auth/utils.js +0 -32
- package/libx/audit-log/client.cds +0 -0
- package/libx/audit-log/client.js +0 -0
|
@@ -30,6 +30,7 @@ const _addKeysDeep = (keys, keysCollector, ignoreManagedBacklinks) => {
|
|
|
30
30
|
function _keysOf(entity, ignoreManagedBacklinks) {
|
|
31
31
|
const keysCollector = []
|
|
32
32
|
if (!entity || !entity.keys) return keysCollector
|
|
33
|
+
|
|
33
34
|
_addKeysDeep(entity.keys, keysCollector, ignoreManagedBacklinks)
|
|
34
35
|
return keysCollector
|
|
35
36
|
}
|
|
@@ -174,15 +175,16 @@ function _convertVal(element, value) {
|
|
|
174
175
|
throw new Error('Not a valid integer') // TODO
|
|
175
176
|
|
|
176
177
|
case 'cds.String':
|
|
177
|
-
case 'cds.LargeString':
|
|
178
|
+
case 'cds.LargeString':
|
|
179
|
+
return String(value)
|
|
180
|
+
case 'cds.Double':
|
|
181
|
+
return parseFloat(value)
|
|
178
182
|
case 'cds.Decimal':
|
|
179
183
|
case 'cds.DecimalFloat':
|
|
180
|
-
case 'cds.Double':
|
|
181
184
|
case 'cds.Int64':
|
|
182
185
|
case 'cds.Integer64':
|
|
183
186
|
if (typeof value === 'string') return value
|
|
184
187
|
return String(value)
|
|
185
|
-
|
|
186
188
|
case 'cds.Boolean':
|
|
187
189
|
return typeof value === 'string' ? value === 'true' : value
|
|
188
190
|
|
package/libx/odata/cqn2odata.js
CHANGED
|
@@ -73,7 +73,7 @@ function hasValidProps(obj, ...names) {
|
|
|
73
73
|
return true
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function _args(args) {
|
|
76
|
+
function _args(args, func) {
|
|
77
77
|
const res = []
|
|
78
78
|
|
|
79
79
|
for (const cur of args) {
|
|
@@ -83,11 +83,11 @@ function _args(args) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
if (hasValidProps(cur, 'func', 'args')) {
|
|
86
|
-
res.push(`${cur.func}(${_args(cur.args)})`)
|
|
86
|
+
res.push(`${cur.func}(${_args(cur.args, cur.func)})`)
|
|
87
87
|
} else if (hasValidProps(cur, 'ref')) {
|
|
88
88
|
res.push(_format(cur))
|
|
89
89
|
} else if (hasValidProps(cur, 'val')) {
|
|
90
|
-
res.push(_format(cur))
|
|
90
|
+
res.push(_format(cur, null, null, null, null, func))
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -111,20 +111,20 @@ const _odataV2Func = (func, args) => {
|
|
|
111
111
|
// this doesn't support the contains signature with two collections as args, introduced in odata v4.01
|
|
112
112
|
return `substringof(${_args([args[1], args[0]])})`
|
|
113
113
|
default:
|
|
114
|
-
return `${func}(${_args(args)})`
|
|
114
|
+
return `${func}(${_args(args, func)})`
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
const _format = (cur, elementName, target, kind, isLambda) => {
|
|
118
|
+
const _format = (cur, elementName, target, kind, isLambda, func) => {
|
|
119
119
|
if (typeof cur !== 'object') return encodeURIComponent(formatVal(cur, elementName, target, kind))
|
|
120
120
|
if (hasValidProps(cur, 'ref'))
|
|
121
121
|
return encodeURIComponent(isLambda ? [LAMBDA_VARIABLE, ...cur.ref].join('/') : cur.ref[0].id || cur.ref.join('/'))
|
|
122
|
-
if (hasValidProps(cur, 'val')) return encodeURIComponent(formatVal(cur.val, elementName, target, kind))
|
|
122
|
+
if (hasValidProps(cur, 'val')) return encodeURIComponent(formatVal(cur.val, elementName, target, kind, func))
|
|
123
123
|
if (hasValidProps(cur, 'xpr')) return `(${_xpr(cur.xpr, target, kind, isLambda)})`
|
|
124
124
|
// REVISIT: How to detect the types for all functions?
|
|
125
125
|
if (hasValidProps(cur, 'func')) {
|
|
126
126
|
if (cur.args?.length) {
|
|
127
|
-
return kind === 'odata-v2' ? _odataV2Func(cur.func, cur.args) : `${cur.func}(${_args(cur.args)})`
|
|
127
|
+
return kind === 'odata-v2' ? _odataV2Func(cur.func, cur.args) : `${cur.func}(${_args(cur.args, cur.func)})`
|
|
128
128
|
}
|
|
129
129
|
return `${cur.func}()`
|
|
130
130
|
}
|
package/libx/odata/utils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const { toBase64url } = require('../_runtime/common/utils/binary')
|
|
2
2
|
const cds = require('../_runtime/cds')
|
|
3
3
|
|
|
4
|
+
const MATH_FUNC = {'round': 1, 'floor': 1, 'ceiling': 1}
|
|
5
|
+
|
|
4
6
|
const getSafeNumber = str => {
|
|
5
7
|
const n = Number(str)
|
|
6
8
|
return Number.isSafeInteger(n) || String(n) === str ? n : str
|
|
@@ -48,11 +50,12 @@ const _getElement = (csnTarget, key) => {
|
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
const formatVal = (val, elementName, csnTarget, kind) => {
|
|
53
|
+
const formatVal = (val, elementName, csnTarget, kind, func) => {
|
|
52
54
|
if (val === null || val === 'null') return 'null'
|
|
53
55
|
if (typeof val === 'boolean') return val
|
|
54
56
|
if (typeof val === 'number') return getSafeNumber(val)
|
|
55
57
|
if (!csnTarget && typeof val === 'string' && UUID.test(val)) return kind === 'odata-v2' ? `guid'${val}'` : val
|
|
58
|
+
if (typeof val === 'string' && func in MATH_FUNC) return val
|
|
56
59
|
const element = _getElement(csnTarget, elementName)
|
|
57
60
|
if (kind === 'odata-v2') {
|
|
58
61
|
switch (element.type) {
|
package/libx/rest/RestAdapter.js
CHANGED
|
@@ -17,9 +17,13 @@ const error = require('./middleware/error')
|
|
|
17
17
|
const { alias2ref } = require('../_runtime/common/utils/csn')
|
|
18
18
|
const { bufferToBase64 } = require('../_runtime/common/utils/binary')
|
|
19
19
|
|
|
20
|
+
const { getAccessRestrictions } = require('../_runtime/common/utils/restrictions')
|
|
21
|
+
|
|
20
22
|
const RestAdapter = function (srv) {
|
|
21
23
|
alias2ref(srv) // REVISIT: that's an anti pattern in new prototocol adapter setups
|
|
22
24
|
|
|
25
|
+
const accessRestrictions = getAccessRestrictions(srv)
|
|
26
|
+
|
|
23
27
|
const router = express.Router()
|
|
24
28
|
|
|
25
29
|
// pass srv-related stuff to middlewares via req
|
|
@@ -64,24 +68,19 @@ const RestAdapter = function (srv) {
|
|
|
64
68
|
// REVISIT: ensure there always is a user (should be the case with new middlewares -> remove with old middlewares)
|
|
65
69
|
if (!req.user) req.user = new cds.User.default
|
|
66
70
|
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// > unauthorized or forbidden?
|
|
77
|
-
if (req.user._is_anonymous) {
|
|
78
|
-
// NOTE: "return req._login()" would not invoke custom error handlers
|
|
79
|
-
if (req._login) res.set('WWW-Authenticate', `Basic realm="Users"`)
|
|
80
|
-
else if (req.user._challenges) res.set('WWW-Authenticate', req.user._challenges.join(';'))
|
|
81
|
-
throw cds.error('Unauthorized', { statusCode: 401, code: '401' })
|
|
82
|
-
} else {
|
|
71
|
+
// check @restrict and @requires as soon as possible (DoS)
|
|
72
|
+
if (!accessRestrictions.some(r => req.user.is(r))) {
|
|
73
|
+
// > unauthorized or forbidden?
|
|
74
|
+
if (req.user._is_anonymous) {
|
|
75
|
+
// NOTE: "return req._login()" would not invoke custom error handlers
|
|
76
|
+
if (req._login) res.set('WWW-Authenticate', `Basic realm="Users"`)
|
|
77
|
+
else if (req.user._challenges) res.set('WWW-Authenticate', req.user._challenges.join(';'))
|
|
78
|
+
throw cds.error('Unauthorized', { statusCode: 401, code: '401' })
|
|
79
|
+
}
|
|
83
80
|
throw cds.error('Forbidden', { statusCode: 403, code: '403' })
|
|
84
81
|
}
|
|
82
|
+
|
|
83
|
+
next()
|
|
85
84
|
})
|
|
86
85
|
|
|
87
86
|
// -----------------------------------------------------------------------------------------
|
package/package.json
CHANGED
package/lib/auth/xsuaa-auth.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
const UNAUTHORIZED = { statusCode: 401, code: '401', message: 'Unauthorized' }
|
|
2
|
-
const FORBIDDEN = { statusCode: 403, code: '403', message: 'Forbidden' }
|
|
3
|
-
|
|
4
|
-
const getRequiresAsArray = definition => {
|
|
5
|
-
const requires = definition['@requires']
|
|
6
|
-
if (requires) return Array.isArray(requires) ? requires : [requires]
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const isRestricted = srv => {
|
|
10
|
-
if (srv.definition['@requires']) return true
|
|
11
|
-
|
|
12
|
-
const entities = srv.entities
|
|
13
|
-
const entitiesKeys = Object.keys(entities)
|
|
14
|
-
|
|
15
|
-
return !!(
|
|
16
|
-
entitiesKeys.some(entity => entities[entity]['@requires'] || entities[entity]['@restrict']) ||
|
|
17
|
-
entitiesKeys.some(entity => {
|
|
18
|
-
const actions = entities[entity].actions
|
|
19
|
-
actions && Object.keys(actions).some(action => actions[action]['@requires'] || actions[action]['@restrict'])
|
|
20
|
-
}) ||
|
|
21
|
-
Object.keys(srv.operations).some(
|
|
22
|
-
operation => srv.operations[operation]['@requires'] || srv.operations[operation]['@restrict']
|
|
23
|
-
)
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
UNAUTHORIZED,
|
|
29
|
-
FORBIDDEN,
|
|
30
|
-
getRequiresAsArray,
|
|
31
|
-
isRestricted
|
|
32
|
-
}
|
|
File without changes
|
package/libx/audit-log/client.js
DELETED
|
File without changes
|