scimgateway 4.2.13 → 4.2.15
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/README.md +16 -0
- package/lib/plugin-azure-ad.js +2 -2
- package/lib/plugin-ldap.js +2 -2
- package/lib/plugin-loki.js +2 -2
- package/lib/plugin-mongodb.js +2 -2
- package/lib/scimgateway.js +98 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1170,6 +1170,20 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1170
1170
|
|
|
1171
1171
|
## Change log
|
|
1172
1172
|
|
|
1173
|
+
### v4.2.15
|
|
1174
|
+
|
|
1175
|
+
[Added]
|
|
1176
|
+
|
|
1177
|
+
- Plugin can set error statusCode returned by scimgateway through error object key `err.name`. This can be done by adding suffix `#code` to err.name where code is HTTP status code e.g., `err.name += '#401'`. This can be useful for auth.PassThrough and other scenarios like createUser where user already exist (409) and modifyUser where user does not exist (404)
|
|
1178
|
+
|
|
1179
|
+
This change replace statusCode logic introduced in v4.2.11
|
|
1180
|
+
|
|
1181
|
+
### v4.2.14
|
|
1182
|
+
|
|
1183
|
+
[Fixed]
|
|
1184
|
+
|
|
1185
|
+
- PUT now returning 404 instead of 500 when trying to update a user/group that does not exist
|
|
1186
|
+
|
|
1173
1187
|
### v4.2.13
|
|
1174
1188
|
|
|
1175
1189
|
[Fixed]
|
|
@@ -1186,6 +1200,8 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1186
1200
|
|
|
1187
1201
|
[Added]
|
|
1188
1202
|
|
|
1203
|
+
Note, obsolete - see v4.2.15 comments
|
|
1204
|
+
|
|
1189
1205
|
- Plugin can set error statusCode returned by scimgateway through error message. Error message must then contain string `"statusCode":xxx` where xxx is HTTP status code e.g., 401. Plugin using REST will have statusCode automatically included in error message thrown by plugin. This could be useful for auth.PassThrough.
|
|
1190
1206
|
|
|
1191
1207
|
### v4.2.10
|
package/lib/plugin-azure-ad.js
CHANGED
|
@@ -267,7 +267,7 @@ scimgateway.createUser = async (baseEntity, userObj, ctx) => {
|
|
|
267
267
|
} else return (null)
|
|
268
268
|
} catch (err) {
|
|
269
269
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
270
|
-
if (err.message.includes('userPrincipalName already exists')) newErr.name
|
|
270
|
+
if (err.message.includes('userPrincipalName already exists')) newErr.name += '#409' // customErrCode
|
|
271
271
|
throw newErr
|
|
272
272
|
}
|
|
273
273
|
}
|
|
@@ -685,7 +685,7 @@ scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
|
685
685
|
return null
|
|
686
686
|
} catch (err) {
|
|
687
687
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
688
|
-
if (err.message.includes('already exist')) newErr.name
|
|
688
|
+
if (err.message.includes('already exist')) newErr.name += '#409' // customErrCode
|
|
689
689
|
throw newErr
|
|
690
690
|
}
|
|
691
691
|
}
|
package/lib/plugin-ldap.js
CHANGED
|
@@ -322,7 +322,7 @@ scimgateway.createUser = async (baseEntity, userObj, ctx) => {
|
|
|
322
322
|
return null
|
|
323
323
|
} catch (err) {
|
|
324
324
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
325
|
-
if (newErr.message.includes('ENTRY_EXISTS')) newErr.name
|
|
325
|
+
if (newErr.message.includes('ENTRY_EXISTS')) newErr.name += '#409' // customErrCode
|
|
326
326
|
throw newErr
|
|
327
327
|
}
|
|
328
328
|
}
|
|
@@ -654,7 +654,7 @@ scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
|
654
654
|
return null
|
|
655
655
|
} catch (err) {
|
|
656
656
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
657
|
-
if (newErr.message.includes('ENTRY_EXISTS')) newErr.name
|
|
657
|
+
if (newErr.message.includes('ENTRY_EXISTS')) newErr.name += '#409' // customErrCode
|
|
658
658
|
throw newErr
|
|
659
659
|
}
|
|
660
660
|
}
|
package/lib/plugin-loki.js
CHANGED
|
@@ -228,7 +228,7 @@ scimgateway.createUser = async (baseEntity, userObj, ctx) => {
|
|
|
228
228
|
} catch (err) {
|
|
229
229
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
230
230
|
if (err.message && err.message.startsWith('Duplicate key')) {
|
|
231
|
-
newErr.name
|
|
231
|
+
newErr.name += '#409' // customErrorCode
|
|
232
232
|
}
|
|
233
233
|
throw newErr
|
|
234
234
|
}
|
|
@@ -472,7 +472,7 @@ scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
|
472
472
|
} catch (err) {
|
|
473
473
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
474
474
|
if (err.message && err.message.startsWith('Duplicate key')) {
|
|
475
|
-
newErr.name
|
|
475
|
+
newErr.name += '#409' // customErrorCode
|
|
476
476
|
}
|
|
477
477
|
throw newErr
|
|
478
478
|
}
|
package/lib/plugin-mongodb.js
CHANGED
|
@@ -319,7 +319,7 @@ scimgateway.createUser = async (baseEntity, userObj, ctx) => {
|
|
|
319
319
|
} catch (err) {
|
|
320
320
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
321
321
|
if (err.message && err.message.includes('duplicate key')) {
|
|
322
|
-
newErr.name
|
|
322
|
+
newErr.name += '#409' // customErrorCode
|
|
323
323
|
}
|
|
324
324
|
throw newErr
|
|
325
325
|
}
|
|
@@ -627,7 +627,7 @@ scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
|
627
627
|
} catch (err) {
|
|
628
628
|
const newErr = new Error(`${action} error: ${err.message}`)
|
|
629
629
|
if (err.message && err.message.includes('duplicate key')) {
|
|
630
|
-
newErr.name
|
|
630
|
+
newErr.name += '#409' // customErrorCode
|
|
631
631
|
}
|
|
632
632
|
throw newErr
|
|
633
633
|
}
|
package/lib/scimgateway.js
CHANGED
|
@@ -330,35 +330,11 @@ const ScimGateway = function () {
|
|
|
330
330
|
if (authType === 'Basic') [userName] = (Buffer.from(authToken, 'base64').toString() || '').split(':')
|
|
331
331
|
if (!userName && authType === 'Bearer') userName = 'token'
|
|
332
332
|
if (ctx.response.status < 200 || ctx.response.status > 299) {
|
|
333
|
-
//
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const rePattern = new RegExp(reJson, 'i')
|
|
338
|
-
if (res.body.detail) {
|
|
339
|
-
const arrMatches = res.body.detail.match(rePattern)
|
|
340
|
-
if (Array.isArray(arrMatches) && arrMatches.length === 3) {
|
|
341
|
-
pluginStatusCode = parseInt(arrMatches[2])
|
|
342
|
-
}
|
|
343
|
-
} else if (res.body.Errors) {
|
|
344
|
-
if (Array.isArray(res.body.Errors) && res.body.Errors[0].description && res.body.Errors[0].description) {
|
|
345
|
-
const arrMatches = res.body.Errors[0].description.match(rePattern)
|
|
346
|
-
if (Array.isArray(arrMatches) && arrMatches.length === 3) {
|
|
347
|
-
pluginStatusCode = parseInt(arrMatches[2])
|
|
348
|
-
}
|
|
349
|
-
}
|
|
333
|
+
if (ctx.response.status === 401 || ctx.response.status === 403) { // don't reveal original SCIM error message details related to access denied (e.g. using Auth PassThrough and customErrCode)
|
|
334
|
+
ctx.response.set('Content-Type', 'application/json; charset=utf-8')
|
|
335
|
+
ctx.response.body = { error: 'Access denied' }
|
|
336
|
+
res.body = ctx.response.body
|
|
350
337
|
}
|
|
351
|
-
if (pluginStatusCode > 0) {
|
|
352
|
-
ctx.response.status = pluginStatusCode // auto change ctx.response.message
|
|
353
|
-
res.statusCode = ctx.response.status
|
|
354
|
-
res.statusMessage = ctx.response.message
|
|
355
|
-
if (pluginStatusCode === 401 || pluginStatusCode === 403) { // don't reveal original SCIM error message details related to access denied (e.g. using Auth PassThrough)
|
|
356
|
-
ctx.response.set('Content-Type', 'application/json; charset=utf-8')
|
|
357
|
-
ctx.response.body = { error: 'Access denied' }
|
|
358
|
-
res.body = ctx.response.body
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
// back to logResult...
|
|
362
338
|
logger.error(`${gwName}[${pluginName}] ${ellapsed} ${ctx.request.ipcli} ${userName} ${ctx.request.method} ${ctx.request.href} Inbound = ${JSON.stringify(ctx.request.body)} Outbound = ${JSON.stringify(res)}${(config.log.loglevel.file === 'debug' && ctx.request.url !== '/ping') ? '\n' : ''}`)
|
|
363
339
|
} else logger.info(`${gwName}[${pluginName}] ${ellapsed} ${ctx.request.ipcli} ${userName} ${ctx.request.method} ${ctx.request.href} Inbound = ${JSON.stringify(ctx.request.body)} Outbound = ${JSON.stringify(res)}${(config.log.loglevel.file === 'debug' && ctx.request.url !== '/ping') ? '\n' : ''}`)
|
|
364
340
|
requestCounter += 1 // logged on exit (not win process termination)
|
|
@@ -634,7 +610,7 @@ const ScimGateway = function () {
|
|
|
634
610
|
if (ipAllowListChecker(ctx.request.ipcli)) return resolve(next())
|
|
635
611
|
logger.debug(`${gwName}[${pluginName}] client ip ${ctx.request.ipcli} not in ipAllowList`)
|
|
636
612
|
ctx.status = 401
|
|
637
|
-
ctx.body = 'Access denied'
|
|
613
|
+
ctx.body = { error: 'Access denied' }
|
|
638
614
|
resolve(ctx)
|
|
639
615
|
})
|
|
640
616
|
}
|
|
@@ -806,9 +782,10 @@ const ScimGateway = function () {
|
|
|
806
782
|
const tx = scimDef.Schemas.Resources.find(el => el.name === schemaName)
|
|
807
783
|
if (!tx) {
|
|
808
784
|
ctx.status = 404
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
ctx.
|
|
785
|
+
const err = new Error(`Schema '${schemaName}' not found`)
|
|
786
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
787
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
788
|
+
ctx.body = e
|
|
812
789
|
} else {
|
|
813
790
|
ctx.body = tx
|
|
814
791
|
}
|
|
@@ -855,9 +832,10 @@ const ScimGateway = function () {
|
|
|
855
832
|
|
|
856
833
|
if (scimdata.Resources.length !== 1) {
|
|
857
834
|
ctx.status = 404
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
ctx.
|
|
835
|
+
const err = new Error(`${handle.description} ${getObj.value} not found`)
|
|
836
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
837
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
838
|
+
ctx.body = e
|
|
861
839
|
return
|
|
862
840
|
}
|
|
863
841
|
|
|
@@ -898,7 +876,8 @@ const ScimGateway = function () {
|
|
|
898
876
|
ctx.body = scimdata
|
|
899
877
|
} catch (err) {
|
|
900
878
|
ctx.status = 404
|
|
901
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
879
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
880
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
902
881
|
ctx.body = e
|
|
903
882
|
}
|
|
904
883
|
})
|
|
@@ -961,12 +940,10 @@ const ScimGateway = function () {
|
|
|
961
940
|
// err.name = 'invalidFilter'
|
|
962
941
|
}
|
|
963
942
|
if (err) {
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
} else ctx.status = 500
|
|
969
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err, scimType)
|
|
943
|
+
if (isScimv2) ctx.status = 400
|
|
944
|
+
else ctx.status = 500
|
|
945
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
946
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
970
947
|
ctx.body = e
|
|
971
948
|
return
|
|
972
949
|
}
|
|
@@ -1104,12 +1081,10 @@ const ScimGateway = function () {
|
|
|
1104
1081
|
|
|
1105
1082
|
ctx.body = scimdata
|
|
1106
1083
|
} catch (err) {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
} else ctx.status = 500
|
|
1112
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err, scimType)
|
|
1084
|
+
if (isScimv2) ctx.status = 400
|
|
1085
|
+
else ctx.status = 500
|
|
1086
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1087
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1113
1088
|
ctx.body = e
|
|
1114
1089
|
}
|
|
1115
1090
|
})
|
|
@@ -1139,21 +1114,24 @@ const ScimGateway = function () {
|
|
|
1139
1114
|
const strBody = JSON.stringify(jsonBody)
|
|
1140
1115
|
if (strBody === '{}') {
|
|
1141
1116
|
ctx.status = 500
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
ctx.
|
|
1117
|
+
const err = new Error('Not accepting empty or none JSON formatted POST requests')
|
|
1118
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1119
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1120
|
+
ctx.body = e
|
|
1145
1121
|
return
|
|
1146
1122
|
} else if (handle.createMethod === 'createUser' && !jsonBody.userName && !jsonBody.externalId) {
|
|
1147
1123
|
ctx.status = 500
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
ctx.
|
|
1124
|
+
const err = new Error('userName or externalId is mandatory')
|
|
1125
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1126
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1127
|
+
ctx.body = e
|
|
1151
1128
|
return
|
|
1152
1129
|
} else if (handle.createMethod === 'createGroup' && !jsonBody.displayName && !jsonBody.externalId) {
|
|
1153
1130
|
ctx.status = 500
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
ctx.
|
|
1131
|
+
const err = new Error('displayName or externalId is mandatory')
|
|
1132
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1133
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1134
|
+
ctx.body = e
|
|
1157
1135
|
return
|
|
1158
1136
|
}
|
|
1159
1137
|
|
|
@@ -1163,7 +1141,8 @@ const ScimGateway = function () {
|
|
|
1163
1141
|
logger.debug(`${gwName}[${pluginName}] convertedBody=${JSON.stringify(scimdata)}`)
|
|
1164
1142
|
if (err) {
|
|
1165
1143
|
ctx.status = 500
|
|
1166
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1144
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1145
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1167
1146
|
ctx.body = e
|
|
1168
1147
|
return
|
|
1169
1148
|
}
|
|
@@ -1208,16 +1187,10 @@ const ScimGateway = function () {
|
|
|
1208
1187
|
ctx.status = 201
|
|
1209
1188
|
ctx.body = jsonBody
|
|
1210
1189
|
} catch (err) {
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
else {
|
|
1216
|
-
if (isScimv2) ctx.status = 400
|
|
1217
|
-
else ctx.status = 500
|
|
1218
|
-
}
|
|
1219
|
-
} else ctx.status = 500
|
|
1220
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err, scimType)
|
|
1190
|
+
if (isScimv2) ctx.status = 400
|
|
1191
|
+
else ctx.status = 500
|
|
1192
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1193
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1221
1194
|
ctx.body = e
|
|
1222
1195
|
}
|
|
1223
1196
|
}) // post
|
|
@@ -1248,7 +1221,8 @@ const ScimGateway = function () {
|
|
|
1248
1221
|
ctx.status = 204
|
|
1249
1222
|
} catch (err) {
|
|
1250
1223
|
ctx.status = 500
|
|
1251
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1224
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1225
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1252
1226
|
ctx.body = e
|
|
1253
1227
|
}
|
|
1254
1228
|
}) // delete
|
|
@@ -1289,9 +1263,10 @@ const ScimGateway = function () {
|
|
|
1289
1263
|
const strBody = JSON.stringify(jsonBody)
|
|
1290
1264
|
if (strBody === '{}') {
|
|
1291
1265
|
ctx.status = 500
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
ctx.
|
|
1266
|
+
const err = new Error('Not accepting empty or none JSON formatted PATCH request')
|
|
1267
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1268
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1269
|
+
ctx.body = e
|
|
1295
1270
|
} else {
|
|
1296
1271
|
logger.debug(`${gwName}[${pluginName}] [Modify ${handle.description}] id=${id}`)
|
|
1297
1272
|
let scimdata, err
|
|
@@ -1300,7 +1275,8 @@ const ScimGateway = function () {
|
|
|
1300
1275
|
logger.debug(`${gwName}[${pluginName}] convertedBody=${JSON.stringify(scimdata)}`)
|
|
1301
1276
|
if (err) {
|
|
1302
1277
|
ctx.status = 500
|
|
1303
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1278
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1279
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1304
1280
|
ctx.body = e
|
|
1305
1281
|
return
|
|
1306
1282
|
}
|
|
@@ -1340,7 +1316,8 @@ const ScimGateway = function () {
|
|
|
1340
1316
|
ctx.body = scimdata
|
|
1341
1317
|
} catch (err) {
|
|
1342
1318
|
ctx.status = 500
|
|
1343
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1319
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1320
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1344
1321
|
ctx.body = e
|
|
1345
1322
|
}
|
|
1346
1323
|
}
|
|
@@ -1360,9 +1337,10 @@ const ScimGateway = function () {
|
|
|
1360
1337
|
const strBody = JSON.stringify(jsonBody)
|
|
1361
1338
|
if (strBody === '{}') {
|
|
1362
1339
|
ctx.status = 500
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
ctx.
|
|
1340
|
+
const err = new Error('Not accepting empty or none JSON formatted PUT requests')
|
|
1341
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1342
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1343
|
+
ctx.body = e
|
|
1366
1344
|
} else {
|
|
1367
1345
|
logger.debug(`${gwName}[${pluginName}] PUT ${ctx.originalUrl} body=${strBody}`)
|
|
1368
1346
|
try {
|
|
@@ -1370,11 +1348,22 @@ const ScimGateway = function () {
|
|
|
1370
1348
|
logger.debug(`${gwName}[${pluginName}] calling "${handle.getMethod}" and awaiting result`)
|
|
1371
1349
|
let res = await this[handle.getMethod](ctx.params.baseEntity, { attribute: 'id', operator: 'eq', value: id }, [], ctx.ctxCopy)
|
|
1372
1350
|
|
|
1373
|
-
let currentObj
|
|
1374
|
-
if (res && res.Resources && Array.isArray(res.Resources)
|
|
1375
|
-
|
|
1351
|
+
let currentObj
|
|
1352
|
+
if (res && res.Resources && Array.isArray(res.Resources)) {
|
|
1353
|
+
if (res.Resources.length === 1) currentObj = res.Resources[0]
|
|
1354
|
+
else currentObj = {}
|
|
1355
|
+
} else if (Array.isArray(res) && res.length === 1) currentObj = res[0]
|
|
1376
1356
|
else if (res && typeof (res) === 'object' && Object.keys(res).length > 0) currentObj = res
|
|
1377
|
-
else
|
|
1357
|
+
else currentObj = {}
|
|
1358
|
+
|
|
1359
|
+
if (typeof (currentObj) !== 'object' || Object.keys(currentObj).length === 0) {
|
|
1360
|
+
ctx.status = 404
|
|
1361
|
+
const err = new Error(`put using method ${handle.getMethod} error: ${handle.description.toLowerCase()} id=${id} does not exist`)
|
|
1362
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1363
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1364
|
+
ctx.body = e
|
|
1365
|
+
return
|
|
1366
|
+
}
|
|
1378
1367
|
|
|
1379
1368
|
const clearedObj = clearObjectValues(currentObj)
|
|
1380
1369
|
delete clearedObj.active
|
|
@@ -1565,7 +1554,8 @@ const ScimGateway = function () {
|
|
|
1565
1554
|
ctx.body = scimdata
|
|
1566
1555
|
} catch (err) {
|
|
1567
1556
|
ctx.status = 500
|
|
1568
|
-
const e = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1557
|
+
const [e, customErrorCode] = jsonErr(config.scim.version, pluginName, ctx.status, err)
|
|
1558
|
+
if (customErrorCode) ctx.status = customErrorCode
|
|
1569
1559
|
ctx.body = e
|
|
1570
1560
|
}
|
|
1571
1561
|
}
|
|
@@ -2966,10 +2956,29 @@ const clearObjectValues = (o, parent) => {
|
|
|
2966
2956
|
//
|
|
2967
2957
|
// SCIM error formatting
|
|
2968
2958
|
//
|
|
2969
|
-
const jsonErr = (scimVersion, pluginName, htmlErrCode, err
|
|
2959
|
+
const jsonErr = (scimVersion, pluginName, htmlErrCode, err) => {
|
|
2970
2960
|
let errJson = {}
|
|
2961
|
+
let customErrCode = null
|
|
2962
|
+
let scimType = 'invalidSyntax'
|
|
2971
2963
|
let msg = `scimgateway[${pluginName}] `
|
|
2972
|
-
err.constructor === Error
|
|
2964
|
+
if (err.constructor === Error) {
|
|
2965
|
+
if (err.name) { // customErrCode can be set by including suffix "#<number>" e.g., "<scimType>#404"
|
|
2966
|
+
const arr = err.name.split('#')
|
|
2967
|
+
if (arr.length > 1 && !isNaN(arr[arr.length - 1])) {
|
|
2968
|
+
customErrCode = arr[arr.length - 1]
|
|
2969
|
+
const code = parseInt(customErrCode)
|
|
2970
|
+
if (code < 300 && code > 199) customErrCode = null
|
|
2971
|
+
arr.splice(-1)
|
|
2972
|
+
err.name = arr.join('#') // back to original having customErrCode removed
|
|
2973
|
+
} else if (err.name === 'uniqueness') customErrCode = '409' // legacy support
|
|
2974
|
+
scimType = err.name
|
|
2975
|
+
if (scimType === 'Error') scimType = 'invalidSyntax' // default err.name used
|
|
2976
|
+
if (customErrCode === 409) scimType = 'uniqueness'
|
|
2977
|
+
}
|
|
2978
|
+
msg += err.message
|
|
2979
|
+
} else {
|
|
2980
|
+
msg += err
|
|
2981
|
+
}
|
|
2973
2982
|
|
|
2974
2983
|
if (scimVersion !== '2.0' && scimVersion !== 2) { // v1.1
|
|
2975
2984
|
errJson =
|
|
@@ -2977,7 +2986,7 @@ const jsonErr = (scimVersion, pluginName, htmlErrCode, err, scimType) => {
|
|
|
2977
2986
|
Errors: [
|
|
2978
2987
|
{
|
|
2979
2988
|
description: msg,
|
|
2980
|
-
code: htmlErrCode
|
|
2989
|
+
code: customErrCode || htmlErrCode
|
|
2981
2990
|
}
|
|
2982
2991
|
]
|
|
2983
2992
|
}
|
|
@@ -2987,10 +2996,12 @@ const jsonErr = (scimVersion, pluginName, htmlErrCode, err, scimType) => {
|
|
|
2987
2996
|
schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
|
|
2988
2997
|
scimType: scimType,
|
|
2989
2998
|
detail: msg,
|
|
2990
|
-
status: htmlErrCode
|
|
2999
|
+
status: customErrCode || htmlErrCode
|
|
2991
3000
|
}
|
|
2992
3001
|
}
|
|
2993
|
-
|
|
3002
|
+
|
|
3003
|
+
if (customErrCode) customErrCode = parseInt(customErrCode)
|
|
3004
|
+
return [errJson, customErrCode]
|
|
2994
3005
|
}
|
|
2995
3006
|
|
|
2996
3007
|
//
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scimgateway",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.15",
|
|
4
4
|
"description": "Using SCIM protocol as a gateway for user provisioning to other endpoints",
|
|
5
5
|
"author": "Jarle Elshaug <jarle.elshaug@gmail.com> (https://elshaug.xyz)",
|
|
6
6
|
"homepage": "https://elshaug.xyz",
|