@sap/cds 7.4.2 → 7.5.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.
Files changed (115) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/apis/cds.d.ts +1 -38
  3. package/apis/core.d.ts +21 -101
  4. package/apis/cqn.d.ts +18 -76
  5. package/apis/csn.d.ts +18 -114
  6. package/apis/events.d.ts +16 -123
  7. package/apis/internal/inference.d.ts +18 -32
  8. package/apis/linked.d.ts +18 -97
  9. package/apis/log.d.ts +19 -164
  10. package/apis/models.d.ts +18 -180
  11. package/apis/ql.d.ts +16 -323
  12. package/apis/reflect.d.ts +32 -0
  13. package/apis/server.d.ts +18 -135
  14. package/apis/services.d.ts +18 -380
  15. package/bin/cds-serve.js +5 -2
  16. package/bin/serve.js +7 -16
  17. package/lib/auth/basic-auth.js +3 -1
  18. package/lib/auth/ias-auth.js +62 -48
  19. package/lib/auth/ias-claims.js +34 -0
  20. package/lib/auth/index.js +55 -33
  21. package/lib/auth/jwt-auth.js +55 -52
  22. package/lib/compile/cdsc.js +2 -2
  23. package/lib/compile/to/edm.js +4 -4
  24. package/lib/compile/to/hdbtabledata.js +5 -8
  25. package/lib/compile/to/srvinfo.js +2 -2
  26. package/lib/env/cds-env.js +3 -9
  27. package/lib/env/cds-requires.js +16 -17
  28. package/lib/env/compat.js +0 -9
  29. package/lib/env/defaults.js +17 -6
  30. package/lib/i18n/localize.js +46 -42
  31. package/lib/index.js +6 -8
  32. package/lib/linked/classes.js +7 -118
  33. package/lib/linked/entities.js +1 -1
  34. package/lib/log/cds-log.js +15 -10
  35. package/lib/log/format/aspects/als.js +41 -0
  36. package/lib/log/format/aspects/cf.js +36 -0
  37. package/lib/log/format/json.js +96 -0
  38. package/lib/plugins.js +7 -3
  39. package/lib/req/context.js +4 -2
  40. package/lib/srv/cds-connect.js +3 -5
  41. package/lib/srv/cds-serve.js +13 -26
  42. package/lib/srv/factory.js +3 -3
  43. package/lib/srv/middlewares/index.js +0 -2
  44. package/lib/srv/middlewares/trace.js +2 -3
  45. package/lib/srv/protocols/_legacy.js +27 -30
  46. package/lib/srv/protocols/index.js +173 -58
  47. package/lib/srv/protocols/odata-v4.js +29 -16
  48. package/lib/srv/srv-api.js +8 -13
  49. package/lib/srv/srv-handlers.js +14 -14
  50. package/lib/utils/cds-utils.js +15 -0
  51. package/libx/_runtime/auth/index.js +4 -5
  52. package/libx/_runtime/auth/strategies/basic.js +2 -2
  53. package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +23 -13
  54. package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +6 -15
  55. package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +10 -3
  56. package/libx/_runtime/cds-services/adapter/odata-v4/to.js +5 -2
  57. package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +2 -1
  58. package/libx/_runtime/cds-services/services/utils/columns.js +3 -9
  59. package/libx/_runtime/cds.js +13 -0
  60. package/libx/_runtime/common/composition/data.js +3 -0
  61. package/libx/_runtime/common/composition/delete.js +1 -1
  62. package/libx/_runtime/common/error/frontend.js +2 -2
  63. package/libx/_runtime/common/generic/auth/readOnly.js +1 -1
  64. package/libx/_runtime/common/generic/auth/restrictions.js +1 -1
  65. package/libx/_runtime/common/generic/sorting.js +4 -5
  66. package/libx/_runtime/common/utils/csn.js +23 -18
  67. package/libx/_runtime/common/utils/restrictions.js +6 -15
  68. package/libx/_runtime/db/generic/input.js +3 -2
  69. package/libx/_runtime/fiori/generic/readOverDraft.js +2 -5
  70. package/libx/_runtime/fiori/lean-draft.js +69 -5
  71. package/libx/_runtime/hana/Service.js +1 -1
  72. package/libx/_runtime/messaging/AMQPWebhookMessaging.js +1 -1
  73. package/libx/_runtime/messaging/Outbox.js +3 -8
  74. package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -0
  75. package/libx/_runtime/messaging/enterprise-messaging.js +1 -1
  76. package/libx/_runtime/messaging/file-based.js +1 -1
  77. package/libx/_runtime/messaging/service.js +7 -10
  78. package/libx/_runtime/remote/Service.js +15 -45
  79. package/libx/_runtime/remote/utils/client.js +20 -33
  80. package/libx/_runtime/remote/utils/cloudSdkProvider.js +30 -0
  81. package/libx/_runtime/sqlite/Service.js +2 -2
  82. package/libx/odata/afterburner.js +29 -21
  83. package/libx/odata/cqn2odata.js +1 -1
  84. package/libx/odata/error.js +7 -0
  85. package/libx/odata/grammar.peggy +16 -20
  86. package/libx/odata/metadata.js +73 -78
  87. package/libx/odata/parser.js +1 -1
  88. package/libx/odata/read.js +94 -0
  89. package/libx/odata/result.js +91 -0
  90. package/libx/odata/service-document.js +31 -37
  91. package/libx/odata/utils.js +2 -1
  92. package/libx/outbox/index.js +9 -4
  93. package/libx/rest/RestAdapter.js +68 -67
  94. package/libx/rest/middleware/create.js +20 -26
  95. package/libx/rest/middleware/delete.js +5 -3
  96. package/libx/rest/middleware/error.js +2 -3
  97. package/libx/rest/middleware/input.js +5 -5
  98. package/libx/rest/middleware/operation.js +96 -41
  99. package/libx/rest/middleware/parse.js +4 -6
  100. package/libx/rest/middleware/payload.js +5 -5
  101. package/libx/rest/middleware/read.js +11 -17
  102. package/libx/rest/middleware/update.js +20 -25
  103. package/package.json +2 -1
  104. package/server.js +7 -4
  105. package/srv/outbox.cds +9 -10
  106. package/apis/env.d.ts +0 -25
  107. package/apis/test.d.ts +0 -81
  108. package/apis/utils.d.ts +0 -15
  109. package/lib/auth/passport-basic.js +0 -14
  110. package/lib/auth/passport-digest.js +0 -16
  111. package/lib/env/presets.js +0 -35
  112. package/lib/log/format/cf.js +0 -16
  113. package/lib/log/format/kibana.js +0 -92
  114. package/lib/srv/middlewares/ctx-auth.js +0 -11
  115. package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +0 -119
