scimgateway 5.0.15 → 5.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/.github/dependabot.yml +6 -0
- package/.github/workflows/test-master.yml +28 -0
- package/.github/workflows/test-release.yml +25 -0
- package/.travis.yml +1 -1
- package/README.md +71 -10
- package/bun.lockb +0 -0
- package/config/plugin-api.json +1 -0
- package/config/plugin-entra-id.json +1 -0
- package/config/plugin-ldap.json +1 -0
- package/config/plugin-loki.json +1 -0
- package/config/plugin-mongodb.json +1 -0
- package/config/plugin-mssql.json +1 -0
- package/config/plugin-saphana.json +1 -0
- package/config/plugin-scim.json +1 -0
- package/config/plugin-soap.json +1 -0
- package/lib/helper-rest.ts +15 -7
- package/lib/samlAssertion.ts +1 -0
- package/lib/scim-stream.js +1 -1
- package/lib/scimgateway.ts +230 -322
- package/package.json +2 -3
- package/test/lib/plugin-api_test.ts +21 -22
- package/test/lib/plugin-loki_test.ts +108 -106
- package/test/lib/plugin-mongodb_test.ts_excluded +87 -102
- package/test/lib/plugin-scim_test.ts +86 -99
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Test Master Branch
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- master
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout code
|
|
17
|
+
uses: actions/checkout@v3
|
|
18
|
+
|
|
19
|
+
- name: Install Bun
|
|
20
|
+
run: |
|
|
21
|
+
curl -fsSL https://bun.sh/install | bash
|
|
22
|
+
echo "$HOME/.bun/bin" >> $GITHUB_PATH
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: bun install
|
|
26
|
+
|
|
27
|
+
- name: Run master tests
|
|
28
|
+
run: bun run test
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Test Release Workflow
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types:
|
|
6
|
+
- published
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout code
|
|
14
|
+
uses: actions/checkout@v3
|
|
15
|
+
|
|
16
|
+
- name: Install Bun
|
|
17
|
+
run: |
|
|
18
|
+
curl -fsSL https://bun.sh/install | bash
|
|
19
|
+
echo "$HOME/.bun/bin" >> $GITHUB_PATH
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: bun install
|
|
23
|
+
|
|
24
|
+
- name: Run release tests
|
|
25
|
+
run: bun run test
|
package/.travis.yml
CHANGED
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ Validated through IdP's:
|
|
|
16
16
|
|
|
17
17
|
Latest news:
|
|
18
18
|
|
|
19
|
+
- By configuring the chainingBaseUrl, it is now possible to chain multiple gateways in sequence, such as `gateway1->gateway2->gateway3->endpoint`. In this setup, gateway beave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber mode
|
|
19
20
|
- Email, onError and sendMail() supports more secure RESTful OAuth for Microsoft Exchange Online (ExO) and Google Workspace Gmail, alongside traditional SMTP Auth for all mail systems. HelperRest supports a wide range of common authentication methods, including basicAuth, bearerAuth, tokenAuth, oauth, oauthSamlBearer, oauthJwtBearer and Auth PassTrough
|
|
20
21
|
- Major version **v5.0.0** marks a shift to native TypeScript support and prioritizes [Bun](https://bun.sh/) over Node.js. This upgrade requires some modifications to existing plugins.
|
|
21
22
|
- **BREAKING**: [SCIM Stream](https://elshaug.xyz/docs/scim-stream) is the modern way of user provisioning letting clients subscribe to messages instead of traditional IGA top-down provisioning. SCIM Gateway now offers enhanced functionality with support for message subscription and automated provisioning using SCIM Stream
|
|
@@ -58,10 +59,8 @@ Shows how to implement a highly configurable multi tenant or multi endpoint solu
|
|
|
58
59
|
|
|
59
60
|
* **SCIM** (REST Webservice)
|
|
60
61
|
Demonstrates user provisioning towards REST-Based endpoint (type SCIM)
|
|
61
|
-
Using plugin Loki as SCIM endpoint
|
|
62
|
+
Using plugin Loki as SCIM endpoint through HelperRest
|
|
62
63
|
Can be used as SCIM version-gateway e.g. 1.1=>2.0 or 2.0=>1.1
|
|
63
|
-
Can be used to chain several gateways
|
|
64
|
-
|
|
65
64
|
|
|
66
65
|
* **Soap** (SOAP Webservice)
|
|
67
66
|
Demonstrates user provisioning towards SOAP-Based endpoint
|
|
@@ -77,7 +76,7 @@ Demonstrates SAP HANA specific user provisioning
|
|
|
77
76
|
|
|
78
77
|
* **Entra ID** (REST Webservices)
|
|
79
78
|
Entra ID user provisioning including license management (App Service plans) e.g. Office 365
|
|
80
|
-
Using Microsoft Graph API
|
|
79
|
+
Using Microsoft Graph API through HelperRest
|
|
81
80
|
Using customized SCIM attributes according to Microsoft Graph API
|
|
82
81
|
Includes Symantec/Broadcom/CA ConnectorXpress metafile for creating provisioning "Azure - ScimGateway" endpoint type
|
|
83
82
|
|
|
@@ -87,7 +86,7 @@ Pre-configured for Microsoft Active Directory
|
|
|
87
86
|
Using endpointMapper (like plugin-entra-id) for attribute mapping flexibility
|
|
88
87
|
|
|
89
88
|
* **API** (REST Webservices)
|
|
90
|
-
Demonstrates API Gateway/plugin functionality using post/put/patch/get/delete
|
|
89
|
+
Demonstrates API Gateway/plugin functionality using post/put/patch/get/delete combined with HelperRest
|
|
91
90
|
None SCIM plugin, becomes what you want it to become.
|
|
92
91
|
Methods included can also be used in standard SCIM plugins
|
|
93
92
|
Endpoint complexity could be put in this plugin, and client could instead communicate through Gateway using your own simplified REST specification.
|
|
@@ -185,7 +184,7 @@ For Node.js (and also Bun), we might set the property `scimgateway_postinstall_s
|
|
|
185
184
|
// example starting all default plugins:
|
|
186
185
|
// const plugins = ['loki', 'scim', 'entra-id', 'ldap', 'mssql', 'api', 'mongodb', 'saphana', 'soap']
|
|
187
186
|
|
|
188
|
-
const plugins = ['
|
|
187
|
+
const plugins = ['loki']
|
|
189
188
|
|
|
190
189
|
for (const plugin of plugins) {
|
|
191
190
|
try {
|
|
@@ -209,6 +208,7 @@ Below shows an example of config\plugin-saphana.json
|
|
|
209
208
|
"scimgateway": {
|
|
210
209
|
"port": 8884,
|
|
211
210
|
"localhostonly": false,
|
|
211
|
+
"chainingBaseUrl": null,
|
|
212
212
|
"scim": {
|
|
213
213
|
"version": "2.0",
|
|
214
214
|
"skipTypeConvert" : false,
|
|
@@ -354,6 +354,8 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
354
354
|
|
|
355
355
|
- **localhostonly** - true or false. False means gateway accepts incoming requests from all clients. True means traffic from only localhost (127.0.0.1) is accepted.
|
|
356
356
|
|
|
357
|
+
- **chainingBaseUrl** - baseUrl for chaining anohter gateway, syntax: `http(s)://host:port`. If defined, gateway beave much like a reverse proxy, validating authorization unless PassThrough mode is enabled. See `Configuration notes` for details
|
|
358
|
+
|
|
357
359
|
- **idleTimeout** - default 120, sets the the number of seconds to wait before timing out a connection due to inactivity
|
|
358
360
|
|
|
359
361
|
- **scim.version** - "1.1" or "2.0". Default is "2.0".
|
|
@@ -399,7 +401,7 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
399
401
|
|
|
400
402
|
- **auth.bearerJwt** - Array of one or more standard JWT objects. Using **secret** or **publicKey** for signature verification. publicKey should be set to the filename of public key or certificate pem-file located in `<package-root>\config\certs` or absolute path being used. Clear text secret will become encrypted when gateway is started. **options.issuer** is mandatory. Other options may also be included according to jsonwebtoken npm package definition.
|
|
401
403
|
|
|
402
|
-
- **auth.bearerOAuth** - Array of one or more Client Credentials OAuth configuration objects. **`clientId`** and **`clientSecret`** are mandatory. clientSecret value will become encrypted when gateway is started. OAuth token request url is **/oauth/token** e.g. http://localhost:8880/oauth/token
|
|
404
|
+
- **auth.bearerOAuth** - Array of one or more Client Credentials OAuth configuration objects. **`clientId`** and **`clientSecret`** are mandatory. clientSecret value will become encrypted when gateway is started. OAuth token request url is **/oauth/token** e.g. `http://localhost:8880/oauth/token`
|
|
403
405
|
|
|
404
406
|
- **auth.passThrough** - Setting **auth.passThrough.enabled=true** will bypass SCIM Gateway authentication. Gateway will instead pass ctx containing authentication header to the plugin. Plugin could then use this information for endpoint authentication and we don't have any password/token stored at the gateway. Note, this also requires plugin binary having `scimgateway.authPassThroughAllowed = true` and endpoint logic for handling/passing ctx.request.header.authorization
|
|
405
407
|
|
|
@@ -441,9 +443,9 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
441
443
|
- **email.auth** - Authentication configuration
|
|
442
444
|
- **email.auth.type** - `oauth` or `smtp`
|
|
443
445
|
- **email.auth.options** - Authentication options - note, different options for type oauth and smtp
|
|
444
|
-
- **email.auth.options.tenantIdGUID (oauth/ExO)** - Entra
|
|
445
|
-
- **email.auth.options.clientId (oauth/ExO)** - Client ID
|
|
446
|
-
- **email.auth.options.clientSecret (oauth/ExO)** - Client Secret
|
|
446
|
+
- **email.auth.options.tenantIdGUID (oauth/ExO)** - Entra tenant id or domain name
|
|
447
|
+
- **email.auth.options.clientId (oauth/ExO)** - Entra OAuth application Client ID
|
|
448
|
+
- **email.auth.options.clientSecret (oauth/ExO)** - Entra OAuth application Client Secret
|
|
447
449
|
- **email.auth.options.serviceAccountKeyFile (oauth/Gmail)** - Google Service Account key json-file name located in the `package-root>\config\certs` directory unless absolute path being defined
|
|
448
450
|
- **email.auth.options.host (smtp)** - Mailserver e.g. "smtp.gmail.com" - mandatory for smtp
|
|
449
451
|
- **email.auth.options.port (smtp)** - Port used by mailserver e.g. 587, 25 or 465 - mandatory for smtp
|
|
@@ -561,6 +563,50 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
561
563
|
- Licenses > Edit > enable Google Workspace license
|
|
562
564
|
`email.emailOnError.from` mail address must have Google Workspace license
|
|
563
565
|
|
|
566
|
+
- Gateway chainging and chainingBaseUrl configuration
|
|
567
|
+
|
|
568
|
+
By configuring the `chainingBaseUrl`, it is possible to chain multiple gateways in sequence, such as `gateway1->gateway2->gateway3->endpoint`. In this setup, gateway behave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber mode
|
|
569
|
+
|
|
570
|
+
{
|
|
571
|
+
"scimgateway": {
|
|
572
|
+
...
|
|
573
|
+
"chainingBaseUrl": "https:\\gateway2:8880",
|
|
574
|
+
...
|
|
575
|
+
"auth": {
|
|
576
|
+
...
|
|
577
|
+
"passThrough": {
|
|
578
|
+
"enabled": false,
|
|
579
|
+
"readOnly": false,
|
|
580
|
+
"baseEntities": []
|
|
581
|
+
}
|
|
582
|
+
...
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
...
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
Using above configuration example on gateway1, incoming requests will be routed to `https:\\gateway2:8880`
|
|
590
|
+
|
|
591
|
+
The plugin and its associated authentication configuration can mirror the setup running on the final gateway. However, in chaining mode, the plugin binary is used solely for initializing and configuring the gateway. This allows for the use of a simplified `plugin-<name>.ts` binary containing only the essential mandatory components:
|
|
592
|
+
|
|
593
|
+
// start - mandatory plugin initialization
|
|
594
|
+
const ScimGateway: typeof import('scimgateway').ScimGateway = await (async () => {
|
|
595
|
+
try {
|
|
596
|
+
return (await import('scimgateway')).ScimGateway
|
|
597
|
+
} catch (err) {
|
|
598
|
+
const source = './scimgateway.ts'
|
|
599
|
+
return (await import(source)).ScimGateway
|
|
600
|
+
}
|
|
601
|
+
})()
|
|
602
|
+
const scimgateway = new ScimGateway()
|
|
603
|
+
const config = scimgateway.getConfig()
|
|
604
|
+
scimgateway.authPassThroughAllowed = false
|
|
605
|
+
// end - mandatory plugin initialization
|
|
606
|
+
|
|
607
|
+
Using `scimgateway.authPassThroughAllowed = true` and `plugin-<name>.json` configuration `scimgateway.auth.passThrough=true` enables Authentication PassTrhough
|
|
608
|
+
|
|
609
|
+
|
|
564
610
|
|
|
565
611
|
## Manual startup
|
|
566
612
|
|
|
@@ -1136,6 +1182,21 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1136
1182
|
|
|
1137
1183
|
## Change log
|
|
1138
1184
|
|
|
1185
|
+
### v5.1.1
|
|
1186
|
+
|
|
1187
|
+
[Fixed]
|
|
1188
|
+
|
|
1189
|
+
- SCIM Gateway failed to start on linux using Bun >= v1.1.43
|
|
1190
|
+
|
|
1191
|
+
### v5.1.0
|
|
1192
|
+
|
|
1193
|
+
[Improved]
|
|
1194
|
+
|
|
1195
|
+
- By configuring the `chainingBaseUrl`, it is now possible to chain multiple gateways in sequence, such as `gateway1->gateway2->gateway3->endpoint`. In this setup, gateway beave much like a reverse proxy, validating authorization at each step unless PassThrough mode is enabled. Chaining is also supported in stream subscriber mode
|
|
1196
|
+
|
|
1197
|
+
Please see `Configuration notes` for details
|
|
1198
|
+
|
|
1199
|
+
|
|
1139
1200
|
### v5.0.15
|
|
1140
1201
|
|
|
1141
1202
|
[Improved]
|
package/bun.lockb
CHANGED
|
Binary file
|
package/config/plugin-api.json
CHANGED
package/config/plugin-ldap.json
CHANGED
package/config/plugin-loki.json
CHANGED
package/config/plugin-mssql.json
CHANGED
package/config/plugin-scim.json
CHANGED
package/config/plugin-soap.json
CHANGED
package/lib/helper-rest.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
// =================================================================================
|
|
2
|
+
// File: helper-rest.ts
|
|
3
|
+
//
|
|
4
|
+
// Author: Jarle Elshaug
|
|
5
|
+
//
|
|
6
|
+
// Purpose: HelperRest class for executing REST calls supporting various auth types
|
|
7
|
+
// Plugins may use this class: import { HelperRest } from 'scimgateway'
|
|
8
|
+
// =================================================================================
|
|
9
|
+
|
|
1
10
|
import { HttpsProxyAgent } from 'https-proxy-agent'
|
|
2
11
|
import { URL } from 'url'
|
|
3
12
|
import { Buffer } from 'node:buffer'
|
|
4
|
-
import { samlAssertion } from './samlAssertion.ts'
|
|
5
|
-
import
|
|
13
|
+
import { samlAssertion } from './samlAssertion.ts'
|
|
14
|
+
import * as jsonwebtoken from 'jsonwebtoken'
|
|
6
15
|
import fs from 'node:fs'
|
|
7
16
|
import querystring from 'querystring'
|
|
8
17
|
import * as utils from './utils.ts'
|
|
@@ -164,7 +173,7 @@ export class HelperRest {
|
|
|
164
173
|
|
|
165
174
|
form = {
|
|
166
175
|
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
167
|
-
assertion:
|
|
176
|
+
assertion: jsonwebtoken.sign(jwtAttr, privateKey, { algorithm: 'RS256' }),
|
|
168
177
|
}
|
|
169
178
|
break
|
|
170
179
|
|
|
@@ -428,9 +437,9 @@ export class HelperRest {
|
|
|
428
437
|
return cli // final client
|
|
429
438
|
}
|
|
430
439
|
//
|
|
431
|
-
// url path - none config based and used as is (no cache)
|
|
440
|
+
// url path - none config based (enpoint.entity) and used as is (no cache)
|
|
432
441
|
//
|
|
433
|
-
this.scimgateway.logDebug(baseEntity, `${action}: Using
|
|
442
|
+
this.scimgateway.logDebug(baseEntity, `${action}: Using raw client`)
|
|
434
443
|
let options: any = {
|
|
435
444
|
json: true,
|
|
436
445
|
headers: {
|
|
@@ -440,7 +449,7 @@ export class HelperRest {
|
|
|
440
449
|
port: urlObj.port,
|
|
441
450
|
protocol: urlObj.protocol,
|
|
442
451
|
method: method,
|
|
443
|
-
path: urlObj.pathname,
|
|
452
|
+
path: urlObj.pathname + urlObj.search,
|
|
444
453
|
}
|
|
445
454
|
|
|
446
455
|
// proxy
|
|
@@ -516,7 +525,6 @@ export class HelperRest {
|
|
|
516
525
|
const timeout = setTimeout(() => controller.abort(), options.abortTimeout ? options.abortTimeout * 1000 : this.idleTimeout * 1000) // 120 seconds default abort timeout
|
|
517
526
|
options.signal = signal
|
|
518
527
|
const url = `${options.protocol}//${options.host}${options.port ? ':' + options.port : ''}${options.path}`
|
|
519
|
-
if (path.includes(')?$') && !options.headers['Accept-Encoding']) options.headers['Accept-Encoding'] = 'identity' // workaround for bun fetch error: "Decompression error: ShortRead" - have seen this error using OData with "<some-path>('xxx')?$expand=" or "<some-path>('xxx')?$select=" ref: https://github.com/oven-sh/bun/issues/8017
|
|
520
528
|
// execute request
|
|
521
529
|
const f = await fetch(url, options)
|
|
522
530
|
clearTimeout(timeout)
|