@boxyhq/saml-jackson 0.2.3-beta.231 → 0.2.3-beta.235

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/README.md +1 -2
  2. package/package.json +12 -4
  3. package/ nodemon.json +0 -12
  4. package/.dockerignore +0 -2
  5. package/.eslintrc.js +0 -18
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -27
  7. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  8. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -43
  9. package/.github/pull_request_template.md +0 -31
  10. package/.github/workflows/codesee-arch-diagram.yml +0 -81
  11. package/.github/workflows/main.yml +0 -123
  12. package/_dev/docker-compose.yml +0 -37
  13. package/map.js +0 -1
  14. package/prettier.config.js +0 -4
  15. package/src/controller/api.ts +0 -225
  16. package/src/controller/error.ts +0 -13
  17. package/src/controller/oauth/allowed.ts +0 -22
  18. package/src/controller/oauth/code-verifier.ts +0 -11
  19. package/src/controller/oauth/redirect.ts +0 -12
  20. package/src/controller/oauth.ts +0 -334
  21. package/src/controller/utils.ts +0 -17
  22. package/src/db/db.ts +0 -100
  23. package/src/db/encrypter.ts +0 -38
  24. package/src/db/mem.ts +0 -128
  25. package/src/db/mongo.ts +0 -110
  26. package/src/db/redis.ts +0 -103
  27. package/src/db/sql/entity/JacksonIndex.ts +0 -43
  28. package/src/db/sql/entity/JacksonStore.ts +0 -43
  29. package/src/db/sql/entity/JacksonTTL.ts +0 -17
  30. package/src/db/sql/model/JacksonIndex.ts +0 -3
  31. package/src/db/sql/model/JacksonStore.ts +0 -8
  32. package/src/db/sql/sql.ts +0 -181
  33. package/src/db/store.ts +0 -49
  34. package/src/db/utils.ts +0 -26
  35. package/src/env.ts +0 -42
  36. package/src/index.ts +0 -84
  37. package/src/jackson.ts +0 -173
  38. package/src/read-config.ts +0 -29
  39. package/src/saml/claims.ts +0 -41
  40. package/src/saml/saml.ts +0 -233
  41. package/src/saml/x509.ts +0 -51
  42. package/src/test/api.test.ts +0 -270
  43. package/src/test/data/metadata/boxyhq.js +0 -6
  44. package/src/test/data/metadata/boxyhq.xml +0 -30
  45. package/src/test/data/saml_response +0 -1
  46. package/src/test/db.test.ts +0 -313
  47. package/src/test/oauth.test.ts +0 -362
  48. package/src/typings.ts +0 -167
  49. package/tsconfig.build.json +0 -6
  50. package/tsconfig.json +0 -26
package/README.md CHANGED
@@ -357,7 +357,6 @@ To Do
357
357
  Jackson currently supports the following databases.
358
358
 
359
359
  - Postgres
360
- - CockroachDB
361
360
  - MySQL
362
361
  - MariaDB
363
362
  - MongoDB
@@ -381,7 +380,7 @@ The following options are supported and will have to be configured during deploy
381
380
  | IDP_ENABLED (npm: idpEnabled) | Set to `true` to enable IdP initiated login for SAML. SP initiated login is the only recommended flow but you might have to support IdP login at times. | `false` |
382
381
  | DB_ENGINE (npm: db.engine) | Supported values are `redis`, `sql`, `mongo`, `mem`. | `sql` |
383
382
  | DB_URL (npm: db.url) | The database URL to connect to. For example `postgres://postgres:postgres@localhost:5450/jackson` | |
384
- | DB_TYPE (npm: db.type) | Only needed when DB_ENGINE is `sql`. Supported values are `postgres`, `cockroachdb`, `mysql`, `mariadb`. | `postgres` |
383
+ | DB_TYPE (npm: db.type) | Only needed when DB_ENGINE is `sql`. Supported values are `postgres`, `mysql`, `mariadb`. | `postgres` |
385
384
  | DB_TTL (npm: db.ttl) | TTL for the code, session and token stores (in seconds). | 300 |
386
385
  | DB_CLEANUP_LIMIT (npm: db.cleanupLimit) | Limit cleanup of TTL entries to this number. | 1000 |
387
386
  | DB_ENCRYPTION_KEY (npm: db.encryptionKey) | To encrypt data at rest specify a 32 character key. | |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxyhq/saml-jackson",
