Compare commits

...

28 Commits

Author SHA1 Message Date
Deepak Prabhakara 55d8f14d40 Merge branch 'main' into identity-fed-routes 2024-05-06 12:41:13 +01:00
Aswin V 9943a06ace
Extend e2e (#2601)
* Not needed with standalone build in CI as well as local runs

* Start adding tests for main sections under Admin UI

* Add SAML SSO connection

* Remove only

* Debug failing test

* Cleanup debugging changes

* Update mocksaml docker

* Increase number of workers for playwright execution

* Disable multiple workers for now

* Align folder layout with sidebar features

* Enable stdout for webserver

* Try fixture

* Fixture WIP

* WIP fixture tweak and add more test cases

* Fix locator

* Rename test file

* Remove only

* Keep track of connections inside fixture, delete all method fix

* Fix sso naming

* Use portal fixture for common utils

* Make fixture generic for OIDC SSO

* Add OIDC porvider tests

* Comment tweak

* Make client id secret dynamic

* Spec for OAuth2 wrapper + 1 SAML and 1 OIDC providers

* Fixture method to update SSO connection

* Test case for wrong redirect url

* Refactor

* WIP Wrong redirect url test for OIDC provider plus
setup for toggle connection

* WIP inactive connection test

* Set env for credentials login

* Add credentials login to portal fixture

* Fixes
2024-05-06 12:37:12 +01:00
Deepak Prabhakara f08025cc31 updated deployment 2024-05-06 12:36:58 +01:00
Deepak Prabhakara 63baf12a38 Release 1.23.7 2024-05-06 09:16:09 +01:00
Deepak Prabhakara 668a1ba499
Stats for Identity Federation Apps (#2671)
rename
2024-05-06 00:13:25 +01:00
Deepak Prabhakara b6adc308f7 updated package-lock 2024-05-04 23:23:49 +01:00
dependabot[bot] bbcea282f8
Bump @aws-sdk/credential-providers from 3.568.0 to 3.569.0 in /npm (#2669)
Bumps [@aws-sdk/credential-providers](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-providers) from 3.568.0 to 3.569.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-providers/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.569.0/packages/credential-providers)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-providers"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:30:23 +01:00
dependabot[bot] 143ab81eea
Bump @googleapis/admin from 17.1.0 to 18.0.0 in /npm (#2667)
Bumps [@googleapis/admin](https://github.com/googleapis/google-api-nodejs-client) from 17.1.0 to 18.0.0.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/17.1.0...iam-v18.0.0)

---
updated-dependencies:
- dependency-name: "@googleapis/admin"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:30:16 +01:00
dependabot[bot] 14e222163c
Bump @boxyhq/saml20 from 1.5.0 to 1.5.1 in /npm (#2668)
Bumps [@boxyhq/saml20](https://github.com/boxyhq/saml20) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/boxyhq/saml20/releases)
- [Changelog](https://github.com/boxyhq/saml20/blob/main/.release-it.json)
- [Commits](https://github.com/boxyhq/saml20/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: "@boxyhq/saml20"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:01:33 +01:00
dependabot[bot] 571a2d1f0f
Bump @aws-sdk/util-dynamodb from 3.568.0 to 3.569.0 in /npm (#2670)
Bumps [@aws-sdk/util-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/util-dynamodb) from 3.568.0 to 3.569.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/util-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.569.0/packages/util-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/util-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:01:09 +01:00
dependabot[bot] a6e993d1c8
Bump @retracedhq/logs-viewer from 2.7.3 to 2.7.4 (#2662)
Bumps [@retracedhq/logs-viewer](https://github.com/retracedhq/logs-viewer) from 2.7.3 to 2.7.4.
- [Release notes](https://github.com/retracedhq/logs-viewer/releases)
- [Changelog](https://github.com/retracedhq/logs-viewer/blob/main/.release-it.json)
- [Commits](https://github.com/retracedhq/logs-viewer/compare/v2.7.3...v2.7.4)

---
updated-dependencies:
- dependency-name: "@retracedhq/logs-viewer"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:01:00 +01:00
dependabot[bot] bd2dc3d382
Bump @boxyhq/metrics from 0.2.6 to 0.2.7 in /npm (#2666)
Bumps [@boxyhq/metrics](https://github.com/boxyhq/metrics) from 0.2.6 to 0.2.7.
- [Release notes](https://github.com/boxyhq/metrics/releases)
- [Changelog](https://github.com/boxyhq/metrics/blob/main/.release-it.json)
- [Commits](https://github.com/boxyhq/metrics/compare/v0.2.6...v0.2.7)

---
updated-dependencies:
- dependency-name: "@boxyhq/metrics"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:24:19 +01:00
dependabot[bot] de83010f93
Bump @aws-sdk/client-dynamodb from 3.568.0 to 3.569.0 in /npm (#2665)
Bumps [@aws-sdk/client-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-dynamodb) from 3.568.0 to 3.569.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.569.0/clients/client-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:24:11 +01:00
dependabot[bot] 6f14494078
Bump mongodb from 6.5.0 to 6.6.0 in /npm (#2664)
Bumps [mongodb](https://github.com/mongodb/node-mongodb-native) from 6.5.0 to 6.6.0.
- [Release notes](https://github.com/mongodb/node-mongodb-native/releases)
- [Changelog](https://github.com/mongodb/node-mongodb-native/blob/main/HISTORY.md)
- [Commits](https://github.com/mongodb/node-mongodb-native/compare/v6.5.0...v6.6.0)

---
updated-dependencies:
- dependency-name: mongodb
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:15:12 +01:00
dependabot[bot] 71f5a31e0b
Bump @types/lodash from 4.17.0 to 4.17.1 in /npm (#2663)
Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.0 to 4.17.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash)

---
updated-dependencies:
- dependency-name: "@types/lodash"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:15:08 +01:00
dependabot[bot] 7fd15f5b7b
Bump @aws-sdk/util-dynamodb from 3.567.0 to 3.568.0 in /npm (#2661)
Bumps [@aws-sdk/util-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/util-dynamodb) from 3.567.0 to 3.568.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/util-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.568.0/packages/util-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/util-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:14:50 +01:00
dependabot[bot] c0737a20bc
Bump @retracedhq/retraced from 0.7.9 to 0.7.10 (#2660)
Bumps [@retracedhq/retraced](https://github.com/retracedhq/retraced-js) from 0.7.9 to 0.7.10.
- [Release notes](https://github.com/retracedhq/retraced-js/releases)
- [Changelog](https://github.com/retracedhq/retraced-js/blob/main/CHANGELOG)
- [Commits](https://github.com/retracedhq/retraced-js/compare/v0.7.9...v0.7.10)

---
updated-dependencies:
- dependency-name: "@retracedhq/retraced"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 14:14:47 +01:00
dependabot[bot] f3efcdd2ce
Bump @aws-sdk/credential-providers from 3.567.0 to 3.568.0 in /npm (#2655)
Bumps [@aws-sdk/credential-providers](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-providers) from 3.567.0 to 3.568.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-providers/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.568.0/packages/credential-providers)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-providers"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 16:08:38 +01:00
dependabot[bot] 252c8cf775
Bump @aws-sdk/client-dynamodb from 3.567.0 to 3.568.0 in /npm (#2654)
Bumps [@aws-sdk/client-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-dynamodb) from 3.567.0 to 3.568.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.568.0/clients/client-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 12:34:07 +01:00
dependabot[bot] db63d6309f
Bump @aws-sdk/util-dynamodb from 3.565.0 to 3.567.0 in /npm (#2656)
Bumps [@aws-sdk/util-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/util-dynamodb) from 3.565.0 to 3.567.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/util-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.567.0/packages/util-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/util-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 12:33:59 +01:00
dependabot[bot] 08a70476db
Bump @googleapis/admin from 17.0.0 to 17.1.0 in /npm (#2657)
Bumps [@googleapis/admin](https://github.com/googleapis/google-api-nodejs-client) from 17.0.0 to 17.1.0.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/17.1.0/CHANGELOG.md)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/iam-v17.0.0...17.1.0)

---
updated-dependencies:
- dependency-name: "@googleapis/admin"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 12:33:55 +01:00
dependabot[bot] 9e1f149983
Bump vite from 5.2.10 to 5.2.11 in /internal-ui (#2658)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.2.10 to 5.2.11.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.2.11/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 12:33:52 +01:00
dependabot[bot] bedcba0fe5
Bump daisyui from 4.10.3 to 4.10.5 (#2659)
Bumps [daisyui](https://github.com/saadeghi/daisyui) from 4.10.3 to 4.10.5.
- [Release notes](https://github.com/saadeghi/daisyui/releases)
- [Changelog](https://github.com/saadeghi/daisyui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/saadeghi/daisyui/compare/v4.10.3...v4.10.5)

---
updated-dependencies:
- dependency-name: daisyui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 12:33:48 +01:00
dependabot[bot] 7022aa68e1
Bump @types/node from 20.12.7 to 20.12.8 in /npm (#2648)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.7 to 20.12.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:16:19 +01:00
dependabot[bot] 49c611a09a
Bump @aws-sdk/client-dynamodb from 3.565.0 to 3.567.0 in /npm (#2649)
Bumps [@aws-sdk/client-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-dynamodb) from 3.565.0 to 3.567.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-dynamodb/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.567.0/clients/client-dynamodb)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-dynamodb"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:16:14 +01:00
dependabot[bot] a8c14dec7a
Bump @aws-sdk/credential-providers from 3.565.0 to 3.567.0 in /npm (#2650)
Bumps [@aws-sdk/credential-providers](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-providers) from 3.565.0 to 3.567.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-providers/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.567.0/packages/credential-providers)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-providers"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:04:00 +01:00
dependabot[bot] 3ee670f057
Bump @types/node from 20.12.7 to 20.12.8 in /internal-ui (#2651)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.7 to 20.12.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:03:55 +01:00
dependabot[bot] 044f452945
Bump daisyui from 4.10.2 to 4.10.3 (#2652)
Bumps [daisyui](https://github.com/saadeghi/daisyui) from 4.10.2 to 4.10.3.
- [Release notes](https://github.com/saadeghi/daisyui/releases)
- [Changelog](https://github.com/saadeghi/daisyui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/saadeghi/daisyui/compare/v4.10.2...v4.10.3)

---
updated-dependencies:
- dependency-name: daisyui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:03:51 +01:00
20 changed files with 1446 additions and 2571 deletions

View File

@ -111,7 +111,7 @@ jobs:
ports:
- '8000:8000'
mocksaml:
image: boxyhq/mock-saml:1.2.0
image: boxyhq/mock-saml:1.3.9
ports:
- 4000:4000
env:

View File

@ -0,0 +1,2 @@
export { Portal } from './portal';
export { SSOPage } from './sso-page';

View File

@ -0,0 +1,20 @@
import { Locator, Page, expect } from '@playwright/test';
export class Portal {
userAvatarLocator: Locator;
constructor(public readonly page: Page) {
this.userAvatarLocator = this.page.getByTestId('user-avatar');
}
async doCredentialsLogin() {
await this.page.goto('/admin/auth/login');
await this.page.getByPlaceholder('Email').fill('super@boxyhq.com');
await this.page.getByPlaceholder('Password').fill('999login');
await this.page.getByRole('button', { name: 'Sign In' }).click();
}
async isLoggedIn() {
// assert login state
await expect(this.userAvatarLocator).toBeVisible();
}
}

View File

@ -0,0 +1,178 @@
import type { Page, Locator } from '@playwright/test';
import { adminPortalSSODefaults } from '@lib/env';
const ADMIN_PORTAL_TENANT = adminPortalSSODefaults.tenant;
const ADMIN_PORTAL_PRODUCT = adminPortalSSODefaults.product;
const MOCKSAML_ORIGIN = process.env.MOCKSAML_ORIGIN || 'https://mocksaml.com';
const MOCKSAML_SIGNIN_BUTTON_NAME = 'Sign In';
const MOCKLAB_ORIGIN = 'https://oauth.wiremockapi.cloud';
const MOCKLAB_CLIENT_ID = 'mocklab_oauth2';
const MOCKLAB_CLIENT_SECRET = 'mocklab_secret';
const MOCKLAB_SIGNIN_BUTTON_NAME = 'Login';
const MOCKLAB_DISCOVERY_ENDPOINT = 'https://oauth.wiremockapi.cloud/.well-known/openid-configuration';
export class SSOPage {
private readonly createConnection: Locator;
private readonly nameInput: Locator;
private readonly tenantInput: Locator;
private readonly productInput: Locator;
private readonly redirectURLSInput: Locator;
private readonly defaultRedirectURLInput: Locator;
private readonly metadataUrlInput: Locator;
private readonly oidcDiscoveryUrlInput: Locator;
private readonly oidcClientIdInput: Locator;
private readonly oidcClientSecretInput: Locator;
private readonly saveConnection: Locator;
private readonly deleteButton: Locator;
private readonly confirmButton: Locator;
private readonly toggleConnectionStatusCheckbox: Locator;
private readonly toggleConnectionStatusLabel: Locator;
private connections: string[];
constructor(public readonly page: Page) {
this.connections = [];
this.createConnection = this.page.getByTestId('create-connection');
this.nameInput = this.page.getByLabel('Connection name (Optional)');
this.tenantInput = this.page.getByLabel('Tenant');
this.productInput = this.page.getByLabel('Product');
this.redirectURLSInput = page
.getByRole('group')
.filter({ hasText: 'Allowed redirect URLs' })
.locator(page.getByRole('textbox').first());
this.defaultRedirectURLInput = this.page.getByLabel('Default redirect URL');
this.metadataUrlInput = this.page.getByLabel('Metadata URL');
this.oidcDiscoveryUrlInput = this.page.getByLabel('Well-known URL of OpenID Provider');
this.oidcClientIdInput = this.page.getByLabel('Client ID');
this.oidcClientSecretInput = this.page.getByLabel('Client Secret');
this.saveConnection = this.page.getByRole('button', { name: /save/i });
this.toggleConnectionStatusCheckbox = this.page.getByRole('checkbox', { name: 'Active' });
this.toggleConnectionStatusLabel = this.page.locator('label').filter({ hasText: 'Active' });
this.deleteButton = this.page.getByRole('button', { name: 'Delete' });
this.confirmButton = this.page.getByRole('button', { name: 'Confirm' });
}
async goto() {
const url = new URL(this.page.url());
if (url.pathname !== '/admin/sso-connection') {
await this.page.goto('/admin/sso-connection');
}
}
async addSSOConnection({
name,
type = 'saml',
baseURL,
}: {
name: string;
type: 'saml' | 'oidc';
baseURL: string;
}) {
const connectionIndex = this.connections.length + 1;
const ssoName = `${name}-${connectionIndex}`;
// Find the new connection button and click on it
await this.createConnection.click();
if (type === 'oidc') {
// Toggle connection type to OIDC
await this.page.getByLabel('OIDC').check();
}
// Fill the name for the connection
await this.nameInput.fill(ssoName);
// Fill the tenant for the connection
await this.tenantInput.fill(ADMIN_PORTAL_TENANT);
// Fill the product for the connection
await this.productInput.fill(ADMIN_PORTAL_PRODUCT);
// Fill the Allowed redirect URLs for the connection
await this.redirectURLSInput.fill(baseURL!);
// Fill the default redirect URLs for the connection
await this.defaultRedirectURLInput.fill(`${baseURL}/admin/auth/idp-login`);
if (type === 'saml') {
// Enter the metadata url for mocksaml in the form
await this.metadataUrlInput.fill(`${MOCKSAML_ORIGIN}/api/namespace/${ssoName}/saml/metadata`);
}
if (type === 'oidc') {
// Enter the OIDC client credentials for mocklab in the form
await this.oidcClientIdInput.fill(`${MOCKLAB_CLIENT_ID}-${connectionIndex}`);
await this.oidcClientSecretInput.fill(`${MOCKLAB_CLIENT_SECRET}-${connectionIndex}`);
// Enter the OIDC discovery url for mocklab in the form
await this.oidcDiscoveryUrlInput.fill(MOCKLAB_DISCOVERY_ENDPOINT);
}
// submit the form
await this.saveConnection.click();
this.connections = [...this.connections, ssoName];
}
async gotoEditView(name: string) {
await this.goto();
const editButton = this.page.getByText(name).locator('xpath=..').getByLabel('Edit');
await editButton.click();
}
async toggleConnectionStatus(newStatus: boolean) {
const isChecked = await this.toggleConnectionStatusCheckbox.isChecked();
if (isChecked && !newStatus) {
await this.toggleConnectionStatusLabel.click();
await this.confirmButton.click();
} else if (!isChecked && newStatus) {
await this.toggleConnectionStatusLabel.click();
await this.confirmButton.click();
}
}
async updateSSOConnection({ name, url, newStatus }: { name: string; url: string; newStatus?: boolean }) {
await this.gotoEditView(name);
await this.redirectURLSInput.fill(url);
await this.saveConnection.click();
if (typeof newStatus === 'boolean') {
await this.gotoEditView(name);
await this.toggleConnectionStatus(newStatus);
}
}
async deleteSSOConnection(name: string) {
await this.gotoEditView(name);
// click the delete and confirm deletion
await this.deleteButton.click();
await this.confirmButton.click();
}
async deleteAllSSOConnections() {
let _connection;
while ((_connection = this.connections.shift())) {
await this.deleteSSOConnection(_connection);
}
}
async logout() {
const userAvatarLocator = this.page.getByTestId('user-avatar');
// Logout from the magic link authentication
await userAvatarLocator.click();
await this.page.getByTestId('logout').click();
}
async signInWithSSO() {
await this.page.getByTestId('sso-login-button').click();
}
async selectIdP(name: string) {
const idpSelectionTitle = 'Select an Identity Provider to continue';
await this.page.getByText(idpSelectionTitle).waitFor();
await this.page.getByRole('button', { name }).click();
}
async signInWithMockSAML() {
// Perform sign in at mocksaml
await this.page.waitForURL((url) => url.origin === MOCKSAML_ORIGIN);
await this.page.getByPlaceholder('jackson').fill('bob');
await this.page.getByRole('button', { name: MOCKSAML_SIGNIN_BUTTON_NAME }).click();
}
async signInWithMockLab() {
// Perform sign in at mocklab
await this.page.waitForURL((url) => url.origin === MOCKLAB_ORIGIN);
await this.page.getByPlaceholder('yours@example.com').fill('bob@oidc.com');
await this.page.getByRole('button', { name: MOCKLAB_SIGNIN_BUTTON_NAME }).click();
}
}

View File

@ -0,0 +1,110 @@
import { test as baseTest, expect } from '@playwright/test';
import { Portal, SSOPage } from 'e2e/support/fixtures';
type MyFixtures = {
ssoPage: SSOPage;
portal: Portal;
};
export const test = baseTest.extend<MyFixtures>({
portal: async ({ page }, use) => {
const portal = new Portal(page);
await use(portal);
},
ssoPage: async ({ page, portal }, use) => {
const ssoPage = new SSOPage(page);
await ssoPage.goto();
await use(ssoPage);
await portal.doCredentialsLogin();
await portal.isLoggedIn();
await ssoPage.deleteAllSSOConnections();
},
});
test('OAuth2 wrapper + SAML provider + wrong redirectUrl', async ({ ssoPage, page, baseURL }, testInfo) => {
const ssoName = `saml-${testInfo.workerIndex}`;
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
// check if the first added connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
await ssoPage.updateSSOConnection({
name: `${ssoName}-1`,
url: 'https://invalid-url.com',
});
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Wait for browser to redirect to error page
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
// Assert error text
await expect(page.getByText(`SSO error: Redirect URL is not allowed.`)).toBeVisible();
});
test('OAuth2 wrapper + SAML provider + inactive connection', async ({ ssoPage, page, baseURL }, testInfo) => {
const ssoName = `saml-${testInfo.workerIndex}`;
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
// check if the first added connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
await ssoPage.updateSSOConnection({
name: `${ssoName}-1`,
url: baseURL!,
newStatus: false,
});
// Confirm connection label inactive is displayed
await expect(
page.getByText(`${ssoName}-1`).locator('xpath=..').getByRole('cell', { name: 'Inactive', exact: true })
).toBeVisible();
// Logout and try to sign in with connection
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Wait for browser to redirect to error page
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
// Assert error text
await expect(
page.getByText('SSO error: SSO connection is deactivated. Please contact your administrator.')
).toBeVisible();
});
test('OAuth2 wrapper + OIDC provider + wrong redirectUrl', async ({ ssoPage, page, baseURL }, testInfo) => {
const ssoName = `oidc-${testInfo.workerIndex}`;
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
// check if the oidc connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
await ssoPage.updateSSOConnection({
name: `${ssoName}-1`,
url: 'https://invalid-url.com',
});
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Wait for browser to redirect to error page
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
// Assert error text
await expect(page.getByText('SSO error: Redirect URL is not allowed.')).toBeVisible();
});
test('OAuth2 wrapper + OIDC provider + inactive connection', async ({ ssoPage, page, baseURL }, testInfo) => {
const ssoName = `oidc-${testInfo.workerIndex}`;
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
// check if the oidc connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
await ssoPage.updateSSOConnection({
name: `${ssoName}-1`,
url: baseURL!,
newStatus: false,
});
// Confirm connection label inactive is displayed
await expect(
page.getByText(`${ssoName}-1`).locator('xpath=..').getByRole('cell', { name: 'Inactive', exact: true })
).toBeVisible();
// Logout and try to sign in with connection
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Wait for browser to redirect to error page
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
// Assert error text
await expect(
page.getByText('SSO error: SSO connection is deactivated. Please contact your administrator.')
).toBeVisible();
});

View File

@ -0,0 +1,57 @@
import { test as baseTest, expect } from '@playwright/test';
import { Portal, SSOPage } from 'e2e/support/fixtures';
type MyFixtures = {
ssoPage: SSOPage;
portal: Portal;
};
export const test = baseTest.extend<MyFixtures>({
ssoPage: async ({ page, baseURL }, use, testInfo) => {
const ssoPage = new SSOPage(page);
const ssoName = `oidc-${testInfo.workerIndex}`;
await ssoPage.goto();
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
await use(ssoPage);
await ssoPage.deleteAllSSOConnections();
},
portal: async ({ page }, use) => {
const portal = new Portal(page);
await use(portal);
},
});
test('OAuth2 wrapper + OIDC provider', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
// check if the first added connection appears in the connection list
await expect(page.getByText(`oidc-${testInfo.workerIndex}-1`)).toBeVisible();
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Login using MockLab
await ssoPage.signInWithMockLab();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
});
test('OAuth2 wrapper + 2 OIDC providers', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
const ssoName = `oidc-${testInfo.workerIndex}`;
// check if the first added connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
// Add second OIDC connection
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
// check if the second added connection appears in the connection list
await expect(page.getByText(`${ssoName}-2`)).toBeVisible();
// Logout of magic link login
await ssoPage.logout();
// Login using MockLab
await ssoPage.signInWithSSO();
// Select IdP from selection screen
await ssoPage.selectIdP(`${ssoName}-2`);
await ssoPage.signInWithMockLab();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
});

View File

@ -0,0 +1,62 @@
import { test as baseTest, expect } from '@playwright/test';
import { Portal, SSOPage } from 'e2e/support/fixtures';
type MyFixtures = {
ssoPage: SSOPage;
portal: Portal;
};
export const test = baseTest.extend<MyFixtures>({
ssoPage: async ({ page, baseURL }, use, testInfo) => {
const ssoPage = new SSOPage(page);
let ssoName = `saml-${testInfo.workerIndex}`;
await ssoPage.goto();
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
await ssoPage.goto();
ssoName = `oidc-${testInfo.workerIndex}`;
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
await use(ssoPage);
await ssoPage.deleteAllSSOConnections();
},
portal: async ({ page }, use) => {
const portal = new Portal(page);
await use(portal);
},
});
test('OAuth2 wrapper + SAML provider + OIDC provider', async ({
ssoPage,
portal,
page,
baseURL,
}, testInfo) => {
// check if the first added connection appears in the connection list
await expect(page.getByText(`saml-${testInfo.workerIndex}-1`)).toBeVisible();
// check if the second added connection appears in the connection list
await expect(page.getByText(`oidc-${testInfo.workerIndex}-2`)).toBeVisible();
// Logout of magic link login
await ssoPage.logout();
// Login using MockSAML
await ssoPage.signInWithSSO();
// Select IdP from selection screen
await ssoPage.selectIdP(`saml-${testInfo.workerIndex}-1`);
// Login using MockSAML
await ssoPage.signInWithMockSAML();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
// Logout of SAML login
await ssoPage.logout();
// Login using MockLab
await ssoPage.signInWithSSO();
// Select IdP from selection screen
await ssoPage.selectIdP(`oidc-${testInfo.workerIndex}-2`);
// Login using MockLab
await ssoPage.signInWithMockLab();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
});

View File

@ -0,0 +1,57 @@
import { test as baseTest, expect } from '@playwright/test';
import { Portal, SSOPage } from 'e2e/support/fixtures';
type MyFixtures = {
ssoPage: SSOPage;
portal: Portal;
};
export const test = baseTest.extend<MyFixtures>({
ssoPage: async ({ page, baseURL }, use, testInfo) => {
const ssoPage = new SSOPage(page);
const ssoName = `saml-${testInfo.workerIndex}`;
await ssoPage.goto();
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
await use(ssoPage);
await ssoPage.deleteAllSSOConnections();
},
portal: async ({ page }, use) => {
const portal = new Portal(page);
await use(portal);
},
});
test('OAuth2 wrapper + SAML provider', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
// check if the first added connection appears in the connection list
await expect(page.getByText(`saml-${testInfo.workerIndex}-1`)).toBeVisible();
// Logout of magic link login
await ssoPage.logout();
await ssoPage.signInWithSSO();
// Login using MockSAML
await ssoPage.signInWithMockSAML();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
});
test('OAuth2 wrapper + 2 SAML providers', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
const ssoName = `saml-${testInfo.workerIndex}`;
// check if the first added connection appears in the connection list
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
// Add second SAML connection
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
// check if the second added connection appears in the connection list
await expect(page.getByText(`${ssoName}-2`)).toBeVisible();
// Logout of magic link login
await ssoPage.logout();
// Login using MockSAML
await ssoPage.signInWithSSO();
// Select IdP from selection screen
await ssoPage.selectIdP(`${ssoName}-2`);
await ssoPage.signInWithMockSAML();
// Wait for browser to redirect back to admin portal
await page.waitForURL((url) => url.origin === baseURL);
// Assert logged in state
await portal.isLoggedIn();
});

View File

@ -75,7 +75,7 @@ test.describe('Admin Portal SSO - SAML', () => {
test('delete the SAML SSO connection', async ({ page }) => {
await page.goto('/admin/settings');
// select the row of the connection list table, then locate the edit button
const editButton = page.getByText(TEST_SAML_SSO_CONNECTION_NAME).locator('..').getByLabel('Edit');
const editButton = page.getByText(TEST_SAML_SSO_CONNECTION_NAME).locator('xpath=..').getByLabel('Edit');
await editButton.click();
// click the delete and confirm deletion
await page.getByRole('button', { name: 'Delete' }).click();
@ -138,7 +138,7 @@ test.describe('Admin Portal SSO - OIDC', () => {
await page.getByTestId('logout').click();
// Click on login with sso button
await page.getByTestId('sso-login-button').click();
// Perform sign in at mocksaml
// Perform sign in at mocklab
await page.waitForURL((url) => url.origin === MOCKLAB_ORIGIN);
await page.getByPlaceholder('yours@example.com').fill('bob@oidc.com');
await page.getByRole('button', { name: MOCKLAB_SIGNIN_BUTTON_NAME }).click();

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
},
"devDependencies": {
"@rollup/plugin-typescript": "11.1.6",
"@types/node": "20.12.7",
"@types/node": "20.12.8",
"@types/react": "18.3.1",
"@typescript-eslint/eslint-plugin": "7.8.0",
"@typescript-eslint/parser": "7.8.0",
@ -37,7 +37,7 @@
"prettier": "3.2.5",
"react-daisyui": "5.0.0",
"typescript": "5.4.5",
"vite": "5.2.10"
"vite": "5.2.11"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.17.2"

View File

@ -22,4 +22,4 @@ patches:
images:
- name: boxyhq/jackson
newTag: 1.23.5
newTag: 1.23.7

View File

@ -22,4 +22,4 @@ patches:
images:
- name: boxyhq/jackson
newTag: 1.23.5
newTag: 1.23.7

716
npm/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -39,19 +39,19 @@
"coverage-map": "map.js"
},
"dependencies": {
"@aws-sdk/client-dynamodb": "3.565.0",
"@aws-sdk/credential-providers": "3.565.0",
"@aws-sdk/util-dynamodb": "3.565.0",
"@aws-sdk/client-dynamodb": "3.569.0",
"@aws-sdk/credential-providers": "3.569.0",
"@aws-sdk/util-dynamodb": "3.569.0",
"@boxyhq/error-code-mnemonic": "0.1.1",
"@boxyhq/metrics": "0.2.6",
"@boxyhq/saml20": "1.5.0",
"@googleapis/admin": "17.0.0",
"@boxyhq/metrics": "0.2.7",
"@boxyhq/saml20": "1.5.1",
"@googleapis/admin": "18.0.0",
"axios": "1.6.8",
"encoding": "0.1.13",
"jose": "5.2.4",
"lodash": "4.17.21",
"mixpanel": "0.18.0",
"mongodb": "6.5.0",
"mongodb": "6.6.0",
"mssql": "10.0.2",
"mysql2": "3.9.7",
"node-forge": "1.3.1",
@ -64,8 +64,8 @@
},
"devDependencies": {
"@faker-js/faker": "8.4.1",
"@types/lodash": "4.17.0",
"@types/node": "20.12.7",
"@types/lodash": "4.17.1",
"@types/node": "20.12.8",
"@types/sinon": "17.0.3",
"@types/tap": "15.0.11",
"cross-env": "7.0.3",

814
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "jackson",
"version": "1.23.6",
"version": "1.23.7",
"private": true,
"description": "SAML 2.0 service",
"keywords": [
@ -66,8 +66,8 @@
"@boxyhq/react-ui": "3.3.43",
"@boxyhq/saml-jackson": "file:npm",
"@heroicons/react": "2.1.3",
"@retracedhq/logs-viewer": "2.7.3",
"@retracedhq/retraced": "0.7.9",
"@retracedhq/logs-viewer": "2.7.4",
"@retracedhq/retraced": "0.7.10",
"@tailwindcss/typography": "0.5.13",
"axios": "1.6.8",
"blockly": "10.4.3",
@ -75,7 +75,7 @@
"classnames": "2.5.1",
"cors": "2.8.5",
"cross-env": "7.0.3",
"daisyui": "4.10.2",
"daisyui": "4.10.5",
"formik": "2.4.6",
"i18next": "23.11.3",
"medium-zoom": "1.1.0",

View File

@ -20,15 +20,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
const { connectionAPIController, directorySyncController } = await jackson();
const { connectionAPIController, directorySyncController, samlFederatedController } = await jackson();
const sso_connections_count = await connectionAPIController.getCount();
const dsync_connections_count = await directorySyncController.directories.getCount();
const identity_federation_count = await samlFederatedController.app.getCount();
return res.json({
data: {
sso_connections: sso_connections_count,
dsync_connections: dsync_connections_count,
identity_federation_apps: identity_federation_count,
},
});
};

View File

@ -38,7 +38,7 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse) => {
// Get counts for product
let sso_connections_count = 0;
let dsync_connections_count = 0;
let saml_federation_count = 0;
let identity_federation_count = 0;
for (const product of products) {
if (product) {
@ -60,7 +60,7 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse) => {
name: IndexNames.Product,
value: product,
});
saml_federation_count += count || 0;
identity_federation_count += count || 0;
}
}
}
@ -69,7 +69,7 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse) => {
data: {
sso_connections: sso_connections_count,
dsync_connections: dsync_connections_count,
saml_federation: saml_federation_count,
identity_federation_apps: identity_federation_count,
},
});
}

View File

@ -22,7 +22,8 @@ const config: PlaywrightTestConfig = {
timeout: 60 * 1000,
reuseExistingServer: !process.env.CI,
env: {
NODE_ENV: 'test',
DEBUG: 'pw:webserver',
NEXTAUTH_ADMIN_CREDENTIALS: 'super@boxyhq.com:999login',
},
},