From 6b4eb860a47034f6cd7f4056fa16362973e27511 Mon Sep 17 00:00:00 2001
From: Russell Vinegar <38586679+rustyjux@users.noreply.github.com>
Date: Tue, 22 Oct 2024 09:40:42 -0700
Subject: [PATCH 01/37] tweak style for gateway list item hover (#1184)
* tweak style for gateway list item hover
* ns to gw text
---
src/nextapp/pages/manager/gateways/detail.tsx | 2 +-
src/nextapp/pages/manager/gateways/list.tsx | 16 ++++++++++++----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/nextapp/pages/manager/gateways/detail.tsx b/src/nextapp/pages/manager/gateways/detail.tsx
index a4d597d9d..b63036fb8 100644
--- a/src/nextapp/pages/manager/gateways/detail.tsx
+++ b/src/nextapp/pages/manager/gateways/detail.tsx
@@ -247,7 +247,7 @@ const NamespacesPage: React.FC = () => {
If you need to change the Organization or Business Unit for
- your Namespace, submit a request through the{' '}
+ your Gateway, submit a request through the{' '}
{
onClick={handleNamespaceChange(namespace)}
cursor="pointer"
transition="background-color 0.2s"
- _hover={{ backgroundColor: "#f0f0f0" }}
+ _hover={{
+ backgroundColor: "#EDEBE9",
+ h2: {
+ color: 'bc-blue',
+ textDecor: 'underline',
+ },
+
+ cursor: 'pointer',
+ }}
>
@@ -302,15 +310,15 @@ const MyGatewaysPage: React.FC = () => {
mr={4}
boxSize={4}
/>
-
{namespace.displayName}
-
+
{namespace.name}
From 50433c878040efd17f46b26b66480c35b0e91df9 Mon Sep 17 00:00:00 2001
From: Russell Vinegar <38586679+rustyjux@users.noreply.github.com>
Date: Wed, 6 Nov 2024 15:45:14 -0800
Subject: [PATCH 02/37] fix tests to handle redirect away from your products
(#1185)
* fix tests to handle redirect away from your products
* upload astra scan results to debug
* fix legal terms URL
---
.github/workflows/aps-cypress-e2e.yaml | 6 ++++++
.github/workflows/scripts/feeder-init/legal.yaml | 2 +-
e2e/cypress/tests/20-gateways/02-dropdown.ts | 10 +++++++---
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index 8a8046f89..aaef58651 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -76,6 +76,12 @@ jobs:
name: code-coverage
path: ${{ github.workspace }}/e2e/coverage
+ - name: Upload Astra scan results
+ uses: actions/upload-artifact@v4
+ with:
+ name: astra-scan-results
+ path: ${{ github.workspace }}/e2e/cypress/fixtures/state/scanResult.json
+
- name: Instrument the code for coverage analysis
run: |
# Rewrite the paths as the coverage starts with '../app'!
diff --git a/.github/workflows/scripts/feeder-init/legal.yaml b/.github/workflows/scripts/feeder-init/legal.yaml
index 257fc7a0d..26a7b2b03 100644
--- a/.github/workflows/scripts/feeder-init/legal.yaml
+++ b/.github/workflows/scripts/feeder-init/legal.yaml
@@ -2,6 +2,6 @@ entity: Legal
record:
id: "terms-of-use-for-api-gateway-1"
title: "Terms of Use for API Gateway"
- link: "https://www2.gov.bc.ca/gov/content/data/open-data/api-terms-of-use-for-ogl-information"
+ link: "https://www2.gov.bc.ca/gov/content/data/policy-standards/open-data/api-terms-of-use-for-ogl-information"
document: terms-of-use
version: 1
diff --git a/e2e/cypress/tests/20-gateways/02-dropdown.ts b/e2e/cypress/tests/20-gateways/02-dropdown.ts
index 8841c581c..886110317 100644
--- a/e2e/cypress/tests/20-gateways/02-dropdown.ts
+++ b/e2e/cypress/tests/20-gateways/02-dropdown.ts
@@ -37,7 +37,11 @@ describe('Gateway selector dropdown', () => {
it('Get current total number of gateways', () => {
// Create a new gateway to ensure there is at least one gateway
- cy.createGateway();
+ cy.createGateway().then((response) => {
+ const namespace = response.gatewayId
+ cy.log('New namespace created: ' + namespace)
+ cy.activateGateway(namespace);
+ });
cy.visit(ad.yourProductsPath);
cy.get('[data-testid="ns-dropdown-btn"]').click();
@@ -81,8 +85,8 @@ describe('Gateway selector dropdown', () => {
it('Recently used gateways are shown in the dropdown', () => {
cy.visit(ns.listPath)
cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click()
- cy.get('[data-testid="ns-dropdown-btn"]').click()
- cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).click()
+ cy.visit(ns.listPath)
+ cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace2"].gatewayId + '-' + customId}"]`).click()
cy.get('[data-testid="ns-dropdown-btn"]').click()
cy.get('[data-testid="ns-dropdown-heading"]').should('contain.text', "Recently viewed")
cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist')
From a36e6729524e282cd1a52f39beacd30e39d6439a Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 9 Dec 2024 09:21:17 -0800
Subject: [PATCH 03/37] add PR review reminders
---
.github/workflows/pr-reminder.yaml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 .github/workflows/pr-reminder.yaml
diff --git a/.github/workflows/pr-reminder.yaml b/.github/workflows/pr-reminder.yaml
new file mode 100644
index 000000000..63a532f9a
--- /dev/null
+++ b/.github/workflows/pr-reminder.yaml
@@ -0,0 +1,14 @@
+name: 'Send review reminders'
+on:
+ schedule:
+ - cron: '30 8 * * 1,3,5' # Scheduled to run at 1:30 AM, Monday, Wednesday, Friday
+
+jobs:
+ remind:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Run PR reviewer reminder
+ uses: bcgov/aps-devops/pr-reminder@dev
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ dry_run: "false"
From acb9071d1ebb1bbedb6a73477ce69d07c498dd78 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 16 Dec 2024 12:06:55 -0800
Subject: [PATCH 04/37] set OS for Jira GHA runner
---
.github/workflows/jira.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/jira.yaml b/.github/workflows/jira.yaml
index af57a5b5a..c05fbe0e5 100644
--- a/.github/workflows/jira.yaml
+++ b/.github/workflows/jira.yaml
@@ -4,7 +4,7 @@ on: [issues, issue_comment]
jobs:
sync-issues:
name: Sync issues to Jira
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- uses: ikethecoder/sync-issues-github-jira@dev
with:
From 1df2aabaedd87c70035aa802720fbf10103ae836 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 16 Dec 2024 12:18:40 -0800
Subject: [PATCH 05/37] Update GitHub Actions to use CodeQL SARIF upload v2 in
image scan workflows
---
.github/workflows/ci-anchore-img-scan.yaml | 2 +-
.github/workflows/ci-trivy-img-scan.yaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci-anchore-img-scan.yaml b/.github/workflows/ci-anchore-img-scan.yaml
index 39ee38ae8..c809879b9 100644
--- a/.github/workflows/ci-anchore-img-scan.yaml
+++ b/.github/workflows/ci-anchore-img-scan.yaml
@@ -19,6 +19,6 @@ jobs:
acs-report-enable: true
fail-build: false
- name: Upload Anchore Scan Results
- uses: github/codeql-action/upload-sarif@v1
+ uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
diff --git a/.github/workflows/ci-trivy-img-scan.yaml b/.github/workflows/ci-trivy-img-scan.yaml
index 4a08ebeda..bcea8fdba 100644
--- a/.github/workflows/ci-trivy-img-scan.yaml
+++ b/.github/workflows/ci-trivy-img-scan.yaml
@@ -24,6 +24,6 @@ jobs:
template: '@/contrib/sarif.tpl'
output: 'trivy-results.sarif'
- name: Upload Trivy Scan Results
- uses: github/codeql-action/upload-sarif@v1
+ uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
From f3bbbd34850aa7adbefb8e506975563b4787b667 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 16 Dec 2024 12:52:39 -0800
Subject: [PATCH 06/37] Update GitHub Actions to use CodeQL SARIF upload v3 in
image scan workflows
---
.github/workflows/ci-anchore-img-scan.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci-anchore-img-scan.yaml b/.github/workflows/ci-anchore-img-scan.yaml
index c809879b9..61670c497 100644
--- a/.github/workflows/ci-anchore-img-scan.yaml
+++ b/.github/workflows/ci-anchore-img-scan.yaml
@@ -19,6 +19,6 @@ jobs:
acs-report-enable: true
fail-build: false
- name: Upload Anchore Scan Results
- uses: github/codeql-action/upload-sarif@v2
+ uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
From e21eafaceb6f49e32d7fb2584efbcb4afa1725ee Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 16 Dec 2024 13:55:48 -0800
Subject: [PATCH 07/37] Remove deprecated acs-report-enable option from Anchore
image scan workflow
---
.github/workflows/ci-anchore-img-scan.yaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/ci-anchore-img-scan.yaml b/.github/workflows/ci-anchore-img-scan.yaml
index 61670c497..8c60b6393 100644
--- a/.github/workflows/ci-anchore-img-scan.yaml
+++ b/.github/workflows/ci-anchore-img-scan.yaml
@@ -16,7 +16,6 @@ jobs:
uses: anchore/scan-action@main
with:
image: 'bcgov/api-services-portal:anchore-scan'
- acs-report-enable: true
fail-build: false
- name: Upload Anchore Scan Results
uses: github/codeql-action/upload-sarif@v3
From bc59a964267fada73336369217c5220c1eed906f Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 17 Dec 2024 12:31:49 -0800
Subject: [PATCH 08/37] Update Dockerfiles to use Node.js 22
---
Dockerfile | 2 +-
feeds/Dockerfile | 2 +-
local/cypress-jwks-url/Dockerfile | 2 +-
local/html-sample-app/Dockerfile | 2 +-
local/portal/Dockerfile.E2E | 2 +-
oauth2-proxy/sample-upstream/Dockerfile | 2 +-
src/package.json | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 35c3ec152..afaf9c2e1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
#FROM node:lts-alpine3.17
-FROM node:16.14.2-alpine3.15
+FROM node:22.12.0-alpine3.21
ARG APP_VERSION
ENV NEXT_PUBLIC_APP_VERSION=${APP_VERSION}
diff --git a/feeds/Dockerfile b/feeds/Dockerfile
index 71762d635..bfda758c6 100644
--- a/feeds/Dockerfile
+++ b/feeds/Dockerfile
@@ -1,5 +1,5 @@
#FROM node:lts-alpine3.17
-FROM node:16.14.2-alpine3.15
+FROM node:22.12.0-alpine3.21
RUN apk add curl jq
diff --git a/local/cypress-jwks-url/Dockerfile b/local/cypress-jwks-url/Dockerfile
index 9090ef854..34ab14541 100644
--- a/local/cypress-jwks-url/Dockerfile
+++ b/local/cypress-jwks-url/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16.14.2-alpine3.15
+FROM node:22.12.0-alpine3.21
WORKDIR /src
diff --git a/local/html-sample-app/Dockerfile b/local/html-sample-app/Dockerfile
index 14ff920ab..5613684e8 100644
--- a/local/html-sample-app/Dockerfile
+++ b/local/html-sample-app/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16.14.2-alpine3.15
+FROM node:22.12.0-alpine3.21
WORKDIR /src
diff --git a/local/portal/Dockerfile.E2E b/local/portal/Dockerfile.E2E
index c18e31adf..d0a18f2e6 100644
--- a/local/portal/Dockerfile.E2E
+++ b/local/portal/Dockerfile.E2E
@@ -1,5 +1,5 @@
#FROM node:lts-alpine3.18
-FROM node:16.14.2-alpine3.15
+FROM node:22.12.0-alpine3.21
ARG APP_VERSION
ENV APP_VERSION=${APP_VERSION}
diff --git a/oauth2-proxy/sample-upstream/Dockerfile b/oauth2-proxy/sample-upstream/Dockerfile
index f76d6f332..6f5e0b281 100644
--- a/oauth2-proxy/sample-upstream/Dockerfile
+++ b/oauth2-proxy/sample-upstream/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16.14.2-alpine3.15 AS BUILD
+FROM node:22.12.0-alpine3.21 AS BUILD
COPY package*.json /app/
diff --git a/src/package.json b/src/package.json
index 147f8aad3..8d04ff94f 100644
--- a/src/package.json
+++ b/src/package.json
@@ -43,7 +43,7 @@
"mock-server": "nodemon ./test/mock-server/server.js",
"ks-build": "cross-env NODE_ENV=production keystone build --entry=dist/server.js --out=dist2",
"start": "cross-env NODE_ENV=production keystone start --entry=dist/server.js",
- "build": "NODE_OPTIONS='--dns-result-order=ipv4first' npm-run-all delete-assets copy-assets tsoa-build-v1 tsoa-build-v2 tsoa-build-v3 ts-build ks-build copy-keystone-admin-assets",
+ "build": "NODE_OPTIONS='--dns-result-order=ipv4first --openssl-legacy-provider' npm-run-all delete-assets copy-assets tsoa-build-v1 tsoa-build-v2 tsoa-build-v3 ts-build ks-build copy-keystone-admin-assets",
"create-tables": "cross-env CREATE_TABLES=true keystone create-tables --entry=dist/server.js",
"lint": "eslint ./nextapp --ext .ts,.tsx --quiet",
"lint:ts": "tsc -p ./nextapp/tsconfig.json --noEmit",
From 184c5f35dc75bf6377210f84e4a6119663f5d121 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 17 Dec 2024 12:49:18 -0800
Subject: [PATCH 09/37] update reminder schedule
---
.github/workflows/pr-reminder.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/pr-reminder.yaml b/.github/workflows/pr-reminder.yaml
index 63a532f9a..bbec23c1d 100644
--- a/.github/workflows/pr-reminder.yaml
+++ b/.github/workflows/pr-reminder.yaml
@@ -1,7 +1,7 @@
name: 'Send review reminders'
on:
schedule:
- - cron: '30 8 * * 1,3,5' # Scheduled to run at 1:30 AM, Monday, Wednesday, Friday
+ - cron: '30 8 * * 1,2,3,4,5' # Scheduled to run at 1:30 AM, weekdays
jobs:
remind:
From cc306eb06fbc91aec1d43dad868f1086c50bc114 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 17 Dec 2024 12:58:40 -0800
Subject: [PATCH 10/37] adjust PR reminder timing
---
.github/workflows/pr-reminder.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/pr-reminder.yaml b/.github/workflows/pr-reminder.yaml
index bbec23c1d..aab1e8922 100644
--- a/.github/workflows/pr-reminder.yaml
+++ b/.github/workflows/pr-reminder.yaml
@@ -1,7 +1,7 @@
name: 'Send review reminders'
on:
schedule:
- - cron: '30 8 * * 1,2,3,4,5' # Scheduled to run at 1:30 AM, weekdays
+ - cron: '30 13 * * 1,2,3,4,5' # Scheduled to run at 5:30 AM PST, weekdays
jobs:
remind:
From 091b77ed3793b2fb74ee1f0cabcae0b8ebbcacd7 Mon Sep 17 00:00:00 2001
From: Russell Vinegar <38586679+rustyjux@users.noreply.github.com>
Date: Tue, 17 Dec 2024 15:26:09 -0800
Subject: [PATCH 11/37] update ns --> gw in API endpoint names and descriptions
* rename namespace-profile endpoint
* update ns --> gw in API descriptions
* delete routes.ts and openapi.yaml (generated during build)
---
src/controllers/v3/DatasetController.ts | 4 +-
src/controllers/v3/GatewayController.ts | 16 +-
.../v3/GatewayDirectoryController.ts | 2 +-
.../v3/GatewayServicesController.ts | 2 +-
src/controllers/v3/IssuerController.ts | 4 +-
src/controllers/v3/OrganizationController.ts | 12 +-
src/controllers/v3/openapi.yaml | 1722 ----------------
src/controllers/v3/routes.ts | 1726 -----------------
8 files changed, 20 insertions(+), 3468 deletions(-)
delete mode 100644 src/controllers/v3/openapi.yaml
delete mode 100644 src/controllers/v3/routes.ts
diff --git a/src/controllers/v3/DatasetController.ts b/src/controllers/v3/DatasetController.ts
index 57ff6a119..0bab150bd 100644
--- a/src/controllers/v3/DatasetController.ts
+++ b/src/controllers/v3/DatasetController.ts
@@ -40,7 +40,7 @@ export class DatasetController extends Controller {
/**
* Update metadata about a Dataset
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Update Dataset
*/
@@ -66,7 +66,7 @@ export class DatasetController extends Controller {
/**
* Get metadata about a Dataset
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Get Dataset
*/
diff --git a/src/controllers/v3/GatewayController.ts b/src/controllers/v3/GatewayController.ts
index 20e208481..7e7e70831 100644
--- a/src/controllers/v3/GatewayController.ts
+++ b/src/controllers/v3/GatewayController.ts
@@ -121,7 +121,7 @@ export class NamespaceController extends Controller {
/**
* Get details about the gateway, such as permissions for what the gateway is setup with.
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Gateway Summary
* @param ns
@@ -129,7 +129,7 @@ export class NamespaceController extends Controller {
* @returns
*/
@Get('/{gatewayId}')
- @OperationId('namespace-profile')
+ @OperationId('gateway-profile')
@Security('jwt', ['Namespace.Manage'])
public async profile(
@Path() gatewayId: string,
@@ -174,7 +174,7 @@ export class NamespaceController extends Controller {
errors[`d${ind}`] = { message: err.message };
});
logger.error('%j', result);
- throw new ValidateError(errors, 'Unable to create namespace');
+ throw new ValidateError(errors, 'Unable to create Gateway');
}
return {
gatewayId: result.data.createNamespace.name,
@@ -184,7 +184,7 @@ export class NamespaceController extends Controller {
/**
* Delete the gateway
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Delete Gateway
* @param ns
@@ -192,7 +192,7 @@ export class NamespaceController extends Controller {
* @returns
*/
@Delete('/{gatewayId}')
- @OperationId('delete-namespace')
+ @OperationId('delete-gateway')
@Security('jwt', ['Namespace.Manage'])
public async delete(
@Path() gatewayId: string,
@@ -218,9 +218,9 @@ export class NamespaceController extends Controller {
}
/**
- * > `Required Scope:` Namespace.View
+ * > `Required Scope:` Gateway.View
*
- * @summary Get administration activity for this gateway
+ * @summary Get administration activity for this Gateway
* @param ns
* @param first
* @param skip
@@ -251,7 +251,7 @@ export class NamespaceController extends Controller {
/**
* Get a summary of your endpoints
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Get endpoints
*/
diff --git a/src/controllers/v3/GatewayDirectoryController.ts b/src/controllers/v3/GatewayDirectoryController.ts
index a5de7ce90..fbbb44bbf 100644
--- a/src/controllers/v3/GatewayDirectoryController.ts
+++ b/src/controllers/v3/GatewayDirectoryController.ts
@@ -61,7 +61,7 @@ export class GatewayDirectoryController extends Controller {
/**
* Used primarily for "Preview Mode"
- * List the datasets belonging to a particular namespace
+ * List the datasets belonging to a particular Gateway
*
* @param ns
* @param name
diff --git a/src/controllers/v3/GatewayServicesController.ts b/src/controllers/v3/GatewayServicesController.ts
index 801e5837b..eb902cce6 100644
--- a/src/controllers/v3/GatewayServicesController.ts
+++ b/src/controllers/v3/GatewayServicesController.ts
@@ -47,7 +47,7 @@ export class GatewayController extends Controller {
/**
* Get a summary of your Gateway Services
- * > `Required Scope:` Namespace.Manage
+ * > `Required Scope:` Gateway.Manage
*
* @summary Get Gateway Services
*/
diff --git a/src/controllers/v3/IssuerController.ts b/src/controllers/v3/IssuerController.ts
index 98598932c..e87b34c85 100644
--- a/src/controllers/v3/IssuerController.ts
+++ b/src/controllers/v3/IssuerController.ts
@@ -60,8 +60,8 @@ export class IssuerController extends Controller {
}
/**
- * Get Authorization Profiles setup in this namespace
- * > `Required Scope:` Namespace.Manage
+ * Get Authorization Profiles setup in this Gateway
+ * > `Required Scope:` Gateway.Manage
*
* @summary Get Authorization Profiles
*/
diff --git a/src/controllers/v3/OrganizationController.ts b/src/controllers/v3/OrganizationController.ts
index a4d904cfc..1597c3a26 100644
--- a/src/controllers/v3/OrganizationController.ts
+++ b/src/controllers/v3/OrganizationController.ts
@@ -181,7 +181,7 @@ export class OrganizationController extends Controller {
}
/**
- * > `Required Scope:` Namespace.Assign
+ * > `Required Scope:` Gateway.Assign
*/
@Get('{org}/gateways')
@OperationId('organization-gateways')
@@ -196,7 +196,7 @@ export class OrganizationController extends Controller {
}
/**
- * > `Required Scope:` Namespace.Assign
+ * > `Required Scope:` Gateway.Assign
*/
@Put('{org}/{orgUnit}/gateways/{gatewayId}')
@OperationId('assign-namespace-to-organization')
@@ -231,7 +231,7 @@ export class OrganizationController extends Controller {
}
/**
- * > `Required Scope:` Namespace.Assign
+ * > `Required Scope:` Gateway.Assign
*/
@Delete('{org}/{orgUnit}/gateways/{gatewayId}')
@OperationId('unassign-namespace-from-organization')
@@ -265,16 +265,16 @@ export class OrganizationController extends Controller {
}
/**
- * > `Required Scope:` Namespace.Assign
+ * > `Required Scope:` Gateway.Assign
*
- * @summary Get administration activity for gateways associated with this Organization
+ * @summary Get administration activity for Gateways associated with this Organization
* @param org
* @param first
* @param skip
* @returns Activity[]
*/
@Get('{org}/activity')
- @OperationId('org-namespace-activity')
+ @OperationId('org-gateway-activity')
@Security('jwt', ['Namespace.Assign'])
public async namespaceActivity(
@Path() org: string,
diff --git a/src/controllers/v3/openapi.yaml b/src/controllers/v3/openapi.yaml
deleted file mode 100644
index ec2d79f47..000000000
--- a/src/controllers/v3/openapi.yaml
+++ /dev/null
@@ -1,1722 +0,0 @@
-components:
- examples: {}
- headers: {}
- parameters: {}
- requestBodies: {}
- responses: {}
- schemas:
- DatasetContact:
- properties:
- name:
- type: string
- email:
- type: string
- role:
- type: string
- enum:
- - pointOfContact
- nullable: false
- type: object
- additionalProperties: false
- DatasetResource:
- properties:
- id:
- type: string
- name:
- type: string
- format:
- type: string
- enum:
- - openapi-json
- - json
- url:
- type: string
- type: object
- additionalProperties: false
- OrganizationRefID:
- type: string
- OrganizationUnitRefID:
- type: string
- Dataset:
- properties:
- extForeignKey:
- type: string
- name:
- type: string
- license_title:
- type: string
- security_class:
- type: string
- view_audience:
- type: string
- download_audience:
- type: string
- record_publish_date:
- type: string
- notes:
- type: string
- title:
- type: string
- isInCatalog:
- type: string
- isDraft:
- type: string
- contacts:
- items:
- $ref: '#/components/schemas/DatasetContact'
- type: array
- resources:
- items:
- $ref: '#/components/schemas/DatasetResource'
- type: array
- extSource:
- type: string
- extRecordHash:
- type: string
- tags:
- items:
- type: string
- type: array
- organization:
- $ref: '#/components/schemas/OrganizationRefID'
- organizationUnit:
- $ref: '#/components/schemas/OrganizationUnitRefID'
- type: object
- additionalProperties: false
- BatchResult:
- properties:
- status:
- type: number
- format: double
- result:
- type: string
- reason:
- type: string
- id:
- type: string
- ownedBy:
- type: string
- childResults:
- items:
- $ref: '#/components/schemas/BatchResult'
- type: array
- required:
- - status
- - result
- type: object
- additionalProperties: false
- DraftDataset:
- properties:
- name:
- type: string
- license_title:
- type: string
- security_class:
- type: string
- enum:
- - HIGH-CABINET
- - HIGH-CONFIDENTIAL
- - HIGH-SENSITIVITY
- - MEDIUM-SENSITIVITY
- - MEDIUM-PERSONAL
- - LOW-SENSITIVITY
- - LOW-PUBLIC
- - PUBLIC
- - 'PROTECTED A'
- - 'PROTECTED B'
- - 'PROTECTED C'
- view_audience:
- type: string
- enum:
- - Public
- - Government
- - 'Named users'
- - 'Government and Business BCeID'
- download_audience:
- type: string
- enum:
- - Public
- - Government
- - 'Named users'
- - 'Government and Business BCeID'
- record_publish_date:
- type: string
- notes:
- type: string
- title:
- type: string
- isInCatalog:
- type: boolean
- isDraft:
- type: boolean
- contacts:
- items:
- $ref: '#/components/schemas/DatasetContact'
- type: array
- resources:
- items:
- $ref: '#/components/schemas/DatasetResource'
- type: array
- tags:
- items:
- type: string
- type: array
- organization:
- $ref: '#/components/schemas/OrganizationRefID'
- organizationUnit:
- $ref: '#/components/schemas/OrganizationUnitRefID'
- type: object
- additionalProperties: false
- example:
- name: my_sample_dataset
- license_title: 'Open Government Licence - British Columbia'
- security_class: PUBLIC
- view_audience: Public
- download_audience: Public
- record_publish_date: '2017-09-05'
- notes: 'Some notes'
- title: 'A title about my dataset'
- tags:
- - tag1
- - tag2
- organization: ministry-of-citizens-services
- organizationUnit: databc
- Gateway:
- properties:
- gatewayId:
- type: string
- displayName:
- type: string
- type: object
- additionalProperties: false
- ActivityDetail:
- properties:
- id:
- type: string
- message:
- type: string
- params:
- properties: {}
- additionalProperties:
- type: string
- type: object
- activityAt: {}
- blob: {}
- required:
- - message
- - params
- - activityAt
- type: object
- additionalProperties: false
- PublishResult:
- properties:
- message:
- type: string
- results:
- type: string
- error:
- type: string
- type: object
- additionalProperties: false
- GatewayServiceRefID:
- type: string
- GatewayRouteRefID:
- type: string
- GatewayPlugin:
- properties:
- extForeignKey:
- type: string
- name:
- type: string
- extSource:
- type: string
- extRecordHash:
- type: string
- tags:
- items:
- type: string
- type: array
- config: {}
- service:
- $ref: '#/components/schemas/GatewayServiceRefID'
- route:
- $ref: '#/components/schemas/GatewayRouteRefID'
- type: object
- additionalProperties: false
- GatewayRoute:
- properties:
- extForeignKey:
- type: string
- name:
- type: string
- gatewayId:
- type: string
- extSource:
- type: string
- extRecordHash:
- type: string
- tags:
- items:
- type: string
- type: array
- methods:
- items:
- type: string
- type: array
- paths:
- items:
- type: string
- type: array
- hosts:
- items:
- type: string
- type: array
- service:
- $ref: '#/components/schemas/GatewayServiceRefID'
- plugins:
- items:
- $ref: '#/components/schemas/GatewayPlugin'
- type: array
- type: object
- additionalProperties: false
- IssuerEnvironmentConfig:
- properties:
- environment:
- type: string
- exists:
- type: boolean
- issuerUrl:
- type: string
- clientRegistration:
- type: string
- enum:
- - anonymous
- - managed
- - iat
- clientId:
- type: string
- clientSecret:
- type: string
- initialAccessToken:
- type: string
- type: object
- additionalProperties: false
- example:
- environment: dev
- issuerUrl: 'https://idp.site/auth/realms/my-realm'
- clientRegistration: managed
- clientId: a-client-id
- clientSecret: a-client-secret
- undefinedRefID:
- type: string
- CredentialIssuer:
- properties:
- name:
- type: string
- gatewayId:
- type: string
- description:
- type: string
- flow:
- type: string
- enum:
- - client-credentials
- nullable: false
- mode:
- type: string
- enum:
- - auto
- nullable: false
- authPlugin:
- type: string
- clientAuthenticator:
- type: string
- enum:
- - client-secret
- - client-jwt
- - client-jwt-jwks-url
- instruction:
- type: string
- environmentDetails:
- items:
- $ref: '#/components/schemas/IssuerEnvironmentConfig'
- type: array
- resourceType:
- type: string
- resourceAccessScope:
- type: string
- isShared:
- type: boolean
- apiKeyName:
- type: string
- availableScopes:
- items:
- type: string
- type: array
- resourceScopes:
- items:
- type: string
- type: array
- clientRoles:
- items:
- type: string
- type: array
- clientMappers:
- items:
- type: string
- type: array
- inheritFrom:
- $ref: '#/components/schemas/undefinedRefID'
- owner:
- $ref: '#/components/schemas/undefinedRefID'
- type: object
- additionalProperties: false
- example:
- name: my-auth-profile
- description: 'Auth connection to my IdP'
- flow: client-credentials
- clientAuthenticator: client-secret
- mode: auto
- environmentDetails: []
- owner: janis@gov.bc.ca
- OrganizationUnit:
- properties:
- extForeignKey:
- type: string
- name:
- type: string
- sector:
- type: string
- title:
- type: string
- description:
- type: string
- extSource:
- type: string
- extRecordHash:
- type: string
- tags:
- items:
- type: string
- type: array
- type: object
- additionalProperties: false
- Organization:
- properties:
- extForeignKey:
- type: string
- name:
- type: string
- sector:
- type: string
- title:
- type: string
- description:
- type: string
- extSource:
- type: string
- extRecordHash:
- type: string
- tags:
- items:
- type: string
- type: array
- orgUnits:
- items:
- $ref: '#/components/schemas/OrganizationUnit'
- type: array
- type: object
- additionalProperties: false
- GroupPermission:
- properties:
- resource:
- type: string
- scopes:
- items:
- type: string
- type: array
- required:
- - scopes
- type: object
- additionalProperties: false
- GroupRole:
- properties:
- name:
- type: string
- permissions:
- items:
- $ref: '#/components/schemas/GroupPermission'
- type: array
- required:
- - name
- - permissions
- type: object
- additionalProperties: false
- GroupAccess:
- properties:
- name:
- type: string
- parent:
- type: string
- roles:
- items:
- $ref: '#/components/schemas/GroupRole'
- type: array
- required:
- - roles
- type: object
- additionalProperties: false
- UserReference:
- properties:
- id:
- type: string
- email:
- type: string
- type: object
- additionalProperties: false
- GroupMember:
- properties:
- member:
- $ref: '#/components/schemas/UserReference'
- roles:
- items:
- type: string
- type: array
- required:
- - member
- - roles
- type: object
- additionalProperties: false
- GroupMembership:
- properties:
- name:
- type: string
- parent:
- type: string
- members:
- items:
- $ref: '#/components/schemas/GroupMember'
- type: array
- type: object
- additionalProperties: false
- OrgNamespace:
- properties:
- name:
- type: string
- orgUnit:
- type: string
- enabled:
- type: boolean
- updatedAt:
- type: number
- format: double
- required:
- - name
- - orgUnit
- - enabled
- - updatedAt
- type: object
- additionalProperties: false
- DraftDatasetRefID:
- type: string
- LegalRefID:
- type: string
- CredentialIssuerRefID:
- type: string
- Environment:
- properties:
- appId:
- type: string
- name:
- type: string
- enum:
- - dev
- - test
- - prod
- - sandbox
- - other
- active:
- type: boolean
- approval:
- type: boolean
- flow:
- type: string
- enum:
- - public
- - protected-externally
- - authorization-code
- - client-credentials
- - kong-acl-only
- - kong-api-key-only
- - kong-api-key-acl
- additionalDetailsToRequest:
- type: string
- services:
- items:
- $ref: '#/components/schemas/GatewayServiceRefID'
- type: array
- legal:
- $ref: '#/components/schemas/LegalRefID'
- credentialIssuer:
- $ref: '#/components/schemas/CredentialIssuerRefID'
- type: object
- additionalProperties: false
- example:
- name: dev
- active: false
- approval: false
- flow: public
- appId: '00000000'
- Product:
- properties:
- appId:
- type: string
- name:
- type: string
- description:
- type: string
- gatewayId:
- type: string
- dataset:
- $ref: '#/components/schemas/DraftDatasetRefID'
- environments:
- items:
- $ref: '#/components/schemas/Environment'
- type: array
- type: object
- additionalProperties: false
- example:
- name: my-new-product
- appId: '000000000000'
- environments:
- -
- name: dev
- active: false
- approval: false
- flow: public
- appId: '00000000'
- securitySchemes:
- jwt:
- type: oauth2
- description: 'Authz Client Credential'
- flows:
- clientCredentials:
- tokenUrl: 'https://token_endpoint'
- scopes: {}
- portal:
- type: http
- description: 'Authz Portal Login'
- scheme: bearer
- bearerFormat: JWT
- openid:
- type: openIdConnect
- description: 'OIDC Login'
- openIdConnectUrl: 'https://well_known_endpoint'
-info:
- title: 'APS Directory API'
- version: 3.0.0
- description: 'API Services Portal by BC Gov API Programme Services'
- license:
- name: MIT
- contact:
- name: 'BC Gov APS'
-openapi: 3.0.0
-paths:
- '/organizations/{org}/datasets':
- get:
- operationId: organization-datasets
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/Dataset'
- type: array
- description: "Get metadata about Datasets that are available by API for this organization\n> `Required Scope:` Dataset.Manage"
- summary: 'Get Organization Datasets'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Dataset.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- put:
- operationId: put-organization-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Manage metadata about Datasets that are available by API for this organization\n> `Required Scope:` Dataset.Manage"
- summary: 'Manage Organization Datasets'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Dataset.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/DraftDataset'
- '/organizations/{org}/datasets/{name}':
- delete:
- operationId: delete-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Delete a Dataset\n> `Required Scope:` Dataset.Manage"
- summary: 'Delete a dataset'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Dataset.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- -
- in: path
- name: name
- required: true
- schema:
- type: string
- get:
- operationId: get-organization-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Dataset'
- description: "Get metadata about a Dataset that are available by API for this organization\n> `Required Scope:` Dataset.Manage"
- summary: 'Get Organization Dataset'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Dataset.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- -
- in: path
- name: name
- required: true
- schema:
- type: string
- /directory:
- get:
- operationId: directory-list
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - 'API Directory'
- security: []
- parameters: []
- '/directory/{id}':
- get:
- operationId: directory-item
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - 'API Directory'
- security: []
- parameters:
- -
- in: path
- name: id
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/datasets':
- put:
- operationId: put-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Update metadata about a Dataset\n> `Required Scope:` Namespace.Manage"
- summary: 'Update Dataset'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/DraftDataset'
- '/gateways/{gatewayId}/datasets/{name}':
- get:
- operationId: get-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Dataset'
- description: "Get metadata about a Dataset\n> `Required Scope:` Namespace.Manage"
- summary: 'Get Dataset'
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: path
- name: name
- required: true
- schema:
- type: string
- /routes/availability:
- get:
- operationId: check-availability
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - 'Service Routes'
- security: []
- parameters:
- -
- in: query
- name: serviceName
- required: true
- schema:
- type: string
- -
- in: query
- name: gatewayId
- required: true
- schema:
- type: string
- /gateways/report:
- get:
- operationId: report
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - Gateways
- security:
- -
- jwt: []
- parameters:
- -
- in: query
- name: ids
- required: false
- schema:
- default: '[]'
- type: string
- /gateways:
- get:
- operationId: gateway-list
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/Gateway'
- type: array
- summary: 'List of Gateways available to the user'
- tags:
- - Gateways
- security:
- -
- jwt: []
- parameters: []
- post:
- operationId: create-gateway
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Gateway'
- description: 'Create a gateway'
- summary: 'Create Gateway'
- tags:
- - Gateways
- security:
- -
- jwt: []
- parameters: []
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Gateway'
- '/gateways/{gatewayId}':
- get:
- operationId: namespace-profile
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Gateway'
- description: "Get details about the gateway, such as permissions for what the gateway is setup with.\n> `Required Scope:` Namespace.Manage"
- summary: 'Gateway Summary'
- tags:
- - Gateways
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- delete:
- operationId: delete-namespace
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Gateway'
- description: "Delete the gateway\n> `Required Scope:` Namespace.Manage"
- summary: 'Delete Gateway'
- tags:
- - Gateways
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: query
- name: force
- required: false
- schema:
- default: false
- type: boolean
- '/gateways/{gatewayId}/activity':
- get:
- operationId: gateway-admin-activity
- responses:
- '200':
- description: 'Activity[]'
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/ActivityDetail'
- type: array
- description: '> `Required Scope:` Namespace.View'
- summary: 'Get administration activity for this gateway'
- tags:
- - Gateways
- security:
- -
- jwt:
- - Namespace.View
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: query
- name: first
- required: false
- schema:
- default: 20
- format: double
- type: number
- -
- in: query
- name: skip
- required: false
- schema:
- default: 0
- format: double
- type: number
- '/gateways/{gatewayId}/links':
- get:
- operationId: get-gateway-links
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- properties: {host: {type: string}}
- required: [host]
- type: object
- type: array
- description: "Get a summary of your endpoints\n> `Required Scope:` Namespace.Manage"
- summary: 'Get endpoints'
- tags:
- - Gateways
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/directory/{id}':
- get:
- operationId: get-ns-directory-dataset
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- description: "Used primarily for \"Preview Mode\"\nGet a particular Dataset"
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: path
- name: id
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/directory':
- get:
- operationId: get-ns-directory
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- description: "Used primarily for \"Preview Mode\"\nList the datasets belonging to a particular namespace"
- tags:
- - 'API Directory (Administration)'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/services':
- put:
- operationId: publish-gateway-config
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/PublishResult'
- tags:
- - 'Gateway Services'
- security:
- -
- jwt:
- - Gateway.Config
- parameters: []
- requestBody:
- required: true
- content:
- multipart/form-data:
- schema:
- type: object
- properties:
- dryRun:
- type: string
- configFile:
- type: string
- format: binary
- required:
- - dryRun
- - configFile
- get:
- operationId: get-gateway-routes
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/GatewayRoute'
- type: array
- description: "Get a summary of your Gateway Services\n> `Required Scope:` Namespace.Manage"
- summary: 'Get Gateway Services'
- tags:
- - 'Gateway Services'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- '/identifiers/{type}':
- get:
- operationId: GetNewID
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- type: string
- tags:
- - 'New Identifiers'
- security: []
- parameters:
- -
- in: path
- name: type
- required: true
- schema:
- type: string
- enum:
- - environment
- - product
- - application
- - gateway
- '/gateways/{gatewayId}/issuers':
- put:
- operationId: put-issuer
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Create or Update Authorization Profiles\n> `Required Scope:` CredentialIssuer.Admin"
- summary: 'Manage Authorization Profiles'
- tags:
- - 'Authorization Profiles'
- security:
- -
- jwt:
- - CredentialIssuer.Admin
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/CredentialIssuer'
- get:
- operationId: get-issuers
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/CredentialIssuer'
- type: array
- description: "Get Authorization Profiles setup in this namespace\n> `Required Scope:` Namespace.Manage"
- summary: 'Get Authorization Profiles'
- tags:
- - 'Authorization Profiles'
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/issuers/{name}':
- delete:
- operationId: delete-issuer
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Delete an Authorization Profile\n> `Required Scope:` CredentialIssuer.Admin"
- summary: 'Delete Profile'
- tags:
- - 'Authorization Profiles'
- security:
- -
- jwt:
- - CredentialIssuer.Admin
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: path
- name: name
- required: true
- schema:
- type: string
- /organizations:
- get:
- operationId: organization-list
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items: {}
- type: array
- tags:
- - Organizations
- security: []
- parameters: []
- '/organizations/{org}':
- put:
- operationId: put-organization
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Create Organization\n> `Required Scope:` GroupAccess.Manage"
- summary: 'Create Organizations'
- tags:
- - Organizations
- security:
- -
- jwt:
- - GroupAccess.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Organization'
- get:
- operationId: organization-units
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - Organizations
- security: []
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- '/organizations/{org}/roles':
- get:
- operationId: get-organization-roles
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/GroupAccess'
- description: '> `Required Scope:` GroupAccess.Manage'
- tags:
- - Organizations
- security:
- -
- jwt:
- - GroupAccess.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- '/organizations/{org}/access':
- get:
- operationId: get-organization-access
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/GroupMembership'
- description: '> `Required Scope:` GroupAccess.Manage'
- tags:
- - Organizations
- security:
- -
- jwt:
- - GroupAccess.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- put:
- operationId: put-organization-access
- responses:
- '204':
- description: 'No content'
- description: '> `Required Scope:` GroupAccess.Manage'
- tags:
- - Organizations
- security:
- -
- jwt:
- - GroupAccess.Manage
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/GroupMembership'
- '/organizations/{org}/gateways':
- get:
- operationId: organization-gateways
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/OrgNamespace'
- type: array
- description: '> `Required Scope:` Namespace.Assign'
- tags:
- - Organizations
- security:
- -
- jwt:
- - Namespace.Assign
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- '/organizations/{org}/{orgUnit}/gateways/{gatewayId}':
- put:
- operationId: assign-namespace-to-organization
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- properties:
- result: {type: string}
- required:
- - result
- type: object
- description: '> `Required Scope:` Namespace.Assign'
- tags:
- - Organizations
- security:
- -
- jwt:
- - Namespace.Assign
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- -
- in: path
- name: orgUnit
- required: true
- schema:
- type: string
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: query
- name: enable
- required: false
- schema:
- default: true
- type: boolean
- delete:
- operationId: unassign-namespace-from-organization
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- properties:
- result: {type: string}
- required:
- - result
- type: object
- description: '> `Required Scope:` Namespace.Assign'
- tags:
- - Organizations
- security:
- -
- jwt:
- - Namespace.Assign
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- -
- in: path
- name: orgUnit
- required: true
- schema:
- type: string
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- '/organizations/{org}/activity':
- get:
- operationId: org-namespace-activity
- responses:
- '200':
- description: 'Activity[]'
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/ActivityDetail'
- type: array
- description: '> `Required Scope:` Namespace.Assign'
- summary: 'Get administration activity for gateways associated with this Organization'
- tags:
- - Organizations
- security:
- -
- jwt:
- - Namespace.Assign
- parameters:
- -
- in: path
- name: org
- required: true
- schema:
- type: string
- -
- in: query
- name: first
- required: false
- schema:
- default: 20
- format: double
- type: number
- -
- in: query
- name: skip
- required: false
- schema:
- default: 0
- format: double
- type: number
- /roles:
- get:
- operationId: GetRoles
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema: {}
- tags:
- - Organizations
- security: []
- parameters: []
- '/gateways/{gatewayId}/products':
- put:
- operationId: put-product
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Manage Products for APIs that will appear on the API Directory\n> `Required Scope:` Namespace.Manage"
- summary: 'Manage Products'
- tags:
- - Products
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/Product'
- get:
- operationId: get-products
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- items:
- $ref: '#/components/schemas/Product'
- type: array
- description: "Get Products describing APIs that will appear on the API Directory\n> `Required Scope:` Namespace.Manage"
- summary: 'Get Products'
- tags:
- - Products
- security:
- -
- jwt:
- - Namespace.Manage
- parameters: []
- '/gateways/{gatewayId}/products/{appId}':
- delete:
- operationId: delete-product
- responses:
- '200':
- description: Ok
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/BatchResult'
- description: "Delete a Product\n> `Required Scope:` Namespace.Manage"
- summary: 'Manage Products'
- tags:
- - Products
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: path
- name: appId
- required: true
- schema:
- type: string
- '/gateways/{gatewayId}/environments/{appId}':
- delete:
- operationId: delete-product-environment
- responses:
- '204':
- description: 'No content'
- description: "Delete a Product Environment\n> `Required Scope:` Namespace.Manage"
- summary: 'Delete a Product Environment'
- tags:
- - Products
- security:
- -
- jwt:
- - Namespace.Manage
- parameters:
- -
- in: path
- name: gatewayId
- required: true
- schema:
- type: string
- -
- in: path
- name: appId
- required: true
- schema:
- type: string
- -
- in: query
- name: force
- required: false
- schema:
- default: false
- type: boolean
-servers:
- -
- url: /ds/api/v3
-tags:
- -
- name: 'API Directory'
- description: 'Discover all the great BC Government APIs'
- -
- name: 'API Directory (Administration)'
- description: 'Administer datasets on the API Directory'
- -
- name: Organizations
- description: 'Manage organizational access control'
- -
- name: Gateways
- description: 'Get aggregated information about gateways'
- -
- name: 'Gateway Services'
- description: 'View your Gateway Service details'
- -
- name: Products
- description: 'Manage your Products and Environments for publishing to the API Directory'
- -
- name: 'Authorization Profiles'
- description: 'Configure the integration to external Identity Providers'
diff --git a/src/controllers/v3/routes.ts b/src/controllers/v3/routes.ts
deleted file mode 100644
index 3de19b1d6..000000000
--- a/src/controllers/v3/routes.ts
+++ /dev/null
@@ -1,1726 +0,0 @@
-/* tslint:disable */
-/* eslint-disable */
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { Controller, ValidationService, FieldErrors, ValidateError, TsoaRoute, HttpStatusCodeLiteral, TsoaResponse } from '@tsoa/runtime';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { OrgDatasetController } from './OrgDatasetController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { DirectoryController } from './DirectoryController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { DatasetController } from './DatasetController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { EndpointsController } from './EndpointsController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { NamespaceController } from './GatewayController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { GatewayDirectoryController } from './GatewayDirectoryController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { GatewayController } from './GatewayServicesController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { IdentifiersController } from './IdentifierController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { IssuerController } from './IssuerController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { OrganizationController } from './OrganizationController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { OrgRoleController } from './OrgRoleController';
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-import { ProductController } from './ProductController';
-import { expressAuthentication } from './../../auth/auth-tsoa';
-// @ts-ignore - no great way to install types from subpackage
-const promiseAny = require('promise.any');
-import { iocContainer } from './../ioc';
-import { IocContainer, IocContainerFactory } from '@tsoa/runtime';
-import * as express from 'express';
-const multer = require('multer');
-const upload = multer();
-
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
-const models: TsoaRoute.Models = {
- "DatasetContact": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string"},
- "email": {"dataType":"string"},
- "role": {"dataType":"enum","enums":["pointOfContact"]},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "DatasetResource": {
- "dataType": "refObject",
- "properties": {
- "id": {"dataType":"string"},
- "name": {"dataType":"string"},
- "format": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["openapi-json"]},{"dataType":"enum","enums":["json"]}]},
- "url": {"dataType":"string"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "OrganizationRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "OrganizationUnitRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "Dataset": {
- "dataType": "refObject",
- "properties": {
- "extForeignKey": {"dataType":"string"},
- "name": {"dataType":"string"},
- "license_title": {"dataType":"string"},
- "security_class": {"dataType":"string"},
- "view_audience": {"dataType":"string"},
- "download_audience": {"dataType":"string"},
- "record_publish_date": {"dataType":"string"},
- "notes": {"dataType":"string"},
- "title": {"dataType":"string"},
- "isInCatalog": {"dataType":"string"},
- "isDraft": {"dataType":"string"},
- "contacts": {"dataType":"array","array":{"dataType":"refObject","ref":"DatasetContact"}},
- "resources": {"dataType":"array","array":{"dataType":"refObject","ref":"DatasetResource"}},
- "extSource": {"dataType":"string"},
- "extRecordHash": {"dataType":"string"},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- "organization": {"ref":"OrganizationRefID"},
- "organizationUnit": {"ref":"OrganizationUnitRefID"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "BatchResult": {
- "dataType": "refObject",
- "properties": {
- "status": {"dataType":"double","required":true},
- "result": {"dataType":"string","required":true},
- "reason": {"dataType":"string"},
- "id": {"dataType":"string"},
- "ownedBy": {"dataType":"string"},
- "childResults": {"dataType":"array","array":{"dataType":"refObject","ref":"BatchResult"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "DraftDataset": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string"},
- "license_title": {"dataType":"string"},
- "security_class": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["HIGH-CABINET"]},{"dataType":"enum","enums":["HIGH-CONFIDENTIAL"]},{"dataType":"enum","enums":["HIGH-SENSITIVITY"]},{"dataType":"enum","enums":["MEDIUM-SENSITIVITY"]},{"dataType":"enum","enums":["MEDIUM-PERSONAL"]},{"dataType":"enum","enums":["LOW-SENSITIVITY"]},{"dataType":"enum","enums":["LOW-PUBLIC"]},{"dataType":"enum","enums":["PUBLIC"]},{"dataType":"enum","enums":["PROTECTED A"]},{"dataType":"enum","enums":["PROTECTED B"]},{"dataType":"enum","enums":["PROTECTED C"]}]},
- "view_audience": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["Public"]},{"dataType":"enum","enums":["Government"]},{"dataType":"enum","enums":["Named users"]},{"dataType":"enum","enums":["Government and Business BCeID"]}]},
- "download_audience": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["Public"]},{"dataType":"enum","enums":["Government"]},{"dataType":"enum","enums":["Named users"]},{"dataType":"enum","enums":["Government and Business BCeID"]}]},
- "record_publish_date": {"dataType":"string"},
- "notes": {"dataType":"string"},
- "title": {"dataType":"string"},
- "isInCatalog": {"dataType":"boolean"},
- "isDraft": {"dataType":"boolean"},
- "contacts": {"dataType":"array","array":{"dataType":"refObject","ref":"DatasetContact"}},
- "resources": {"dataType":"array","array":{"dataType":"refObject","ref":"DatasetResource"}},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- "organization": {"ref":"OrganizationRefID"},
- "organizationUnit": {"ref":"OrganizationUnitRefID"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "Gateway": {
- "dataType": "refObject",
- "properties": {
- "gatewayId": {"dataType":"string"},
- "displayName": {"dataType":"string"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "ActivityDetail": {
- "dataType": "refObject",
- "properties": {
- "id": {"dataType":"string"},
- "message": {"dataType":"string","required":true},
- "params": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"string"},"required":true},
- "activityAt": {"dataType":"any","required":true},
- "blob": {"dataType":"any"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "PublishResult": {
- "dataType": "refObject",
- "properties": {
- "message": {"dataType":"string"},
- "results": {"dataType":"string"},
- "error": {"dataType":"string"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GatewayServiceRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GatewayRouteRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GatewayPlugin": {
- "dataType": "refObject",
- "properties": {
- "extForeignKey": {"dataType":"string"},
- "name": {"dataType":"string"},
- "extSource": {"dataType":"string"},
- "extRecordHash": {"dataType":"string"},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- "config": {"dataType":"any"},
- "service": {"ref":"GatewayServiceRefID"},
- "route": {"ref":"GatewayRouteRefID"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GatewayRoute": {
- "dataType": "refObject",
- "properties": {
- "extForeignKey": {"dataType":"string"},
- "name": {"dataType":"string"},
- "gatewayId": {"dataType":"string"},
- "extSource": {"dataType":"string"},
- "extRecordHash": {"dataType":"string"},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- "methods": {"dataType":"array","array":{"dataType":"string"}},
- "paths": {"dataType":"array","array":{"dataType":"string"}},
- "hosts": {"dataType":"array","array":{"dataType":"string"}},
- "service": {"ref":"GatewayServiceRefID"},
- "plugins": {"dataType":"array","array":{"dataType":"refObject","ref":"GatewayPlugin"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "IssuerEnvironmentConfig": {
- "dataType": "refObject",
- "properties": {
- "environment": {"dataType":"string"},
- "exists": {"dataType":"boolean"},
- "issuerUrl": {"dataType":"string"},
- "clientRegistration": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["anonymous"]},{"dataType":"enum","enums":["managed"]},{"dataType":"enum","enums":["iat"]}]},
- "clientId": {"dataType":"string"},
- "clientSecret": {"dataType":"string"},
- "initialAccessToken": {"dataType":"string"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "undefinedRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "CredentialIssuer": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string"},
- "gatewayId": {"dataType":"string"},
- "description": {"dataType":"string"},
- "flow": {"dataType":"enum","enums":["client-credentials"]},
- "mode": {"dataType":"enum","enums":["auto"]},
- "authPlugin": {"dataType":"string"},
- "clientAuthenticator": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["client-secret"]},{"dataType":"enum","enums":["client-jwt"]},{"dataType":"enum","enums":["client-jwt-jwks-url"]}]},
- "instruction": {"dataType":"string"},
- "environmentDetails": {"dataType":"array","array":{"dataType":"refObject","ref":"IssuerEnvironmentConfig"}},
- "resourceType": {"dataType":"string"},
- "resourceAccessScope": {"dataType":"string"},
- "isShared": {"dataType":"boolean"},
- "apiKeyName": {"dataType":"string"},
- "availableScopes": {"dataType":"array","array":{"dataType":"string"}},
- "resourceScopes": {"dataType":"array","array":{"dataType":"string"}},
- "clientRoles": {"dataType":"array","array":{"dataType":"string"}},
- "clientMappers": {"dataType":"array","array":{"dataType":"string"}},
- "inheritFrom": {"ref":"undefinedRefID"},
- "owner": {"ref":"undefinedRefID"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "OrganizationUnit": {
- "dataType": "refObject",
- "properties": {
- "extForeignKey": {"dataType":"string"},
- "name": {"dataType":"string"},
- "sector": {"dataType":"string"},
- "title": {"dataType":"string"},
- "description": {"dataType":"string"},
- "extSource": {"dataType":"string"},
- "extRecordHash": {"dataType":"string"},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "Organization": {
- "dataType": "refObject",
- "properties": {
- "extForeignKey": {"dataType":"string"},
- "name": {"dataType":"string"},
- "sector": {"dataType":"string"},
- "title": {"dataType":"string"},
- "description": {"dataType":"string"},
- "extSource": {"dataType":"string"},
- "extRecordHash": {"dataType":"string"},
- "tags": {"dataType":"array","array":{"dataType":"string"}},
- "orgUnits": {"dataType":"array","array":{"dataType":"refObject","ref":"OrganizationUnit"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GroupPermission": {
- "dataType": "refObject",
- "properties": {
- "resource": {"dataType":"string"},
- "scopes": {"dataType":"array","array":{"dataType":"string"},"required":true},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GroupRole": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string","required":true},
- "permissions": {"dataType":"array","array":{"dataType":"refObject","ref":"GroupPermission"},"required":true},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GroupAccess": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string"},
- "parent": {"dataType":"string"},
- "roles": {"dataType":"array","array":{"dataType":"refObject","ref":"GroupRole"},"required":true},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "UserReference": {
- "dataType": "refObject",
- "properties": {
- "id": {"dataType":"string"},
- "email": {"dataType":"string"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GroupMember": {
- "dataType": "refObject",
- "properties": {
- "member": {"ref":"UserReference","required":true},
- "roles": {"dataType":"array","array":{"dataType":"string"},"required":true},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "GroupMembership": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string"},
- "parent": {"dataType":"string"},
- "members": {"dataType":"array","array":{"dataType":"refObject","ref":"GroupMember"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "OrgNamespace": {
- "dataType": "refObject",
- "properties": {
- "name": {"dataType":"string","required":true},
- "orgUnit": {"dataType":"string","required":true},
- "enabled": {"dataType":"boolean","required":true},
- "updatedAt": {"dataType":"double","required":true},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "DraftDatasetRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "LegalRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "CredentialIssuerRefID": {
- "dataType": "refAlias",
- "type": {"dataType":"string","validators":{}},
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "Environment": {
- "dataType": "refObject",
- "properties": {
- "appId": {"dataType":"string"},
- "name": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["dev"]},{"dataType":"enum","enums":["test"]},{"dataType":"enum","enums":["prod"]},{"dataType":"enum","enums":["sandbox"]},{"dataType":"enum","enums":["other"]}]},
- "active": {"dataType":"boolean"},
- "approval": {"dataType":"boolean"},
- "flow": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["public"]},{"dataType":"enum","enums":["protected-externally"]},{"dataType":"enum","enums":["authorization-code"]},{"dataType":"enum","enums":["client-credentials"]},{"dataType":"enum","enums":["kong-acl-only"]},{"dataType":"enum","enums":["kong-api-key-only"]},{"dataType":"enum","enums":["kong-api-key-acl"]}]},
- "additionalDetailsToRequest": {"dataType":"string"},
- "services": {"dataType":"array","array":{"dataType":"refAlias","ref":"GatewayServiceRefID"}},
- "legal": {"ref":"LegalRefID"},
- "credentialIssuer": {"ref":"CredentialIssuerRefID"},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- "Product": {
- "dataType": "refObject",
- "properties": {
- "appId": {"dataType":"string"},
- "name": {"dataType":"string"},
- "description": {"dataType":"string"},
- "gatewayId": {"dataType":"string"},
- "dataset": {"ref":"DraftDatasetRefID"},
- "environments": {"dataType":"array","array":{"dataType":"refObject","ref":"Environment"}},
- },
- "additionalProperties": false,
- },
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-};
-const validationService = new ValidationService(models);
-
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
-export function RegisterRoutes(app: express.Router) {
- // ###########################################################################################################
- // NOTE: If you do not see routes for all of your controllers in this file, then you might not have informed tsoa of where to look
- // Please look into the "controllerPathGlobs" config option described in the readme: https://github.com/lukeautry/tsoa
- // ###########################################################################################################
- app.get('/ds/api/v3/organizations/:org/datasets',
- authenticateMiddleware([{"jwt":["Dataset.Manage"]}]),
-
- async function OrgDatasetController_getDatasets(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrgDatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getDatasets.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/organizations/:org/datasets',
- authenticateMiddleware([{"jwt":["Dataset.Manage"]}]),
-
- async function OrgDatasetController_putDataset(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"DraftDataset"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrgDatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.putDataset.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/organizations/:org/datasets/:name',
- authenticateMiddleware([{"jwt":["Dataset.Manage"]}]),
-
- async function OrgDatasetController_delete(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- name: {"in":"path","name":"name","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrgDatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.delete.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org/datasets/:name',
- authenticateMiddleware([{"jwt":["Dataset.Manage"]}]),
-
- async function OrgDatasetController_getDataset(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- name: {"in":"path","name":"name","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrgDatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getDataset.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/directory',
-
- async function DirectoryController_list(request: any, response: any, next: any) {
- const args = {
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(DirectoryController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.list.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/directory/:id',
-
- async function DirectoryController_get(request: any, response: any, next: any) {
- const args = {
- id: {"in":"path","name":"id","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(DirectoryController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.get.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/gateways/:gatewayId/datasets',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function DatasetController_put(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"DraftDataset"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(DatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.put.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/datasets/:name',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function DatasetController_getDataset(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- name: {"in":"path","name":"name","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(DatasetController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getDataset.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/routes/availability',
-
- async function EndpointsController_check(request: any, response: any, next: any) {
- const args = {
- serviceName: {"in":"query","name":"serviceName","required":true,"dataType":"string"},
- gatewayId: {"in":"query","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(EndpointsController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.check.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/report',
- authenticateMiddleware([{"jwt":[]}]),
-
- async function NamespaceController_report(request: any, response: any, next: any) {
- const args = {
- req: {"in":"request","name":"req","required":true,"dataType":"object"},
- ids: {"default":"[]","in":"query","name":"ids","dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.report.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways',
- authenticateMiddleware([{"jwt":[]}]),
-
- async function NamespaceController_list(request: any, response: any, next: any) {
- const args = {
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.list.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function NamespaceController_profile(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.profile.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.post('/ds/api/v3/gateways',
- authenticateMiddleware([{"jwt":[]}]),
-
- async function NamespaceController_create(request: any, response: any, next: any) {
- const args = {
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- vars: {"in":"body","name":"vars","required":true,"ref":"Gateway"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.create.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/gateways/:gatewayId',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function NamespaceController_delete(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- force: {"default":false,"in":"query","name":"force","dataType":"boolean"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.delete.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/activity',
- authenticateMiddleware([{"jwt":["Namespace.View"]}]),
-
- async function NamespaceController_namespaceActivity(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- first: {"default":20,"in":"query","name":"first","dataType":"double"},
- skip: {"default":0,"in":"query","name":"skip","dataType":"double"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.namespaceActivity.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/links',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function NamespaceController_get(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(NamespaceController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.get.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/directory/:id',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function GatewayDirectoryController_getDataset(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- id: {"in":"path","name":"id","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(GatewayDirectoryController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getDataset.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/directory',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function GatewayDirectoryController_getDatasets(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(GatewayDirectoryController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getDatasets.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/gateways/:gatewayId/services',
- authenticateMiddleware([{"jwt":["Gateway.Config"]}]),
- upload.single('configFile'),
-
- async function GatewayController_put(request: any, response: any, next: any) {
- const args = {
- dryRun: {"in":"formData","name":"dryRun","required":true,"dataType":"string"},
- configFile: {"in":"formData","name":"configFile","required":true,"dataType":"file"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(GatewayController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.put.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/services',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function GatewayController_getServices(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(GatewayController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getServices.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/identifiers/:type',
-
- async function IdentifiersController_getNewID(request: any, response: any, next: any) {
- const args = {
- type: {"in":"path","name":"type","required":true,"dataType":"union","subSchemas":[{"dataType":"enum","enums":["environment"]},{"dataType":"enum","enums":["product"]},{"dataType":"enum","enums":["application"]},{"dataType":"enum","enums":["gateway"]}]},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(IdentifiersController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getNewID.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/gateways/:gatewayId/issuers',
- authenticateMiddleware([{"jwt":["CredentialIssuer.Admin"]}]),
-
- async function IssuerController_put(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"CredentialIssuer"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(IssuerController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.put.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/issuers',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function IssuerController_get(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(IssuerController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.get.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/gateways/:gatewayId/issuers/:name',
- authenticateMiddleware([{"jwt":["CredentialIssuer.Admin"]}]),
-
- async function IssuerController_delete(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- name: {"in":"path","name":"name","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(IssuerController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.delete.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations',
-
- async function OrganizationController_listOrganizations(request: any, response: any, next: any) {
- const args = {
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.listOrganizations.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/organizations/:org',
- authenticateMiddleware([{"jwt":["GroupAccess.Manage"]}]),
-
- async function OrganizationController_post(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"Organization"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.post.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org',
-
- async function OrganizationController_listOrganizationUnits(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.listOrganizationUnits.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org/roles',
- authenticateMiddleware([{"jwt":["GroupAccess.Manage"]}]),
-
- async function OrganizationController_getPolicies(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getPolicies.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org/access',
- authenticateMiddleware([{"jwt":["GroupAccess.Manage"]}]),
-
- async function OrganizationController_get(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.get.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/organizations/:org/access',
- authenticateMiddleware([{"jwt":["GroupAccess.Manage"]}]),
-
- async function OrganizationController_put(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"GroupMembership"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.put.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org/gateways',
- authenticateMiddleware([{"jwt":["Namespace.Assign"]}]),
-
- async function OrganizationController_listNamespaces(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.listNamespaces.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/organizations/:org/:orgUnit/gateways/:gatewayId',
- authenticateMiddleware([{"jwt":["Namespace.Assign"]}]),
-
- async function OrganizationController_assignNamespace(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- orgUnit: {"in":"path","name":"orgUnit","required":true,"dataType":"string"},
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- enable: {"default":true,"in":"query","name":"enable","dataType":"boolean"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.assignNamespace.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/organizations/:org/:orgUnit/gateways/:gatewayId',
- authenticateMiddleware([{"jwt":["Namespace.Assign"]}]),
-
- async function OrganizationController_unassignNamespace(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- orgUnit: {"in":"path","name":"orgUnit","required":true,"dataType":"string"},
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.unassignNamespace.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/organizations/:org/activity',
- authenticateMiddleware([{"jwt":["Namespace.Assign"]}]),
-
- async function OrganizationController_namespaceActivity(request: any, response: any, next: any) {
- const args = {
- org: {"in":"path","name":"org","required":true,"dataType":"string"},
- first: {"default":20,"in":"query","name":"first","dataType":"double"},
- skip: {"default":0,"in":"query","name":"skip","dataType":"double"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrganizationController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.namespaceActivity.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/roles',
-
- async function OrgRoleController_getRoles(request: any, response: any, next: any) {
- const args = {
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(OrgRoleController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.getRoles.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.put('/ds/api/v3/gateways/:gatewayId/products',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function ProductController_put(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- body: {"in":"body","name":"body","required":true,"ref":"Product"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(ProductController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.put.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.get('/ds/api/v3/gateways/:gatewayId/products',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function ProductController_get(request: any, response: any, next: any) {
- const args = {
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(ProductController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.get.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/gateways/:gatewayId/products/:appId',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function ProductController_delete(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- appId: {"in":"path","name":"appId","required":true,"dataType":"string"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(ProductController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.delete.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- app.delete('/ds/api/v3/gateways/:gatewayId/environments/:appId',
- authenticateMiddleware([{"jwt":["Namespace.Manage"]}]),
-
- async function ProductController_deleteEnvironment(request: any, response: any, next: any) {
- const args = {
- gatewayId: {"in":"path","name":"gatewayId","required":true,"dataType":"string"},
- appId: {"in":"path","name":"appId","required":true,"dataType":"string"},
- force: {"default":false,"in":"query","name":"force","dataType":"boolean"},
- request: {"in":"request","name":"request","required":true,"dataType":"object"},
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- let validatedArgs: any[] = [];
- try {
- validatedArgs = getValidatedArgs(args, request, response);
-
- const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;
-
- const controller: any = await container.get(ProductController);
- if (typeof controller['setStatus'] === 'function') {
- controller.setStatus(undefined);
- }
-
-
- const promise = controller.deleteEnvironment.apply(controller, validatedArgs as any);
- promiseHandler(controller, promise, response, undefined, next);
- } catch (err) {
- return next(err);
- }
- });
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- function authenticateMiddleware(security: TsoaRoute.Security[] = []) {
- return async function runAuthenticationMiddleware(request: any, _response: any, next: any) {
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- // keep track of failed auth attempts so we can hand back the most
- // recent one. This behavior was previously existing so preserving it
- // here
- const failedAttempts: any[] = [];
- const pushAndRethrow = (error: any) => {
- failedAttempts.push(error);
- throw error;
- };
-
- const secMethodOrPromises: Promise[] = [];
- for (const secMethod of security) {
- if (Object.keys(secMethod).length > 1) {
- const secMethodAndPromises: Promise[] = [];
-
- for (const name in secMethod) {
- secMethodAndPromises.push(
- expressAuthentication(request, name, secMethod[name])
- .catch(pushAndRethrow)
- );
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- secMethodOrPromises.push(Promise.all(secMethodAndPromises)
- .then(users => { return users[0]; }));
- } else {
- for (const name in secMethod) {
- secMethodOrPromises.push(
- expressAuthentication(request, name, secMethod[name])
- .catch(pushAndRethrow)
- );
- }
- }
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- try {
- request['user'] = await promiseAny(secMethodOrPromises);
- next();
- }
- catch(err) {
- // Show most recent error as response
- const error = failedAttempts.pop();
- error.status = error.status || 401;
- next(error);
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
- }
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- function isController(object: any): object is Controller {
- return 'getHeaders' in object && 'getStatus' in object && 'setStatus' in object;
- }
-
- function promiseHandler(controllerObj: any, promise: any, response: any, successStatus: any, next: any) {
- return Promise.resolve(promise)
- .then((data: any) => {
- let statusCode = successStatus;
- let headers;
- if (isController(controllerObj)) {
- headers = controllerObj.getHeaders();
- statusCode = controllerObj.getStatus() || statusCode;
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- returnHandler(response, statusCode, data, headers)
- })
- .catch((error: any) => next(error));
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- function returnHandler(response: any, statusCode?: number, data?: any, headers: any = {}) {
- if (response.headersSent) {
- return;
- }
- Object.keys(headers).forEach((name: string) => {
- response.set(name, headers[name]);
- });
- if (data && typeof data.pipe === 'function' && data.readable && typeof data._read === 'function') {
- data.pipe(response);
- } else if (data !== null && data !== undefined) {
- response.status(statusCode || 200).json(data);
- } else {
- response.status(statusCode || 204).end();
- }
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- function responder(response: any): TsoaResponse {
- return function(status, data, headers) {
- returnHandler(response, status, data, headers);
- };
- };
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-
- function getValidatedArgs(args: any, request: any, response: any): any[] {
- const fieldErrors: FieldErrors = {};
- const values = Object.keys(args).map((key) => {
- const name = args[key].name;
- switch (args[key].in) {
- case 'request':
- return request;
- case 'query':
- return validationService.ValidateParam(args[key], request.query[name], name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- case 'path':
- return validationService.ValidateParam(args[key], request.params[name], name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- case 'header':
- return validationService.ValidateParam(args[key], request.header(name), name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- case 'body':
- return validationService.ValidateParam(args[key], request.body, name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- case 'body-prop':
- return validationService.ValidateParam(args[key], request.body[name], name, fieldErrors, 'body.', {"noImplicitAdditionalProperties":"throw-on-extras"});
- case 'formData':
- if (args[key].dataType === 'file') {
- return validationService.ValidateParam(args[key], request.file, name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- } else if (args[key].dataType === 'array' && args[key].array.dataType === 'file') {
- return validationService.ValidateParam(args[key], request.files, name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- } else {
- return validationService.ValidateParam(args[key], request.body[name], name, fieldErrors, undefined, {"noImplicitAdditionalProperties":"throw-on-extras"});
- }
- case 'res':
- return responder(response);
- }
- });
-
- if (Object.keys(fieldErrors).length > 0) {
- throw new ValidateError(fieldErrors, '');
- }
- return values;
- }
-
- // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
-}
-
-// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
From 3c4c009c4db74e44475bf3c9a9721dc840542aa7 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 20 Dec 2024 08:02:46 -0800
Subject: [PATCH 12/37] Update Node.js engine requirement in package.json to
support versions 22.x
---
src/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/package.json b/src/package.json
index 8d04ff94f..14d3343ef 100644
--- a/src/package.json
+++ b/src/package.json
@@ -8,7 +8,7 @@
"homepage": "https://github.com/keystonejs/keystone",
"license": "MIT",
"engines": {
- "node": ">=10.0.0"
+ "node": ">=22.0.0 <23.0.0"
},
"main": "dist/server.js",
"nodemonConfig": {
From e964a72059722ff5a11c832442a226ff0a0130b1 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 20 Dec 2024 12:29:35 -0800
Subject: [PATCH 13/37] Avoid socket hangup: enhance Keycloak auth in group
service with retry logic; improve error handling in namespace service login
---
src/services/keycloak/group-service.ts | 57 ++++++++++++++++++++------
src/services/org-groups/namespace.ts | 7 +++-
2 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/src/services/keycloak/group-service.ts b/src/services/keycloak/group-service.ts
index 45a72b7ca..d6c23c896 100644
--- a/src/services/keycloak/group-service.ts
+++ b/src/services/keycloak/group-service.ts
@@ -15,6 +15,10 @@ const logger = Logger('kc.group');
export class KeycloakGroupService {
private allGroups: any = undefined;
private kcAdminClient: KeycloakAdminClient;
+ private clientId: string;
+ private clientSecret: string;
+ private lastAuthTime: number = 0;
+ private readonly AUTH_TIMEOUT = 280 * 1000; // 280 seconds (slightly less than typical 5 min token lifetime)
constructor(issuerUrl: string) {
const baseUrl = issuerUrl.substr(0, issuerUrl.indexOf('/realms'));
@@ -23,26 +27,52 @@ export class KeycloakGroupService {
this.kcAdminClient = new KcAdminClient({ baseUrl, realmName });
}
+ private async ensureAuthenticated(): Promise {
+ if (this.clientId && (Date.now() - this.lastAuthTime > this.AUTH_TIMEOUT)) {
+ logger.debug('[ensureAuthenticated] Re-authenticating due to timeout');
+ await this.login(this.clientId, this.clientSecret);
+ }
+ }
+
public async cacheGroups() {
this.allGroups = await this.getAllGroups();
}
public async login(
clientId: string,
- clientSecret: string
+ clientSecret: string,
+ retryAttempts: number = 3
): Promise {
- logger.debug('[login] %s', clientId);
-
- await this.kcAdminClient
- .auth({
- grantType: 'client_credentials',
- clientId: clientId,
- clientSecret: clientSecret,
- })
- .catch((err: any) => {
- logger.error('[login] Login failed %s', err);
- throw err;
- });
+ this.clientId = clientId;
+ this.clientSecret = clientSecret;
+
+ const result = await this._login(retryAttempts);
+ this.lastAuthTime = Date.now();
+ return result;
+ }
+
+ private async _login(retryAttempts: number): Promise {
+ logger.debug('[login] %s', this.clientId);
+
+ for (let attempt = 1; attempt <= retryAttempts; attempt++) {
+ try {
+ await this.kcAdminClient
+ .auth({
+ grantType: 'client_credentials',
+ clientId: this.clientId,
+ clientSecret: this.clientSecret,
+ });
+ return this;
+ } catch (err: any) {
+ if (attempt === retryAttempts) {
+ logger.error('[login] Login failed after %d attempts: %s', retryAttempts, err);
+ throw err;
+ }
+ logger.warn('[login] Attempt %d failed, retrying: %s', attempt, err);
+ // Add exponential backoff
+ await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
+ }
+ }
return this;
}
@@ -70,6 +100,7 @@ export class KeycloakGroupService {
}
public async updateGroup(group: GroupRepresentation): Promise {
+ await this.ensureAuthenticated();
logger.debug('[updateGroup] %j', group);
await this.kcAdminClient.groups.update({ id: group.id }, group);
}
diff --git a/src/services/org-groups/namespace.ts b/src/services/org-groups/namespace.ts
index ef321f51f..42c26f77a 100644
--- a/src/services/org-groups/namespace.ts
+++ b/src/services/org-groups/namespace.ts
@@ -13,7 +13,12 @@ export class NamespaceService {
}
async login(clientId: string, clientSecret: string) {
- await this.groupService.login(clientId, clientSecret);
+ try {
+ await this.groupService.login(clientId, clientSecret);
+ } catch (err) {
+ logger.error('[login] Failed to login to Keycloak: %s', err);
+ throw new Error('Failed to authenticate with Keycloak');
+ }
}
async markNotification(ns: string, viewed: boolean): Promise {
From afea353cf82efb2d07484d71f5842582398787b3 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 20 Dec 2024 15:16:56 -0800
Subject: [PATCH 14/37] Enhance Cypress E2E test logging in GitHub Actions
workflow; added current test progress
---
.github/workflows/aps-cypress-e2e.yaml | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index aaef58651..ac811a32d 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -53,8 +53,16 @@ jobs:
docker compose down
break
else
- echo "Waiting for Cypress to Complete E2E Tests....."
- sleep 1m
+ echo "Current Test Progress:"
+ docker logs cypress-e2e 2>&1 | grep -E "Running:|✓|×" | tail -n 5
+
+ # Get failure count from the most recent logs
+ FAILURES=$(docker logs cypress-e2e 2>&1 | grep -c "×" || true)
+ if [ $FAILURES -gt 0 ]; then
+ echo "❌ Current failure count: $FAILURES"
+ fi
+
+ sleep 30s
fi
done
From 3075f0913b5193b6358682b026499f70077f9b1f Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 20 Dec 2024 16:28:17 -0800
Subject: [PATCH 15/37] bump cli version in tests
---
e2e/Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/e2e/Dockerfile b/e2e/Dockerfile
index 2a093d736..74f6b878b 100644
--- a/e2e/Dockerfile
+++ b/e2e/Dockerfile
@@ -22,7 +22,7 @@ COPY e2e/*.yml /e2e
COPY e2e/entrypoint.sh /tmp
ADD e2e/cypress /e2e/cypress
-RUN curl -v -L -O https://github.com/bcgov/gwa-cli/releases/download/v3.0.4/gwa_Linux_x86_64.tgz \
+RUN curl -v -L -O https://github.com/bcgov/gwa-cli/releases/download/v3.0.5/gwa_Linux_x86_64.tgz \
&& tar -xzf gwa_Linux_x86_64.tgz \
&& mv gwa /usr/local/bin/.
From f472539c0761b4cd336d060ddce4871c643a3be9 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 24 Dec 2024 08:17:46 -0800
Subject: [PATCH 16/37] modify show cypress progress
---
.github/workflows/aps-cypress-e2e.yaml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index ac811a32d..d4d76d6db 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -54,10 +54,11 @@ jobs:
break
else
echo "Current Test Progress:"
- docker logs cypress-e2e 2>&1 | grep -E "Running:|✓|×" | tail -n 5
+ docker logs cypress-e2e 2>&1 | grep -E "Running:|✓|^[0-9]+\)" | tail -n 5
# Get failure count from the most recent logs
- FAILURES=$(docker logs cypress-e2e 2>&1 | grep -c "×" || true)
+ # Count lines starting with a number followed by ')'
+ FAILURES=$(docker logs cypress-e2e 2>&1 | grep -c "^[0-9]\+)" || true)
if [ $FAILURES -gt 0 ]; then
echo "❌ Current failure count: $FAILURES"
fi
From 5b049957f32181466cdecbfdaba52435425f5bc3 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 24 Dec 2024 14:16:02 -0800
Subject: [PATCH 17/37] peg ubuntu version for GHA runner, stream all cypress
logs
---
.github/workflows/aps-cypress-e2e.yaml | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index d4d76d6db..517aab511 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -17,7 +17,7 @@ env:
jobs:
cypress-run:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
steps:
- name: Build GWA API Image
run: |
@@ -47,22 +47,19 @@ jobs:
- name: Execute Tests & Clean Up
run: |
+ # Start following logs in the background with continuous output
+ docker logs -f cypress-e2e 2>&1 &
+ LOG_PID=$!
+
while true; do
if [ "$(docker ps -aq -f status=exited -f name=cypress-e2e)" ]; then
+ echo "Cypress tests completed."
+ # Kill the log following process
+ kill $LOG_PID
# cleanup
docker compose down
break
else
- echo "Current Test Progress:"
- docker logs cypress-e2e 2>&1 | grep -E "Running:|✓|^[0-9]+\)" | tail -n 5
-
- # Get failure count from the most recent logs
- # Count lines starting with a number followed by ')'
- FAILURES=$(docker logs cypress-e2e 2>&1 | grep -c "^[0-9]\+)" || true)
- if [ $FAILURES -gt 0 ]; then
- echo "❌ Current failure count: $FAILURES"
- fi
-
sleep 30s
fi
done
From 00bc2d0d2e9b90075c93b4e23de40d447c8703b7 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 31 Dec 2024 11:23:41 -0800
Subject: [PATCH 18/37] use ubuntu-latest, gwa-api v1.0.40
---
.github/workflows/aps-cypress-e2e.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index 517aab511..68a8e809f 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -17,11 +17,11 @@ env:
jobs:
cypress-run:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
steps:
- name: Build GWA API Image
run: |
- git clone https://github.com/bcgov/gwa-api.git
+ git clone https://github.com/bcgov/gwa-api.git --branch v1.0.40
cd gwa-api/microservices/gatewayApi
docker build -t gwa-api:e2e .
From 1eed10b6ad371e138f004c8cd2ff376d5ed35f7a Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 31 Dec 2024 08:43:03 -0800
Subject: [PATCH 19/37] add data_plane_config for gwa api
---
local/gwa-api/.env.local | 1 +
local/gwa-api/data_planes_config.json | 9 +++++++++
2 files changed, 10 insertions(+)
create mode 100644 local/gwa-api/data_planes_config.json
diff --git a/local/gwa-api/.env.local b/local/gwa-api/.env.local
index 7cf8877d2..be995a043 100644
--- a/local/gwa-api/.env.local
+++ b/local/gwa-api/.env.local
@@ -4,6 +4,7 @@ OIDC_BASE_URL=http://keycloak.localtest.me:9081/auth/realms/master
TOKEN_MATCH_AUD=gwa
WORKING_FOLDER=/tmp
CONFIG_PATH=/tmp/production.json
+DATA_PLANES_CONFIG_PATH=/tmp/gwa/data_planes_config.json
ENVIRONMENT=production
KONG_ADMIN_URL=http://kong.localtest.me:8001
KC_SERVER_URL=http://keycloak.localtest.me:9081/auth/
diff --git a/local/gwa-api/data_planes_config.json b/local/gwa-api/data_planes_config.json
new file mode 100644
index 000000000..5015c1c75
--- /dev/null
+++ b/local/gwa-api/data_planes_config.json
@@ -0,0 +1,9 @@
+{
+ "data_planes": {
+ "local.dataplane": {
+ "kube-api": "https://api.cloud",
+ "kube-ns": "xxxxxx-dev",
+ "validate-upstreams": false
+ }
+ }
+}
\ No newline at end of file
From 23932d80d28362b1b2832d3fc01d7c0fb0cb1427 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Thu, 2 Jan 2025 15:07:52 -0800
Subject: [PATCH 20/37] disable migrate user tests
---
e2e/cypress.config.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/e2e/cypress.config.ts b/e2e/cypress.config.ts
index 43b2102f1..2789d860c 100644
--- a/e2e/cypress.config.ts
+++ b/e2e/cypress.config.ts
@@ -26,7 +26,7 @@ export default defineConfig({
'./cypress/tests/07-*/*.ts',
'./cypress/tests/03-*/*.ts',
'./cypress/tests/04-*/*.ts',
- './cypress/tests/05-*/*.ts',
+ // './cypress/tests/05-*/*.ts',
'./cypress/tests/08-*/*.ts',
'./cypress/tests/09-*/*.ts',
'./cypress/tests/10-*/*.ts',
@@ -59,7 +59,7 @@ export default defineConfig({
},
chromeWebSecurity: false,
env: {
- ASTRA_SCAN_ENABLED: true,
+ ASTRA_SCAN_ENABLED: false,
CLIENT_ID: 'aps-portal',
CLIENT_SECRET: '8e1a17ed-cb93-4806-ac32-e303d1c86018',
OIDC_ISSUER: 'http://keycloak.localtest.me:9081/auth/realms/master',
From b95c0a3c7c9d129c29d152ab12f22678f7ff5099 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Thu, 2 Jan 2025 16:17:21 -0800
Subject: [PATCH 21/37] fix error msg for generate-config service validation
---
.../tests/16-gwa-cli/02-cli-generate-config-quick-start.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config-quick-start.ts b/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config-quick-start.ts
index 403087a01..b19f5d0aa 100644
--- a/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config-quick-start.ts
+++ b/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config-quick-start.ts
@@ -103,7 +103,7 @@ describe('Verify CLI commands for generate/apply config', () => {
cy.executeCliCommand('gwa gateway create --generate').then((response) => {
const namespace = response.stdout.match(/\bgw-\w+/g)[0]
cy.executeCliCommand(command).then((response) => {
- expect(response.stderr).to.contain(`Error: Service ${serviceName} is already in use. Suggestion: ${namespace}-${serviceName}`)
+ expect(response.stderr).to.contain(`Error: Checking service availability: Service ${serviceName} is already in use. Suggestion: ${namespace}-${serviceName}`)
});
});
})
From dab5b6d343988c58c006cdc3cad671c4e128c0ff Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 09:44:34 -0800
Subject: [PATCH 22/37] Change regex validation in utils.ts to use assert.ok
---
src/services/utils.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/utils.ts b/src/services/utils.ts
index 7bcfb87d4..427cd4a57 100644
--- a/src/services/utils.ts
+++ b/src/services/utils.ts
@@ -58,7 +58,7 @@ export function regExprValidation(
errorMessage: string
) {
const re = new RegExp(rule);
- assert.strictEqual(re.test(value), true, errorMessage);
+ assert.ok(re.test(value), errorMessage);
}
export async function fetchWithTimeout(resource: string, options: any = {}) {
From ebf6f2bb78b5beb8eacba9cc143817f3694d3b0d Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 10:02:47 -0800
Subject: [PATCH 23/37] Update error message for Gateway ID validation
---
e2e/cypress/tests/19-api-v3/03-gateways.ts | 2 +-
src/lists/extensions/Namespace.ts | 2 +-
src/services/keycloak/namespace-details.ts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/e2e/cypress/tests/19-api-v3/03-gateways.ts b/e2e/cypress/tests/19-api-v3/03-gateways.ts
index 09db841b3..a3620c29a 100644
--- a/e2e/cypress/tests/19-api-v3/03-gateways.ts
+++ b/e2e/cypress/tests/19-api-v3/03-gateways.ts
@@ -188,7 +188,7 @@ describe('Gateways', () => {
details: {
d0: {
message:
- 'Namespace name must be between 5 and 15 alpha-numeric lowercase characters and start and end with an alphabet.',
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.',
},
},
}
diff --git a/src/lists/extensions/Namespace.ts b/src/lists/extensions/Namespace.ts
index 85b5565a7..773e9d294 100644
--- a/src/lists/extensions/Namespace.ts
+++ b/src/lists/extensions/Namespace.ts
@@ -251,7 +251,7 @@ module.exports = {
assert.strictEqual(
re.test(args.namespace),
true,
- 'Gateway name must be between 5 and 15 alpha-numeric lowercase characters and begin with an alphabet.'
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.'
);
const noauthContext = context.createContext({
skipAccessControl: true,
diff --git a/src/services/keycloak/namespace-details.ts b/src/services/keycloak/namespace-details.ts
index 14cbdd831..021248c2e 100644
--- a/src/services/keycloak/namespace-details.ts
+++ b/src/services/keycloak/namespace-details.ts
@@ -195,7 +195,7 @@ export function validateNamespaceName(name: string) {
regExprValidation(
namespaceValidationRule,
name,
- 'Namespace name must be between 5 and 15 alpha-numeric lowercase characters and start and end with an alphabet.'
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.'
);
}
From 231a4cd7ca427dc13bb8968b2a1b12b058b7f6bb Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 13:56:08 -0800
Subject: [PATCH 24/37] upgrade node-fetch
---
src/package.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/package.json b/src/package.json
index 14d3343ef..d238add76 100644
--- a/src/package.json
+++ b/src/package.json
@@ -110,6 +110,7 @@
"keycloak-connect": "^17.0.1",
"lodash": "^4.17.21",
"multer": "^1.4.2",
+ "node-fetch": "^2.7.0",
"nodemailer": "^6.6.0",
"npmlog": "^6.0.1",
"numeral": "^2.0.6",
From 406337b47fe02cfb96828b45caea716e86abaff6 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 14:18:22 -0800
Subject: [PATCH 25/37] ensure subsequent steps are run in aps-cypress-e2e GHA
---
.github/workflows/aps-cypress-e2e.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index 68a8e809f..781b364d5 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -65,18 +65,21 @@ jobs:
done
- name: Upload E2E Test Results HTML Report
+ if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-html
path: ${{ github.workspace }}/e2e/results/report
- name: Upload E2E Test Results JSON Report
+ if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-json
path: ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json
- name: Upload E2E Code Coverage Report
+ if: always()
uses: actions/upload-artifact@v4
with:
name: code-coverage
@@ -89,6 +92,7 @@ jobs:
path: ${{ github.workspace }}/e2e/cypress/fixtures/state/scanResult.json
- name: Instrument the code for coverage analysis
+ if: always()
run: |
# Rewrite the paths as the coverage starts with '../app'!
sed -e 's/..\/app/./g' ./e2e/coverage/lcov.info > lcov.info
@@ -98,6 +102,7 @@ jobs:
#npx nyc instrument --compact=false . --in-place
- name: SonarCloud Scan
+ if: always()
uses: sonarsource/sonarcloud-github-action@master
with:
args: >
@@ -113,6 +118,7 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Check for failed tests and create Issue
+ if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
From cb4b85d020a4c153546aa2c900738d12e2ef301b Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 14:19:50 -0800
Subject: [PATCH 26/37] enable astra scan
---
e2e/cypress.config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/e2e/cypress.config.ts b/e2e/cypress.config.ts
index 2789d860c..9e9a28add 100644
--- a/e2e/cypress.config.ts
+++ b/e2e/cypress.config.ts
@@ -59,7 +59,7 @@ export default defineConfig({
},
chromeWebSecurity: false,
env: {
- ASTRA_SCAN_ENABLED: false,
+ ASTRA_SCAN_ENABLED: true,
CLIENT_ID: 'aps-portal',
CLIENT_SECRET: '8e1a17ed-cb93-4806-ac32-e303d1c86018',
OIDC_ISSUER: 'http://keycloak.localtest.me:9081/auth/realms/master',
From cf0fc043d8be5bfd53e4d2783daf527809d9b684 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 3 Jan 2025 14:27:52 -0800
Subject: [PATCH 27/37] upgrade upload-sarif for trivy, try fixing output path
for anchore
---
.github/workflows/ci-anchore-img-scan.yaml | 3 ++-
.github/workflows/ci-trivy-img-scan.yaml | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci-anchore-img-scan.yaml b/.github/workflows/ci-anchore-img-scan.yaml
index 8c60b6393..0764cf241 100644
--- a/.github/workflows/ci-anchore-img-scan.yaml
+++ b/.github/workflows/ci-anchore-img-scan.yaml
@@ -17,7 +17,8 @@ jobs:
with:
image: 'bcgov/api-services-portal:anchore-scan'
fail-build: false
+ output-file: 'anchore-results.sarif'
- name: Upload Anchore Scan Results
uses: github/codeql-action/upload-sarif@v3
with:
- sarif_file: results.sarif
+ sarif_file: anchore-results.sarif
diff --git a/.github/workflows/ci-trivy-img-scan.yaml b/.github/workflows/ci-trivy-img-scan.yaml
index bcea8fdba..0a2ced443 100644
--- a/.github/workflows/ci-trivy-img-scan.yaml
+++ b/.github/workflows/ci-trivy-img-scan.yaml
@@ -24,6 +24,6 @@ jobs:
template: '@/contrib/sarif.tpl'
output: 'trivy-results.sarif'
- name: Upload Trivy Scan Results
- uses: github/codeql-action/upload-sarif@v2
+ uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
From 0f1d3563b557e973273a9beee882d615dd7634cc Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 6 Jan 2025 08:39:23 -0800
Subject: [PATCH 28/37] Refactor GitHub Actions workflow for Cypress E2E tests
- Removed redundant log process termination.
- Reordered step to create a GitHub issue if failures are detected.
- Updated the SonarCloud scan action to use the latest SonarQube GitHub action.
---
.github/workflows/aps-cypress-e2e.yaml | 52 ++++++++++++--------------
1 file changed, 24 insertions(+), 28 deletions(-)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index 781b364d5..b6572d0d4 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -54,8 +54,6 @@ jobs:
while true; do
if [ "$(docker ps -aq -f status=exited -f name=cypress-e2e)" ]; then
echo "Cypress tests completed."
- # Kill the log following process
- kill $LOG_PID
# cleanup
docker compose down
break
@@ -90,9 +88,31 @@ jobs:
with:
name: astra-scan-results
path: ${{ github.workspace }}/e2e/cypress/fixtures/state/scanResult.json
+
+ - name: Check for failed tests and create Issue
+ if: always()
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ FAILURE_COUNT=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq '.stats.failures')
+ if [[ "$FAILURE_COUNT" -gt 0 ]]; then
+ FAILED_TESTS=$(jq -r '
+ .results[] |
+ (.file | split("/") | .[2:] | join("/")) as $file |
+ .. |
+ .tests? // empty |
+ .[] |
+ select(.fail == true) |
+ "- " + $file + " - " + .title
+ ' ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json)
+ STATS=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq -r '.stats | to_entries | map("\(.key)\t\(.value)") | .[]' | column -t)
+ echo -e "Stats: $STATS\n\nFailed Tests:\n$FAILED_TESTS\n\nRun Link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" > msg
+ export MSG=$(cat msg)
+ gh issue create --title "FAILED: Automated Tests($FAILURE_COUNT)" --body "$MSG" --label "automation" --assignee "${{ env.GIT_COMMIT_AUTHOR }}"
+ exit 1
+ fi
- name: Instrument the code for coverage analysis
- if: always()
run: |
# Rewrite the paths as the coverage starts with '../app'!
sed -e 's/..\/app/./g' ./e2e/coverage/lcov.info > lcov.info
@@ -102,8 +122,7 @@ jobs:
#npx nyc instrument --compact=false . --in-place
- name: SonarCloud Scan
- if: always()
- uses: sonarsource/sonarcloud-github-action@master
+ uses: sonarsource/sonarqube-scan-action@master
with:
args: >
-Dsonar.organization=bcgov-oss
@@ -117,29 +136,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- - name: Check for failed tests and create Issue
- if: always()
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- FAILURE_COUNT=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq '.stats.failures')
- if [[ "$FAILURE_COUNT" -gt 0 ]]; then
- FAILED_TESTS=$(jq -r '
- .results[] |
- (.file | split("/") | .[2:] | join("/")) as $file |
- .. |
- .tests? // empty |
- .[] |
- select(.fail == true) |
- "- " + $file + " - " + .title
- ' ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json)
- STATS=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq -r '.stats | to_entries | map("\(.key)\t\(.value)") | .[]' | column -t)
- echo -e "Stats: $STATS\n\nFailed Tests:\n$FAILED_TESTS\n\nRun Link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" > msg
- export MSG=$(cat msg)
- gh issue create --title "FAILED: Automated Tests($FAILURE_COUNT)" --body "$MSG" --label "automation" --assignee "${{ env.GIT_COMMIT_AUTHOR }}"
- exit 1
- fi
-
- name: Set up Python 3.9
if: failure()
uses: actions/setup-python@v2
From 47d3f0040cef36197fab451a37882e5c47f2c350 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Mon, 6 Jan 2025 08:44:10 -0800
Subject: [PATCH 29/37] Trigger E2E tests on PRs to `dev`
---
.github/workflows/aps-cypress-e2e.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml
index b6572d0d4..5245af7bf 100644
--- a/.github/workflows/aps-cypress-e2e.yaml
+++ b/.github/workflows/aps-cypress-e2e.yaml
@@ -4,6 +4,8 @@ on:
workflow_dispatch: {}
push:
branches: ['test', 'cypress/*']
+ pull_request:
+ branches: ['dev']
env:
DASHBOARD_PROJECT_ID: ${{ secrets.CY_DASHBOARD_PRJ_ID }}
From 46e23ade4bb56acec4de00a16bb5b421ae875910 Mon Sep 17 00:00:00 2001
From: James Elson
Date: Mon, 6 Jan 2025 13:41:14 -0800
Subject: [PATCH 30/37] Try different redirect to detail page from list page
---
src/nextapp/pages/manager/gateways/list.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx
index 43edcc43e..cd50c39c5 100644
--- a/src/nextapp/pages/manager/gateways/list.tsx
+++ b/src/nextapp/pages/manager/gateways/list.tsx
@@ -120,7 +120,7 @@ const MyGatewaysPage: React.FC = () => {
status: 'success',
isClosable: true,
});
- await router.push('/manager/gateways/detail');
+ window.location.assign('/manager/gateways/detail');
} catch (err) {
toast.closeAll();
toast({
From ed30e1921f9b27d87025e0f759542ef46b4e7faa Mon Sep 17 00:00:00 2001
From: James Elson
Date: Mon, 6 Jan 2025 13:59:08 -0800
Subject: [PATCH 31/37] Revert change
---
src/nextapp/pages/manager/gateways/list.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx
index cd50c39c5..43edcc43e 100644
--- a/src/nextapp/pages/manager/gateways/list.tsx
+++ b/src/nextapp/pages/manager/gateways/list.tsx
@@ -120,7 +120,7 @@ const MyGatewaysPage: React.FC = () => {
status: 'success',
isClosable: true,
});
- window.location.assign('/manager/gateways/detail');
+ await router.push('/manager/gateways/detail');
} catch (err) {
toast.closeAll();
toast({
From 5e8d9c0856b1148c2b1b4c72b3548f45b120e79f Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 7 Jan 2025 08:25:12 -0800
Subject: [PATCH 32/37] update sonar scan action in sonar GHA workflow
---
.github/workflows/ci-feat-sonar.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci-feat-sonar.yaml b/.github/workflows/ci-feat-sonar.yaml
index efcf4a03a..6c2644dec 100644
--- a/.github/workflows/ci-feat-sonar.yaml
+++ b/.github/workflows/ci-feat-sonar.yaml
@@ -42,7 +42,7 @@ jobs:
docker compose down
- name: SonarCloud Scan
- uses: sonarsource/sonarcloud-github-action@master
+ uses: sonarsource/sonarqube-scan-action@master
with:
args: >
-Dsonar.organization=bcgov-oss
From 5fca87fe76ca757e43e1f646543debba05cb31d1 Mon Sep 17 00:00:00 2001
From: ike thecoder
Date: Mon, 13 Jan 2025 11:04:23 -0800
Subject: [PATCH 33/37] fix for click on gateway error (#1217)
* some console log for testing in dev
* wait for finished fetching
* tweak auth context
* Remove unnecessary namespace.isLoading condition
---------
Co-authored-by: Russell Vinegar
---
src/nextapp/pages/devportal/api-directory/your-products.tsx | 2 +-
src/nextapp/pages/manager/gateways/detail.tsx | 2 +-
src/nextapp/shared/services/auth/auth-context.tsx | 3 ++-
src/nextapp/shared/services/auth/use-session.ts | 4 +++-
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/nextapp/pages/devportal/api-directory/your-products.tsx b/src/nextapp/pages/devportal/api-directory/your-products.tsx
index fb19b180f..875a3e09b 100644
--- a/src/nextapp/pages/devportal/api-directory/your-products.tsx
+++ b/src/nextapp/pages/devportal/api-directory/your-products.tsx
@@ -29,7 +29,7 @@ const ApiDiscoveryPage: React.FC = () => {
const hasNamespace = !!user?.namespace;
const title = (
<>
- {(namespace.isFetching || namespace.isLoading) && (
+ {(namespace.isFetching) && (
)}
{namespace.isSuccess && !namespace.isFetching && (
diff --git a/src/nextapp/pages/manager/gateways/detail.tsx b/src/nextapp/pages/manager/gateways/detail.tsx
index b63036fb8..87ea56439 100644
--- a/src/nextapp/pages/manager/gateways/detail.tsx
+++ b/src/nextapp/pages/manager/gateways/detail.tsx
@@ -187,7 +187,7 @@ const NamespacesPage: React.FC = () => {
}, [client, mutate, router, toast, user]);
const title = (
<>
- {(namespace.isFetching || namespace.isLoading) && (
+ {(namespace.isFetching) && (
)}
{namespace.isSuccess && !namespace.isFetching && (
diff --git a/src/nextapp/shared/services/auth/auth-context.tsx b/src/nextapp/shared/services/auth/auth-context.tsx
index d8b6776eb..6d246e030 100644
--- a/src/nextapp/shared/services/auth/auth-context.tsx
+++ b/src/nextapp/shared/services/auth/auth-context.tsx
@@ -10,6 +10,7 @@ import { useSession, UserSessionResult } from './use-session';
const authContext = React.createContext({
isLoading: false,
+ isFetching: false,
ok: false,
maintenance: false,
status: 'idle',
@@ -48,7 +49,7 @@ export const AuthProvider: React.FC = ({ children }) => {
requiresNamespace &&
!session.user.namespace;
- if (noNamespace) {
+ if (noNamespace && session.isFetching == false) {
router?.push('/manager/gateways/list').then(() => {
toast({
title: `First select a Gateway to view that page`,
diff --git a/src/nextapp/shared/services/auth/use-session.ts b/src/nextapp/shared/services/auth/use-session.ts
index 9d6524dae..90a6365e8 100644
--- a/src/nextapp/shared/services/auth/use-session.ts
+++ b/src/nextapp/shared/services/auth/use-session.ts
@@ -8,6 +8,7 @@ export interface AuthFailedResponse {
export interface UserSessionResult {
isLoading: boolean;
+ isFetching: boolean;
ok: boolean;
maintenance: boolean;
user?: UserData;
@@ -64,7 +65,7 @@ export const getSessionL = async (): Promise => {
};
export const useSession = (): UserSessionResult => {
- const { data, status, error, isLoading } = useQuery(
+ const { data, status, error, isLoading, isFetching } = useQuery(
'user',
getSessionL,
{
@@ -75,6 +76,7 @@ export const useSession = (): UserSessionResult => {
return {
isLoading,
+ isFetching,
ok: Boolean(data?.user),
user: data?.user,
maintenance: data?.maintenance,
From 39c30d449608b6c6bb68ddebf2047cba399e7f59 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Tue, 14 Jan 2025 12:49:41 -0800
Subject: [PATCH 34/37] Revert "Avoid socket hangup: enhance Keycloak auth in
group service with retry logic; improve error handling in namespace service
login"
This reverts commit e964a72059722ff5a11c832442a226ff0a0130b1.
---
src/services/keycloak/group-service.ts | 62 ++++++++------------------
src/services/org-groups/namespace.ts | 7 +--
2 files changed, 20 insertions(+), 49 deletions(-)
diff --git a/src/services/keycloak/group-service.ts b/src/services/keycloak/group-service.ts
index d6c23c896..d791d0a24 100644
--- a/src/services/keycloak/group-service.ts
+++ b/src/services/keycloak/group-service.ts
@@ -13,66 +13,43 @@ import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRep
const logger = Logger('kc.group');
export class KeycloakGroupService {
+ private static instanceCount = 0; // Track total instances created
+ private instanceId: string;
+ private createdAt: Date;
private allGroups: any = undefined;
private kcAdminClient: KeycloakAdminClient;
- private clientId: string;
- private clientSecret: string;
- private lastAuthTime: number = 0;
- private readonly AUTH_TIMEOUT = 280 * 1000; // 280 seconds (slightly less than typical 5 min token lifetime)
constructor(issuerUrl: string) {
+ this.instanceId = `kc-group-${++KeycloakGroupService.instanceCount}`;
+ this.createdAt = new Date();
+ logger.info('[Instance Created] id=%s, created=%s', this.instanceId, this.createdAt);
+
const baseUrl = issuerUrl.substr(0, issuerUrl.indexOf('/realms'));
const realmName = issuerUrl.substr(issuerUrl.lastIndexOf('/') + 1);
logger.debug('%s %s', baseUrl, realmName);
this.kcAdminClient = new KcAdminClient({ baseUrl, realmName });
}
- private async ensureAuthenticated(): Promise {
- if (this.clientId && (Date.now() - this.lastAuthTime > this.AUTH_TIMEOUT)) {
- logger.debug('[ensureAuthenticated] Re-authenticating due to timeout');
- await this.login(this.clientId, this.clientSecret);
- }
- }
-
public async cacheGroups() {
this.allGroups = await this.getAllGroups();
}
public async login(
clientId: string,
- clientSecret: string,
- retryAttempts: number = 3
+ clientSecret: string
): Promise {
- this.clientId = clientId;
- this.clientSecret = clientSecret;
-
- const result = await this._login(retryAttempts);
- this.lastAuthTime = Date.now();
- return result;
- }
-
- private async _login(retryAttempts: number): Promise {
- logger.debug('[login] %s', this.clientId);
+ logger.debug('[login] %s', clientId);
- for (let attempt = 1; attempt <= retryAttempts; attempt++) {
- try {
- await this.kcAdminClient
- .auth({
- grantType: 'client_credentials',
- clientId: this.clientId,
- clientSecret: this.clientSecret,
- });
- return this;
- } catch (err: any) {
- if (attempt === retryAttempts) {
- logger.error('[login] Login failed after %d attempts: %s', retryAttempts, err);
- throw err;
- }
- logger.warn('[login] Attempt %d failed, retrying: %s', attempt, err);
- // Add exponential backoff
- await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
- }
- }
+ await this.kcAdminClient
+ .auth({
+ grantType: 'client_credentials',
+ clientId: clientId,
+ clientSecret: clientSecret,
+ })
+ .catch((err: any) => {
+ logger.error('[login] Login failed %s', err);
+ throw err;
+ });
return this;
}
@@ -100,7 +77,6 @@ export class KeycloakGroupService {
}
public async updateGroup(group: GroupRepresentation): Promise {
- await this.ensureAuthenticated();
logger.debug('[updateGroup] %j', group);
await this.kcAdminClient.groups.update({ id: group.id }, group);
}
diff --git a/src/services/org-groups/namespace.ts b/src/services/org-groups/namespace.ts
index 42c26f77a..ef321f51f 100644
--- a/src/services/org-groups/namespace.ts
+++ b/src/services/org-groups/namespace.ts
@@ -13,12 +13,7 @@ export class NamespaceService {
}
async login(clientId: string, clientSecret: string) {
- try {
- await this.groupService.login(clientId, clientSecret);
- } catch (err) {
- logger.error('[login] Failed to login to Keycloak: %s', err);
- throw new Error('Failed to authenticate with Keycloak');
- }
+ await this.groupService.login(clientId, clientSecret);
}
async markNotification(ns: string, viewed: boolean): Promise {
From 5055584a8fdabd68c7ac7151e4ce9607e0064007 Mon Sep 17 00:00:00 2001
From: Elson9
Date: Thu, 16 Jan 2025 09:35:18 -0800
Subject: [PATCH 35/37] Transform dataset contacts to string (#1218)
---
feeds/testdata/dataset.json | 2 +-
src/batch/data-rules.js | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/feeds/testdata/dataset.json b/feeds/testdata/dataset.json
index 21792fc27..9ea415b3f 100644
--- a/feeds/testdata/dataset.json
+++ b/feeds/testdata/dataset.json
@@ -124,7 +124,7 @@
"name": "travel planning"
}
],
- "contacts": "[{\"name\":\"DataBC Operations\",\"email\":\"data@gov.bc.ca\",\"org\":\"d2e433a1-b785-4d03-8a2b-392069175eb4\",\"role\":\"pointOfContact\",\"displayed\":true}]",
+ "contacts": "[{\"name\":\"DataBC Operations\",\"email\":\"data@gov.bc.ca\",\"org\":\"d2e433a1-b785-4d03-8a2b-392069175eb4\",\"role\":\"pointOfContact\",\"displayed\":[\"displayed\"]}]",
"resource_status": "completed",
"tracking_summary": {
"total": 917,
diff --git a/src/batch/data-rules.js b/src/batch/data-rules.js
index 08fc326af..7d91c6274 100644
--- a/src/batch/data-rules.js
+++ b/src/batch/data-rules.js
@@ -62,6 +62,7 @@ const metadata = {
transformations: {
tags: { name: 'toStringDefaultArray' },
resources: { name: 'toStringDefaultArray' },
+ contacts: { name: 'toStringDefaultArray' },
organization: {
name: 'connectOne',
key: 'organization.id',
From b8628d0f88c7f0bbe04868a0d961c1e7eb4d023b Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 24 Jan 2025 16:43:28 -0800
Subject: [PATCH 36/37] Update gateway ID validation error message
---
e2e/cypress/tests/19-api-v3/03-gateways.ts | 2 +-
src/lists/extensions/Namespace.ts | 2 +-
src/services/keycloak/namespace-details.ts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/e2e/cypress/tests/19-api-v3/03-gateways.ts b/e2e/cypress/tests/19-api-v3/03-gateways.ts
index a3620c29a..e0918bdbc 100644
--- a/e2e/cypress/tests/19-api-v3/03-gateways.ts
+++ b/e2e/cypress/tests/19-api-v3/03-gateways.ts
@@ -188,7 +188,7 @@ describe('Gateways', () => {
details: {
d0: {
message:
- 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.',
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start with a letter.',
},
},
}
diff --git a/src/lists/extensions/Namespace.ts b/src/lists/extensions/Namespace.ts
index 773e9d294..48041f554 100644
--- a/src/lists/extensions/Namespace.ts
+++ b/src/lists/extensions/Namespace.ts
@@ -251,7 +251,7 @@ module.exports = {
assert.strictEqual(
re.test(args.namespace),
true,
- 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.'
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start with a letter.'
);
const noauthContext = context.createContext({
skipAccessControl: true,
diff --git a/src/services/keycloak/namespace-details.ts b/src/services/keycloak/namespace-details.ts
index 021248c2e..63adf88b6 100644
--- a/src/services/keycloak/namespace-details.ts
+++ b/src/services/keycloak/namespace-details.ts
@@ -195,7 +195,7 @@ export function validateNamespaceName(name: string) {
regExprValidation(
namespaceValidationRule,
name,
- 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start and end with a letter.'
+ 'Gateway ID must be between 5 and 15 lowercase alpha-numeric characters and start with a letter.'
);
}
From 7fa55adab6cc24114de14eb6b26d27bec9e06076 Mon Sep 17 00:00:00 2001
From: Russell Vinegar
Date: Fri, 24 Jan 2025 16:48:26 -0800
Subject: [PATCH 37/37] remove additional logging in KeycloakGroupService
---
src/services/keycloak/group-service.ts | 7 -------
1 file changed, 7 deletions(-)
diff --git a/src/services/keycloak/group-service.ts b/src/services/keycloak/group-service.ts
index d791d0a24..45a72b7ca 100644
--- a/src/services/keycloak/group-service.ts
+++ b/src/services/keycloak/group-service.ts
@@ -13,17 +13,10 @@ import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRep
const logger = Logger('kc.group');
export class KeycloakGroupService {
- private static instanceCount = 0; // Track total instances created
- private instanceId: string;
- private createdAt: Date;
private allGroups: any = undefined;
private kcAdminClient: KeycloakAdminClient;
constructor(issuerUrl: string) {
- this.instanceId = `kc-group-${++KeycloakGroupService.instanceCount}`;
- this.createdAt = new Date();
- logger.info('[Instance Created] id=%s, created=%s', this.instanceId, this.createdAt);
-
const baseUrl = issuerUrl.substr(0, issuerUrl.indexOf('/realms'));
const realmName = issuerUrl.substr(issuerUrl.lastIndexOf('/') + 1);
logger.debug('%s %s', baseUrl, realmName);