scimgateway 6.1.0 → 6.1.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/README.md CHANGED
@@ -8,18 +8,18 @@ Author: Jarle Elshaug
8
8
  Validated through IdP's:
9
9
 
10
10
  - Symantec/Broadcom Identity Manager
11
- - Microsoft Entra ID
12
- - One Identity Manager/OneLogin
13
- - Okta
14
- - Omada
15
- - SailPoint/IdentityNow
11
+ - Microsoft Entra ID
12
+ - One Identity Manager
13
+ - Okta
14
+ - Omada
15
+ - SailPoint/IdentityNow
16
16
 
17
17
  Latest news:
18
18
 
19
- - tsx is now included, allowing SCIM Gateway to be run as a module in Node.js. Bun binary build is now supported. A single binary can be compiled that includes both the gateway and the plugin.
19
+ - Bun binary build is now supported, allowing SCIM Gateway to be compiled into a single executable binary for simplified deployment and execution. SCIM Gateway can now run as an ES module (TypeScript) in Node.js.
20
20
  - Major release **v6.0.0** introduces changes to API method response bodies (not SCIM-related) and a new method `publicApi()` for handling public path `/pub/api` requests with no authentication required. In addition, the configuration option `bearerJwtAzure.tenantIdGUID` has been replaced by `bearerJwt.azureTenantId`. See the version history for details.