3
- "version": "0.2.3-beta.231",
3
+ "version": "0.2.3-beta.235",
4
4
  "license": "Apache 2.0",
5
5
  "description": "SAML 2.0 service",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,8 @@
25
25
  "pre-loaded-db": "cross-env JACKSON_API_KEYS=secret PRE_LOADED_CONFIG='./_config' nodemon --config nodemon.json src/jackson.ts",
26
26
  "test": "tap --ts --timeout=100 src/**/*.test.ts",
27
27
  "dev-dbs": "docker-compose -f ./_dev/docker-compose.yml up -d",
28
- "dev-dbs-destroy": "docker-compose -f ./_dev/docker-compose.yml down --volumes --remove-orphans"
28
+ "dev-dbs-destroy": "docker-compose -f ./_dev/docker-compose.yml down --volumes --remove-orphans",
29
+ "db:migration:generate": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n Initial"
29
30
  },
30
31
  "tap": {
31
32
  "coverage-map": "map.js",
@@ -54,6 +55,8 @@
54
55
  "xmlbuilder": "15.1.1"
55
56
  },
56
57
  "devDependencies": {
58
+ "@types/express": "^4.17.13",
59
+ "@types/node": "^16.11.17",
57
60
  "@types/redis": "4.0.11",
58
61
  "@types/sinon": "10.0.6",
59
62
  "@types/tap": "15.0.5",
@@ -69,10 +72,15 @@
69
72
  "sinon": "12.0.1",
70
73
  "tap": "15.1.5",
71
74
  "ts-node": "10.4.0",
72
- "typescript": "^4.5.4"
75
+ "tsconfig-paths": "3.12.0",
76
+ "typescript": "4.5.4"
73
77
  },
74
78
  "lint-staged": {
75
79
  "*.{js,ts}": "eslint --cache --fix",
76
80
  "*.{js,ts,css,md}": "prettier --write"
77
- }
81
+ },
82
+ "files": [
83
+ "dist",
84
+ "Dockerfile"
85
+ ]
78
86
  }
