@sap/cds 8.4.2 → 8.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.
- package/CHANGELOG.md +42 -1
- package/_i18n/messages.properties +99 -0
- package/bin/serve.js +2 -2
- package/lib/compile/cdsc.js +9 -4
- package/lib/compile/to/srvinfo.js +4 -4
- package/lib/core/entities.js +1 -0
- package/lib/core/types.js +1 -1
- package/lib/dbs/cds-deploy.js +5 -2
- package/lib/env/defaults.js +7 -6
- package/lib/env/schemas/cds-rc.js +132 -22
- package/lib/i18n/bundles.js +111 -0
- package/lib/i18n/files.js +134 -0
- package/lib/i18n/index.js +63 -0
- package/lib/i18n/localize.js +101 -237
- package/lib/i18n/resources.js +150 -0
- package/lib/index.js +1 -0
- package/lib/log/format/aspects/cls.js +6 -1
- package/lib/log/format/json.js +1 -1
- package/lib/ql/CREATE.js +1 -0
- package/lib/ql/DELETE.js +1 -0
- package/lib/ql/DROP.js +1 -0
- package/lib/ql/INSERT.js +9 -8
- package/lib/ql/Query.js +18 -8
- package/lib/ql/SELECT.js +1 -0
- package/lib/ql/UPDATE.js +2 -1
- package/lib/ql/UPSERT.js +1 -1
- package/lib/ql/Whereable.js +3 -3
- package/lib/ql/cds-ql.js +12 -18
- package/lib/req/user.js +1 -0
- package/lib/req/validate.js +12 -3
- package/lib/srv/factory.js +2 -2
- package/lib/{auth → srv/middlewares/auth}/basic-auth.js +1 -1
- package/lib/{auth → srv/middlewares/auth}/dummy-auth.js +1 -1
- package/lib/srv/middlewares/auth/ias-auth.js +96 -0
- package/lib/{auth → srv/middlewares/auth}/index.js +2 -2
- package/lib/srv/middlewares/auth/jwt-auth.js +62 -0
- package/lib/{auth → srv/middlewares/auth}/mocked-users.js +1 -1
- package/lib/srv/middlewares/auth/xssec.js +7 -0
- package/lib/srv/middlewares/index.js +1 -1
- package/lib/utils/cds-utils.js +15 -19
- package/lib/utils/tar.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +1 -1
- package/libx/_runtime/common/error/frontend.js +2 -6
- package/libx/_runtime/common/error/log.js +7 -8
- package/libx/_runtime/common/error/utils.js +3 -7
- package/libx/_runtime/common/generic/auth/capabilities.js +1 -1
- package/libx/_runtime/common/generic/input.js +41 -6
- package/libx/_runtime/common/i18n/index.js +8 -15
- package/libx/_runtime/common/utils/compareJson.js +10 -1
- package/libx/_runtime/common/utils/resolveView.js +1 -1
- package/libx/_runtime/fiori/lean-draft.js +77 -26
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +5 -1
- package/libx/_runtime/messaging/kafka.js +1 -1
- package/libx/odata/ODataAdapter.js +2 -1
- package/libx/odata/index.js +3 -0
- package/libx/odata/middleware/batch.js +4 -0
- package/libx/odata/middleware/create.js +8 -6
- package/libx/odata/middleware/update.js +24 -21
- package/libx/odata/parse/afterburner.js +16 -3
- package/libx/odata/parse/grammar.peggy +24 -7
- package/libx/odata/parse/parser.js +1 -1
- package/libx/odata/utils/index.js +1 -0
- package/libx/odata/utils/postProcess.js +4 -1
- package/libx/rest/RestAdapter.js +2 -1
- package/libx/rest/middleware/error.js +0 -50
- package/package.json +1 -1
- package/lib/auth/ias-auth.js +0 -68
- package/lib/auth/ias-claims.js +0 -34
- package/lib/auth/jwt-auth.js +0 -70
- package/libx/_runtime/common/i18n/messages.properties +0 -99
- package/libx/_runtime/common/utils/require.js +0 -9
package/lib/auth/ias-claims.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
module.exports = Object.values({
|
|
2
|
-
/*
|
|
3
|
-
* JWT claims (https://datatracker.ietf.org/doc/html/rfc7519#section-4)
|
|
4
|
-
*/
|
|
5
|
-
ISSUER: 'iss',
|
|
6
|
-
SUBJECT: 'sub',
|
|
7
|
-
AUDIENCE: 'aud',
|
|
8
|
-
EXPIRATION_TIME: 'exp',
|
|
9
|
-
NOT_BEFORE: 'nbf',
|
|
10
|
-
ISSUED_AT: 'iat',
|
|
11
|
-
JWT_ID: 'jti',
|
|
12
|
-
/*
|
|
13
|
-
* TokenClaims (com.sap.cloud.security.token.TokenClaims)
|
|
14
|
-
*/
|
|
15
|
-
// ISSUER: "iss", //> already in JWT claims
|
|
16
|
-
IAS_ISSUER: 'ias_iss',
|
|
17
|
-
// EXPIRATION: "exp", //> already in JWT claims
|
|
18
|
-
// AUDIENCE: "aud", //> already in JWT claims
|
|
19
|
-
// NOT_BEFORE: "nbf", //> already in JWT claims
|
|
20
|
-
// SUBJECT: "sub", //> already in JWT claims
|
|
21
|
-
// USER_NAME: 'user_name', //> do not exclude
|
|
22
|
-
// GIVEN_NAME: 'given_name', //> do not exclude
|
|
23
|
-
// FAMILY_NAME: 'family_name', //> do not exclude
|
|
24
|
-
// EMAIL: 'email', //> do not exclude
|
|
25
|
-
SAP_GLOBAL_SCIM_ID: 'scim_id',
|
|
26
|
-
SAP_GLOBAL_USER_ID: 'user_uuid', //> exclude for now
|
|
27
|
-
SAP_GLOBAL_ZONE_ID: 'zone_uuid',
|
|
28
|
-
// GROUPS: 'groups', //> do not exclude
|
|
29
|
-
AUTHORIZATION_PARTY: 'azp',
|
|
30
|
-
CNF: 'cnf',
|
|
31
|
-
CNF_X5T: 'x5t#S256',
|
|
32
|
-
// own
|
|
33
|
-
APP_TENANT_ID: 'app_tid'
|
|
34
|
-
})
|
package/lib/auth/jwt-auth.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
const cds = require('../')
|
|
2
|
-
const LOG = cds.log('auth')
|
|
3
|
-
|
|
4
|
-
// _require for better error message
|
|
5
|
-
const _require = require('../../libx/_runtime/common/utils/require')
|
|
6
|
-
|
|
7
|
-
let xssec = _require('@sap/xssec')
|
|
8
|
-
// use v3 compat api
|
|
9
|
-
if (xssec.v3) xssec = xssec.v3
|
|
10
|
-
|
|
11
|
-
module.exports = function jwt_auth(config) {
|
|
12
|
-
const { kind, credentials } = config
|
|
13
|
-
|
|
14
|
-
if (!credentials) {
|
|
15
|
-
let msg = `Authentication kind "${kind}" configured, but no XSUAA instance bound to application.`
|
|
16
|
-
msg += ' Either bind an XSUAA instance, or switch to an authentication kind that does not require a binding.'
|
|
17
|
-
throw new Error(msg)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function getUser(tokenInfo) {
|
|
21
|
-
const payload = tokenInfo.getPayload()
|
|
22
|
-
|
|
23
|
-
let id = payload.user_name
|
|
24
|
-
|
|
25
|
-
// Roles = scope names w/o xsappname
|
|
26
|
-
const xsappname = new RegExp(`^${credentials.xsappname}\\.`)
|
|
27
|
-
let roles = payload.scope.map(s => s.replace(xsappname, ''))
|
|
28
|
-
|
|
29
|
-
// Disallow setting system roles from external
|
|
30
|
-
roles = roles.filter(r => !(r in { 'internal-user': 1, 'system-user': 1 }))
|
|
31
|
-
|
|
32
|
-
if (payload.grant_type in { client_credentials: 1, client_x509: 1 }) {
|
|
33
|
-
id = 'system'
|
|
34
|
-
roles.push('system-user')
|
|
35
|
-
if (tokenInfo.getClientId() === credentials.clientid) roles.push('internal-user')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const attr = Object.assign({}, payload['xs.user.attributes'])
|
|
39
|
-
if (kind === 'xsuaa') {
|
|
40
|
-
attr.logonName = payload.user_name
|
|
41
|
-
attr.givenName = payload.given_name
|
|
42
|
-
attr.familyName = payload.family_name
|
|
43
|
-
attr.email = payload.email
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return new cds.User({ id, roles, attr, tokenInfo })
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return (req, _, next) => {
|
|
50
|
-
if (!req.headers.authorization) return next()
|
|
51
|
-
|
|
52
|
-
const token = req.headers.authorization.split(/^bearer /i)[1]
|
|
53
|
-
xssec.createSecurityContext(token, credentials, function (err, securityContext, tokenInfo) {
|
|
54
|
-
if (err) {
|
|
55
|
-
const level = (err.statusCode >= 400 && err.statusCode < 500) ? 'warn' : 'error'
|
|
56
|
-
LOG[level]('User could not be authenticated due to error:', err)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (!securityContext) return next(new cds.error('Unauthorized', { code: 401, statusCode: 401 }))
|
|
60
|
-
|
|
61
|
-
const ctx = cds.context
|
|
62
|
-
ctx.user = getUser(tokenInfo)
|
|
63
|
-
ctx.tenant = tokenInfo.getZoneId()
|
|
64
|
-
|
|
65
|
-
req.authInfo = securityContext //> compat req.authInfo
|
|
66
|
-
|
|
67
|
-
next()
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
400=Bad Request
|
|
2
|
-
401=Unauthorized
|
|
3
|
-
403=Forbidden
|
|
4
|
-
404=Not Found
|
|
5
|
-
405=Method Not Allowed
|
|
6
|
-
406=Not Acceptable
|
|
7
|
-
407=Proxy Authentication Required
|
|
8
|
-
408=Request Timeout
|
|
9
|
-
409=Conflict
|
|
10
|
-
410=Gone
|
|
11
|
-
411=Length Required
|
|
12
|
-
412=Precondition Failed
|
|
13
|
-
413=Payload Too Large
|
|
14
|
-
414=URI Too Long
|
|
15
|
-
415=Unsupported Media Type
|
|
16
|
-
416=Range Not Satisfiable
|
|
17
|
-
417=Expectation Failed
|
|
18
|
-
422=Unprocessable Content
|
|
19
|
-
424=Failed Dependency
|
|
20
|
-
428=Precondition Required
|
|
21
|
-
429=Too Many Requests
|
|
22
|
-
431=Request Header Fields Too Large
|
|
23
|
-
451=Unavailable For Legal Reasons
|
|
24
|
-
500=Internal Server Error
|
|
25
|
-
501=The server does not support the functionality required to fulfill the request
|
|
26
|
-
502=Bad Gateway
|
|
27
|
-
503=Service Unavailable
|
|
28
|
-
504=Gateway Timeout
|
|
29
|
-
|
|
30
|
-
MULTIPLE_ERRORS=Multiple errors occurred. Please see the details for more information.
|
|
31
|
-
|
|
32
|
-
# -------------------------------------------------------------------------------------------------
|
|
33
|
-
# all texts below are subject to change!
|
|
34
|
-
# -------------------------------------------------------------------------------------------------
|
|
35
|
-
|
|
36
|
-
# fragments
|
|
37
|
-
ENTITY=entity
|
|
38
|
-
TYPE=type
|
|
39
|
-
FUNCTION=function
|
|
40
|
-
ACTION=action
|
|
41
|
-
|
|
42
|
-
# assert
|
|
43
|
-
ASSERT_VALID_ELEMENT=Element is not valid
|
|
44
|
-
ASSERT_RANGE=Value {0} is not in specified range [{1}, {2}]
|
|
45
|
-
ASSERT_FORMAT=Value "{0}" is not in specified format "{1}"
|
|
46
|
-
ASSERT_DATA_TYPE=Value {0} is not a valid {1}
|
|
47
|
-
ASSERT_ARRAY=Value must be an array
|
|
48
|
-
ASSERT_ENUM=Value {0} is invalid according to enum declaration {{1}}
|
|
49
|
-
ASSERT_NOT_NULL=Value is required
|
|
50
|
-
ASSERT_TARGET="Value doesn't exist"
|
|
51
|
-
|
|
52
|
-
# db
|
|
53
|
-
NO_DATABASE_CONNECTION=No database connection
|
|
54
|
-
ENTITY_ALREADY_EXISTS=Entity already exists
|
|
55
|
-
ENTITY_LOCKED=Entity locked
|
|
56
|
-
UNIQUE_CONSTRAINT_VIOLATION=Unique constraint violation
|
|
57
|
-
FK_CONSTRAINT_VIOLATION=Foreign key constraint violation
|
|
58
|
-
|
|
59
|
-
# remote
|
|
60
|
-
INVALID_CONTENT_TYPE_ONLY_JSON=Invalid content type. Only "application/json" is supported.
|
|
61
|
-
|
|
62
|
-
# access control
|
|
63
|
-
INSERTABLE=insertable
|
|
64
|
-
READABLE=readable
|
|
65
|
-
UPDATABLE=updatable
|
|
66
|
-
DELETABLE=deletable
|
|
67
|
-
ENTITY_IS_INSERT_ONLY=Entity "{0}" is insert-only
|
|
68
|
-
ENTITY_IS_READ_ONLY=Entity "{0}" is read-only
|
|
69
|
-
ENTITY_IS_NOT_CRUD=Entity "{0}" is not {1}
|
|
70
|
-
ENTITY_IS_NOT_CRUD_VIA_NAVIGATION=Entity "{0}" is not {1} via navigation "{2}"
|
|
71
|
-
ENTITY_IS_AUTOEXPOSED=Entity "{0}" is not explicitly exposed as part of the service
|
|
72
|
-
ENTITY_IS_AUTOEXPOSE_READONLY=Entity "{0}" is explicitly exposed as readonly
|
|
73
|
-
EXPAND_IS_RESTRICTED=Navigation property "{0}" is not allowed for expand operation
|
|
74
|
-
|
|
75
|
-
# rest protocol adapter
|
|
76
|
-
INVALID_RESOURCE="{0}" is not a valid resource
|
|
77
|
-
INVALID_PARAMETER="{0}" is not a valid parameter
|
|
78
|
-
INVALID_PARAMETER_VALUE_TYPE=Parameter value for "{0}" must be of type "{1}"
|
|
79
|
-
INVALID_OPERATION_FOR_ENTITY=Entity "{0}" has no {1} "{2}"
|
|
80
|
-
NO_MATCHING_RESOURCE=The server has not found a resource matching the requested URI
|
|
81
|
-
INVALID_POST=POST is only allowed on resource collections and actions
|
|
82
|
-
INVALID_PUT=PUT is only allowed on a specific resource
|
|
83
|
-
INVALID_PATCH=PATCH is only allowed on a specific resource
|
|
84
|
-
INVALID_DELETE=DELETE is only supported on a specific resource
|
|
85
|
-
CRUD_VIA_NAVIGATION_NOT_SUPPORTED=CRUD via navigations is not yet supported
|
|
86
|
-
|
|
87
|
-
# OData protocol adapter
|
|
88
|
-
BATCH_TOO_MANY_REQ=Batch request contains too many requests
|
|
89
|
-
|
|
90
|
-
# draft
|
|
91
|
-
DRAFT_ALREADY_EXISTS=A draft for this entity already exists
|
|
92
|
-
DRAFT_NOT_EXISTING=No draft for this entity exists
|
|
93
|
-
DRAFT_LOCKED_BY_ANOTHER_USER=The entity is locked by user "{0}"
|
|
94
|
-
DRAFT_MODIFICATION_ONLY_VIA_ROOT=A draft-enabled entity can only be modified via its root entity
|
|
95
|
-
ACTIVE_MODIFICATION_VIA_DRAFT=Active entities cannot be modified via draft request
|
|
96
|
-
DRAFT_ACTIVE_DELETE_FORBIDDEN_DRAFT_EXISTS=Entity cannot be deleted because a draft exists
|
|
97
|
-
|
|
98
|
-
# singleton
|
|
99
|
-
SINGLETON_NOT_NULLABLE=The singleton entity is not nullable
|