21
- - Entra ID [Federated Identity Credentials](https://learn.microsoft.com/en-us/graph/api/resources/federatedidentitycredentials-overview?view=graph-rest-1.0) is now supported. Identity federation allows SCIM Gateway to access Microsoft Entra protected resources without needing to manage secrets
22
- - External JWKS (JSON Web Key Set) is now supported by JWT Authentication. These are public and typically frequent rotated by modern identity providers
21
+ - Support for Entra ID [Federated Identity Credentials](https://learn.microsoft.com/en-us/graph/api/resources/federatedidentitycredentials-overview?view=graph-rest-1.0) has been added through internal JWKS (JSON Web Key Set), allowing SCIM Gateway to access Microsoft Entraprotected resources without the need to manage secrets
22
+ - External JWKS (JSON Web Key Set) is now supported by JWT authentication, allowing external applications to access SCIM Gateway without the need to manage secrets
23
23
  - [Azure Relay](https://learn.microsoft.com/en-us/azure/azure-relay/relay-what-is-it) is now supported for secure and hassle-free outbound communication — with just one minute of configuration
24
24
  - [ETag](https://datatracker.ietf.org/doc/html/rfc7644#section-3.14) is now supported
25
25
  - [Bulk Operations](https://datatracker.ietf.org/doc/html/rfc7644#section-3.7) is now supported
@@ -46,86 +46,43 @@ Latest news:
46
46
 
47
47
  SCIM Gateway facilitates user management using the standardized REST-based SCIM 1.1 or 2.0 protocol, offering easier, more powerful, and consistent provisioning while avoiding vendor lock-in. Acting as a translator for incoming SCIM requests, the gateway seamlessly enables CRUD functionality (create, read, update, and delete) for users and groups. By implementing endpoint-specific protocols, it ensures provisioning across diverse destinations. With the gateway, your destinations become SCIM-compatible interfaces, streamlining integration and simplifying user management.
48
48
 
49
-
50
49
  ![](https://jelhub.github.io/images/ScimGateway.svg)
51
50
 
52
- SCIM Gateway is based on popular asynchronous event driven framework [Bun](https://bun.sh/) or [Node.js](https://nodejs.dev/) using TypeScript/JavaScript. It is cloud and firewall friendly. Runs on almost all operating systems, and may load balance between hosts (horizontal) and cpu's (vertical).
53
-
54
- **Following example plugins are included:**
55
-
56
- * **Loki** (NoSQL Document-Oriented Database)
57
- SCIM Gateway becomes a standalone SCIM endpoint
58
- Demonstrates user provisioning towards document-oriented database
59
- Using [LokiJS](https://github.com/techfort/LokiJS) for a fast, in-memory document-oriented database (much like MongoDB/PouchDB)
60
- Default gives two predefined test users loaded using in-memory only (no persistence)
61
- Configuration `{"persistence": true}` gives persistence file store (no test users)
62
- Example of a fully functional SCIM Gateway plugin
63
-
64
- * **MongoDB** (NoSQL Document-Oriented Database)
65
- Same as plugin "Loki", but using external MongoDB
66
- Shows how to implement a highly configurable multi tenant or multi endpoint solution through `baseEntity` in URL
67
-
68
- * **SCIM** (REST Webservice)
69
- Demonstrates user provisioning towards REST-Based endpoint (type SCIM)
70
- Using plugin Loki as SCIM endpoint through HelperRest
71
- Can be used as SCIM version-gateway e.g. 1.1=>2.0 or 2.0=>1.1
72
-
73
- * **Soap** (SOAP Webservice)
74
- Demonstrates user provisioning towards SOAP-Based endpoint
75
- Example WSDLs are included
76
- Using endpoint "Forwardinc" as an example (comes with Symantec/Broadcom/CA IM SDK - SDKWS)
77
- Shows how to implement a highly configurable multi tenant or multi endpoint solution through `baseEntity` in URL
78
-
79
- * **MSSQL** (MSSQL Database)
80
- Demonstrates user provisioning towards MSSQL database
81
-
82
- * **SAP HANA** (SAP HANA Database)
83
- Demonstrates SAP HANA specific user provisioning
84
-
85
- * **Entra ID** (REST Webservices)
86
- Entra ID user provisioning including license management (App Service plans) e.g. Office 365
87
- Using Microsoft Graph API through HelperRest
88
- Using customized SCIM attributes according to Microsoft Graph API
89
- Includes Symantec/Broadcom ConnectorXpress metafile for creating provisioning "Azure - ScimGateway" endpoint type
90
-
91
- * **LDAP** (Directory)
92
- Fully functional LDAP plugin
93
- Pre-configured for Microsoft Active Directory
94
- Using endpointMapper (like plugin-entra-id) for attribute mapping flexibility
95
-
96
- * **API** (REST Webservices)
97
- Demonstrates API Gateway/plugin functionality using post/put/patch/get/delete combined with HelperRest
98
- None SCIM plugin, becomes what you want it to become.
99
- Methods included can also be used in standard SCIM plugins
100
- Endpoint complexity could be put in this plugin, and client could instead communicate through Gateway using your own simplified REST specification.
101
- One example of usage could be creation of tickets in ServiceDesk and also the other way, closing a ticket could automatically approve/reject corresponding workflow in IdP.
51
+ SCIM Gateway is built on the modern, asynchronous, event-driven framework [Bun](https://bun.sh/) or [Node.js](https://nodejs.dev/) using TypeScript/JavaScript. It is designed to be cloud and firewall friendly, runs on nearly all operating systems
52
+
53
+ The following fully functional plugins are included for demonstration and production use:
54
+
55
+ | Plugin | Endpoint Type | Description |
56
+ | :--- | :--- | :--- |
57
+ | **Loki** | NoSQL Database | Makes the SCIM Gateway a standalone SCIM endpoint using internal [LokiJS](https://github.com/techfort/LokiJS) |
58
+ | **MongoDB** | NoSQL Database | Like plugin Loki, but using external MongoDB. Demonstrates multi-tenant or multi-endpoint through `baseEntity`|
59
+ | **Entra ID** | REST Webservices | Entra ID user provisioning via Microsoft Graph API |
60
+ | **SCIM** | REST Webservice | Using plugin Loki as a SCIM provisioning endpoint. May become a SCIM version-gateway (e.g., 1.1 => 2.0) |
61
+ | **API** | REST Webservices | A non-SCIM plugin demonstrating API Gateway functionality for custom REST specifications |
62
+ | **Soap** | SOAP Webservice | Demonstrates user provisioning to a SOAP-based endpoint with example WSDLs |
63
+ | **MSSQL** | Database | Demonstrates user provisioning to an MSSQL database |
64
+ | **SAP HANA** | Database | Demonstrates SAP HANA-specific user provisioning |
65
+ | **LDAP** | Directory | A fully functional LDAP plugin pre-configured for Microsoft Active Directory |
102
66
 
103
-
104
67
  ## Installation
105
68
 
106
69
  #### Install Bun
107
70
 
108
- [Bun](https://bun.sh/) is a prerequisite and must be installed on the server.
71
+ [Bun](https://bun.sh/) is a prerequisite and must be installed
109
72
 
110
73
  Note, Bun installs by default in the current user’s `HOMEPATH\.bun`. To install it elsewhere, set `BUN_INSTALL=<install-path>` as a global or system environment variable before installing. The installation will add Bun to the current user’s path, but consider adding it to the global or system path for easier access across all users.
111
74
 
112
- #### Install SCIM Gateway
75
+ #### SCIM Gateway Installation
113
76
 
114
- Open a command window (run as administrator)
115
- Create your own package directory e.g. c:\my-scimgateway and install SCIM Gateway within this package.
77
+ Create a package directory and install the SCIM Gateway:
116
78
 
117
79
  mkdir c:\my-scimgateway
118
80
  cd c:\my-scimgateway
119
81
  bun init -y
120
82
  bun install scimgateway
121
83
  bun pm trust scimgateway
122
-
123
- **c:\\my-scimgateway** will now be `<package-root>`
124
84
 
125
- index.ts, lib and config directories containing example plugins have been copied to your package from the original scimgateway package located under node_modules. Bun requires `bun pm trust scimgateway` for allowing postinstall copying these files.
126
-
127
- If internet connection is blocked, we could install on another machine and copy the `<package-root>` folder.
128
-
85
+ index.ts, lib and config directories containing example plugins are copied to your package. The command `bun pm trust scimgateway` is required to allow the `postinstall` script to copy these files.
129
86
 
130
87
  #### Startup and verify default Loki plugin
131
88
 
@@ -159,28 +116,15 @@ If internet connection is blocked, we could install on another machine and copy
159
116
 
160
117
  "Ctrl + c" to stop the SCIM Gateway
161
118
 
162
- >Tip, take a look at bun test scripts located in `node_modules\scimgateway\test\lib`
163
-
164
- > If using Node.js instead of Bun, startup will then be:
119
+ > For Node.js, the startup command is:
165
120
  `node --import=tsx ./index.ts`
166
121
 
167
- #### Upgrade SCIM Gateway
168
-
169
- Not needed after a fresh install
170
-
171
- The best and easiest way to upgrade is renaming existing scimgateway package folder, create a new one and do a fresh installation. After the installation we copy `index.ts, config and lib folder` (customized plugins) from previous installation to the new installation. You should also read the version history to see if custom plugins needs to be updated.
122
+ #### Upgrade Process
172
123
 
173
- Alternatives are:
124
+ The recommended upgrade method is to rename the existing package folder, perform a fresh installation, and then copy your custom `index.ts`, `config`, and `lib` folders from the previous installation.
174
125
 
175
- Upgrade to latest minor version:
176
-
177
- cd c:\my-scimgateway
178
- bun install scimgateway
179
-
180
- Note, always backup/copy c:\\my-scimgateway before upgrading. Custom plugins and corresponding configuration files will not be affected.
181
-
182
- To force a major upgrade (version x.\*.\* => y.\*.\*) that will brake compability with any existing custom plugins, we have to include the `@latest` suffix in the install command:
183
- `bun install scimgateway@latest`
126
+ - Minor Upgrade: `bun install scimgateway`
127
+ - Major Upgrade: `bun install scimgateway@latest` (Use with caution, as it may break compatibility with existing custom plugins)
184
128
 
185
129
  ##### Avoid (re-)adding the files created during `postinstall`
186
130
 
@@ -191,171 +135,32 @@ For Node.js (and also Bun), we might set the property `scimgateway_postinstall_s
191
135
 
192
136
  ## Configuration
193
137
 
194
- **index.ts** defines one or more plugins to be started by the `import statement`.
195
-
138
+ **index.ts** defines one or more plugins to be started
139
+
196
140
  // start one or more plugins:
197
- // import './lib/plugin-scim.ts'
198
- // import './lib/plugin-entra-id.ts'
199
- // import './lib/plugin-ldap.ts'
200
- // import './lib/plugin-mongodb.ts'
201
- // import './lib/plugin-api.ts'
202
- // import './lib/plugin-mssql.ts'
203
- // import './lib/plugin-saphana.ts'
204
- // import './lib/plugin-soap.ts'
205
-
206
- import './lib/plugin-loki.ts'
141
+ import './lib/plugin-entra-id.ts'
207
142
  export {}
208
143
 
209
144
 
210
145
  Each endpoint plugin needs a TypeScript file (.ts) and a configuration file (.json).
211
- **They both must have the same naming prefix**. For SAP Hana endpoint we have:
212
- >lib\plugin-saphana.ts
213
- >config\plugin-saphana.json
146
+ **They both must have the same naming prefix**. For Entra ID endpoint we have:
147
+ >lib\plugin-entra-id.ts
148
+ >config\plugin-entra-id.json
214
149
 
150
+ A plugin configuration file has two main JSON objects: `scimgateway` and `endpoint`
215
151
 
216
- Edit specific plugin configuration file according to your needs.
217
- Below shows an example of config\plugin-saphana.json
218
-
219
152
  {
220
153
  "scimgateway": {
221
- "port": 8884,
222
- "localhostonly": false,
223
- "chainingBaseUrl": null,
224
- "scim": {
225
- "version": "2.0",
226
- "skipTypeConvert" : false,
227
- "skipMetaLocation" false,
228
- "groupMemberOfUser": false
229
- "usePutSoftSync" : false
230
- },
231
- "log": {
232
- "loglevel": {
233
- "file": "debug",
234
- "console": "error"
235
- },
236
- "customMasking": []
237
- },
238
- "auth": {
239
- "basic": [
240
- {
241
- "username": "gwadmin",
242
- "password": "password",
243
- "readOnly": false,
244
- "baseEntities": []
245
- }
246
- ],
247
- "bearerToken": [
248
- {
249
- "token": null,
250
- "readOnly": false,
251
- "baseEntities": []
252
- }
253
- ],
254
- "bearerJwt": [
255
- {
256
- "secret": null,
257
- "publicKey": null,
258
- "wellKnownUri": null,
259
- "azureTenantId": null,
260
- "options": {
261
- "issuer": null
262
- },
263
- "readOnly": false,
264
- "baseEntities": []
265
- }
266
- ],
267
- "bearerOAuth": [
268
- {
269
- "clientId": null,
270
- "clientSecret": null,
271
- "readOnly": false,
272
- "baseEntities": []
273
- }
274
- ],
275
- "passThrough": {
276
- "enabled": false,
277
- "readOnly": false,
278
- "baseEntities": []
279
- }
280
- },
281
- "certificate": {
282
- "key": null,
283
- "cert": null,
284
- "ca": null,
285
- "pfx": {
286
- "bundle": null,
287
- "password": null
288
- }
289
- },
290
- "ipAllowList": [],
291
- "email": {
292
- "auth": {
293
- "type": "oauth",
294
- "options": {
295
- "azureTenantId": null,
296
- "clientId": null,
297
- "clientSecret": null
298
- }
299
- },
300
- "emailOnError": {
301
- "enabled": false,
302
- "from": null,
303
- "to": null
304
- }
305
- },
306
- "stream": {
307
- "baseUrls": [],
308
- "certificate": {
309
- "ca": null
310
- },
311
- "subscriber": {
312
- "enabled": false,
313
- "entity": {
314
- "undefined": {
315
- "nats": {
316
- "tenant": null,
317
- "subject": null,
318
- "jwt": null,
319
- "secret": null
320
- },
321
- "deleteUserOnLastGroupRoleRemoval": false,
322
- "convertRolesToGroups": false,
323
- "generateUserPassword": false,
324
- "modifyOnly": false,
325
- "replaceDomains": []
326
- }
327
- }
328
- },
329
- "publisher": {
330
- "enabled": false,
331
- "entity": {
332
- "undefined": {
333
- "nats": {
334
- "tenant": null,
335
- "subject": null,
336
- "jwt": null,
337
- "secret": null
338
- }
339
- }
340
- }
341
- }
342
- }
154
+ ...
343
155
  },
344
156
  "endpoint": {
345
- "host": "hostname",
346
- "port": 30015,
347
- "username": "username",
348
- "password": "password",
349
- "saml_provider": "saml_provider_name"
157
+ ...
350
158
  }
351
159
  }
352
160
 
161
+ `scimgateway`: Contains fixed attributes used by the core gateway functionality (e.g., port, logging, and authentication).
353
162
 
354
- Configuration file have two main JSON objects: `scimgateway` and `endpoint`
355
-
356
- Definitions in `scimgateway` object have fixed attributes, but values can be modified. Sections not used/configured can be removed. This object is used by the core functionality of the SCIM Gateway.
357
-
358
- Definitions in `endpoint` object are customized according to our plugin code. Plugin typically need this information for communicating with endpoint
163
+ `endpoint`: Contains customized definitions required by the plugin code for communication with the destination system (e.g., host, port, credentials).
359
164
 
360
165
  - **port** - Gateway will listen on this port number. Clients (e.g. Provisioning Server) will be using this port number for communicating with the gateway
361
166
 
@@ -916,16 +721,16 @@ If several SCIM Gateway´s (same plugin) connect listeners using the same Azure
916
721
 
917
722
  ### Configuration notes - running SCIM Gateway as a single binary
918
723
 
919
- A single binary can be compiled that includes both the gateway and the plugin. The binary must have the same name (prefix) as the configuration file in the config directory, and this directory must be located in the same folder as the binary.
724
+ Bun binary build allowing SCIM Gateway to be compiled into a single executable binary for simplified deployment and execution. The binary must have the same name (prefix) as the configuration file in the config directory, and this directory must be located in the same folder as the binary.
920
725
 
921
726
  cd my-scimgateway
922
- bun build --compile --target=bun-darwin-arm64 --outfile ./build/plugin-loki ./lib/plugin-loki.ts
923
- // for target options, see: https://bun.com/docs/bundler/executables#cross-compile-to-other-platforms
727
+ bun build --compile ./lib/plugin-loki.ts --target=bun-darwin-arm64 --outfile ./build/plugin-loki
728
+ # for target options, see: https://bun.com/docs/bundler/executables#cross-compile-to-other-platforms
924
729
 
925
730
  cp -r ./config ./build
926
- // build directory now have what is needed and can be put into production
731
+ # build directory now ready for production deployment
927
732
  cd build
928
- // run the binary - note, binary must have same name (prefix) as the configuration file in the config directory
733
+ # run the binary - note, binary must have same name (prefix) as the configuration file in the config directory
929
734
  ./plugin-loki
930
735
 
931
736
 
@@ -1545,11 +1350,22 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
1545
1350
 
1546
1351
  ## Change log
1547
1352
 
1353
+ ### v6.1.1
1354
+
1355
+ [Fixed]
1356
+
1357
+ - plugin-ldap, a createUser operation followed immediately by a readUser (automatically performed by SCIM Gateway) may not find the newly created user on some systems, such as Samba AD, due to timing issues
1358
+
1359
+
1360
+ [Improved]
1361
+
1362
+ - the final info log message now includes a JSON serialization of all elements, such as durationMs, status, requestBody, responseBody, ...
1363
+
1548
1364
  ### v6.1.0
1549
1365
 
1550
1366
  [Improved]
1551
1367
 
1552
- - tsx is now included, allowing SCIM Gateway to be run as a module in Node.js. The mandatory plugin section, which previously required complex dynamic loading, can now be simplified using static imports
1368
+ - `tsx` is now included, allowing SCIM Gateway to run as an ES module (TypeScript) in Node.js. The mandatory plugin section, which previously required complex dynamic loading, can now be simplified using static imports
1553
1369
 
1554
1370
  **Old plugin-xxx.ts:**
1555
1371
 
@@ -1613,17 +1429,16 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
1613
1429
  import './lib/plugin-loki.ts'
1614
1430
  export {}
1615
1431
 
1616
-
1617
- - Bun binary build is now supported. A single binary can be compiled that includes both the gateway and the plugin. The binary must have the same name (prefix) as the configuration file in the config directory, and this directory must be located in the same folder as the binary.
1432
+ - Bun binary build is now supported allowing SCIM Gateway to be compiled into a single executable binary for simplified deployment and execution. The binary must have the same name (prefix) as the configuration file in the config directory, and this directory must be located in the same folder as the binary.
1618
1433
 
1619
1434
  cd my-scimgateway
1620
- bun build --compile --target=bun-darwin-arm64 --outfile ./build/plugin-loki ./lib/plugin-loki.ts
1621
- // for target options, see: https://bun.com/docs/bundler/executables#cross-compile-to-other-platforms
1435
+ bun build --compile ./lib/plugin-loki.ts --target=bun-darwin-arm64 --outfile ./build/plugin-loki
1436
+ # for target options, see: https://bun.com/docs/bundler/executables#cross-compile-to-other-platforms
1622
1437
 
1623
1438
  cp -r ./config ./build
1624
- // build directory now have what is needed and can be put into production
1439
+ # build directory now ready for production deployment
1625
1440
  cd build
1626
- // run the binary - note, binary must have same name (prefix) as the configuration file in the config directory
1441
+ # run the binary - note, binary must have same name (prefix) as the configuration file in the config directory
1627
1442
  ./plugin-loki
1628
1443
 
1629
1444
  - Dependencies bump
@@ -144,13 +144,13 @@
144
144
  "namingAttribute": {
145
145
  "user": [
146
146
  {
147
- "attribute": "cn",
147
+ "attribute": "CN",
148
148
  "mapTo": "userName"
149
149
  }
150
150
  ],
151
151
  "group": [
152
152
  {
153
- "attribute": "cn",
153
+ "attribute": "CN",
154
154
  "mapTo": "displayName"
155
155
  }
156
156
  ]
@@ -706,7 +706,7 @@ export class HelperRest {
706
706
  } catch (err) { void 0 }
707
707
  }
708
708
  }
709
- if (f.status < 200 || f.status > 299) {
709
+ if (f.status > 399) {
710
710
  if (f.status === 429) { // throttle
711
711
  const v = f.headers.get('retry-after')
712
712
  if (v) retryAfter = parseInt(v, 10) + 1
@@ -131,7 +131,7 @@ scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx) => {
131
131
  const method = 'search'
132
132
  const scope = 'sub'
133
133
  let base = config.entity[baseEntity].ldap.userBase
134
- let ldapOptions
134
+ let ldapOptions: Record<string, any>
135
135
 
136
136
  const [userIdAttr, err] = scimgateway.endpointMapper('outbound', 'userName', config.map.user) // e.g. 'userName' => 'sAMAccountName'
137
137
  if (err) throw new Error(`${action} error: ${err.message}`)
@@ -177,6 +177,7 @@ scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx) => {
177
177
  }
178
178
  }
179
179
  }
180
+ ldapOptions.paged = false
180
181
  } else if (getObj.operator === 'eq' && getObj.attribute === 'group.value') {
181
182
  // optional - only used when groups are member of users, not default behavior - correspond to getGroupUsers() in versions < 4.x.x
182
183
  throw new Error(`${action} error: not supporting groups member of user filtering: ${getObj.rawFilter}`)
@@ -1433,7 +1434,7 @@ const doRequest = async (baseEntity: string, method: string, base: any, options:
1433
1434
  client = await getServiceClient(baseEntity, ctx)
1434
1435
  switch (method) {
1435
1436
  case 'search':
1436
- options.paged = { pageSize: 200, pagePause: false } // parse entire directory calling 'page' method for each page
1437
+ if (options.paged !== false) options.paged = { pageSize: 200, pagePause: false } // parse entire directory calling 'page' method for each page
1437
1438
  result = await new Promise((resolve, reject) => {
1438
1439
  const results: any = []
1439
1440
 
@@ -74,7 +74,7 @@ scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx) => {
74
74
 
75
75
  try {
76
76
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
77
- if (response.statusCode < 200 || response.statusCode > 299) {
77
+ if (response.statusCode > 399) {
78
78
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
79
79
  } else if (!response.body) {
80
80
  throw new Error('got empty response on REST request')
@@ -170,7 +170,7 @@ scimgateway.createUser = async (baseEntity, userObj, ctx) => {
170
170
 
171
171
  try {
172
172
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
173
- if (response.statusCode < 200 || response.statusCode > 299) {
173
+ if (response.statusCode > 399) {
174
174
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
175
175
  }
176
176
  return null
@@ -192,7 +192,7 @@ scimgateway.deleteUser = async (baseEntity, id, ctx) => {
192
192
 
193
193
  try {
194
194
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
195
- if (response.statusCode < 200 || response.statusCode > 299) {
195
+ if (response.statusCode > 399) {
196
196
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
197
197
  }
198
198
  return null
@@ -275,7 +275,7 @@ scimgateway.modifyUser = async (baseEntity, id, attrObj, ctx) => {
275
275
 
276
276
  try {
277
277
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
278
- if (response.statusCode < 200 || response.statusCode > 299) {
278
+ if (response.statusCode > 399) {
279
279
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
280
280
  }
281
281
  return null
@@ -327,7 +327,7 @@ scimgateway.getGroups = async (baseEntity, getObj, attributes, ctx) => {
327
327
 
328
328
  try {
329
329
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
330
- if (response.statusCode < 200 || response.statusCode > 299) {
330
+ if (response.statusCode > 399) {
331
331
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
332
332
  } else if (!response.body) {
333
333
  throw new Error('got empty response on REST request')
@@ -377,7 +377,7 @@ scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
377
377
 
378
378
  try {
379
379
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
380
- if (response.statusCode < 200 || response.statusCode > 299) {
380
+ if (response.statusCode > 399) {
381
381
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
382
382
  }
383
383
  return null
@@ -399,7 +399,7 @@ scimgateway.deleteGroup = async (baseEntity, id, ctx) => {
399
399
 
400
400
  try {
401
401
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
402
- if (response.statusCode < 200 || response.statusCode > 299) {
402
+ if (response.statusCode > 399) {
403
403
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
404
404
  }
405
405
  return null
@@ -471,7 +471,7 @@ scimgateway.modifyGroup = async (baseEntity, id, attrObj, ctx) => {
471
471
 
472
472
  try {
473
473
  const response = await helper.doRequest(baseEntity, method, path, body, ctx)
474
- if (response.statusCode < 200 || response.statusCode > 299) {
474
+ if (response.statusCode > 399) {
475
475
  throw new Error(`${response.statusMessage} - ${JSON.stringify(response.body)}`)
476
476
  }
477
477
  return null