package/ nodemon.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "restartable": "rs",
3
- "ignore": [".git", "node_modules/", "dist/", "coverage/"],
4
- "watch": ["src/"],
5
- "execMap": {
6
- "ts": "node -r ts-node/register"
7
- },
8
- "env": {
9
- "NODE_ENV": "development"
10
- },
11
- "ext": "js,json,ts"
12
- }
package/.dockerignore DELETED
@@ -1,2 +0,0 @@
1
- node_modules
2
- npm-debug.log
package/.eslintrc.js DELETED
@@ -1,18 +0,0 @@
1
- module.exports = {
2
- env: {
3
- es2021: true,
4
- node: true,
5
- },
6
- parserOptions: {
7
- ecmaVersion: 13,
8
- sourceType: 'module',
9
- },
10
- root: true,
11
- parser: '@typescript-eslint/parser',
12
- plugins: ['@typescript-eslint'],
13
- extends: [
14
- 'eslint:recommended',
15
- 'plugin:@typescript-eslint/recommended',
16
- 'prettier',
17
- ],
18
- };
@@ -1,27 +0,0 @@
1
- ---
2
- name: Bug report
3
- about: Report any issues with the platform
4
- title: ""
5
- labels: bug
6
- assignees: ""
7
- ---
8
-
9
- Found a bug? Please fill out the sections below. 👍
10
-
11
- ### Issue Summary
12
-
13
- A summary of the issue. This needs to be a clear detailed-rich summary.
14
-
15
- ### Steps to Reproduce
16
-
17
- 1. (for example) Went to ...
18
- 2. Clicked on...
19
- 3. ...
20
-
21
- Any other relevant information. For example, why do you consider this a bug and what did you expect to happen instead?
22
-
23
- ### Technical details
24
-
25
- - Browser version: You can use https://www.whatsmybrowser.org/ to find this out.
26
- - Node.js version
27
- - Anything else that you think could be an issue.
@@ -1,5 +0,0 @@
1
- blank_issues_enabled: false
2
- contact_links:
3
- - name: Questions
4
- url: https://github.com/boxyhq/jackson/discussions
5
- about: Ask a general question about the project on our GitHub Discussion page
@@ -1,43 +0,0 @@
1
- ---
2
- name: Feature request
3
- about: Suggest a feature or idea
4
- title: ""
5
- labels: enhancement
6
- assignees: ""
7
- ---
8
-
9
- > Please check if your Feature Request has not been already raised in the [Discussions Tab](https://github.com/boxyhq/jackson/discussions), as we would like to reduce duplicates. If it has been already raised, simply upvote it 🔼.
10
-
11
- ### Is your proposal related to a problem?
12
-
13
- <!--
14
- Provide a clear and concise description of what the problem is.
15
- For example, "I'm always frustrated when..."
16
- -->
17
-
18
- (Write your answer here.)
19
-
20
- ### Describe the solution you'd like
21
-
22
- <!--
23
- Provide a clear and concise description of what you want to happen.
24
- -->
25
-
26
- (Describe your proposed solution here.)
27
-
28
- ### Describe alternatives you've considered
29
-
30
- <!--
31
- Let us know about other solutions you've tried or researched.
32
- -->
33
-
34
- (Write your answer here.)
35
-
36
- ### Additional context
37
-
38
- <!--
39
- Is there anything else you can add about the proposal?
40
- You might want to link to related issues here, if you haven't already.
41
- -->
42
-
43
- (Write your answer here.)
@@ -1,31 +0,0 @@
1
- ## What does this PR do?
2
-
3
- <!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->
4
-
5
- Fixes # (issue)
6
-
7
- ## Type of change
8
-
9
- <!-- Please delete options that are not relevant. -->
10
-
11
- - [ ] Bug fix (non-breaking change which fixes an issue)
12
- - [ ] New feature (non-breaking change which adds functionality)
13
- - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
14
- - [ ] This change requires a documentation update
15
-
16
- ## How should this be tested?
17
-
18
- <!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration -->
19
-
20
- - [ ] Test A
21
- - [ ] Test B
22
-
23
- ## Checklist:
24
-
25
- - [ ] My code follows the style guidelines of this project
26
- - [ ] I have performed a self-review of my own code and corrected any misspellings
27
- - [ ] I have commented my code, particularly in hard-to-understand areas
28
- - [ ] I have made corresponding changes to the documentation
29
- - [ ] My changes generate no new warnings
30
- - [ ] I have added tests that prove my fix is effective or that my feature works
31
- - [ ] New and existing unit tests pass locally with my changes
@@ -1,81 +0,0 @@
1
- on:
2
- push:
3
- branches:
4
- - main
5
- pull_request_target:
6
- types: [opened, synchronize, reopened]
7
-
8
- name: CodeSee Map
9
-
10
- jobs:
11
- test_map_action:
12
- runs-on: ubuntu-latest
13
- continue-on-error: true
14
- name: Run CodeSee Map Analysis
15
- steps:
16
- - name: checkout
17
- id: checkout
18
- uses: actions/checkout@v2
19
- with:
20
- repository: ${{ github.event.pull_request.head.repo.full_name }}
21
- ref: ${{ github.event.pull_request.head.ref }}
22
- fetch-depth: 0
23
-
24
- # codesee-detect-languages has an output with id languages.
25
- - name: Detect Languages
26
- id: detect-languages
27
- uses: Codesee-io/codesee-detect-languages-action@latest
28
-
29
- - name: Configure JDK 16
30
- uses: actions/setup-java@v2
31
- if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }}
32
- with:
33
- java-version: '16'
34
- distribution: 'zulu'
35
-
36
- # CodeSee Maps Go support uses a static binary so there's no setup step required.
37
-
38
- - name: Configure Node.js 14
39
- uses: actions/setup-node@v2
40
- if: ${{ fromJSON(steps.detect-languages.outputs.languages).javascript }}
41
- with:
42
- node-version: '14'
43
-
44
- - name: Configure Python 3.x
45
- uses: actions/setup-python@v2
46
- if: ${{ fromJSON(steps.detect-languages.outputs.languages).python }}
47
- with:
48
- python-version: '3.x'
49
- architecture: 'x64'
50
-
51
- - name: Configure Ruby '3.x'
52
- uses: ruby/setup-ruby@v1
53
- if: ${{ fromJSON(steps.detect-languages.outputs.languages).ruby }}
54
- with:
55
- ruby-version: '3.0'
56
-
57
- # CodeSee Maps Rust support uses a static binary so there's no setup step required.
58
-
59
- - name: Generate Map
60
- id: generate-map
61
- uses: Codesee-io/codesee-map-action@latest
62
- with:
63
- step: map
64
- github_ref: ${{ github.ref }}
65
- languages: ${{ steps.detect-languages.outputs.languages }}
66
-
67
- - name: Upload Map
68
- id: upload-map
69
- uses: Codesee-io/codesee-map-action@latest
70
- with:
71
- step: mapUpload
72
- api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
73
- github_ref: ${{ github.ref }}
74
-
75
- - name: Insights
76
- id: insights
77
- uses: Codesee-io/codesee-map-action@latest
78
- with:
79
- step: insights
80
- api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
81
- github_ref: ${{ github.ref }}
@@ -1,123 +0,0 @@
1
- # This is a basic workflow to help you get started with Actions
2
-
3
- name: CI
4
-
5
- # Controls when the workflow will run
6
- on:
7
- # Triggers the workflow on push or pull request events but only for the main branch
8
- push:
9
- branches:
10
- - '*'
11
- pull_request:
12
- types: [opened, synchronize, reopened]
13
-
14
- # Allows you to run this workflow manually from the Actions tab
15
- workflow_dispatch:
16
-
17
- # A workflow run is made up of one or more jobs that can run sequentially or in parallel
18
- jobs:
19
- publish:
20
- runs-on: ubuntu-latest
21
-
22
- strategy:
23
- matrix:
24
- node-version: [16.x]
25
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
26
-
27
- services:
28
- postgres:
29
- image: postgres:13
30
- ports:
31
- - 5432:5432
32
- env:
33
- POSTGRES_PASSWORD: ""
34
- POSTGRES_HOST_AUTH_METHOD: "trust"
35
- # Set health checks to wait until postgres has started
36
- options: >-
37
- --health-cmd pg_isready
38
- --health-interval 10s
39
- --health-timeout 5s
40
- --health-retries 5
41
- redis:
42
- image: redis:6.2.5-alpine
43
- ports:
44
- - 6379:6379
45
- mongo:
46
- image: mongo:4.4.10
47
- ports:
48
- - 27017:27017
49
- mysql:
50
- image: mysql:5.7
51
- ports:
52
- - 3307:3306
53
- env:
54
- MYSQL_DATABASE: mysql
55
- MYSQL_ROOT_PASSWORD: mysql
56
- maria:
57
- image: mariadb:10.4.22
58
- ports:
59
- - 3306:3306
60
- env:
61
- MARIADB_DATABASE: mysql
62
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "yes"
63
-
64
- steps:
65
- - uses: actions/checkout@v2
66
- - name: Use Node.js ${{ matrix.node-version }}
67
- uses: actions/setup-node@v2
68
- with:
69
- always-auth: true
70
- node-version: ${{ matrix.node-version }}
71
- registry-url: https://registry.npmjs.org
72
- scope: '@boxyhq'
73
- cache: 'npm'
74
- - run: npm ci
75
- - run: npm run test
76
- - run: |
77
- publishTag="latest"
78
- if [[ "$GITHUB_REF" == *\/release ]]
79
- then
80
- echo "Release branch"
81
- else
82
- echo "Dev branch"
83
- publishTag="beta"
84
- versionSuffixTag="-beta.${GITHUB_RUN_NUMBER}"
85
- sed "s/\(^[ ]*\"version\"\:[ ]*\".*\)\",/\1${versionSuffixTag}\",/" < package.json > package.json.new
86
- mv package.json.new package.json
87
- fi
88
- npm publish --tag $publishTag --access public
89
- env:
90
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
91
- build:
92
- needs: publish
93
- runs-on: ubuntu-latest
94
-
95
- steps:
96
- - name: Check Out Repo
97
- uses: actions/checkout@v2
98
-
99
- - name: Get short SHA
100
- id: slug
101
- run: echo "::set-output name=sha7::$(echo ${GITHUB_SHA} | cut -c1-7)"
102
-
103
- - name: Set up Docker Buildx
104
- id: buildx
105
- uses: docker/setup-buildx-action@v1
106
-
107
- - name: Login to Docker Hub
108
- uses: docker/login-action@v1
109
- with:
110
- username: ${{ secrets.DOCKER_HUB_USERNAME }}
111
- password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
112
-
113
- - name: Build and push
114
- id: docker_build
115
- uses: docker/build-push-action@v2
116
- with:
117
- context: ./
118
- file: ./Dockerfile
119
- push: true
120
- tags: ${{ github.repository }}:latest,${{ github.repository }}:${{ steps.slug.outputs.sha7 }}
121
-
122
- - name: Image digest
123
- run: echo ${{ steps.docker_build.outputs.digest }}
@@ -1,37 +0,0 @@
1
- # this file is a helper to run all the supported dbs locally, the data is ephemeral since no host volumes will be mounted
2
- version: "3.6"
3
- services:
4
- postgres:
5
- image: postgres:13
6
- ports:
7
- - "5432:5432"
8
- restart: always
9
- environment:
10
- POSTGRES_PASSWORD: ""
11
- POSTGRES_HOST_AUTH_METHOD: trust
12
- redis:
13
- image: redis:6.2.5-alpine
14
- ports:
15
- - "6379:6379"
16
- restart: always
17
- mongo:
18
- image: mongo:4.4.10
19
- ports:
20
- - "27017:27017"
21
- restart: always
22
- mysql:
23
- image: mysql:5.7
24
- ports:
25
- - "3307:3306"
26
- restart: always
27
- environment:
28
- MYSQL_DATABASE: mysql
29
- MYSQL_ROOT_PASSWORD: mysql
30
- maria:
31
- image: mariadb:10.4.22
32
- ports:
33
- - "3306:3306"
34
- restart: always
35
- environment:
36
- MARIADB_DATABASE: mysql
37
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "yes"
package/map.js DELETED
@@ -1 +0,0 @@
1
- module.exports = (test) => test.replace(/\.test\.js$/, '.js');
@@ -1,4 +0,0 @@
1
- module.exports = {
2
- singleQuote: true,
3
- trailingComma: 'es5',
4
- };
@@ -1,225 +0,0 @@
1
- import crypto from 'crypto';
2
- import { IdPConfig, ISAMLConfig, OAuth, Storable } from 'saml-jackson';
3
- import * as dbutils from '../db/utils';
4
- import saml from '../saml/saml';
5
- import { JacksonError } from './error';
6
- import { IndexNames } from './utils';
7
- import x509 from '../saml/x509';
8
-
9
- export class SAMLConfig implements ISAMLConfig {
10
- private configStore: Storable;
11
-
12
- constructor({ configStore }) {
13
- this.configStore = configStore;
14
- }
15
-
16
- private _validateIdPConfig(body: IdPConfig): void {
17
- const { rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product } =
18
- body;
19
-
20
- if (!rawMetadata) {
21
- throw new JacksonError('Please provide rawMetadata', 400);
22
- }
23
-
24
- if (!defaultRedirectUrl) {
25
- throw new JacksonError('Please provide a defaultRedirectUrl', 400);
26
- }
27
-
28
- if (!redirectUrl) {
29
- throw new JacksonError('Please provide redirectUrl', 400);
30
- }
31
-
32
- if (!tenant) {
33
- throw new JacksonError('Please provide tenant', 400);
34
- }
35
-
36
- if (!product) {
37
- throw new JacksonError('Please provide product', 400);
38
- }
39
- }
40
-
41
- public async create(body: IdPConfig): Promise<OAuth> {
42
- const { rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product } =
43
- body;
44
-
45
- this._validateIdPConfig(body);
46
-
47
- const idpMetadata = await saml.parseMetadataAsync(rawMetadata);
48
-
49
- // extract provider
50
- let providerName = extractHostName(idpMetadata.entityID);
51
- if (!providerName) {
52
- providerName = extractHostName(
53
- idpMetadata.sso.redirectUrl || idpMetadata.sso.postUrl
54
- );
55
- }
56
-
57
- idpMetadata.provider = providerName ? providerName : 'Unknown';
58
-
59
- const clientID = dbutils.keyDigest(
60
- dbutils.keyFromParts(tenant, product, idpMetadata.entityID)
61
- );
62
-
63
- let clientSecret;
64
-
65
- const exists = await this.configStore.get(clientID);
66
-
67
- if (exists) {
68
- clientSecret = exists.clientSecret;
69
- } else {
70
- clientSecret = crypto.randomBytes(24).toString('hex');
71
- }
72
-
73
- const certs = await x509.generate();
74
-
75
- if (!certs) {
76
- throw new Error('Error generating x59 certs');
77
- }
78
-
79
- await this.configStore.put(
80
- clientID,
81
- {
82
- idpMetadata,
83
- defaultRedirectUrl,
84
- redirectUrl: JSON.parse(redirectUrl), // redirectUrl is a stringified array
85
- tenant,
86
- product,
87
- clientID,
88
- clientSecret,
89
- certs,
90
- },
91
- {
92
- // secondary index on entityID
93
- name: IndexNames.EntityID,
94
- value: idpMetadata.entityID,
95
- },
96
- {
97
- // secondary index on tenant + product
98
- name: IndexNames.TenantProduct,
99
- value: dbutils.keyFromParts(tenant, product),
100
- }
101
- );
102
-
103
- return {
104
- client_id: clientID,
105
- client_secret: clientSecret,
106
- provider: idpMetadata.provider,
107
- };
108
- }
109
-
110
- public async get(body: {
111
- clientID: string;
112
- tenant: string;
113
- product: string;
114
- }): Promise<Partial<OAuth>> {
115
- const { clientID, tenant, product } = body;
116
-
117
- if (clientID) {
118
- const samlConfig = await this.configStore.get(clientID);
119
-
120
- return samlConfig ? { provider: samlConfig.idpMetadata.provider } : {};
121
- }
122
-
123
- if (tenant && product) {
124
- const samlConfigs = await this.configStore.getByIndex({
125
- name: IndexNames.TenantProduct,
126
- value: dbutils.keyFromParts(tenant, product),
127
- });
128
-
129
- if (!samlConfigs || !samlConfigs.length) {
130
- return {};
131
- }
132
-
133
- return { provider: samlConfigs[0].idpMetadata.provider };
134
- }
135
-
136
- throw new JacksonError(
137
- 'Please provide `clientID` or `tenant` and `product`.',
138
- 400
139
- );
140
- }
141
-
142
- public async delete(body: {
143
- clientID: string;
144
- clientSecret: string;
145
- tenant: string;
146
- product: string;
147
- }): Promise<void> {
148
- const { clientID, clientSecret, tenant, product } = body;
149
-
150
- if (clientID && clientSecret) {
151
- const samlConfig = await this.configStore.get(clientID);
152
-
153
- if (!samlConfig) {
154
- return;
155
- }
156
-
157
- if (samlConfig.clientSecret === clientSecret) {
158
- await this.configStore.delete(clientID);
159
- } else {
160
- throw new JacksonError('clientSecret mismatch.', 400);
161
- }
162
-
163
- return;
164
- }
165
-
166
- if (tenant && product) {
167
- const samlConfigs = await this.configStore.getByIndex({
168
- name: IndexNames.TenantProduct,
169
- value: dbutils.keyFromParts(tenant, product),
170
- });
171
-
172
- if (!samlConfigs || !samlConfigs.length) {
173
- return;
174
- }
175
-
176
- for (const conf of samlConfigs) {
177
- await this.configStore.delete(conf.clientID);
178
- }
179
-
180
- return;
181
- }
182
-
183
- throw new JacksonError(
184
- 'Please provide `clientID` and `clientSecret` or `tenant` and `product`.',
185
- 400
186
- );
187
- }
188
-
189
- // Ensure backward compatibility
190
-
191
- async config(body: IdPConfig): Promise<OAuth> {
192
- return this.create(body);
193
- }
194
-
195
- async getConfig(body: {
196
- clientID: string;
197
- tenant: string;
198
- product: string;
199
- }): Promise<Partial<OAuth>> {
200
- return this.get(body);
201
- }
202
-
203
- async deleteConfig(body: {
204
- clientID: string;
205
- clientSecret: string;
206
- tenant: string;
207
- product: string;
208
- }): Promise<void> {
209
- return this.delete(body);
210
- }
211
- }
212
-
213
- const extractHostName = (url: string): string | null => {
214
- try {
215
- const pUrl = new URL(url);
216
-
217
- if (pUrl.hostname.startsWith('www.')) {
218
- return pUrl.hostname.substring(4);
219
- }
220
-
221
- return pUrl.hostname;
222
- } catch (err) {
223
- return null;
224
- }
225
- };