package/lib/auth/index.js CHANGED
@@ -1,38 +1,60 @@
1
- const cds = require ('../index'), { path, local } = cds.utils
2
-
3
- const _require = require; require = cds.lazified (module) // eslint-disable-line no-global-assign
4
- module.exports = Object.assign (auth_factory, {
5
- mocked: require('./basic-auth'),
6
- basic: require('./basic-auth'),
7
- dummy: require('./dummy-auth'),
8
- ias: require('./ias-auth'),
9
- jwt: require('./jwt-auth'),
10
- xsuaa: require('./jwt-auth'),
11
- })
12
- require = _require // eslint-disable-line no-global-assign
1
+ const cds = require ('../index')
2
+
3
+ const _builtin = {
4
+ mocked: 'basic-auth',
5
+ basic: 'basic-auth',
6
+ ias: 'ias-auth',
7
+ jwt: 'jwt-auth',
8
+ xsuaa: 'jwt-auth',
9
+ dummy: 'dummy-auth',
10
+ }
11
+ for (let b in _builtin) _builtin[b+'-auth'] = _builtin[b]
12
+
13
13
 
14
14
  /**
15
- * Constructs one of the above middlewares as configured
15
+ * Constructs auth middlewares as configured
16
16
  */
17
- function auth_factory (options) {
18
- const o = { ...options, ...cds.requires.auth }
19
- let kind = o.impl ? 'custom' : o.kind || o.strategy
20
- let middleware = cds.auth[kind] || cds.auth[kind?.replace(/-auth$/, '')]
21
- if (middleware) {
22
- // REVISIT: here, kind may be misleading, e.g., "basic-auth" instead of "mocked" -> _kind workaround
23
- const _kind = (o._kind || kind).replace(/-auth$/, '') //> official auth kinds are NOT postfixed with "-auth"
24
- cds.log().info ('using authentication:', { kind: _kind }, '\n')
25
- } else {
26
- let impl = kind === 'custom' ? cds.resolve (o.impl)?.[0] : path.resolve (__dirname, kind)
27
- try { impl = require.resolve (impl) } catch {
28
- const e = o.impl ? `Cannot find custom impl at: ${o.impl}` : `Cannot find unknown auth kind: ${o.kind}`
29
- throw cds.error(e)
30
- }
31
- cds.log().info ('using authentication:', { kind, impl: local(impl) }, '\n')
32
- middleware = require(impl)
33
- }
34
- if ((typeof middleware === 'function' && middleware.length === 3) || Array.isArray(middleware)) {
35
- return middleware
17
+ module.exports = function auth_factory (o) {
18
+
19
+ // prepare options
20
+ const options = { ...o, ...cds.requires.auth }
21
+ let { kind, impl } = options
22
+
23
+ // if no impl is given, it's a built-in strategy
24
+ if (!impl) impl = __dirname + '/' + _builtin[kind]
25
+ else if (kind in _builtin) kind = 'custom'
26
+ // NOTE: ^^^^^^^^^^^^^^^
27
+ // This is a workaround to avoid displaying kind:'mocked-auth'
28
+ // from [development] defaults with impl: './custom-auth'
29
+ // from cds.requires.auth in the log or error output below.
30
+
31
+ // try resolving the impl, throw if not found
32
+ const config = { kind, impl: cds.utils.local(impl) }
33
+ // use cds.resolve() to allow './srv/auth.js' and 'srv/auth.js'
34
+ try { impl = require.resolve (cds.resolve (impl)?.[0], {paths:[cds.root]}) } catch {
35
+ throw cds.error `Didn't find auth implementation for ${config}`
36
36
  }
37
- return middleware(o)
37
+
38
+ // load the auth middleware from the resolved path
39
+ cds.log().info ('using auth strategy', config, '\n')
40
+ let auth = require (impl)
41
+
42
+ // if auth is a factory itself, call it to get the middleware
43
+ if (typeof auth === 'function' && auth.length < 3) auth = auth(options)
44
+
45
+ // return the auth middleware followed by a middleware to fill in cds.context
46
+ return [ auth, ctx_auth ]
38
47
  }
48
+
49
+ /**
50
+ * Propagate user and tenant from req to cds.context
51
+ */
52
+ function ctx_auth (req, res, next) {
53
+ const ctx = cds.context
54
+ ctx.user = req.user
55
+ ctx.tenant = req.tenant || ctx.user?.tenant
56
+ next()
57
+ }
58
+
59
+ // export ctx_auth for legacy protocol adapter -> remove with cds^8
60
+ module.exports._ctx_auth = ctx_auth
@@ -3,76 +3,79 @@ const LOG = cds.log('auth')
3
3
 
4
4
  // _require for better error message
5
5
  const _require = require('../../libx/_runtime/common/utils/require')
6
- const express = _require('express')
7
- const passport = _require('passport')
8
- const { JWTStrategy } = _require('@sap/xssec')
6
+ const xssec = _require('@sap/xssec')
9
7
 
10
8
  module.exports = function jwt_auth(config) {
11
- if (!config.credentials) {
12
- let msg = `Authentication kind "${config.kind}" configured, but no XSUAA instance bound to application.`
9
+ const { kind, credentials } = config
10
+
11
+ if (!credentials) {
12
+ let msg = `Authentication kind "${kind}" configured, but no XSUAA instance bound to application.`
13
13
  msg += ' Either bind an IAS instance, or switch to an authentication kind that does not require a binding.'
14
14
  throw new Error(msg)
15
15
  }
16
16
 
17
- passport.use('JWT', new JWTStrategy(config.credentials))
18
-
19
- return express
20
- .Router()
21
- .use((req, res, next) => {
22
- // callback needed in order to suppress 401 and continue with anonymous to allow @requires: 'any'/ restrict_all_services=false
23
- const callback = (err, user, info, _status) => {
24
- if (err) return next(err)
25
-
26
- if (user) {
27
- req.user = user
28
- req.authInfo = info
29
- } else {
30
- req.user = new cds.User.default
31
- if (LOG._debug && req.tokenInfo)
32
- LOG.debug('Error during token validation:', req.tokenInfo.getErrorObject().message)
33
- }
17
+ function getUser(tokenInfo) {
18
+ const payload = tokenInfo.getPayload()
34
19
 
35
- next()
36
- }
37
- passport.authenticate('JWT', { session: false }, callback)(req, res, next)
38
- })
39
- .use((req, res, next) => {
40
- if (!('authInfo' in req)) return next()
20
+ let id = payload.user_name
41
21
 
42
- const payload = req.tokenInfo.getPayload()
22
+ // Roles = scope names w/o xsappname
23
+ const xsappname = new RegExp(`^${credentials.xsappname}\\.`)
24
+ let roles = payload.scope.map(s => s.replace(xsappname, ''))
43
25
 
44
- let id = req.user.id
26
+ // Disallow setting system roles from external
27
+ roles = roles.filter(r => !(r in { 'internal-user': 1, 'system-user': 1 }))
45
28
 
46
- // Roles = scope names w/o xsappname
47
- let xsappname = new RegExp(`^${config.credentials.xsappname}\\.`)
48
- let roles = payload.scope.map(s => s.replace(xsappname, ''))
29
+ if (payload.grant_type in { client_credentials: 1, client_x509: 1 }) {
30
+ id = 'system'
31
+ roles.push('system-user')
32
+ if (tokenInfo.getClientId() === credentials.clientid) roles.push('internal-user')
33
+ }
49
34
 
50
- // Disallow setting system roles from external
51
- roles = roles.filter(r => !(r in { 'internal-user': 1, 'system-user': 1 }))
35
+ const attr = Object.assign({}, payload['xs.user.attributes'])
36
+ if (kind === 'xsuaa') {
37
+ attr.logonName = payload.user_name
38
+ attr.givenName = payload.given_name
39
+ attr.familyName = payload.family_name
40
+ attr.email = payload.email
41
+ }
52
42
 
53
- roles.push('identified-user')
54
- if (payload.grant_type) {
55
- // > not "weak"
56
- roles.push('authenticated-user')
43
+ return new cds.User({ id, roles, attr })
44
+ }
57
45
 
58
- if (payload.grant_type in { client_credentials: 1, client_x509: 1 }) {
59
- id = 'system'
60
- roles.push('system-user')
61
- if (req.tokenInfo.getClientId() === config.credentials.clientid) roles.push('internal-user')
62
- }
46
+ return (req, _, next) => {
47
+ const token = req.headers.authorization?.split(/^bearer /i)[1]
48
+ xssec.createSecurityContext(token, credentials, function (err, securityContext, tokenInfo) {
49
+ if (err && !tokenInfo) {
50
+ // here, there is a general problem, .e.g., bad credentials -> throw the error
51
+ return next(err)
63
52
  }
64
53
 
65
- let attr = req.authInfo.getAttributes() || {}
66
- if (config.kind === 'xsuaa') {
67
- attr.logonName = req.authInfo.getLogonName()
68
- attr.givenName = req.authInfo.getGivenName()
69
- attr.familyName = req.authInfo.getFamilyName()
70
- attr.email = req.authInfo.getEmail()
54
+ if (err && LOG._debug) LOG.debug('User could not be authenticated due to error:', err)
55
+
56
+ // if no general problem, tokenInfo object is always available -> add to req via getter for compat reasons
57
+ Object.defineProperty(req, 'tokenInfo', {
58
+ get() {
59
+ cds._logDeprecation('req.tokenInfo was added for compatibility purposes but will be removed in the next major version.')
60
+ return tokenInfo
61
+ }
62
+ })
63
+
64
+ if (!securityContext) {
65
+ if (!req.headers.authorization) {
66
+ LOG._debug && LOG.debug('No authorization header provided, continuing with default user.')
67
+ req.user = new cds.User.default()
68
+ return next()
69
+ }
70
+ return next(new cds.error('Unauthorized', { statusCode: 401 }))
71
71
  }
72
72
 
73
- req.user = new cds.User({ id, roles, attr })
74
- req.tenant = req.tokenInfo.getZoneId?.()
73
+ req.user = getUser(tokenInfo)
74
+ req.tenant = tokenInfo.getZoneId()
75
+
76
+ req.authInfo = securityContext //> compat req.authInfo
75
77
 
76
78
  next()
77
79
  })
80
+ }
78
81
  }
@@ -63,8 +63,8 @@ const _options = {for: Object.assign (_options4, {
63
63
 
64
64
  sql(o,_env) {
65
65
  // REVISIT: compiler requires to only provide assertIntegrityType if defined
66
- let assertIntegrity = cds.env.features.assert_integrity
67
- let constraints = assertIntegrity && { assertIntegrityType: cds.env.features.assert_integrity_type }
66
+ let { assert_integrity } = cds.env.features
67
+ let constraints = assert_integrity && { assertIntegrityType: assert_integrity.toUpperCase() }
68
68
  return _options4 ({ ...constraints, ..._env||cds.env.sql, ...o }, {
69
69
  sql_mapping : 'names', //> legacy
70
70
  sqlDialect : 'dialect', //> legacy
@@ -3,12 +3,12 @@ const cds = require ('../../index')
3
3
 
4
4
  if (cds.env.features.precompile_edms !== false) {
5
5
  const _precompiled = new WeakMap
6
+ const to_edm = cdsc.to.edm
6
7
  cdsc.to.edm = Object.assign((csn, o) => {
7
- if (o.to === 'openapi') return cdsc.to.edm.all(csn, o)[o.service]
8
+ if (o.to === 'openapi') return to_edm(csn, o)
8
9
  if (!_precompiled.has(csn)) {
9
- // only for services that are served via odata
10
- const serviceNames = o.serviceNames || Object.values(csn.definitions).filter(d => d.kind === 'service' && d.endpoints?.some(e => e.kind.match(/odata/i))).map(d => d.name)
11
- _precompiled.set(csn, cdsc.to.edm.all(csn, Object.assign({ serviceNames }, o)))
10
+ if (!o.serviceNames) o = { ...o, serviceNames: cds.linked(csn).services.filter(srv => srv._serves_odata).map(d => d.name) }
11
+ _precompiled.set(csn, cdsc.to.edm.all(csn, o))
12
12
  }
13
13
  return _precompiled.get(csn)[o.service]
14
14
  }, { all: cdsc.to.edm.all })
@@ -2,13 +2,9 @@ const cds = require('../../../lib')
2
2
  const { getElementCdsPersistenceName, getArtifactCdsPersistenceName } = require('@sap/cds-compiler')
3
3
  const { fs, path, isdir, csv } = cds.utils
4
4
  const { readdir } = fs.promises
5
- let logger = cds.log('cds')
5
+ let LOG = cds.log('hdbtabledata|build|all')
6
6
 
7
7
  module.exports = async (model, options = {}) => {
8
- if (options.logger) {
9
- logger = options.logger
10
- }
11
-
12
8
  model = cds.minify(model)
13
9
  const baseDir = options.baseDir // where the hdbtabledata will be located, for usage in the file_name path
14
10
  const dirs = Array.isArray(options.dirs) ? options.dirs : _csvDirs(model.$sources.map(path.dirname))
@@ -36,7 +32,7 @@ async function _tabledata4(dir, csvFile, model, baseDir, naming) {
36
32
  .filter(name => !name.startsWith('localized.'))
37
33
  .find(name => name.toLowerCase().includes(entityName.toLowerCase()))
38
34
  if (candidate) message += `. Did you mean '${candidate}'?`
39
- return logger.warn(`[hdbtabledata] ${message}`)
35
+ return LOG.warn(`[hdbtabledata] ${message}`)
40
36
  }
41
37
 
42
38
  const tableName = getArtifactCdsPersistenceName(entity.name, naming, model, 'hana')
@@ -95,7 +91,7 @@ function _entity4(name, csn) {
95
91
  }
96
92
  return
97
93
  }
98
- if (entity['@cds.persistence.skip'] === true) return logger.warn(`[hdbtabledata] exclude skipped entity '${name}'`)
94
+ if (entity['@cds.persistence.skip'] === true) return LOG.warn(`[hdbtabledata] exclude skipped entity '${name}'`)
99
95
  const p = entity.query && entity.query.SELECT || entity.projection
100
96
  if (p) {
101
97
  let from = p.from
@@ -120,6 +116,7 @@ function _csvDirs(sources) {
120
116
  return folders
121
117
  }
122
118
 
119
+
123
120
  function _csvs(filename, _, allFiles) {
124
121
  if (filename[0] === '-' || !filename.endsWith('.csv')) return false
125
122
  // ignores 'Books_texts.csv' if there is any 'Books_texts_LANG.csv'
@@ -127,7 +124,7 @@ function _csvs(filename, _, allFiles) {
127
124
  const basename = RegExp.$1
128
125
  const monoLangFiles = allFiles.filter(file => new RegExp(basename + '_texts_').test(file))
129
126
  if (monoLangFiles.length > 0) {
130
- logger._debug && logger.debug(`[hdbtabledata] ignoring '${filename}' in favor of [${monoLangFiles}]`)
127
+ LOG.debug(`[hdbtabledata] ignoring '${filename}' in favor of [${monoLangFiles}]`)
131
128
  return false
132
129
  }
133
130
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  const cds = require('../..')
3
- const { isfile, path: { join, posix: { normalize } } } = cds.utils
3
+ const { isfile, path: { join } } = cds.utils
4
4
 
5
5
  // Produces information on provided services in the model:
6
6
  // name, expected URL path at runtime,...
@@ -37,7 +37,7 @@ module.exports = (model, options={}) => {
37
37
  function _makeNode(service) {
38
38
  return {
39
39
  name: service.name,
40
- urlPath: _url4 (cds.service.path4(service)),
40
+ urlPath: _url4 (cds.service.protocols.path4(service)),
41
41
  destination: 'srv-api', // the name to register in xs-app.json
42
42
  runtime: 'Node.js',
43
43
  location: service.$location
@@ -1,7 +1,6 @@
1
1
  const { isdir, isfile, fs, path } = require('../utils/cds-utils')
2
2
  const DEFAULTS = require('./defaults'), defaults = require.resolve ('./defaults')
3
3
  const compat = require('./compat')
4
- const presets = require('./presets')
5
4
  const serviceBindings = require('./serviceBindings');
6
5
 
7
6
 
@@ -88,10 +87,6 @@ class Config {
88
87
  // Complete service configurations from cloud service bindings
89
88
  this._add_cloud_service_bindings(process.env)
90
89
 
91
- // Apply presets
92
- presets (this)
93
-
94
-
95
90
  // Only if feature is enabled
96
91
  if (this.features && this.features.emulate_vcap_services) {
97
92
  this._emulate_vcap_services()
@@ -127,8 +122,7 @@ class Config {
127
122
 
128
123
 
129
124
  get plugins() {
130
- let DEV = this._profiles.has('development')
131
- return super.plugins = require('../plugins').fetch(DEV)
125
+ return super.plugins = require('../plugins').fetch()
132
126
  }
133
127
 
134
128
 
@@ -390,7 +384,7 @@ class Config {
390
384
  _fetch ({ type: conf.dialect || conf.kind })
391
385
 
392
386
  function _fetch (predicate) {
393
- for (let k of Object.keys(predicate).reverse()) {
387
+ for (let k in predicate) {
394
388
  const v = predicate[k]; if (!v) continue
395
389
  const filter = k === 'tag' ? e => _array(e,'tags').includes(v) : e => e[k] === v
396
390
  for (let stype in vcaps) {
@@ -472,7 +466,7 @@ function _merge (dst, src, _profiles) {
472
466
  }
473
467
 
474
468
  const v = pd.value
475
- if (typeof v === 'object' && !Array.isArray(v)) {
469
+ if (typeof v === 'object' && !Array.isArray(v) && v != null) {
476
470
  if (!dst[p]) dst[p] = {}
477
471
  if (typeof dst[p] !== 'object') dst[p] = v
478
472
  else _merge (dst[p], v, _profiles)
@@ -14,7 +14,6 @@ exports = module.exports = {
14
14
  '[production]': { kind: 'jwt-auth' }
15
15
  },
16
16
 
17
-
18
17
  /**
19
18
  * This is the implementation for `cds.requires` which is `cds.env.requires`
20
19
  * plus additional entries for all cds.required.<name>.service
@@ -36,18 +35,16 @@ exports = module.exports = {
36
35
 
37
36
  const admin = [ 'cds.Subscriber', 'admin' ]
38
37
  const builder = [ 'cds.ExtensionDeveloper', 'cds.UIFlexDeveloper' ]
39
-
40
38
  const _authentication_strategies = {
41
39
 
42
40
  "basic-auth": {
43
- kind: 'basic-auth', // this is to override kind from cds.requires.auth
44
- strategy: 'mock', // REVISIT: Can be removed when we switch to new auth middlewars
41
+ kind: 'basic',
45
42
  users: {},
46
43
  tenants: {}
47
44
  },
48
45
  "mocked-auth": {
49
- _kind: 'mocked', // REVISIT: workaround to distinguish from 'basic-auth' (cf. restrict_all_services)
50
- kind: 'basic-auth',
46
+ restrict_all_services: false,
47
+ kind: 'mocked',
51
48
  users: {
52
49
  alice: { tenant: 't1', roles: [ ...admin ] },
53
50
  bob: { tenant: 't1', roles: [ ...builder ] },
@@ -65,25 +62,30 @@ const _authentication_strategies = {
65
62
  }
66
63
  },
67
64
  "jwt-auth": {
68
- strategy: 'JWT', // REVISIT: Can be removed when we switch to new auth middlewars
69
- kind: 'jwt-auth',
65
+ kind: 'jwt',
70
66
  vcap: { label: 'xsuaa' }
71
67
  },
72
68
  "ias-auth": {
73
- kind: 'ias-auth',
69
+ kind: 'ias',
74
70
  vcap: { label: 'identity' }
75
71
  },
76
- "xsuaa": { // CLARIFY why is this not -auth postfixed?
77
- strategy: 'xsuaa', // REVISIT: Can be removed when we switch to new auth middlewars
72
+ "xsuaa-auth": {
78
73
  kind: 'xsuaa',
79
74
  vcap: { label: 'xsuaa' }
80
75
  },
81
76
  "dummy-auth": {
82
- strategy: 'dummy', // REVISIT: Can be removed when we switch to new auth middlewars
77
+ kind: 'dummy',
83
78
  },
84
79
 
85
80
  }
86
81
 
82
+ for (let each of Object.values(_authentication_strategies)) {
83
+ Object.defineProperty (each, 'strategy', {get() {
84
+ if (process.env.NODE_ENV !== 'production') console.trace('WARNING: auth.strategy is deprecated, use auth.kind instead')
85
+ return { jwt: 'JWT', mocked: 'mock' }[this.kind] || this.kind
86
+ }})
87
+ }
88
+
87
89
 
88
90
  const _services = {
89
91
 
@@ -127,7 +129,6 @@ const _databases = {
127
129
  impl: `${_runtime}/sqlite/Service.js`,
128
130
  credentials: { url: 'db.sqlite' },
129
131
  },
130
-
131
132
  "better-sqlite": {
132
133
  credentials: { url: ":memory:" },
133
134
  impl: "@cap-js/sqlite",
@@ -162,16 +163,14 @@ const _databases = {
162
163
 
163
164
  const _outbox = {
164
165
 
165
- outbox: {
166
- kind: "persistent-outbox",
167
- parallel: true
168
- },
166
+ outbox: "persistent-outbox",
169
167
 
170
168
  "in-memory-outbox": {},
171
169
  "persistent-outbox": {
172
170
  model: "@sap/cds/srv/outbox",
173
171
  maxAttempts: 20,
174
172
  chunkSize: 100,
173
+ parallel: true,
175
174
  storeLastError: true
176
175
  }
177
176
 
package/lib/env/compat.js CHANGED
@@ -7,15 +7,6 @@ module.exports = function (conf) {
7
7
  set(x) { _.log.levels.cli = x },
8
8
  },
9
9
 
10
- auth: {value:{
11
- get passport() {
12
- return _.requires.auth
13
- },
14
- set passport(v) {
15
- _.requires.auth = v
16
- }
17
- }},
18
-
19
10
  data: {value:{
20
11
  get model(){
21
12
  const db = _.requires.db; if (!db) return undefined
@@ -5,8 +5,6 @@ const defaults = module.exports = {
5
5
 
6
6
  production,
7
7
 
8
- cov2ap: false, // REVISIT: workaround for bug in @cap-js-community/odata-v2-adapter/cds-plugin -> cds/tests/_runtime/remote/__tests__/integration/mocked-v2-consumption/v2.test.js
9
-
10
8
  requires: require('./cds-requires'),
11
9
 
12
10
  server: {
@@ -14,6 +12,13 @@ const defaults = module.exports = {
14
12
  port: 4004,
15
13
  },
16
14
 
15
+ protocols: {
16
+ 'odata-v4' : { path: '/odata/v4' },
17
+ 'odata-v2' : { path: '/odata/v2' },
18
+ 'rest' : { path: '/rest' },
19
+ 'hcql' : { path: '/hcql' },
20
+ },
21
+
17
22
  // kept for backwards compatibility
18
23
  schemas: {
19
24
  'cds-rc.json': join(__dirname, 'schemas/cds-rc.json'),
@@ -56,21 +61,27 @@ const defaults = module.exports = {
56
61
 
57
62
  log: {
58
63
  Logger: undefined, //> use default
64
+ '[development]': { format: 'plain' },
65
+ '[production]': { format: 'json' },
59
66
  levels: {
60
67
  compile: 'warn',
61
68
  cli: 'warn',
62
69
  deploy: 'info',
63
70
  serve: 'info',
64
- server: 'info',
71
+ server: 'info'
65
72
  },
66
73
  service: false,
74
+ // the rest is only applicable for the json formatter
75
+ user: false,
76
+ mask_headers: ['/authorization/i', '/cookie/i'],
77
+ aspects: ['./aspects/cf', './aspects/als'], //> EXPERIMENTAL!!!
67
78
  // adds custom fields in kibana's error rendering (unknown fields are ignored); key: index
68
- kibana_custom_fields: {
79
+ // note: custom fields are a feature of Application Logging Service (ALS) and not Kibana per se
80
+ als_custom_fields: {
69
81
  // sql
70
82
  query: 0,
71
83
  // generic validations
72
- target: 1,
73
- details: 2
84
+ target: 1, details: 2
74
85
  }
75
86
  },
76
87